mod_csi_simple: Consider messages encrypted payload as important (fixes part of ...
[prosody.git] / plugins / mod_csi_simple.lua
blobda2dd953bad87d57d18c44a276cf97dbcb7e9003
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 if stanza:get_child("encryption", "urn:xmpp:eme:0") then
80 return true;
81 end
82 return false;
83 end
84 return true;
85 end, -1);
87 module:hook("csi-client-inactive", function (event)
88 local session = event.origin;
89 if session.pump then
90 session.pump:pause();
91 else
92 local bare_jid = jid.join(session.username, session.host);
93 local send = session.send;
94 session._orig_send = send;
95 local pump = new_pump(session.send, queue_size);
96 pump:pause();
97 session.pump = pump;
98 function session.send(stanza)
99 if session.state == "active" or module:fire_event("csi-is-stanza-important", { stanza = stanza, session = session }) then
100 pump:flush();
101 send(stanza);
102 else
103 if st.is_stanza(stanza) and stanza.attr.xmlns == nil and stanza.name ~= "iq" then
104 stanza = st.clone(stanza);
105 stanza:add_direct_child(st.stanza("delay", {xmlns = "urn:xmpp:delay", from = bare_jid, stamp = dt.datetime()}));
107 pump:push(stanza);
109 return true;
112 end);
114 module:hook("csi-client-active", function (event)
115 local session = event.origin;
116 if session.pump then
117 session.pump:resume();
119 end);