Annotate

mod_muc_markers/mod_muc_markers.lua @ 4282:281a864e7472

mod_pubsub_feeds: Don't skip publishing items after an existing one I encountered a feed which was backwards, such that older entries were considered first and then it would skip newer entries. This may however run into trouble if the feed contains more items than what's persisted in pubsub.
author Kim Alvefur <zash@zash.se>
date Mon, 30 Nov 2020 15:17:29 +0100
parent 4071:8e28d0918abc
child 4298:020dd0a59f1f
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");
4065
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
24
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
25 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
26
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
27 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
28
92152437ecfe mod_muc_markers: replace configurable multi-marker tracking with better system
Matthew Wild <mwild1@gmail.com>
parents: 4056
diff changeset
29 -- "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
30 -- 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
31 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
32 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
33 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
34
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 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
36
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 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
38 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
39 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
40 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
41 end
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 return nil;
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 end
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 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
47 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
48
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 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
50 -- 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
51 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
52
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 -- Add stanza id as id attribute
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 stanza.attr.id = archive_id;
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 -- 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
56 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
57 end, -1);
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 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
60 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
61 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
62 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
63 end
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 -- 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
66 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
67 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
68
4025
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
69 end);
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
70
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
71 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
72 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
73
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
74 -- 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
75 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
76 return false
57b4cdeba318 mod_muc_markers: Prevent storage instead of broadcast
Kim Alvefur <zash@zash.se>
parents: 4024
diff changeset
77 end
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 end);
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79
4026
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
80 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
81 -- Find their current nickname
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
82 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
83 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
84 return nick;
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
85 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
86 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
87 -- Or if they're not here
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
88 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
89 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
90 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
91
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
92 -- Synthesize markers
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
93 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
94 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
95 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
96 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
97 if not markers then return end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
98 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
99 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
100 if room_nick then
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
101 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
102 :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
103 room:route_stanza(recv_marker);
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
104 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
105 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
106 end);
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
107 end
e3964f876b5d mod_muc_markers: Broadcast current markers on join
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
108
3972
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 -- Public API
4032
787fc3030087 mod_muc_markers: luacheck annotation
Matthew Wild <mwild1@gmail.com>
parents: 4026
diff changeset
110 --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
111
45c5603a6c07 mod_muc_markers: New module for server-side receipt tracking in MUCs
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 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
113 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
114 end
4056
554f64c8d0c0 mod_muc_markers: Expose is_markable utility function to other modules
Matthew Wild <mwild1@gmail.com>
parents: 4033
diff changeset
115
554f64c8d0c0 mod_muc_markers: Expose is_markable utility function to other modules
Matthew Wild <mwild1@gmail.com>
parents: 4033
diff changeset
116 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
117 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
118 end