diff mod_muc_bot/mod_muc_bot.lua @ 4563:30f2d7c3f946

mod_muc_bot: Attempt at module easing creation of stateless bots
author Kim Alvefur <zash@zash.se>
date Thu, 01 Apr 2021 13:15:05 +0200
parents
children d25f0fea270f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_muc_bot/mod_muc_bot.lua	Thu Apr 01 13:15:05 2021 +0200
@@ -0,0 +1,57 @@
+local st = require "util.stanza";
+local jid = require "util.jid";
+
+local bots = module:get_option_set("known_bots", {});
+
+module:hook("muc-occupant-groupchat", function(event)
+	if event.occupant then return end -- skip messages from actual occupants
+	local room = event.room;
+
+	if bots:contains(jid.bare(event.from)) or bots:contains(jid.host(event.from)) then
+
+		local nick = room:get_registered_nick(jid);
+
+		if not nick then
+			-- Allow bot to specify its own nick, but we're appending '[bot]' to it.
+			-- FIXME HATS!!!
+			nick = event.stanza:get_child_text("nick", "http://jabber.org/protocol/nick");
+			nick = (nick or jid.bare(event.from)) .. "[bot]";
+		end
+
+		local virtual_occupant_jid = jid.prep(room.jid .. "/" .. nick, true);
+		if not virtual_occupant_jid then
+			module:send(st.error_reply(event.stanza, "modify", "jid-malformed", "Nickname must pass strict validation", room.jid));
+			return true;
+		end
+
+		-- Inject virtual occupant to trick all the other hooks on this event that
+		-- this is an actual legitimate participant.
+		-- XXX Hack!
+		event.occupant = {
+			nick = virtual_occupant_jid;
+			bare_jid = jid.bare(event.from);
+			role = "participant";
+		};
+
+	end
+end, 66);
+
+module:hook("muc-occupant-pre-join", function(event)
+	local room = event.room;
+	local nick = jid.resource(event.occupant.nick);
+	if nick:sub(-5, -1) == "[bot]" then
+		event.origin.send(st.error_reply(event.stanza, "modify", "policy-violation", "Only known bots may use the [bot] suffix", room.jid));
+		return true;
+	end
+end, 3);
+
+module:hook("muc-occupant-pre-change", function(event)
+	local room = event.room;
+	local nick = jid.resource(event.dest_occupant.nick);
+	if nick:sub(-5, -1) == "[bot]" then
+		event.origin.send(st.error_reply(event.stanza, "modify", "policy-violation", "Only known bots may use the [bot] suffix", room.jid));
+		return true;
+	end
+end, 3);
+
+assert(string.sub("foo[bot]", -5, -1) == "[bot]", "substring indicies, how do they work?");