plugins/github.lua

1
-- Plugin for querying a Github issue-tracker
2
--
3
-- Example config:
4
-- github = {
5
--   ["project@conference.example.org"] = {
6
--     user = "TheArchitect";
7
--     repo = "TheMatrix";
8
--   }
9
-- }
10
 
11
local url = require"socket.url";
12
local json = require"prosody.util.json";
13
local http = require"prosody.net.http";
14
 
15
function riddim.plugins.github(bot)
16
	local conf = bot.config.github;
17
	local base_url = url.parse("https://api.github.com/repos/x/y/issues/123");
18
	local base_path = url.parse_path(base_url.path);
19
 
20
	local ex = {
21
		headers = {
22
			Accept = "application/vnd.github.v3+json";
23
		};
24
	};
25
 
26
	local function get_issue_url(conf, number)
27
		base_path[2] = conf.user;
28
		base_path[3] = conf.repo or conf.project;
29
		base_path[5] = number;
30
		base_url.path = url.build_path(base_path);
31
		local url = url.build(base_url);
32
		return url;
33
	end
34
 
35
	bot:hook("commands/issue", function (command)
36
		local issue_id = tonumber(command.param);
37
		if not issue_id then return; end
38
		local current_conf = conf[command.room and command.room.jid] or conf;
39
		if not current_conf.user then return end
40
		assert(http.request(get_issue_url(current_conf, issue_id), ex, function (issue, code)
41
			if code > 400 then
42
				return command:reply("HTTP Error "..code.." :(");
43
			end
44
			issue = issue and json.decode(issue);
45
			if not issue then
46
				return command:reply("Got invalid JSON back :(");
47
			end
48
			command:reply(("%s #%d\n%s"):format(issue.title, issue.number, issue.html_url));
49
		end));
50
		return true;
51
	end);
52
 
53
	local function check_for_issue_id(message)
54
		local issue_id = message.body and message.body:match"#(%d+)";
55
		if issue_id then
56
			return bot:event("commands/issue", { param = issue_id, reply = message.reply, });
57
		end
58
	end
59
 
60
	bot:hook("groupchat/joining", function (room)
61
		room:hook("message", check_for_issue_id);
62
	end);
63
end