Comparison

plugins/muc/vcard.lib.lua @ 13657:404d3644ac4a

mod_muc: Integrate support for vcards/avatars on MUC rooms This was previously served by a community module (mod_vcard_muc). It can be disabled by setting `vcard_muc = false` in the config.
author Matthew Wild <mwild1@gmail.com>
date Thu, 06 Feb 2025 17:08:46 +0000
child 13660:31f8fd2bcab9
comparison
equal deleted inserted replaced
13656:4298e6565fec 13657:404d3644ac4a
1 local mod_vcard = module:depends("vcard");
2
3 local jid = require "prosody.util.jid";
4 local st = require "prosody.util.stanza";
5
6 -- This must be the same event that mod_vcard hooks
7 local vcard_event = "iq/bare/vcard-temp:vCard";
8 local advertise_hashes = module:get_option("muc_avatar_advertise_hashes");
9
10 --luacheck: ignore 113/get_room_from_jid
11
12 local function get_avatar_hash(room)
13 if room.avatar_hash then return room.avatar_hash; end
14
15 local room_node = jid.split(room.jid);
16 local hash = mod_vcard.get_avatar_hash(room_node);
17 room.avatar_hash = hash;
18
19 return hash;
20 end
21
22 local function send_avatar_hash(room, to)
23 local hash = get_avatar_hash(room);
24
25 local presence_vcard = st.presence({to = to, from = room.jid})
26 :tag("x", { xmlns = "vcard-temp:x:update" })
27 :tag("photo"):text(hash):up();
28
29 if to == nil then
30 if not advertise_hashes or advertise_hashes == "presence" then
31 room:broadcast_message(presence_vcard);
32 end
33 if not advertise_hashes or advertise_hashes == "message" then
34 room:broadcast_message(st.message({ from = room.jid, type = "groupchat" })
35 :tag("x", { xmlns = "http://jabber.org/protocol/muc#user" })
36 :tag("status", { code = "104" }));
37 end
38
39 else
40 module:send(presence_vcard);
41 end
42 end
43
44 module:hook(vcard_event, function (event)
45 local stanza = event.stanza;
46 local to = stanza.attr.to;
47
48 if stanza.attr.type ~= "set" then
49 return;
50 end
51
52 local room = get_room_from_jid(to);
53 if not room then
54 return;
55 end
56
57 local sender_affiliation = room:get_affiliation(stanza.attr.from);
58 if sender_affiliation == "owner" then
59 event.allow_vcard_modification = true;
60 end
61 end, 10);
62
63 if advertise_hashes ~= "none" then
64 module:hook("muc-occupant-joined", function (event)
65 send_avatar_hash(event.room, event.stanza.attr.from);
66 end);
67 module:hook("vcard-updated", function (event)
68 local room = get_room_from_jid(event.stanza.attr.to);
69 send_avatar_hash(room, nil);
70 end);
71 end
72
73 module:hook("muc-disco#info", function (event)
74 event.reply:tag("feature", { var = "vcard-temp" }):up();
75
76 table.insert(event.form, {
77 name = "muc#roominfo_avatarhash",
78 type = "text-multi",
79 });
80 event.formdata["muc#roominfo_avatarhash"] = get_avatar_hash(event.room);
81 end);