Mon, 21 Dec 2009 19:27:08 +0000
Initial commit, hello world!
0 | 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; |