Mercurial > prosody-modules
changeset 6500:36b9d79e04b7
mod_muc_auto_hats: New module to dynamically assign hats based on config
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Wed, 25 Mar 2026 18:47:51 +0000 |
| parents | 1213145e27fc |
| children | f7158c0e2202 |
| files | mod_muc_auto_hats/README.md mod_muc_auto_hats/mod_muc_auto_hats.lua |
| diffstat | 2 files changed, 86 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_muc_auto_hats/README.md Wed Mar 25 18:47:51 2026 +0000 @@ -0,0 +1,51 @@ +--- +labels: +- 'Stage-Alpha' +summary: 'Dynamically set hats based on configurable policies' +... + +Introduction +============ + +This module lets you dynamically assign hats to MUC occupants based on +configuration rules. + +Currently the only supported rule type is based on the host that the user is +joining from. More rule types may be added in the future. + +Configuration +============= + +Add the module to the MUC host (not the global modules\_enabled): + + +``` {.lua} + Component "conference.example.com" "muc" + modules_enabled = { "muc_auto_hats" } +``` + +Then add configuration rules. + +Hats are identified by URIs, which must be unique (they are not displayed to +the user). If you don't specify one, Prosody will generate a unique one for +you. Each hat also has a human-readable 'title'. Again, Prosody will generate +a default if you don't specify one. + +## By user host + +``` {.lua} +muc_auto_hats_by_host = { + ["anon.example.com"] = { + title = "Web chat"; + }; + ["staff.example.com"] = { + title = "Staff"; + uri = "https://example.com/roles/staff"; + }; +} +``` + +Compatibility +============= + +Requires Prosody 13.0+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_muc_auto_hats/mod_muc_auto_hats.lua Wed Mar 25 18:47:51 2026 +0000 @@ -0,0 +1,35 @@ +local jid = require "prosody.util.jid"; +local sha256 = require "prosody.util.hashes".sha256; +local st = require "prosody.util.stanza"; + +local host_hats = module:get_option("muc_auto_hats_by_host"); + +for hat_host, hat_config in pairs(host_hats) do + if not hat_config.uri then + hat_config.uri = ("xmpp:%s/hats/%s"):format(module.host, sha256(hat_host..","..module.host, true)); + end + if not hat_config.title then + hat_config.title = hat_host; + end +end + +module:hook("muc-build-occupant-presence", function (event) + local pres = event.stanza; + + local bare_jid = event.occupant and event.occupant.bare_jid or event.bare_jid; + local occ_host = jid.host(bare_jid); + + local host_hat = host_hats[occ_host]; + + if not host_hat then + return; + end + + local hats_el = pres:get_child("hats", "urn:xmpp:hats:0"); + if not hats_el then + hats_el = st.stanza("hats", "urn:xmpp:hats:0"); + pres:add_direct_child(hats_el); + end + + hats_el:text_tag("hat", nil, { uri = host_hat.uri, title = host_hat.title }); +end);
