Skip to content

Commit 18f6ddf

Browse files
committed
Add tutorial for MUC Hats
1 parent 373f881 commit 18f6ddf

File tree

2 files changed

+305
-0
lines changed

2 files changed

+305
-0
lines changed

content/tutorials/muc-hats.md

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
# MUC Hats
2+
3+
<!-- md:version improved in [25.xx](../../archive/25.xx/index.md) -->
4+
5+
ejabberd implements support for
6+
[XEP-0317 Hats](https://xmpp.org/extensions/xep-0317.html)
7+
since version 21.12,
8+
as implemented in commit
9+
[5d0e599](https://github.com/processone/ejabberd/commit/5d0e599f1784d7529dcd365ad8c3dd46c1ac85ad).
10+
In ejabberd 25.xx, support has been improved to XEP v0.2.0,
11+
with some minor differences to the examples in the protocol,
12+
which are described here.
13+
14+
## Configuration
15+
16+
To test those examples, let's apply some configuration changes to the default ejabberd configuration file:
17+
18+
```diff
19+
diff --git a/ejabberd.yml.example b/ejabberd.yml.example
20+
index 0964afa06..ae782dde0 100644
21+
--- a/ejabberd.yml.example
22+
+++ b/ejabberd.yml.example
23+
@@ -16,6 +16,7 @@
24+
25+
hosts:
26+
- localhost
27+
+ - example.edu
28+
29+
loglevel: info
30+
31+
@@ -188,6 +189,7 @@ modules:
32+
default: always
33+
mod_mqtt: {}
34+
mod_muc:
35+
+ host: "courses.@HOST@"
36+
access:
37+
- allow
38+
access_admin:
39+
@@ -198,6 +200,8 @@ modules:
40+
- allow
41+
default_room_options:
42+
mam: true
43+
+ enable_hats: true
44+
+ persistent: true
45+
mod_muc_admin: {}
46+
mod_muc_occupantid: {}
47+
mod_offline:
48+
49+
```
50+
51+
## Adding a Hat
52+
53+
When adding a hat as documented in
54+
[3.2 Adding a Hat](https://xmpp.org/extensions/xep-0317.html#add)
55+
there are a few differences:
56+
57+
- the form provided by ejabberd is slightly different to the examples,
58+
consequently the form filling must be updated.
59+
- form submission in example 5 should have in the `command` element `status='completed'`
60+
61+
In summary, the flow is:
62+
63+
### Admin Requests to Add a Hat
64+
65+
Identical to [Example 3](https://xmpp.org/extensions/xep-0317.html#example-3):
66+
67+
```xml
68+
<iq from='professor@example.edu/office'
69+
id='fdi3n2b6'
70+
to='physicsforpoets@courses.example.edu'
71+
type='set'
72+
xml:lang='en'>
73+
<command xmlns='http://jabber.org/protocol/commands'
74+
action='execute'
75+
node='urn:xmpp:hats:commands:don'/>
76+
</iq>
77+
```
78+
79+
### Service Returns Form to Admin
80+
81+
The formulary provided by ejabberd is slightly different than the one in
82+
[Example 4](https://xmpp.org/extensions/xep-0317.html#example-4):
83+
84+
```xml
85+
<iq from='physicsforpoets@courses.example.edu'
86+
id='fdi3n2b6'
87+
to='professor@example.edu/office'
88+
type='result'
89+
xml:lang='end'>
90+
<command xmlns='http://jabber.org/protocol/commands'
91+
node='urn:xmpp:hats:commands:don'
92+
sessionid='2025-02-14T12:23:47.445692Z'
93+
status='executing'>
94+
<actions execute='complete'>
95+
<complete/>
96+
</actions>
97+
<x type='form' xmlns='jabber:x:data'>
98+
<title>Add a hat to a user</title>
99+
<field var='jid'
100+
type='jid-single'
101+
label='Jabber ID'>
102+
<required/>
103+
</field>
104+
<field var='hat_title'
105+
type='text-single'
106+
label='Hat title'/>
107+
<field var='hat_uri'
108+
type='text-single'
109+
label='Hat URI'>
110+
<required/>
111+
</field>
112+
</x>
113+
</command>
114+
</iq>
115+
```
116+
117+
### Admin Submits Form
118+
119+
Compared to [Example 5](https://xmpp.org/extensions/xep-0317.html#example-5),
120+
the `command` element includes `action='complete'`,
121+
and the form fields are different:
122+
123+
```xml
124+
<iq from='professor@example.edu/office'
125+
id='9fens61z'
126+
to='physicsforpoets@courses.example.edu'
127+
type='set'
128+
xml:lang='en'>
129+
<command xmlns='http://jabber.org/protocol/commands'
130+
node='urn:xmpp:hats:commands:don'
131+
action='complete'
132+
sessionid='2025-02-14T12:23:47.445692Z'>
133+
<x xmlns='jabber:x:data' type='submit'>
134+
<field type='hidden' var='FORM_TYPE'>
135+
<value>urn:xmpp:hats:commands</value>
136+
</field>
137+
<field var='jid'>
138+
<value>terry.anderson@example.edu</value>
139+
</field>
140+
<field var='hat_title'>
141+
<value>Teacher Assistant title</value>
142+
</field>
143+
<field var='hat_uri'>
144+
<value>http://tech.example.edu/hats#TeacherAssistant</value>
145+
</field>
146+
</x>
147+
</command>
148+
</iq>
149+
```
150+
151+
### Service Informs Admin of Completion
152+
153+
The result stanza is similar to [Example 6](https://xmpp.org/extensions/xep-0317.html#example-6):
154+
155+
```xml
156+
<iq from='physicsforpoets@courses.example.edu'
157+
id='9fens61z'
158+
to='professor@example.edu/office'
159+
type='result'
160+
xml:lang='en'>
161+
<command status='completed'
162+
sessionid='2025-02-14T12:23:47.445692Z'
163+
node='urn:xmpp:hats:commands:don'
164+
xmlns='http://jabber.org/protocol/commands'/>
165+
</iq>
166+
```
167+
168+
## Listing Hats
169+
170+
It's useful to be able to list the existing room hats,
171+
but the XEP doesn't document that possibility,
172+
so a custom method is implemented in ejabberd:
173+
sending a command query to node `urn:xmpp:hats:commands:dlist`:
174+
175+
### Admin Requests to List Hats
176+
177+
```xml
178+
<iq from='professor@example.edu/office'
179+
id='fdi3n2b6'
180+
to='physicsforpoets@courses.example.edu'
181+
type='set'
182+
xml:lang='en'>
183+
<command xmlns='http://jabber.org/protocol/commands'
184+
action='execute'
185+
node='urn:xmpp:hats:commands:dlist'/>
186+
</iq>
187+
```
188+
189+
### Service Returns List of Hats
190+
191+
```xml
192+
<iq xml:lang='en'
193+
to='professor@example.edu/office'
194+
from='physicsforpoets@courses.example.edu'
195+
type='result'
196+
id='fdi3n2b6'>
197+
<command status='completed'
198+
sessionid='2025-02-14T12:27:33.414328Z'
199+
node='urn:xmpp:hats:commands:dlist'
200+
xmlns='http://jabber.org/protocol/commands'>
201+
<x type='result' xmlns='jabber:x:data'>
202+
<title>List of users with hats</title>
203+
<reported>
204+
<field var='jid' label='Jabber ID'/>
205+
<field var='hat_title' label='Hat title'/>
206+
<field var='hat_uri' label='Hat URI'/>
207+
</reported>
208+
<item>
209+
<field var='jid'>
210+
<value>terry.anderson@example.edu</value>
211+
</field>
212+
<field var='hat_title'>
213+
<value>http://tech.example.edu/hats#TeacherAssistant</value>
214+
</field>
215+
<field var='hat_uri'>
216+
<value>Teacher Assistant title</value>
217+
</field>
218+
</item>
219+
</x>
220+
</command>
221+
</iq>
222+
223+
```
224+
225+
## Including a Hat in Presence
226+
227+
In the previous examples, `professor` added a hat to `terry.anderson`.
228+
Then let's imagine `terry.anderson` joins the room.
229+
Finally, when any client joins the room, for example `steve`,
230+
he receives a stanza like
231+
the one in [Example 1](https://xmpp.org/extensions/xep-0317.html#example-1):
232+
233+
```xml
234+
<presence from='physicsforpoets@courses.example.edu/Terry'
235+
id='34:271777'
236+
to='steve@example.edu/tablet'
237+
xml:lang='es'>
238+
<x xmlns='http://jabber.org/protocol/muc#user'>
239+
<item role='participant' affiliation='none'/>
240+
</x>
241+
<hats xmlns='urn:xmpp:hats:0'>
242+
<hat uri='http://tech.example.edu/hats#TeacherAssistant'
243+
title='Teacher Assistant title'/>
244+
</hats>
245+
<status>status user1</status>
246+
</presence>
247+
```
248+
249+
## Removing a Hat
250+
251+
This works similarly to the examples in
252+
[3.3 Removing a Hat](https://xmpp.org/extensions/xep-0317.html#remove)
253+
254+
### Admin Requests to Remove a Hat
255+
256+
Remember that the form for the hat is different than the one in
257+
[Example 7](https://xmpp.org/extensions/xep-0317.html#example-7).
258+
259+
```xml
260+
<iq from='professor@example.edu/office'
261+
id='9fens61z'
262+
to='physicsforpoets@courses.example.edu'
263+
type='set'
264+
xml:lang='en'>
265+
<command xmlns='http://jabber.org/protocol/commands'
266+
node='urn:xmpp:hats:commands:doff'
267+
action='complete'
268+
sessionid='2025-02-14T12:23:47.445692Z'>
269+
<x xmlns='jabber:x:data' type='submit'>
270+
<field type='hidden' var='FORM_TYPE'>
271+
<value>urn:xmpp:hats:commands</value>
272+
</field>
273+
<field var='jid'>
274+
<value>terry.anderson@example.edu</value>
275+
</field>
276+
<field var='hat_title'>
277+
<value>Teacher Assistant title</value>
278+
</field>
279+
<field var='hat_uri'>
280+
<value>http://tech.example.edu/hats#TeacherAssistant</value>
281+
</field>
282+
</x>
283+
</command>
284+
</iq>
285+
```
286+
287+
### Service Informs Admin of Completion
288+
289+
The response is similar to
290+
[Example 8](https://xmpp.org/extensions/xep-0317.html#example-8):
291+
292+
```xml
293+
<iq from='physicsforpoets@courses.example.edu'
294+
id='9fens61z'
295+
to='professor@example.edu/office'
296+
type='result'
297+
xml:lang='en'>
298+
<command xmlns='http://jabber.org/protocol/commands'
299+
node='urn:xmpp:hats:commands:doff'
300+
sessionid='2025-02-14T12:23:47.445692Z'
301+
status='completed'/>
302+
</iq>
303+
```
304+

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ nav:
234234
- Tutorials: tutorials/index.md
235235
- " MIX tutorial": tutorials/mix-010.md
236236
- " MQTT tutorial": admin/guide/mqtt/index.md
237+
- " MUC Hats": tutorials/muc-hats.md
237238
- " MUC vCards": tutorials/muc-vcard.md
238239
- " MySQL tutorial": tutorials/mysql.md
239240
- Development:

0 commit comments

Comments
 (0)