Skip to content

Commit f6633b0

Browse files
committed
XEP-0317: Hats, Update and complete the protocol
As a client developper the current Hats XEP is far from be usable and feature complete. The goal of those changes is to: - Allow clients to develop a nice UI to manage and assign hats, for example like Discord is doing (see https://support.discord.com/hc/en-us/articles/214836687-Discord-Roles-and-Permissions) - Reconciliate existing implementations and their specificities, see https://docs.ejabberd.im/tutorials/muc-hats/ - Those changes were meant to be backward compatible with the current 0.2.0 version This PR make the following changes: - Specify a urn:xmpp:hats:commands:dcreate command to add a hat to the available list - Specify a urn:xmpp:hats:commands:ddestroy command to destroy a hat from the list - Clarify how the service should broadcast the hat changes when it is edited, assigned, removed or destroyed - Specify a way for an entity to get the complete list of hats using a hash in disco#info - Add a hue optional parameter allowing entities to assign a color to the hat that can be displayed properly in any conditions on the client (as explained in XEP-0392: Consistent Color Generation) - Fix some typos
1 parent a84e713 commit f6633b0

File tree

1 file changed

+249
-30
lines changed

1 file changed

+249
-30
lines changed

xep-0317.xml

Lines changed: 249 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
<shortname>NOT_YET_ASSIGNED</shortname>
2525
&stpeter;
2626
&mwild;
27+
<revision>
28+
<version>0.3.0</version>
29+
<date>2025-04-30</date>
30+
<initials>tj</initials>
31+
<remark><p>Add hat creation and detruction flows; add hue optional parameter; add chatroom presence hats broadcast; complete disco#info; clarify how the service should broadcast updated hats; typos;</p></remark>
32+
</revision>
2733
<revision>
2834
<version>0.2.0</version>
2935
<date>2023-06-28</date>
@@ -55,29 +61,113 @@
5561
</section1>
5662

5763
<section1 topic='Discovery' anchor='disco'>
58-
<p>A MUC service that supports hats MUST advertise a &xep0030; feature of "urn:xmpp:hats:0".</p>
59-
</section1>
64+
<p>A MUC service that supports hats MUST advertise a &xep0030; feature of "urn:xmpp:hats:0" and list the commands available to the requesting entity.</p>
6065

61-
<section1 topic='Protocol' anchor='protocol'>
62-
<section2 topic='Including a Hat in Presence' anchor='presence'>
63-
<p>MUC already includes a way for the room to signal the roles and affiliations of room occupants. Hats are signalled in a similar way. For example, the following presence notification would be sent by the room for an occupant who is a MUC room moderator but who also has a hat of "teacher's assistant" in an online classroom.</p>
64-
<example caption='Presence With Hat'><![CDATA[
65-
<presence
66-
from='[email protected]/Terry'
67-
id='DE5C66DE-EC7D-4ECB-844A-B717A67CCE3D'
68-
to='[email protected]/tablet'>
69-
<x xmlns='http://jabber.org/protocol/muc#user'>
70-
<item affiliation='owner' role='moderator'/>
71-
</x>
72-
<hats xmlns='urn:xmpp:hats:0'>
73-
<hat uri='http://tech.example.edu/hats#TeacherAssistant' title='Teacher&apos;s Assistant' xml:lang='en-us'/>
74-
</hats>
75-
</presence>
66+
<p>If the room has a list of hats configured, it should advertise it in its 'muc#roominfo' extension form by computing a unique hash based on the list of hats URIs provided. The way the hash is computed is leaved to the implementer.</p>
67+
68+
<example caption='User’s client discovers the hat features of a MUC service'><![CDATA[
69+
<iq type='get'
70+
id='p87Ne'
71+
from='[email protected]/garden'
72+
73+
<query xmlns='http://jabber.org/protocol/disco#info'/>
74+
</iq>]]></example>
75+
<example caption='Room advertises hats support'><![CDATA[
76+
<iq type='result'
77+
id='p87Ne'
78+
to='[email protected]/garden'
79+
80+
<query xmlns='http://jabber.org/protocol/disco#info'>
81+
<identity
82+
category='conference'
83+
type='text'
84+
name='Shakespearean Chat Service'/>
85+
<feature var='urn:xmpp:hats:0'/>
86+
<feature var='urn:xmpp:hats:commands:dcreate'/>
87+
<feature var='urn:xmpp:hats:commands:ddestroy'/>
88+
<feature var='urn:xmpp:hats:commands:don'/>
89+
<feature var='urn:xmpp:hats:commands:doff'/>
90+
<x xmlns='jabber:x:data' type='result'>
91+
<field var='FORM_TYPE' type='hidden'>
92+
<value>http://jabber.org/protocol/muc#roominfo</value>
93+
</field>
94+
...
95+
<field var='muc#roominfo_hatshash'
96+
type='text-single'
97+
label='Hats hash'>
98+
<value>d0f8d96ef806c440d4d2bce0bb56244540fd292f</value>
99+
</field>
100+
...
101+
</x>
102+
...
103+
</query>
104+
</iq>]]></example>
105+
106+
<p>If the requesting entity detects that, based on a mismatching hash, the localy stored hats list is considered outdated.</p>
107+
108+
<section2 topic='Listing Hats'>
109+
<p>An entity might be interested to get all the existing hats available in a chatroom.</p>
110+
111+
<example caption='User’s client request the hats list configured on a MUC service'><![CDATA[
112+
<iq from='[email protected]/office'
113+
id='fdi3n2b6'
114+
115+
type='set'
116+
xml:lang='en'>
117+
<command xmlns='http://jabber.org/protocol/commands'
118+
action='execute'
119+
node='urn:xmpp:hats:commands:dlist'/>
120+
</iq>]]></example>
121+
<example caption='Service returns the list of configured hats'><![CDATA[
122+
123+
id='fdi3n2b6'
124+
to='[email protected]/office'
125+
type='result'
126+
xml:lang='en'>
127+
<command xmlns='http://jabber.org/protocol/commands'
128+
node='urn:xmpp:hats:commands:dlist'
129+
status='completed'
130+
sessionid='A971D19A-2226-4DAD-B261-9D0886B9A026'>
131+
<x xmlns='jabber:x:data' type='result'>
132+
<title>Hats List</title>
133+
<reported>
134+
<field var='hat_title'/>
135+
<field var='hat_uri'/>
136+
<field var='hat_hue'/>
137+
</reported>
138+
<item>
139+
<field var='hat_title'>
140+
<value>Host</value>
141+
</field>
142+
<field var='hat_uri'>
143+
<value>http://schemas.example.com/hats#host</value>
144+
</field>
145+
<field var='hat_hue'>
146+
<value>327.255249</value>
147+
</field>
148+
</item>
149+
<item>
150+
<field var='hat_title'>
151+
<value>Presenter</value>
152+
</field>
153+
<field var='hat_uri'>
154+
<value>http://schemas.example.com/hats#presenter</value>
155+
</field>
156+
<field var='hat_hue'>
157+
<value>171.430664</value>
158+
</field>
159+
</item>
160+
161+
</x>
162+
</command>
163+
</iq>
76164
]]></example>
77-
<p>Every hat is uniquely identified by its URI. Hats also carry a human-readable title for display purposes. Within XMPP, a hat is contained within a &lt;hat/> element in the 'urn:xmpp:hats:0' namespace. This element MUST possess a 'uri' attribute (containing the hat's URI), a 'title' attribute containing the name of the hat for display purposes, and MAY contain an 'xml:lang' attribute that identifies the language used in the 'title' attribute. The &lt;hat/> element MAY contain additional custom payloads defined by other XEPs, or payloads specific to an implementation or deployment.</p>
78-
<p>Entities may have multiple hats. The &lt;hats/> element is defined as a container of zero or more &lt;hat/> elements.</p>
165+
</section2>
166+
</section1>
79167

80-
<p>As noted, a participant can wear many hats. The following example shows a participant who is a MUC room owner and both a "host" and a "presenter" in an online meeting system. This system also demonstrates how hats can be annotated with custom information (here, the example &lt;badge/> element).</p>
168+
<section1 topic='Protocol' anchor='protocol'>
169+
<section2 topic='Hats in Presence' anchor='presence'>
170+
<p>MUC already includes a way for the room to signal the roles and affiliations of room occupants. Hats are signalled in a similar way. A participant can wear many hats. The following example shows a participant who is a MUC room owner and both a "host" and a "presenter" in an online meeting system. This system also demonstrates how hats can be annotated with custom information (here, the example &lt;badge/> element).</p>
81171
<example caption='Presence With Multiple Hats'><![CDATA[
82172
<presence
83173
from='[email protected]/Harry'
@@ -87,20 +177,148 @@
87177
<item affiliation='owner' role='moderator'/>
88178
</x>
89179
<hats xmlns='urn:xmpp:hats:0'>
90-
<hat title='Host' uri='http://schemas.example.com/hats#host' xml:lang='en-us'>
91-
<badge xmlns="urn:example:badges" fgcolor="#000000" bgcolor="#58C5BA"/>
180+
<hat title='Host' uri='http://schemas.example.com/hats#host' hue='327.255249' xml:lang='en-us'>
181+
<badge xmlns="urn:example:badges" level="3"/>
92182
</hat>
93-
<hat title='Presenter' uri='http://schemas.example.com/hats#presenter' xml:lang='en-us'>
94-
<badge xmlns="urn:example:badges" fgcolor="#000000" bgcolor="#EC0524"/>
183+
<hat title='Presenter' uri='http://schemas.example.com/hats#presenter' hue='171.430664' xml:lang='en-us'>
184+
<badge xmlns="urn:example:badges" level="5"/>
95185
</hat>
96186
</hats>
97187
</presence>
188+
]]></example>
189+
<p>Every hat is uniquely identified by its URI. Hats also carry a human-readable title for display purposes. Within XMPP, a hat is contained within a &lt;hat/> element in the 'urn:xmpp:hats:0' namespace. This element MUST possess a 'uri' attribute (containing the hat's URI), a 'title' attribute containing the name of the hat for display purposes, MAY contain an 'xml:lang' attribute that identifies the language used in the 'title' attribute and MAY contain a Hue Angle color that define the hat color to apply. The &lt;hat/> element MAY contain additional custom payloads defined by other XEPs, or payloads specific to an implementation or deployment.</p>
190+
<p>Entities may have multiple hats. The &lt;hats/> element is defined as a container of zero or more &lt;hat/> elements.</p>
191+
192+
</section2>
193+
<section2 topic='Creating and Updating a Hat' anchor='create'>
194+
<p>Hats are created and destroyed using &xep0050;.</p>
195+
<p>The following flow shows how to create a hat.</p>
196+
<p>Updating a hat follows the same flow but set an existing "hat_uri". If a hat is updated the service SHOULD rebroadcast the related JID presences with the refreshed hat list.</p>
197+
<example caption='Admin Requests to Create a Hat'><![CDATA[
198+
<iq from='[email protected]/office'
199+
id='gd53a2b6'
200+
201+
type='set'
202+
xml:lang='en'>
203+
<command xmlns='http://jabber.org/protocol/commands'
204+
action='execute'
205+
node='urn:xmpp:hats:commands:dcreate'/>
206+
</iq>
207+
]]></example>
208+
209+
<example caption='Service Returns Form to Admin'><![CDATA[
210+
211+
id='gd53a2b6'
212+
to='[email protected]/office'
213+
type='result'
214+
xml:lang='en'>
215+
<command xmlns='http://jabber.org/protocol/commands'
216+
node='urn:xmpp:hats:commands:dcreate'
217+
sessionid='A971D19A-2226-4DAD-B261-9D0886B9A026'
218+
status='executing'>
219+
<x xmlns='jabber:x:data' type='form'>
220+
<title>Creating a Hat</title>
221+
<instructions>Fill out this form to create a hat.</instructions>
222+
<field type='hidden' var='FORM_TYPE'>
223+
<value>urn:xmpp:hats:commands</value>
224+
</field>
225+
<field var='hat_title'
226+
type='text-single'
227+
label='Hat title'>
228+
<required/>
229+
</field>
230+
<field var='hat_uri'
231+
type='text-single'
232+
label='Hat URI'>
233+
<required/>
234+
</field>
235+
<field var='hat_hue'
236+
type='text-single'
237+
label='Hat Hue'/>
238+
</x>
239+
</command>
240+
</iq>
241+
]]></example>
242+
<example caption='Admin Submits Form'><![CDATA[
243+
<iq from='[email protected]/office'
244+
id='9fets723'
245+
246+
type='set'
247+
xml:lang='en'>
248+
<command xmlns='http://jabber.org/protocol/commands'
249+
node='urn:xmpp:hats:commands:dcreate'
250+
sessionid='A971D19A-2226-4DAD-B261-9D0886B9A026'>
251+
<x xmlns='jabber:x:data' type='submit'>
252+
<field type='hidden' var='FORM_TYPE'>
253+
<value>urn:xmpp:hats:commands</value>
254+
</field>
255+
<field var='hat_title'>
256+
<value>Assistant</value>
257+
</field>
258+
<field var='hat_uri'>
259+
<value>http://tech.example.edu/hats#TeacherAssistant</value>
260+
</field>
261+
<field var='hat_hue'>
262+
<value>327.255249</value>
263+
</field>
264+
</x>
265+
</command>
266+
</iq>
267+
]]></example>
268+
<example caption='Service Informs Admin of Completion'><![CDATA[
269+
270+
id='9fets723'
271+
to='[email protected]/office'
272+
type='result'
273+
xml:lang='en'>
274+
<command xmlns='http://jabber.org/protocol/commands'
275+
node='urn:xmpp:hats:commands:don'
276+
sessionid='A971D19A-2226-4DAD-B261-9D0886B9A026'
277+
status='completed'/>
278+
</iq>
279+
]]></example>
280+
</section2>
281+
<section2 topic='Destroying a Hat' anchor='destroy'>
282+
<p>The following flow shows how to remove a hat.</p>
283+
<p>When a hat is destroyed, it is automatically removed from all the JIDs where it was assigned.</p>
284+
<p>The service SHOULD rebroadcast the related JID presences with the refreshed hats list.</p>
285+
<example caption='Admin Requests to Destroy a Hat'><![CDATA[
286+
<iq from='[email protected]/office'
287+
id='rei4n2b0'
288+
289+
type='set'
290+
xml:lang='en'>
291+
<command xmlns='http://jabber.org/protocol/commands'
292+
action='execute'
293+
node='urn:xmpp:hats:commands:ddestroy'>
294+
<x xmlns='jabber:x:data' type='submit'>
295+
<field type='hidden' var='FORM_TYPE'>
296+
<value>urn:xmpp:hats:commands</value>
297+
</field>
298+
<field var='hat'>
299+
<value>http://tech.example.edu/hats#TeacherAssistant</value>
300+
</field>
301+
</x>
302+
</command>
303+
</iq>
304+
]]></example>
305+
<example caption='Service Informs Admin of Completion'><![CDATA[
306+
307+
id='rei4n2b0'
308+
to='[email protected]/office'
309+
type='result'
310+
xml:lang='en'>
311+
<command xmlns='http://jabber.org/protocol/commands'
312+
node='urn:xmpp:hats:commands:ddestroy'
313+
sessionid='A971D19A-2226-4DAD-B261-7D0886B9A123'
314+
status='completed'/>
315+
</iq>
98316
]]></example>
99317
</section2>
100-
<section2 topic='Adding a Hat' anchor='add'>
101-
<p>Hats are added and removed using &xep0050;.</p>
102-
<p>The following flow shows how to add a hat.</p>
103-
<example caption='Admin Requests to Add a Hat'><![CDATA[
318+
<section2 topic='Assiging a Hat' anchor='add'>
319+
<p>Hats are assigned and removed using &xep0050;.</p>
320+
<p>The following flow shows how to assign a hat.</p>
321+
<example caption='Admin Requests to Assign a Hat'><![CDATA[
104322
<iq from='[email protected]/office'
105323
id='fdi3n2b6'
106324
@@ -183,6 +401,7 @@
183401
</section2>
184402
<section2 topic='Removing a Hat' anchor='remove'>
185403
<p>The following flow shows how to remove a hat.</p>
404+
<p>When the hat is removed service SHOULD rebroadcast the related JID presence with the refreshed hat list.</p>
186405
<example caption='Admin Requests to Remove a Hat'><![CDATA[
187406
<iq from='[email protected]/office'
188407
id='fdi3n2b6'
@@ -200,15 +419,15 @@
200419
<value>[email protected]</value>
201420
</field>
202421
<field var='hat'>
203-
<option label='Teacher&apos;s Assistant'><value>http://tech.example.edu/hats#TeacherAssistant</value></option>
422+
<value>http://tech.example.edu/hats#TeacherAssistant</value>
204423
</field>
205424
</x>
206425
</command>
207426
</iq>
208427
]]></example>
209428
<example caption='Service Informs Admin of Completion'><![CDATA[
210429
211-
id='9fens61z'
430+
id='fdi3n2b6'
212431
to='[email protected]/office'
213432
type='result'
214433
xml:lang='en'>

0 commit comments

Comments
 (0)