annotate mod_muc_markers/mod_muc_markers.lua @ 4300:3f3b672b7616

mod_vcard_muc: Pass room object around instead of JID, hopefully fixing traceback More efficient to pass the object around instead of using the JID and looking up the object when needed. It seems in some (undetermined) cases get_room_from_jid(room.jid) is nil.
author Matthew Wild <mwild1@gmail.com>
date Tue, 15 Dec 2020 10:49:11 +0000
parents 020dd0a59f1f
children 83f89ffe427b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 -- Track messages received by users of the MUC
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 -- We rewrite the 'id' attribute of outgoing stanzas to match the stanza (archive) id
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 -- This module is therefore incompatible with the muc#stable_id feature
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 -- We rewrite the id because XEP-0333 doesn't tell clients explicitly which id to use
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 -- in marker reports. However it implies the 'id' attribute through examples, and this
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 -- is what some clients implement.
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 -- Notably Conversations will ack the origin-id instead. We need to update the XEP to
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 -- clarify the correct behaviour.
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10
4065
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
11 local set = require "util.set";
4026
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
12 local st = require "util.stanza";
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
13
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 local xmlns_markers = "urn:xmpp:chat-markers:0";
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15
4065
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
16 local marker_order = { "received", "displayed", "acknowledged" };
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
17
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
18 -- Add reverse mapping
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
19 for priority, name in ipairs(marker_order) do
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
20 marker_order[name] = priority;
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
21 end
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
22
4024
95882b487ed2 mod_muc_markers: Allow configuration of which marker to track, default to displayed
Matthew Wild <mwild1@gmail.com>
parents: 3972
diff changeset
23 local marker_element_name = module:get_option_string("muc_marker_type", "displayed");
4298
020dd0a59f1f mod_muc_markers: Add option for @id rewriting, default off (may break some clients)
Matthew Wild <mwild1@gmail.com>
parents: 4071
diff changeset
24 local rewrite_id_attribute = module:get_option_boolean("muc_marker_rewrite_id", false);
4065
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
25
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
26 assert(marker_order[marker_element_name], "invalid marker name: "..marker_element_name);
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
27
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
28 local marker_element_names = set.new();
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
29
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
30 -- "displayed" implies "received", etc. so we'll add the
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
31 -- chosen marker and any "higher" ones to the set
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
32 for i = marker_order[marker_element_name], #marker_order do
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
33 marker_element_names:add(marker_order[i]);
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
34 end
4024
95882b487ed2 mod_muc_markers: Allow configuration of which marker to track, default to displayed
Matthew Wild <mwild1@gmail.com>
parents: 3972
diff changeset
35
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 local muc_marker_map_store = module:open_store("muc_markers", "map");
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 local function get_stanza_id(stanza, by_jid)
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 for tag in stanza:childtags("stanza-id", "urn:xmpp:sid:0") do
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 if tag.attr.by == by_jid then
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 return tag.attr.id;
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 end
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 end
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 return nil;
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 end
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 module:hook("muc-broadcast-message", function (event)
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 local stanza = event.stanza;
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 local archive_id = get_stanza_id(stanza, event.room.jid);
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 -- We are not interested in stanzas that didn't get archived
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 if not archive_id then return; end
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53
4298
020dd0a59f1f mod_muc_markers: Add option for @id rewriting, default off (may break some clients)
Matthew Wild <mwild1@gmail.com>
parents: 4071
diff changeset
54 if rewrite_id_attribute then
020dd0a59f1f mod_muc_markers: Add option for @id rewriting, default off (may break some clients)
Matthew Wild <mwild1@gmail.com>
parents: 4071
diff changeset
55 -- Add stanza id as id attribute
020dd0a59f1f mod_muc_markers: Add option for @id rewriting, default off (may break some clients)
Matthew Wild <mwild1@gmail.com>
parents: 4071
diff changeset
56 stanza.attr.id = archive_id;
020dd0a59f1f mod_muc_markers: Add option for @id rewriting, default off (may break some clients)
Matthew Wild <mwild1@gmail.com>
parents: 4071
diff changeset
57 end
020dd0a59f1f mod_muc_markers: Add option for @id rewriting, default off (may break some clients)
Matthew Wild <mwild1@gmail.com>
parents: 4071
diff changeset
58
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 -- Add markable element to request markers from clients
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 stanza:tag("markable", { xmlns = xmlns_markers }):up();
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 end, -1);
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 module:hook("muc-occupant-groupchat", function (event)
4033
7b6bcb91493e mod_muc_markers: Allow tracking multiple markers
Matthew Wild <mwild1@gmail.com>
parents: 4032
diff changeset
64 local marker = event.stanza:child_with_ns(xmlns_markers);
7b6bcb91493e mod_muc_markers: Allow tracking multiple markers
Matthew Wild <mwild1@gmail.com>
parents: 4032
diff changeset
65 if not marker or not marker_element_names:contains(marker.name) then
7b6bcb91493e mod_muc_markers: Allow tracking multiple markers
Matthew Wild <mwild1@gmail.com>
parents: 4032
diff changeset
66 return; -- No marker, or not one we are interested in
7b6bcb91493e mod_muc_markers: Allow tracking multiple markers
Matthew Wild <mwild1@gmail.com>
parents: 4032
diff changeset
67 end
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 -- Store the id that the user has received to
4071
8e28d0918abc mod_muc_markers: Add room JID to log message
Matthew Wild <mwild1@gmail.com>
parents: 4065
diff changeset
70 module:log("warn", "New marker for %s in %s: %s", event.occupant.bare_jid, event.room.jid, marker.attr.id);
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 muc_marker_map_store:set(event.occupant.bare_jid, event.room.jid, marker.attr.id);
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72
4025
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
73 end);
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
74
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
75 module:hook("muc-message-is-historic", function (event)
4065
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
76 local marker = event.stanza:get_child(nil, xmlns_markers)
4025
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
77
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
78 -- Prevent stanza from reaching the archive (it's just noise)
4065
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
79 if marker and marker_element_names:contains(marker.name) then
4025
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
80 return false
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
81 end
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 end);
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83
4026
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
84 local function find_nickname(room, user_jid)
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
85 -- Find their current nickname
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
86 for nick, occupant in pairs(room._occupants) do
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
87 if occupant.bare_jid == user_jid then
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
88 return nick;
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
89 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
90 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
91 -- Or if they're not here
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
92 local nickname = room:get_affiliation_data(user_jid, "reserved_nickname");
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
93 if nickname then return room.jid.."/"..nickname; end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
94 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
95
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
96 -- Synthesize markers
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
97 if muc_marker_map_store.get_all then
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
98 module:hook("muc-occupant-session-new", function (event)
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
99 local room, to = event.room, event.stanza.attr.from;
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
100 local markers = muc_marker_map_store:get_all(room.jid);
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
101 if not markers then return end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
102 for user_jid, id in pairs(markers) do
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
103 local room_nick = find_nickname(room, user_jid);
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
104 if room_nick then
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
105 local recv_marker = st.message({ type = "groupchat", from = room_nick, to = to })
4065
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
106 :tag(marker_element_name, { xmlns = xmlns_markers, id = id });
4026
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
107 room:route_stanza(recv_marker);
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
108 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
109 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
110 end);
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
111 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
112
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 -- Public API
4032
787fc3030087 mod_muc_markers: luacheck annotation
Matthew Wild <mwild1@gmail.com>
parents: 4026
diff changeset
114 --luacheck: ignore 131
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 function get_user_read_marker(user_jid, room_jid)
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 return muc_marker_map_store:get(user_jid, room_jid);
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 end
4056
554f64c8d0c0 mod_muc_markers: Expose is_markable utility function to other modules
Matthew Wild <mwild1@gmail.com>
parents: 4033
diff changeset
119
554f64c8d0c0 mod_muc_markers: Expose is_markable utility function to other modules
Matthew Wild <mwild1@gmail.com>
parents: 4033
diff changeset
120 function is_markable(stanza)
554f64c8d0c0 mod_muc_markers: Expose is_markable utility function to other modules
Matthew Wild <mwild1@gmail.com>
parents: 4033
diff changeset
121 return not not stanza:get_child("markable", xmlns_markers);
554f64c8d0c0 mod_muc_markers: Expose is_markable utility function to other modules
Matthew Wild <mwild1@gmail.com>
parents: 4033
diff changeset
122 end