Mercurial > prosody-modules
annotate mod_sms_free/mod_sms_free.lua @ 5442:7480dde4cd2e
mod_auth_oauth_external: Stub not implemented auth module methods
Not providing some of these may trigger errors on use, which is
something that would be nice to fix on the Prosody side, one day.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 10 May 2023 19:11:25 +0200 |
parents | 5a70dd2349a7 |
children |
rev | line source |
---|---|
3695
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
1 local http = require "net.http"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
2 local jid_split = require "util.jid".split; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
3 local dataforms_new = require "util.dataforms".new; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
4 local adhoc_new = module:require "adhoc".new; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
5 local adhoc_simple_form = require "util.adhoc".new_simple_form; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
6 local t_concat = table.concat; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
7 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
8 local store = module:open_store(); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
9 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
10 local function api_handler(body, code) |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
11 if code == 200 then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
12 module:log("debug", "SMS correctly sent."); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
13 elseif code == 0 then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
14 module:log("error", "error querying Free API: %s", body); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
15 elseif code >= 400 then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
16 module:log("warn", "received error code %d: %s", code, body); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
17 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
18 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
19 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
20 local function message_handler(event) |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
21 local message = event.stanza; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
22 local username, host = jid_split(message.attr.to); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
23 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
24 -- Only proceed if the user has set Free credentials. |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
25 local data = store:get(username); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
26 if not data then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
27 return; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
28 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
29 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
30 -- Only proceed if the message is of type chat or normal. |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
31 local message_type = message.attr.type; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
32 if message_type == "error" or message_type == "headline" or message_type == "groupchat" then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
33 -- TODO: Maybe handle groupchat or headline in the future. |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
34 return; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
35 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
36 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
37 -- Only proceed if the message contains a body. |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
38 local body = message:get_child_text("body"); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
39 if not body then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
40 return; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
41 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
42 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
43 -- Only proceed if all sessions are "xa", or if there are no sessions. |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
44 local sessions = prosody.hosts[host].sessions[username]; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
45 if sessions then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
46 local do_send = true; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
47 for _, session in pairs(sessions.sessions) do |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
48 local show = session.presence:get_child_text("show"); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
49 if show ~= "xa" then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
50 do_send = false; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
51 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
52 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
53 if not do_send then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
54 return; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
55 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
56 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
57 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
58 -- Then do the actual request to send the SMS. |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
59 local headers = { |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
60 user = data.user, |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
61 pass = data.pass, |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
62 msg = http.urlencode(body), |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
63 }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
64 http.request("https://smsapi.free-mobile.fr/sendmsg", { headers = headers }, api_handler); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
65 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
66 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
67 local set_form = dataforms_new { |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
68 title = "Set mobile.free.fr SMS credentials"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
69 instructions = "Enable the “Notifications by SMS” service at https://mobile.free.fr/moncompte/ and paste the credentials in this form."; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
70 { |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
71 type = "hidden"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
72 name = "FORM_TYPE"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
73 value = "http://prosody.im/protocol/sms_free#set"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
74 }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
75 { |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
76 type = "text-single"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
77 name = "user"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
78 label = "Your login on Free’s website"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
79 }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
80 { |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
81 type = "text-single"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
82 name = "pass"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
83 label = "Your authentication key"; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
84 }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
85 }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
86 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
87 local set_adhoc = adhoc_simple_form(set_form, function (data, errors, state) |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
88 if errors then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
89 local errmsg = {}; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
90 for name, text in pairs(errors) do |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
91 errmsg[#errmsg + 1] = name .. ": " .. text; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
92 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
93 return { status = "completed", error = { message = t_concat(errmsg, "\n") } }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
94 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
95 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
96 local username, host = jid_split(state.from); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
97 module:log("debug", "Setting mobile.free.fr credentials for %s@%s: user=%s, pass=%s", username, host, data.user, data.pass); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
98 local ok, err = store:set(username, { user = data.user, pass = data.pass }); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
99 if ok then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
100 return { status = "completed", info = "SMS notifications to your phone enabled." }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
101 else |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
102 return { status = "completed", error = { message = err } }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
103 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
104 end); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
105 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
106 module:provides("adhoc", adhoc_new("Set mobile.free.fr SMS notification credentials", "http://prosody.im/protocol/sms_free#set", set_adhoc)); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
107 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
108 module:provides("adhoc", adhoc_new("Unset mobile.free.fr SMS notifications", "http://prosody.im/protocol/sms_free#unset", function (_, data) |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
109 if data.action ~= "execute" then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
110 return { status = "canceled" }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
111 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
112 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
113 module:log("debug", "Unsetting mobile.free.fr credentials."); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
114 local username, host = jid_split(data.from); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
115 local ok, err = store:set(username, nil); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
116 if ok then |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
117 return { status = "completed", info = "SMS notifications to your phone disabled." }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
118 else |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
119 return { status = "completed", error = { message = err } }; |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
120 end |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
121 end)); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
122 |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
123 -- Stanzas sent to local clients. |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
124 module:hook("message/bare", message_handler); |
5a70dd2349a7
mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
125 module:hook("message/full", message_handler); |