Software /
code /
prosody-modules
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 |
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 |