mod_csi_simple: Consider messages with subject (eg MUC joins) (fixes part of #1250)
[prosody.git] / plugins / mod_csi_simple.lua
blobda6f49134eec8c313e79edfdf696fb3261e85582
1 -- Copyright (C) 2016-2018 Kim Alvefur
2 --
3 -- This project is MIT/X11 licensed. Please see the
4 -- COPYING file in the source package for more information.
5 --
7 module:depends"csi"
9 local jid = require "util.jid";
10 local st = require "util.stanza";
11 local dt = require "util.datetime";
12 local new_queue = require "util.queue".new;
14 local function new_pump(output, ...)
15 -- luacheck: ignore 212/self
16 local q = new_queue(...);
17 local flush = true;
18 function q:pause()
19 flush = false;
20 end
21 function q:resume()
22 flush = true;
23 return q:flush();
24 end
25 local push = q.push;
26 function q:push(item)
27 local ok = push(self, item);
28 if not ok then
29 q:flush();
30 output(item, self);
31 elseif flush then
32 return q:flush();
33 end
34 return true;
35 end
36 function q:flush()
37 local item = self:pop();
38 while item do
39 output(item, self);
40 item = self:pop();
41 end
42 return true;
43 end
44 return q;
45 end
47 local queue_size = module:get_option_number("csi_queue_size", 256);
49 module:hook("csi-is-stanza-important", function (event)
50 local stanza = event.stanza;
51 if not st.is_stanza(stanza) then
52 return true;
53 end
54 local st_name = stanza.name;
55 if not st_name then return false; end
56 local st_type = stanza.attr.type;
57 if st_name == "presence" then
58 if st_type == nil or st_type == "unavailable" then
59 return false;
60 end
61 return true;
62 elseif st_name == "message" then
63 if st_type == "headline" then
64 return false;
65 end
66 if stanza:get_child("sent", "urn:xmpp:carbons:2") then
67 return true;
68 end
69 local forwarded = stanza:find("{urn:xmpp:carbons:2}received/{urn:xmpp:forward:0}/{jabber:client}message");
70 if forwarded then
71 stanza = forwarded;
72 end
73 if stanza:get_child("body") then
74 return true;
75 end
76 if stanza:get_child("subject") then
77 return true;
78 end
79 return false;
80 end
81 return true;
82 end, -1);
84 module:hook("csi-client-inactive", function (event)
85 local session = event.origin;
86 if session.pump then
87 session.pump:pause();
88 else
89 local bare_jid = jid.join(session.username, session.host);
90 local send = session.send;
91 session._orig_send = send;
92 local pump = new_pump(session.send, queue_size);
93 pump:pause();
94 session.pump = pump;
95 function session.send(stanza)
96 if session.state == "active" or module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then
97 pump:flush();
98 send(stanza);
99 else
100 if st.is_stanza(stanza) and stanza.attr.xmlns == nil and stanza.name ~= "iq" then
101 stanza = st.clone(stanza);
102 stanza:add_direct_child(st.stanza("delay", {xmlns = "urn:xmpp:delay", from = bare_jid, stamp = dt.datetime()}));
104 pump:push(stanza);
106 return true;
109 end);
111 module:hook("csi-client-active", function (event)
112 local session = event.origin;
113 if session.pump then
114 session.pump:resume();
116 end);