Mercurial > prosody-modules
annotate mod_pastebin/mod_pastebin.lua @ 6299:5cf5ee23b361
mod_voipms: New Module to send and receive SMS/MMS via VoIP.ms APIs.
diff --git a/mod_voipms/README.md b/mod_voipms/README.md
new file mode 100644
--- /dev/null
+++ b/mod_voipms/README.md
@@ -0,0 +1,51 @@
+---
+labels:
+- 'Stage-Alpha'
+- 'Type-Web'
+summary: Send and receive SMS/MMS via VoIP.ms APIs.
+rockspec:
+ build:
+ modules:
+ mod_voipms: mod_voipms.lua
+...
+
+Introduction
+============
+
+This is a Prosody module to map JIDs to DIDs on VoIP.ms and support sending/receiving SMS/MMS.
+
+Configuration
+=============
+
+| option | type | default |
+|-----------------------|--------|---------|
+| voipms\_api\_username | string | nil |
+| voipms\_api\_password | string | nil |
+| voipms\_query\_key | string | nil |
+| voipms\_jid\_map | table | nil |
+```
+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_jid_map = {
+ ["your_jid@your_domain.com"] = "+1234567890"
+}
+```
+
+HTTP
+====
+
+The module is served on Prosody's default HTTP ports at the path /voipms. More details on configuring HTTP modules in Prosody can be found in the HTTP documentation.
+
+VoIP.ms Webhook URL
+===================
+
+This module receives the VoIP.ms Webhook URL (POST) at the /voipms endpoint. It uses the sendSMS/sendMMS GET methods against the VoIP.ms APIs. This is an example webhook to use in VoIP.ms:
+
+```
+https://sms.example.com/voipms?key=some_query_key
+```
diff --git a/mod_voipms/mod_voipms.lua b/mod_voipms/mod_voipms.lua
new file mode 100644
--- /dev/null
+++ b/mod_voipms/mod_voipms.lua
@@ -0,0 +1,166 @@
+local http = require "net.http"
+local json = require "util.json"
+local st = require "util.stanza"
+
+local api_username = module:get_option_string("voipms_api_username")
+local api_password = module:get_option_string("voipms_api_password")
+local query_key = module:get_option("voipms_query_key")
+local jid_map = module:get_option("voipms_jid_map") or {}
+local rest_endpoint = "https://voip.ms/api/v1/rest.php"
+
+if not api_username or not api_password or not query_key then
+ module:log("error", "Missing required config values (voipms_api_username, voipms_api_password, voipms_query_key)")
+ return
+end
+
+module:depends("http")
+
+local function normalize_number(num)
+ if not num then return nil end
+ if num:sub(1, 1) ~= "+" then
+ return "+1" .. num
+ end
+ return num
+end
+
+local function extract_query_key(event)
+ return (event.request.url.query or ""):match("key=([^&]+)")
+end
+
+module:provides("http", {
+ route = {
+ ["POST"] = function(event)
+ local req = event.request
+ local body = req.body or ""
+
+ if extract_query_key(event) ~= query_key then
+ module:log("warn", "Unauthorized webhook: missing or invalid key")
+ return { status_code = 403 }
+ end
+
+ local json_payload, err = json.decode(body)
+ if not json_payload then
+ module:log("warn", "Invalid JSON: %s", err or "unknown error")
+ return { status_code = 400 }
+ end
+
+ local payload = json_payload.data and json_payload.data.payload
+ if not payload then
+ module:log("warn", "Missing payload in JSON")
+ return { status_code = 400 }
+ end
+
+ local from = payload.from and payload.from.phone_number
+ local to_list = payload.to or {}
+ local to = #to_list > 0 and to_list[1].phone_number or nil
+
+ if not from or not to then
+ module:log("warn", "Missing phone numbers (from: %s, to: %s)", tostring(from), tostring(to))
+ return { status_code = 400 }
+ end
+
+ 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
+ end
+ end
+
+ if not target_jid then
+ module:log("warn", "No JID mapping for DID %s", normalized_to)
+ return { status_code = 404 }
+ end
+
+ local normalized_from = normalize_number(from)
+ local message_text = payload.text or ""
+
+ local message = st.message({
+ from = normalized_from .. "@" .. module.host,
+ to = target_jid,
+ type = "chat"
+ }):tag("body"):text(message_text):up()
+
+ 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()
+ end
+ end
+ end
+
+ module:send(message)
+ module:log("info", "Delivered SMS from %s to %s", normalized_from, target_jid)
+
+ return { status_code = 204 }
+ end
+ }
+})
+
+module:hook("message/bare", function(event)
+ local stanza = event.stanza
+ if stanza.attr.type ~= "chat" then return end
+
+ local from_jid = stanza.attr.from
+ local to_jid = stanza.attr.to
+ 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
+ module:log("warn", "Malformed JID in message.to: %s", to_jid)
+ return
+ end
+
+ to_number = normalize_number(to_number)
+
+ local media_urls = {}
+ for line in body:gmatch("[^\r\n]+") do
+ if line:match("^https?://") then
+ table.insert(media_urls, line)
+ end
+ end
+
+ local method = (#media_urls > 0) and "sendMMS" or "sendSMS"
+ local query = {
+ api_username = api_username,
+ api_password = api_password,
+ method = method,
+ did = from_number,
+ dst = to_number,
+ message = body
+ }
+
+ if method == "sendMMS" then
+ for i, url in ipairs(media_urls) do
+ query["media_url[" .. (i - 1) .. "]"] = url
+ end
+ end
+
+ local query_str = http.formencode(query)
+
+ http.request(rest_endpoint .. "?" .. query_str, {
+ method = "GET";
+ }, function(response_body, code)
+ if code == 200 then
+ local resp, err = json.decode(response_body)
+ 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)
+ end
+ else
+ module:log("error", "HTTP error sending %s: code %s", method, tostring(code))
+ end
+ end)
+end)
| author | Chaz <menel@snikket.de> |
|---|---|
| date | Mon, 21 Jul 2025 23:57:37 +0200 |
| parents | 8aec430ba205 |
| children | ad9026b6a714 |
| rev | line source |
|---|---|
| 5 | 1 |
| 2 local st = require "util.stanza"; | |
|
654
7e444de959bb
mod_pastebin: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents:
565
diff
changeset
|
3 module:depends("http"); |
| 5 | 4 local uuid_new = require "util.uuid".generate; |
|
12
316e8437f233
mod_pastebin: Allow configurable message length threshold
Matthew Wild <mwild1@gmail.com>
parents:
5
diff
changeset
|
5 local os_time = os.time; |
|
3032
0f2dd6397569
mod_pastebin: Remove unused locals [luacheck]
Kim Alvefur <zash@zash.se>
parents:
3031
diff
changeset
|
6 local t_remove = table.remove; |
|
24
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
7 local add_task = require "util.timer".add_task; |
|
2766
314cebb3071e
mod_pastebin: Check for MUC presence before handling a message.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1343
diff
changeset
|
8 local jid_bare = require "util.jid".bare; |
|
3035
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
9 |
|
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
10 local function get_room_from_jid() end; |
|
3027
ce34cbc10b5b
mod_pastebin: Move result of host detection into a variable to improve readabily
Kim Alvefur <zash@zash.se>
parents:
3008
diff
changeset
|
11 local is_component = module:get_host_type() == "component"; |
|
ce34cbc10b5b
mod_pastebin: Move result of host detection into a variable to improve readabily
Kim Alvefur <zash@zash.se>
parents:
3008
diff
changeset
|
12 if is_component then |
|
3035
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
13 local mod_muc = module:depends "muc"; |
|
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
14 local muc_rooms = rawget(mod_muc, "rooms"); |
|
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
15 get_room_from_jid = rawget(mod_muc, "get_room_from_jid") or |
|
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
16 function (jid) |
|
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
17 return muc_rooms[jid]; |
|
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
18 end |
|
3008
26fe44c68791
mod_pastebin: Fix loading on normal hosts (thanks ppmathis)
Kim Alvefur <zash@zash.se>
parents:
2766
diff
changeset
|
19 end |
| 5 | 20 |
|
444
82ccfba5ac2f
mod_pastebin: Support for changing the summary length (pastebin_summary_length), and including it even in the plaintext version of the generated message
Matthew Wild <mwild1@gmail.com>
parents:
438
diff
changeset
|
21 local utf8_pattern = "[\194-\244][\128-\191]*$"; |
|
190
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
22 local function drop_invalid_utf8(seq) |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
23 local start = seq:byte(); |
|
934
15e2c4fd26a0
mod_pastebin: Fix invalid debug statement
Kim Alvefur <zash@zash.se>
parents:
852
diff
changeset
|
24 module:log("debug", "utf8: %d, %d", start, #seq); |
|
190
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
25 if (start <= 223 and #seq < 2) |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
26 or (start >= 224 and start <= 239 and #seq < 3) |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
27 or (start >= 240 and start <= 244 and #seq < 4) |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
28 or (start > 244) then |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
29 return ""; |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
30 end |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
31 return seq; |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
32 end |
|
7a695ee3884b
mod_pastebin: Better fix for stripping truncated UFT-8 sequences
Matthew Wild <mwild1@gmail.com>
parents:
189
diff
changeset
|
33 |
|
501
e851f386c904
mod_pastebin: Threshold is now UTF-8 characters (thanks Grom_PE for initial patch)
Matthew Wild <mwild1@gmail.com>
parents:
454
diff
changeset
|
34 local function utf8_length(str) |
|
e851f386c904
mod_pastebin: Threshold is now UTF-8 characters (thanks Grom_PE for initial patch)
Matthew Wild <mwild1@gmail.com>
parents:
454
diff
changeset
|
35 local _, count = string.gsub(str, "[^\128-\193]", ""); |
|
e851f386c904
mod_pastebin: Threshold is now UTF-8 characters (thanks Grom_PE for initial patch)
Matthew Wild <mwild1@gmail.com>
parents:
454
diff
changeset
|
36 return count; |
|
e851f386c904
mod_pastebin: Threshold is now UTF-8 characters (thanks Grom_PE for initial patch)
Matthew Wild <mwild1@gmail.com>
parents:
454
diff
changeset
|
37 end |
|
e851f386c904
mod_pastebin: Threshold is now UTF-8 characters (thanks Grom_PE for initial patch)
Matthew Wild <mwild1@gmail.com>
parents:
454
diff
changeset
|
38 |
|
3027
ce34cbc10b5b
mod_pastebin: Move result of host detection into a variable to improve readabily
Kim Alvefur <zash@zash.se>
parents:
3008
diff
changeset
|
39 local pastebin_private_messages = module:get_option_boolean("pastebin_private_messages", not is_component); |
|
445
66ca5e4d9f7b
mod_pastebin: Update to use module:get_option()
Matthew Wild <mwild1@gmail.com>
parents:
444
diff
changeset
|
40 local length_threshold = module:get_option_number("pastebin_threshold", 500); |
|
66ca5e4d9f7b
mod_pastebin: Update to use module:get_option()
Matthew Wild <mwild1@gmail.com>
parents:
444
diff
changeset
|
41 local line_threshold = module:get_option_number("pastebin_line_threshold", 4); |
|
446
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
42 local max_summary_length = module:get_option_number("pastebin_summary_length", 150); |
|
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
43 local html_preview = module:get_option_boolean("pastebin_html_preview", true); |
| 5 | 44 |
|
1017
28e3257d2ae5
mod_pastebin: Ensure base URL always has a trailing / (thanks Masin)
Matthew Wild <mwild1@gmail.com>
parents:
934
diff
changeset
|
45 local base_url = module:get_option_string("pastebin_url", module:http_url()):gsub("/$", "").."/"; |
| 5 | 46 |
|
24
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
47 -- Seconds a paste should live for in seconds (config is in hours), default 24 hours |
|
445
66ca5e4d9f7b
mod_pastebin: Update to use module:get_option()
Matthew Wild <mwild1@gmail.com>
parents:
444
diff
changeset
|
48 local expire_after = math.floor(module:get_option_number("pastebin_expire_after", 24) * 3600); |
|
24
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
49 |
|
445
66ca5e4d9f7b
mod_pastebin: Update to use module:get_option()
Matthew Wild <mwild1@gmail.com>
parents:
444
diff
changeset
|
50 local trigger_string = module:get_option_string("pastebin_trigger"); |
|
167
0d37d18ea073
mod_pastebin: Fix trigger_string matching when no trigger is set, and add support for counting lines (pastebin_line_threshold, default: 4)
Matthew Wild <mwild1@gmail.com>
parents:
156
diff
changeset
|
51 trigger_string = (trigger_string and trigger_string .. " "); |
|
156
b51741b7e86d
mod_pastebin: Optionally bin if message starts with a configurable trigger string
Florian Zeitz <florob@babelmonkeys.de>
parents:
76
diff
changeset
|
52 |
| 5 | 53 local pastes = {}; |
| 54 | |
| 55 local xmlns_xhtmlim = "http://jabber.org/protocol/xhtml-im"; | |
| 56 local xmlns_xhtml = "http://www.w3.org/1999/xhtml"; | |
| 57 | |
|
75
3c7189e26848
mod_pastebin: Rename pastebin_message() to pastebin_text() and make it global so it can be called by other plugins
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
58 function pastebin_text(text) |
| 5 | 59 local uuid = uuid_new(); |
|
3140
11087a72990b
mod_pastebin: Remove reference to removed header table
Kim Alvefur <zash@zash.se>
parents:
3139
diff
changeset
|
60 pastes[uuid] = { body = text, time = os_time(), }; |
|
24
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
61 pastes[#pastes+1] = uuid; |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
62 if not pastes[2] then -- No other pastes, give the timer a kick |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
63 add_task(expire_after, expire_pastes); |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
64 end |
| 5 | 65 return base_url..uuid; |
| 66 end | |
| 67 | |
|
654
7e444de959bb
mod_pastebin: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents:
565
diff
changeset
|
68 function handle_request(event, pasteid) |
|
3139
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
69 event.response.headers.content_type = "text/plain; charset=utf-8"; |
|
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
70 |
|
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
71 if not pasteid then |
|
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
72 return "Invalid paste id, perhaps it expired?"; |
| 5 | 73 end |
|
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
1017
diff
changeset
|
74 |
| 5 | 75 --module:log("debug", "Received request, replying: %s", pastes[pasteid].text); |
|
3139
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
76 local paste = pastes[pasteid]; |
|
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
1017
diff
changeset
|
77 |
|
3139
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
78 if not paste then |
|
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
79 return "Invalid paste id, perhaps it expired?"; |
|
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
80 end |
|
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
81 |
|
03cda95ae97a
mod_pastebin: Prevent header table form being mutated
Kim Alvefur <zash@zash.se>
parents:
3099
diff
changeset
|
82 return paste.body; |
| 5 | 83 end |
| 84 | |
|
3028
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
85 local function replace_tag(s, replacement) |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
86 local once = false; |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
87 s:maptags(function (tag) |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
88 if tag.name == replacement.name and tag.attr.xmlns == replacement.attr.xmlns then |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
89 if not once then |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
90 once = true; |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
91 return replacement; |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
92 else |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
93 return nil; |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
94 end |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
95 end |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
96 return tag; |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
97 end); |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
98 if not once then |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
99 s:add_child(replacement); |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
100 end |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
101 end |
|
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
102 |
| 5 | 103 function check_message(data) |
|
3032
0f2dd6397569
mod_pastebin: Remove unused locals [luacheck]
Kim Alvefur <zash@zash.se>
parents:
3031
diff
changeset
|
104 local stanza = data.stanza; |
|
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
1017
diff
changeset
|
105 |
|
2766
314cebb3071e
mod_pastebin: Check for MUC presence before handling a message.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1343
diff
changeset
|
106 -- Only check for MUC presence when loaded on a component. |
|
3027
ce34cbc10b5b
mod_pastebin: Move result of host detection into a variable to improve readabily
Kim Alvefur <zash@zash.se>
parents:
3008
diff
changeset
|
107 if is_component then |
|
3035
60ca0d03f3e3
mod_pastebin: Support the new MUC API in Prosody trunk
Kim Alvefur <zash@zash.se>
parents:
3034
diff
changeset
|
108 local room = get_room_from_jid(jid_bare(stanza.attr.to)); |
|
2766
314cebb3071e
mod_pastebin: Check for MUC presence before handling a message.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1343
diff
changeset
|
109 if not room then return; end |
|
314cebb3071e
mod_pastebin: Check for MUC presence before handling a message.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1343
diff
changeset
|
110 |
|
314cebb3071e
mod_pastebin: Check for MUC presence before handling a message.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1343
diff
changeset
|
111 local nick = room._jid_nick[stanza.attr.from]; |
|
314cebb3071e
mod_pastebin: Check for MUC presence before handling a message.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1343
diff
changeset
|
112 if not nick then return; end |
|
314cebb3071e
mod_pastebin: Check for MUC presence before handling a message.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1343
diff
changeset
|
113 end |
|
314cebb3071e
mod_pastebin: Check for MUC presence before handling a message.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1343
diff
changeset
|
114 |
|
4700
f821eeac0e50
mod_pastebin: Fix pasting when <body> is not the first tag (thanks thorsten)
Kim Alvefur <zash@zash.se>
parents:
3868
diff
changeset
|
115 local body = stanza:get_child_text("body"); |
|
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
1017
diff
changeset
|
116 |
| 5 | 117 if not body then return; end |
|
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
1017
diff
changeset
|
118 |
|
25
ea59a8d98b03
mod_pastebin: Comment some debug logging on every message
Matthew Wild <mwild1@gmail.com>
parents:
24
diff
changeset
|
119 --module:log("debug", "Body(%s) length: %d", type(body), #(body or "")); |
|
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
1017
diff
changeset
|
120 |
|
3030
4a7f08fe793c
mod_pastebin: Remove redundant check for non-empty body since it returns earlier in that case
Kim Alvefur <zash@zash.se>
parents:
3029
diff
changeset
|
121 if ( #body > length_threshold and utf8_length(body) > length_threshold ) or |
|
167
0d37d18ea073
mod_pastebin: Fix trigger_string matching when no trigger is set, and add support for counting lines (pastebin_line_threshold, default: 4)
Matthew Wild <mwild1@gmail.com>
parents:
156
diff
changeset
|
122 (trigger_string and body:find(trigger_string, 1, true) == 1) or |
|
5872
8aec430ba205
mod_pastebin: Back out 040eaa3844f4
Kim Alvefur <zash@zash.se>
parents:
4700
diff
changeset
|
123 (select(2, body:gsub("\n", "%0")) >= line_threshold) |
|
8aec430ba205
mod_pastebin: Back out 040eaa3844f4
Kim Alvefur <zash@zash.se>
parents:
4700
diff
changeset
|
124 then |
|
3029
7878dc2dbf59
mod_pastebin: Avoid using pattern matching facilities for simple prefix removal
Kim Alvefur <zash@zash.se>
parents:
3028
diff
changeset
|
125 if trigger_string and body:sub(1, #trigger_string) == trigger_string then |
|
7878dc2dbf59
mod_pastebin: Avoid using pattern matching facilities for simple prefix removal
Kim Alvefur <zash@zash.se>
parents:
3028
diff
changeset
|
126 body = body:sub(#trigger_string+1); |
|
167
0d37d18ea073
mod_pastebin: Fix trigger_string matching when no trigger is set, and add support for counting lines (pastebin_line_threshold, default: 4)
Matthew Wild <mwild1@gmail.com>
parents:
156
diff
changeset
|
127 end |
|
75
3c7189e26848
mod_pastebin: Rename pastebin_message() to pastebin_text() and make it global so it can be called by other plugins
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
128 local url = pastebin_text(body); |
|
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
1017
diff
changeset
|
129 module:log("debug", "Pasted message as %s", url); |
| 5 | 130 --module:log("debug", " stanza[bodyindex] = %q", tostring( stanza[bodyindex])); |
|
446
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
131 local summary = (body:sub(1, max_summary_length):gsub(utf8_pattern, drop_invalid_utf8) or ""):match("[^\n]+") or ""; |
|
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
132 summary = summary:match("^%s*(.-)%s*$"); |
|
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
133 local summary_prefixed = summary:match("[,:]$"); |
|
3196
01503000d2f1
mod_pastebin: Make first line and URL more clearly separated
Kim Alvefur <zash@zash.se>
parents:
3140
diff
changeset
|
134 replace_tag(stanza, st.stanza("body"):text(summary .. "\n" .. url)); |
|
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
1017
diff
changeset
|
135 |
|
3034
6e9096b66704
mod_pastebin: Add an OOB tag pointing to the pastebin URL
Kim Alvefur <zash@zash.se>
parents:
3033
diff
changeset
|
136 stanza:add_child(st.stanza("query", { xmlns = "jabber:iq:oob" }):tag("url"):text(url)); |
|
6e9096b66704
mod_pastebin: Add an OOB tag pointing to the pastebin URL
Kim Alvefur <zash@zash.se>
parents:
3033
diff
changeset
|
137 |
|
446
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
138 if html_preview then |
|
513
5e8843a869a3
mod_pastebin: Fix off-by-one in line counting (display issue only)
Matthew Wild <mwild1@gmail.com>
parents:
512
diff
changeset
|
139 local line_count = select(2, body:gsub("\n", "%0")) + 1; |
|
446
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
140 local link_text = ("[view %spaste (%d line%s)]"):format(summary_prefixed and "" or "rest of ", line_count, line_count == 1 and "" or "s"); |
|
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
141 local html = st.stanza("html", { xmlns = xmlns_xhtmlim }):tag("body", { xmlns = xmlns_xhtml }); |
|
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
142 html:tag("p"):text(summary.." "):up(); |
|
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
143 html:tag("a", { href = url }):text(link_text):up(); |
|
3028
ded630a87563
mod_pastebin: Replace tags using :maptags API instead of hacky direct manipulation
Kim Alvefur <zash@zash.se>
parents:
3027
diff
changeset
|
144 replace_tag(stanza, html); |
|
446
56f1c29ee7f1
mod_pastebin: Some experimental summary changes
Matthew Wild <mwild1@gmail.com>
parents:
445
diff
changeset
|
145 end |
| 5 | 146 end |
| 147 end | |
| 148 | |
| 149 module:hook("message/bare", check_message); | |
|
438
7f0cdde1e42a
mod_pastebin: Add option 'pastebin_private_messages', defaults to false for components and true for other hosts (thanks Kelden/Maranda)
Matthew Wild <mwild1@gmail.com>
parents:
190
diff
changeset
|
150 if pastebin_private_messages then |
|
7f0cdde1e42a
mod_pastebin: Add option 'pastebin_private_messages', defaults to false for components and true for other hosts (thanks Kelden/Maranda)
Matthew Wild <mwild1@gmail.com>
parents:
190
diff
changeset
|
151 module:hook("message/full", check_message); |
|
7f0cdde1e42a
mod_pastebin: Add option 'pastebin_private_messages', defaults to false for components and true for other hosts (thanks Kelden/Maranda)
Matthew Wild <mwild1@gmail.com>
parents:
190
diff
changeset
|
152 end |
| 5 | 153 |
|
3345
4a12abccdbaf
mod_pastebin: Advertise a disco feature and current thresholds
Kim Alvefur <zash@zash.se>
parents:
3196
diff
changeset
|
154 module:hook("muc-disco#info", function (event) |
|
4a12abccdbaf
mod_pastebin: Advertise a disco feature and current thresholds
Kim Alvefur <zash@zash.se>
parents:
3196
diff
changeset
|
155 local reply, form, formdata = event.reply, event.form, event.formdata; |
|
4a12abccdbaf
mod_pastebin: Advertise a disco feature and current thresholds
Kim Alvefur <zash@zash.se>
parents:
3196
diff
changeset
|
156 reply:tag("feature", { var = "https://modules.prosody.im/mod_pastebin" }):up(); |
|
3868
09e7e880e056
mod_pastebin: Follow XEP-0068 and use Clark notation in disco#info
Kim Alvefur <zash@zash.se>
parents:
3346
diff
changeset
|
157 table.insert(form, { name = "{https://modules.prosody.im/mod_pastebin}max_lines", datatype = "xs:integer" }); |
|
09e7e880e056
mod_pastebin: Follow XEP-0068 and use Clark notation in disco#info
Kim Alvefur <zash@zash.se>
parents:
3346
diff
changeset
|
158 table.insert(form, { name = "{https://modules.prosody.im/mod_pastebin}max_characters", datatype = "xs:integer" }); |
|
09e7e880e056
mod_pastebin: Follow XEP-0068 and use Clark notation in disco#info
Kim Alvefur <zash@zash.se>
parents:
3346
diff
changeset
|
159 formdata["{https://modules.prosody.im/mod_pastebin}max_lines"] = tostring(line_threshold); |
|
09e7e880e056
mod_pastebin: Follow XEP-0068 and use Clark notation in disco#info
Kim Alvefur <zash@zash.se>
parents:
3346
diff
changeset
|
160 formdata["{https://modules.prosody.im/mod_pastebin}max_characters"] = tostring(length_threshold); |
|
3345
4a12abccdbaf
mod_pastebin: Advertise a disco feature and current thresholds
Kim Alvefur <zash@zash.se>
parents:
3196
diff
changeset
|
161 end); |
|
4a12abccdbaf
mod_pastebin: Advertise a disco feature and current thresholds
Kim Alvefur <zash@zash.se>
parents:
3196
diff
changeset
|
162 |
|
24
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
163 function expire_pastes(time) |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
164 time = time or os_time(); -- COMPAT with 0.5 |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
165 if pastes[1] then |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
166 pastes[pastes[1]] = nil; |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
167 t_remove(pastes, 1); |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
168 if pastes[1] then |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
169 return (expire_after - (time - pastes[pastes[1]].time)) + 1; |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
170 end |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
171 end |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
172 end |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
173 |
|
72bcc0475e2f
mod_pastebin: Expire pastes after 'pastebin_expire_after' hours, 24 by default
Matthew Wild <mwild1@gmail.com>
parents:
23
diff
changeset
|
174 |
|
654
7e444de959bb
mod_pastebin: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents:
565
diff
changeset
|
175 module:provides("http", { |
|
7e444de959bb
mod_pastebin: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents:
565
diff
changeset
|
176 route = { |
|
7e444de959bb
mod_pastebin: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents:
565
diff
changeset
|
177 ["GET /*"] = handle_request; |
|
7e444de959bb
mod_pastebin: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents:
565
diff
changeset
|
178 }; |
|
7e444de959bb
mod_pastebin: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents:
565
diff
changeset
|
179 }); |
|
454
3f101f7a26d0
mod_pastebin: Preserve pastes through a reload
Matthew Wild <mwild1@gmail.com>
parents:
446
diff
changeset
|
180 |
|
517
f866325305ed
mod_pastebin: Make last commit work (also set on restore)
Matthew Wild <mwild1@gmail.com>
parents:
516
diff
changeset
|
181 local function set_pastes_metatable() |
|
3033
b2b129f699ed
mod_pastebin: Silence some warnings [luacheck]
Kim Alvefur <zash@zash.se>
parents:
3032
diff
changeset
|
182 -- luacheck: ignore 212/pastes 431/pastes |
|
516
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
183 if expire_after == 0 then |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
184 local dm = require "util.datamanager"; |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
185 setmetatable(pastes, { |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
186 __index = function (pastes, id) |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
187 if type(id) == "string" then |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
188 return dm.load(id, module.host, "pastebin"); |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
189 end |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
190 end; |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
191 __newindex = function (pastes, id, data) |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
192 if type(id) == "string" then |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
193 dm.store(id, module.host, "pastebin", data); |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
194 end |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
195 end; |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
196 }); |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
197 else |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
198 setmetatable(pastes, nil); |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
199 end |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
200 end |
|
3d3687fef751
mod_pastebin: Fix issue with metatable not being set when a reload changes expires_after to 0
Matthew Wild <mwild1@gmail.com>
parents:
514
diff
changeset
|
201 |
|
517
f866325305ed
mod_pastebin: Make last commit work (also set on restore)
Matthew Wild <mwild1@gmail.com>
parents:
516
diff
changeset
|
202 module.load = set_pastes_metatable; |
|
f866325305ed
mod_pastebin: Make last commit work (also set on restore)
Matthew Wild <mwild1@gmail.com>
parents:
516
diff
changeset
|
203 |
|
454
3f101f7a26d0
mod_pastebin: Preserve pastes through a reload
Matthew Wild <mwild1@gmail.com>
parents:
446
diff
changeset
|
204 function module.save() |
|
3f101f7a26d0
mod_pastebin: Preserve pastes through a reload
Matthew Wild <mwild1@gmail.com>
parents:
446
diff
changeset
|
205 return { pastes = pastes }; |
|
3f101f7a26d0
mod_pastebin: Preserve pastes through a reload
Matthew Wild <mwild1@gmail.com>
parents:
446
diff
changeset
|
206 end |
|
3f101f7a26d0
mod_pastebin: Preserve pastes through a reload
Matthew Wild <mwild1@gmail.com>
parents:
446
diff
changeset
|
207 |
|
3f101f7a26d0
mod_pastebin: Preserve pastes through a reload
Matthew Wild <mwild1@gmail.com>
parents:
446
diff
changeset
|
208 function module.restore(data) |
|
3f101f7a26d0
mod_pastebin: Preserve pastes through a reload
Matthew Wild <mwild1@gmail.com>
parents:
446
diff
changeset
|
209 pastes = data.pastes or pastes; |
|
517
f866325305ed
mod_pastebin: Make last commit work (also set on restore)
Matthew Wild <mwild1@gmail.com>
parents:
516
diff
changeset
|
210 set_pastes_metatable(); |
|
454
3f101f7a26d0
mod_pastebin: Preserve pastes through a reload
Matthew Wild <mwild1@gmail.com>
parents:
446
diff
changeset
|
211 end |
