|
1 local verse = require "verse"; |
|
2 local st = require "util.stanza"; |
|
3 |
|
4 module("riddim", package.seeall); |
|
5 plugins = {}; |
|
6 |
|
7 local riddim_mt = {}; |
|
8 riddim_mt.__index = riddim_mt; |
|
9 |
|
10 function new(stream, config) |
|
11 if not stream then |
|
12 error("riddim.new(): Verse stream required as first parameter", 2); |
|
13 end |
|
14 return setmetatable({ stream = stream, config = config or {} }, riddim_mt); |
|
15 end |
|
16 |
|
17 -- self.conn is ready for stanzas |
|
18 function riddim_mt:start() |
|
19 self:add_plugin("groupchat"); |
|
20 self:add_plugin("commands"); |
|
21 self:add_plugin("ping"); |
|
22 self:event("started"); |
|
23 self.stream:hook("stanza", function (stanza) |
|
24 local body = stanza:get_child("body"); |
|
25 local event = { |
|
26 sender = { jid = stanza.attr.from }; |
|
27 body = (body and body:get_text()) or nil; |
|
28 stanza = stanza; |
|
29 }; |
|
30 if stanza.name == "message" then |
|
31 local replied; |
|
32 local bot = self; |
|
33 function event:reply(reply) |
|
34 if replied then return false; end |
|
35 replied = true; |
|
36 return bot:send_message(stanza.attr.from, reply); |
|
37 end |
|
38 end |
|
39 local ret; |
|
40 if stanza.name == "iq" and (stanza.attr.type == "get" or stanza.attr.type == "set") then |
|
41 local xmlns = stanza.tags[1] and stanza.tags[1].attr.xmlns; |
|
42 if xmlns then |
|
43 event.xmlns = xmlns; |
|
44 print(event.stanza) |
|
45 ret = self:event("iq/"..xmlns, event); |
|
46 if not ret then |
|
47 ret = self:event(stanza.name, event); |
|
48 end |
|
49 end |
|
50 else |
|
51 ret = self:event(stanza.name, event); |
|
52 end |
|
53 |
|
54 if ret and type(ret) == "table" and ret.name then |
|
55 self:send(ret); |
|
56 end |
|
57 return ret; |
|
58 end, 1); |
|
59 end |
|
60 |
|
61 function riddim_mt:send(s) |
|
62 return self.stream:send(tostring(s)); |
|
63 end |
|
64 |
|
65 function riddim_mt:event(name, ...) |
|
66 return self.stream:event("bot/"..name, ...); |
|
67 end |
|
68 |
|
69 function riddim_mt:hook(name, ...) |
|
70 return self.stream:hook("bot/"..name, ...); |
|
71 end |
|
72 |
|
73 function riddim_mt:send_message(to, text, formatted_text) |
|
74 self:send(st.message({ to = to, type = "chat" }):tag("body"):text(text)); |
|
75 end |
|
76 |
|
77 function riddim_mt:add_plugin(name) |
|
78 require("riddim.plugins."..name); |
|
79 return riddim.plugins[name](self); |
|
80 end |
|
81 |
|
82 -- Built-in bot starter |
|
83 if not (... and package.loaded[...] ~= nil) then |
|
84 require "verse.client"; |
|
85 |
|
86 -- Config loading |
|
87 local chunk, err = loadfile("config.lua"); |
|
88 if not chunk then |
|
89 print("File or syntax error:", err); |
|
90 return 1; |
|
91 end |
|
92 |
|
93 local config = {}; |
|
94 setfenv(chunk, setmetatable(config, {__index = _G})); |
|
95 local ok, err = pcall(chunk); |
|
96 if not ok then |
|
97 print("Error while processing config:", err); |
|
98 return 1; |
|
99 end |
|
100 setmetatable(config, nil); |
|
101 |
|
102 if not config.jid then |
|
103 io.write("Enter the bot's JID: "); |
|
104 config.jid = io.read("*l"); |
|
105 end |
|
106 |
|
107 if not config.password then |
|
108 io.write("Enter the password for "..config.jid..": "); |
|
109 config.password = io.read("*l"); |
|
110 end |
|
111 |
|
112 -- Create the stream object and bot object |
|
113 local c = verse.new(); |
|
114 local b = riddim.new(c, config); |
|
115 |
|
116 if config.debug then |
|
117 c:hook("incoming-raw", print); |
|
118 end |
|
119 |
|
120 for _, plugin in ipairs(config.plugins or {"ping"}) do |
|
121 c:add_plugin(plugin); |
|
122 end |
|
123 |
|
124 b:hook("started", function () |
|
125 b:send(verse.presence()); |
|
126 for k, v in pairs(autojoin or {}) do |
|
127 if type(k) == "number" then |
|
128 b:join_room(v); |
|
129 elseif type(k) == "string" then |
|
130 if type(v) == "string" then |
|
131 b:join_room(k, v); |
|
132 end |
|
133 end |
|
134 end |
|
135 end); |
|
136 |
|
137 c:hook("binding-success", function () b:start(); end) |
|
138 |
|
139 c:connect_client(config.jid, config.password); |
|
140 |
|
141 verse.loop(); |
|
142 end |
|
143 |
|
144 return _M; |