Moderation delay (#132):

* displaying the remaining time for moderators.
This commit is contained in:
John Livingston
2024-07-10 16:54:54 +02:00
parent 2f98dfa538
commit 9c200a4e46
43 changed files with 1764 additions and 3869 deletions

View File

@ -23,3 +23,22 @@ VirtualHost "muc.example.com"
modules_enabled = { "muc_moderation_delay" }
moderation_delay_form_position = 96
```
## Additional notes
For moderators, messages that are delayed will contain an extra `moderation-delay` xml tag, with `delay` and `waiting` attribute:
```xml
<message xmlns="jabber:client" type="groupchat" id="18821520-e49b-4e59-b6c6-b45cc133905d" to="root@example.com/QH1H89H1" xml:lang="en" from="8df24108-6e70-4fc8-b1cc-f2db7fcdd535@room.example.com/root">
<body>Hello world</body>
<origin-id id="18821520-e49b-4e59-b6c6-b45cc133905d" xmlns="urn:xmpp:sid:0" />
<markable xmlns="urn:xmpp:chat-markers:0" />
<occupant-id id="V5gJudj4Ii3+LnikqUbSSH3NmPKO82zD+m7jRYushVY=" xmlns="urn:xmpp:occupant-id:0" />
<stanza-id xmlns="urn:xmpp:sid:0" id="xkf36aYefSmQ9evPo1m6Neei" by="8df24108-6e70-4fc8-b1cc-f2db7fcdd535@room.example.com" />
<moderation-delay delay="4" waiting="1720177157" />
</message>
```
Note: the `waiting` attribute is the timestamp at which the message will be broadcasted.
So compatible xmpp clients can display some information.

View File

@ -2,11 +2,13 @@
-- SPDX-License-Identifier: AGPL-3.0-only
local st = require "util.stanza";
local timer = require "util.timer";
local get_time = require "util.time".now;
local get_moderation_delay = module:require("config").get_moderation_delay;
local muc_util = module:require "muc/util";
local valid_roles = muc_util.valid_roles;
local moderation_delay_tag = "moderation-delay";
local xmlns_fasten = "urn:xmpp:fasten:0";
local xmlns_moderated_0 = "urn:xmpp:message-moderate:0";
local xmlns_retract_0 = "urn:xmpp:message-retract:0";
@ -96,23 +98,44 @@ local function handle_broadcast_message(event)
-- * the user that sent the message (if they don't get the echo quickly, their clients could have weird behaviours)
module:log("debug", "Message %s / %s must be delayed by %i seconds, sending first broadcast wave.", id, stanza_id, delay);
local moderator_role_value = valid_roles["moderator"];
local cond_func = function (nick, occupant)
local cloned_stanza = st.clone(stanza); -- we must clone, to send a copy for the second wave.
-- first of all, if the initiator occupant is not moderator, me must send to them.
-- (delaying the echo message could have some quircks in some xmpp clients)
if stanza.attr.from then
local from_occupant = room:get_occupant_by_nick(stanza.attr.from);
if from_occupant and valid_roles[from_occupant.role or "none"] < moderator_role_value then
module:log("debug", "Message %s / %s must be sent separatly to it initialior %s.", id, stanza_id, delay, stanza.attr.from);
room:route_to_occupant(from_occupant, stanza);
end
end
-- adding a tag, so that moderators can know that this message is delayed.
stanza:tag(moderation_delay_tag, {
delay = "" .. delay;
waiting = string.format("%i", get_time() + delay);
}):up();
-- then, sending to moderators (and only moderators):
room:broadcast(stanza, function (nick, occupant)
if valid_roles[occupant.role or "none"] >= moderator_role_value then
return true;
end
if nick == stanza.attr.from then
return true;
end
return false;
end;
local cloned_stanza = st.clone(stanza); -- we must clone, to send a copy for the second wave.
room:broadcast(stanza, cond_func);
end);
local task = timer.add_task(delay, function ()
module:log("debug", "Message %s has been delayed, sending to remaining participants.", id);
room:broadcast(cloned_stanza, function (nick, occupant)
return not cond_func(nick, occupant);
if valid_roles[occupant.role or "none"] >= moderator_role_value then
return false;
end
if nick == stanza.attr.from then
-- we already sent it to them (because they are moderator, or because we sent them separately)
return false;
end
return true;
end);
end);
if stanza_id then