Mercurial > prosody-modules
changeset 6300:8689f49d21ef
mod_voipms: Updates
| author | Menel <menel@snikket.de> |
|---|---|
| date | Tue, 22 Jul 2025 06:24:32 +0200 |
| parents | 5cf5ee23b361 |
| children | 77b5dd33a8f3 |
| files | mod_voipms/README.md mod_voipms/mod_voipms.lua |
| diffstat | 2 files changed, 61 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_voipms/README.md Mon Jul 21 23:57:37 2025 +0200 +++ b/mod_voipms/README.md Tue Jul 22 06:24:32 2025 +0200 @@ -17,22 +17,23 @@ Configuration ============= -| option | type | default | -|-----------------------|--------|---------| -| voipms\_api\_username | string | nil | -| voipms\_api\_password | string | nil | -| voipms\_query\_key | string | nil | -| voipms\_jid\_map | table | nil | +| option | type | default | description +|-----------------------|--------|---------|------------| +| voipms\_api\_username | string | nil | E-mail address used at voip.ms +| voipms\_api\_password | string | nil | API password (not login password) +| voipms\_query\_key | string | nil | Key to secure service (part of webhook) +| voipms\_jid\_map | table | nil | JID -> DIDs mapping ``` VirtualHost "sms.example.com" modules_enabled = { "voipms"; } -voipms_api_username = john@example.com -- E-mail registered with VoIP.ms -voipms_api_password = abcd1234 -- API password configured in VoIP.ms -voipms_query_key = some_query_key -- query param 'key' part of your URL callback +voipms_api_username = john@example.com +voipms_api_password = abcd1234 +voipms_query_key = some_query_key voipms_jid_map = { - ["your_jid@your_domain.com"] = "+1234567890" + ["your_jid@your_domain.com"] = { "+1234567890" }, + ["your_jid2@your_domain.com"] = { "+0123456789", "+18573647583" } } ```
--- a/mod_voipms/mod_voipms.lua Mon Jul 21 23:57:37 2025 +0200 +++ b/mod_voipms/mod_voipms.lua Tue Jul 22 06:24:32 2025 +0200 @@ -13,6 +13,13 @@ return end +for jid, dids in pairs(jid_map) do + if type(dids) ~= "table" then + module:log("error", "Invalid voipms_jid_map entry for %s: must be a list of DIDs", jid) + return + end +end + module:depends("http") local function normalize_number(num) @@ -59,14 +66,18 @@ return { status_code = 400 } end + local normalized_from = normalize_number(from) local normalized_to = normalize_number(to) local target_jid = nil - for jid, did in pairs(jid_map) do - if normalize_number(did) == normalized_to then - target_jid = jid - break + for jid, dids in pairs(jid_map) do + for _, did in ipairs(dids) do + if normalize_number(did) == normalized_to then + target_jid = jid + break + end end + if target_jid then break end end if not target_jid then @@ -74,28 +85,39 @@ return { status_code = 404 } end - local normalized_from = normalize_number(from) local message_text = payload.text or "" + local from_jid = normalized_from .. "%" .. normalized_to .. "@" .. module.host - local message = st.message({ - from = normalized_from .. "@" .. module.host, - to = target_jid, - type = "chat" - }):tag("body"):text(message_text):up() + if message_text ~= "" then + local text_message = st.message({ + from = from_jid, + to = target_jid, + type = "chat" + }):tag("body"):text(message_text):up() + + module:send(text_message) + module:log("info", "Delivered text SMS from %s to %s", normalized_from, target_jid) + end if payload.media and #payload.media > 0 then for _, media_item in ipairs(payload.media) do if media_item.url then - message_text = message_text .. "\n" .. media_item.url - message:tag("x", { xmlns = "jabber:x:oob" }) - :tag("url"):text(media_item.url):up():up() + local media_message = st.message({ + from = from_jid, + to = target_jid, + type = "chat" + }) + :tag("body"):text(media_item.url):up() + :tag("x", { xmlns = "jabber:x:oob" }) + :tag("url"):text(media_item.url):up() + :up() + + module:send(media_message) + module:log("info", "Delivered media URL from %s to %s: %s", normalized_from, target_jid, media_item.url) end end end - module:send(message) - module:log("info", "Delivered SMS from %s to %s", normalized_from, target_jid) - return { status_code = 204 } end } @@ -110,19 +132,20 @@ local body = stanza:get_child_text("body") if not body or body == "" then return end - local from_number = jid_map[from_jid] - if not from_number then - module:log("warn", "No DID mapping for JID %s", from_jid) - return - end - - local to_number = to_jid:match("^([^@]+)") - if not to_number then + local to_node = to_jid:match("^(.-)@") + if not to_node then module:log("warn", "Malformed JID in message.to: %s", to_jid) return end - to_number = normalize_number(to_number) + local dst_number, from_number = to_node:match("([^%%]+)%%(.+)") + if not dst_number or not from_number then + module:log("warn", "Malformed to JID node: %s", to_node) + return + end + + dst_number = normalize_number(dst_number) + from_number = normalize_number(from_number) local media_urls = {} for line in body:gmatch("[^\r\n]+") do @@ -137,7 +160,7 @@ api_password = api_password, method = method, did = from_number, - dst = to_number, + dst = dst_number, message = body } @@ -157,7 +180,7 @@ if not resp or resp.status ~= "success" then module:log("error", "Failed to send %s: %s", method, err or (resp and resp.status) or "unknown") else - module:log("info", "Sent %s from %s to %s", method, from_number, to_number) + module:log("info", "Sent %s from %s to %s", method, from_number, dst_number) end else module:log("error", "HTTP error sending %s: code %s", method, tostring(code))
