# Group Chat 3.0
## Motivation
## Glossary
### Group Chat Terminology
* A **Group** is a group chat which allows multiple XMPP entities to exchange `<message/>` stanzas in a multicast-style fashion.
Groups come in subtypes:
- **Public Group**
- **Private Group**
- **Announcement Group**
* An **Owner** is an XMPP entity which has administrative privileges over a *Group*. Note that being an *Owner* does not imply being a *Participant* (and, of course, vice versa).
* A **Participant** is an XMPP entity which is part of a *Group* chat. In contrast to the *participant* in XEP-0045 terms, a participant in GC3 does not neccessarily have to be online or be receiving messages from the **Group** in order to be a participant.
* Each *Participant* is assigned a unique **Participant ID** by the *Group*. The *Participant ID* occurs in the resource part of the **Group**'s JID on stanzas which are relayed on behalf of the *Participant* or on stanzas which directly related to the *Participant* (see the "Common Protocol" section for information on how to distinguish these two cases).
The *Participant ID* may also occur in XEP-0421 `<occupant-id/>` elements, in particular in stanzas sent in the context of the *Compatibility Profile*.
* The **Participant JID** (not to be confused with the *Participant ID*) of a *Participant* is formed by setting the *Participant ID* of that *Participant* as resource part of the *Group*'s JID.
* A **Server** is an XMPP entity hosts zero or more **Group** entities. Typically, a **Server** is identified by a localpart-less domain-only JID.
* A **Session** is established between a resource (in RFC 6122 terms) of a **Participant** and the **Group**. When a session is established, the Group's Server will send live messages to that resource.
### Access Control Terminology
* An **Affiliation** is a machine-readable label. Each *Affiliation* has a set of *Verbs* assigned. An entity which has a given *Affiliation* is allowed to execute actions corresponding to the *Verbs* assigned to the *Affiliation*.
* The **Configured Affiliation** is an optional *Affiliation* label which is assigned to a bare JID (with or without localpart) on a *Group*.
* The **Effective Affiliation** is the *Affiliation* label which is used for access control checks for any given bare JID.
Every bare JID has a (potentially defaulted) *Effective Affiliation* with every *Group*. The *Effective Affiliation* is used for access control checks.
* A **Verb** is a machine-readable identifier for an action an XMPP entity may attempt to execute.
### Additional Terminology for the Compatibility Profile
* A **XEP-0045 Session** is established when a client joins using the XEP-0045 MUC join protocol. *XEP-0045 Sessions* have extra rules associated with them.
* A **XEP-0045 Participant** is a participant which has been created automatically during the establishment of a *XEP-0045 Session* for a bare JID which is not a *Participant*. *XEP-0045 Participants* have extra rules associated with them.
*Participants* may become *XEP-0045 Participants* under certain circumstances and vice versa.
## Requirements
One of the main goals of GC3 is that it is supposed to be an almost seamless upgrade from XEP-0045. In particular the client ecosystem should be able to continue to interoperate with one another.
However, in a distant future or controlled deployments, it may be desirable to cut off compatibility with XEP-0045 to reduce complexity. For this purpose, the requirements are split between two profiles: the **Core** profile describing GC3 functionality and the **Compatibility** profile, which needs to be seen in addition to the *Core* profile.
### Core Profile
The *Core* profile is sufficient for a fully working Group chat implementation. However, without the *Compatibility* profile, interoperability with XEP-0045 implementations is not possible.
The *Core* profile has the following requirements:
-
### Compatibility Profile
The *Compatibility* profile is defined in order to allow existing XEP-0045 implementations to interoperate with GC3 implementations. The ***Compatibility* profile contains all requirements of the *Core* profile, plus the following**:
-
## Access Control
Group Chat 3.0 uses a role-based access control (RBAC) model. In order to stay consistent with other XMPP extensions, we use the term "affiliation" for the role (in RBAC terms) assigned to a bare JID (not necessarily a Participant).
Each affiliation may be assigned zero or more *verbs* it is allowed to execute. The following verbs are defined on Groups in GC3:
| Verb | Description |
| --- | --- |
| `broadcast-message` | Send a message to a Group and broadcast it to all participants |
| `relay-iq` | Have the Group relay an IQ stanza to another Participant |
| `ban` | Change a `member`, `guest`, or `observer` affiliation to `outcast` or `unrelated`. |
| `invite` | Change an `unrelated` affiliation to `observer`, `guest` or `member`, but at most to the affiliation level the user has themselves. |
| `reinstate` | Change an `outcast` affiliation to `unrelated`. |
| `promote-to-guest` | Change an `observer` affiliation to `guest`. |
| `promote-to-member` | Change a `guest` affiliation to `member`. |
| `promote-to-moderator` | Change a `member` affiliation to `moderator`. |
| `promote-to-owner` | Change a `moderator` affiliation to `owner`. |
| `demote-to-moderator` | Change an `owner` affiliation to `moderator`. |
| `demote-to-member` | Change a `moderator` affiliation to `member`. |
| `demote-to-guest` | Change a `member` affiliation to `guest`. |
| `demote-to-observer` | Change a `guest` affiliation to `observer`. |
| `destroy-group` | Destroy a Group |
The following affiliations are defined in GC3:
| Affiliation | Purpose |
| --- | --- |
| `outcast` | The entity has been explicitly removed from the group and may not become a Participant. |
| `unrelated` | The entity is not part of the group and may not become a Participant. |
| `observer` | The entity may become a Participant. They can establish a Session and choose a display name, but they cannot send messages to the Group. |
| `guest` | The entity may become a Participant, may establish a Session and may send messages to a Group. |
| `member` | Similar to `guest`, but with a higher level of trust. How that trust manifests is service-specific. |
| `moderator` | Moderate use of and conversation in the Group, including inviting new and removing unwanted members. Manage basic Group settings, such as the title and description. |
| `owner` | Manage the administrative concerns of the Group, including potentially dissolving or moving it elsewhere. |
Note that `outcast` and `unrelated` are explicitly distinguished. This is to more fine-grainedly restrict who can re-invite previously banned entities.
The default affiliation for a bare JID for which no affiliation is explicitly configured is controlled by the type of group:
| Group type | Default affiliation |
| --- | --- |
| Private | `unrelated` |
| Public | `guest` |
| Announcement | `observer` |
The *default* assignment of verbs to affiliations is described below. Servers SHOULD use these assigments, barring any overriding settings made via future or compatibility protocols (most notably, existing MUC settings to control, for instance, the sending of private messages through Groups may be applied).
<table>
<tr>
<th>Verb \ Affiliation</th>
<th><code>outcast</code></th>
<th><code>observer</code></th>
<th><code>guest</code></th>
<th><code>member</code></th>
<th><code>moderator</code></th>
<th><code>owner</code></th>
</tr>
<tr>
<th><code>request-join</code></th>
<td>yes(1)</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<th><code>join</code></th>
<td>no</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<th><code>broadcast-message</code></th>
<td>no</td>
<td>no</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<th><code>change-own-display-name</code></th>
<td>no</td>
<td>no</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<th><code>relay-iq</code></th>
<td>no</td>
<td>no</td>
<td>no</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<th><code>destroy-group</code></th>
<td>no</td>
<td>no</td>
<td>no</td>
<td>no</td>
<td>no</td>
<td>yes</td>
</tr>
</table>
Footnotes:
1. Requesting a join does not imply that the join is granted. This depends on the `join` verb, and future specifications may gate joining on moderator approval or similar features.
### Calculating the Effective Affiliation of an Entity
The Effective Affiliation MUST be used to determine whether an XMPP entity is allowed to execute a given Verb. The Effective Affiliation for a given bare JID MUST be calculated as follows:
1. If a Configured Affiliation exists for the bare JID, that Affiliation is used.
2. If the bare JID has a localpart and a Configured Affiliation exists for the domain of the bare JID, that Affiliation is used.
3. The default Affiliation of the Group is used.
An important implication is the following: If an entity's Configured Affiliation is explicitly set to an Affiliation equal to the default Affiliation of the Group, it retains this as Effective and Configured Affiliation even if the default Affiliation of the Group changes or if the Configured Affiliation of the domain of that entity is changed.
## Common Core Protocol
Messages sent in the context of GC3 are of `type="groupchat"`.
When a message is caused by or describes an event related to a specific Participant, it contains the `<nick/>` of the Participant and the resource of the Group's JID is set to the Participant ID of the Participant.
Messages without the `<event/>` element are generated by the Participant identified by participant ID in the resource of the sender JID. Such messages have been relayed by the Group and should be treated as such.
Conversely, messages generated by the Group (for example, in response to administrative action) have resource part or have an `<event/>` element.
For events where the affected Participant and the acting entity differ, the acting Participant is referenced inside the `<event/>` in an `<actor/>` element. The `<actor/>` element contains the `<occupant-id>` and current `<nick/>` of the acting entity.
If the event is caused by a non-participant (such as a non-joined Owner), the `<actor/>` element is present, but empty.
If the event refers to the Group itself, the `<nick/>` element is not included as direct child of the `<message/>` and the resource part is empty.
### Error Cases
This protocol defines a few common error cases, which may occur an any kind of response stanza related to GC3. These errors are *always* contained in a normal stanza with `type="error"`, like `<message type="error"/>`, `<presence type="error"/>` or `<iq type="error"/>`, in accordance with RFC 6120.
Note that these error cases may occur in any kind of interaction and are thus not listed explicitly in the error cases in the below protocol specification.
Erros which are caused by `<message/>` or `<presence/>` stanzas without `id` attribute SHOULD be discarded.
#### Not joined
When an interaction which is defined to happen between a Participant and a Group is initiated or attempted by a bare JID which does not belong to any Participant, the Group MUST reply with a `type="auth"` `<forbidden/>` error, with the `<not-joined/>` application-defined condition:
```xml
<error type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<not-joined xmlns="urn:xmpp:gc3:0"/>
</error>
```
If the "Not joined" error case happens when processing XEP-0045 protocol in the context of the Compatibility Profile, services SHOULD instead reply with a `type="cancel"` `<not-acceptable/>` error, in order to stay compatible to XEP-0410.
#### Not enough permissions
When an interaction is not allowed because the sender is not allowed to execute the respective verb (because their affiliation does not have the necessary permissions), the Group MUST reply with a `type="auth"` `<forbidden/>` error, with the `<permission-denied/>` application-defined condition:
```xml
<error type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<permission-denied xmlns="urn:xmpp:gc3:0" verb="broadcast-message"/>
</error>
```
The verb which was denied MUST be included in the `<permission-denied/>` element's `verb` attribute.
If both the "Not enough permissions" and "Not joined" cases apply, the "Not joined" case SHOULD take precedence.
#### Renamed / Moved
If the Group has been renamed or moved to a different address, the old location MUST reply with a `type="modify"` `<redirect/>` error. The `<redirect/>` element MUST contain the new JID of the Group. The `<no-such-group/>` application-defined condition MUST be included.
```xml
<error type="modify">
<redirect xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">other-place@chats.example</redirect>
<no-such-group xmlns="urn:xmpp:gc3:0"/>
</error>
```
This error MUST be returned on all requests related to the Group, **except** for MAM requests, if any messages still remain in the Message Archive of the Group at the old address. If no messages remain, the redirect error MUST be returned (instead of an empty MAM response).
**Note:** The JID in the `<redirect/>` error might again return a `<redirect/>` error. In order to avoid attacks based on infinite redirects, implementations SHOULD limit the number of redirects they follow. Implementations MUST support at least 10 levels of redirects.
Implementations SHOULD also cache this information and MUST invalidate their cache if an entity replies with a `<redirect/>` to an address which would (directly or indirectly) redirect back to that entity (a loop).
#### Destroyed
If the Group has been destroyed permanently without a replacement, the Server MUST reply with a `type="cancel"` `<gone/>` error on behalf of the Group, with the `<no-such-group/>` application-defined condition:
```xml
<error type="cancel">
<gone xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<no-such-group xmlns="urn:xmpp:gc3:0"/>
</error>
```
To clearly distinguish `<gone/>` vs. `<redirect/>`, the `<gone/>` element MUST NOT contain an alternative address. However, future specifications MAY define use cases for a present address. Implementations which unexpectedly receive an address in the `<gone/>` element should assume that this is due to a future protocol extension they do not understand.
Servers SHOULD reply with this error for at least six months after a Group has been destroyed.
<!-- Note: Future protocols may extend this to allow retrieval of MAM by former Participants after destruction for some period. -->
#### Not found
If a Server receives a Group-related request for a JID which does not host a Group and none of the other cases above apply, it MUST reply with a `type="cancel"` `<item-not-found/>` error, with the `<no-such-group/>` application-defined condition:
```xml
<error type="cancel">
<item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<no-such-group xmlns="urn:xmpp:gc3:0"/>
</error>
```
### Discovering Server Support
In order to discover a GC3 implementation, XMPP entities use the XEP-0030 Service Discovery information request protocol.
Servers MUST publish the `urn:xmpp:gc3:0:server` feature. Groups MUST publish the `urn:xmpp:gc3:0:group` feature.
**Note:** An XMPP entity which is a Server MAY, at the same time, be a Group. In that case, it publishes both features.
### Discovering Publicly Listed Groups
To discover publicly listed Groups, XMPP entities send XEP-0030 Service Discovery item requests to the Server with the `urn:xmpp:gc3:0:groups` `node`:
```xml
<iq
to="chats.example"
from="user1@users.example/client-123"
type="get"
id="disco-items-1">
<query xmlns='http://jabber.org/protocol/disco#items'
node='urn:xmpp:gc3:0:groups' />
</iq>
```
GC3 uses a separate node in order to not cause conflicts with XEP-0045 implementations.
#### Success
If the entity is allowed to list publicly listed Groups, the server replies with a disco#items response where each Group is an `<item/>`:
```xml
<iq
to="chats.example"
from="user1@users.example/client-123"
type="get"
id="disco-items-1">
<query xmlns='http://jabber.org/protocol/disco#items'
node='urn:xmpp:gc3:0:groups'>
<item jid='public-group-a@chats.example'
name='The A Group'/>
<!-- .. -->
</query>
</iq>
```
For each Group, the item's `jid` is set to the address of the Group and the `name` is set to the title of the Group.
Servers MUST NOT return Groups in this listing which are not Public and MUST NOT return Groups which are not explicitly publicly listed, even if the requesting entity is allowed to see or owns the respective groups.
### Discovering Permissions on Servers
Each entity may, at any time, discover the permissions it has at a specific Server.
For this, the entity can send an `<get-permissions/>` IQ request:
```xml
<iq to="chats.example"
from="user1@users.example/client-123"
type="get"
id="perms-1">
<get-permissions xmlns="urn:xmpp:gc3:0"/>
</iq>
```
The Server then replies with a listing of the verbs the entity is allowed to execute. The verbs are listed as `<verb/>` elements nested inside a `<permissions/>` element:
```xml
<iq from="user1@users.example/client-123"
to="chats.example"
type="result"
id="perms-1">
<permissions xmlns="urn:xmpp:gc3:0">
<verb>create-group</verb>
</permissions>
</iq>
```
**Note:** Even if a user is banned from the GC3 services, this IQ request SHOULD return a `result` (instead of an `error`), with an empty `<permissions/>` element. However, implementations MAY choose to return some kind of permission error.
### Discovering Permissions on Groups
Each entity may, at any time, discover the permissions it has within a specific Group.
For this, the entity can send an `<get-permissions/>` IQ request to the Group:
```xml
<iq to="group@chats.example"
from="user1@users.example/client-123"
type="get"
id="perms-2">
<get-permissions xmlns="urn:xmpp:gc3:0"/>
</iq>
```
The Server then replies with a listing of the verbs the entity is allowed to execute. The verbs are listed as `<verb/>` elements nested inside a `<permissions/>` element:
```xml
<iq from="user1@users.example/client-123"
to="group@chats.example"
type="result"
id="perms-2">
<permissions xmlns="urn:xmpp:gc3:0">
<verb>destroy-group</verb>
<verb>read-messages</verb>
<!-- .. -->
</permissions>
</iq>
```
**Note:** Even if a user is banned from a Group, this IQ request SHOULD return a `result` (instead of an `error`), with an empty `<permissions/>` element. However, implementations MAY choose to return some kind of permission error.
## Core Protocol: Participants
### Request to Join a Group
Verb: `request-join`
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
type="set"
id="join-1">
<join xmlns="urn:xmpp:gc3:0">
<nick xmlns='http://jabber.org/protocol/nick'>Yours Truly</nick>
</join>
</iq>
```
#### Success
When a Participant successfully joins a Group, the Group replies with the an IQ with a `<joined/>` payload.
The `<joined/>` element contains information about the new Participant:
- Their occupant ID
- The confirmed nickname
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
type="result"
id="join-1">
<joined xmlns="urn:xmpp:gc3:0">
<nick xmlns='http://jabber.org/protocol/nick'>Yours Truly</nick>
<occupant-id xmlns="urn:xmpp:occupant-id:0" id="45ae790b-41d8-494a-8b2a-192a602c5416"/>
</joined>
</iq>
```
The `id` of the `<occupant-id/>` element contains the Participant's *Participant ID*, which permanently identifies the Participant.
Finally, the Group broadcasts a message to all currently established Sessions. This message contains a `<event type="joined"/>` element as well as the new Participant's display name and occupant ID. In addition, it contains the Stanza ID under which this message can be retrieved from the Group's archive. The stanza is sent from the Participant's *Participant JID*.
```xml
<message
to="group@chats.example/45ae790b-41d8-494a-8b2a-192a602c5416"
from="user2@users.example/other-client"
type="result">
<event xmlns="urn:xmpp:gc3:0" type="joined"/>
<nick xmlns='http://jabber.org/protocol/nick'>Scrooge</nick>
<stanza-id by="group@chats.example" id="495e62fd-4013-4e62-8cc0-4cd045797c41" />
</message>
<!-- .. -->
```
**Note:** All these stanzas MUST be emitted in a single "transaction". In particular, it MUST NOT be possible for a Participant to receive its own join `<message/>` establishing a Session in parallel to joining the room.
#### Error Case: Group policy requires approval
A Group may have a policy that joins are not automatically allowed by the server. In that case, an error of type `wait` is returned:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
type="error"
id="join-1">
<error type="wait">
<policy-violation xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<approval-required xmlns='urn:xmpp:gc3:0'/>
</error>
</iq>
```
The remainder of the protocol for approval of join requests is not yet defined and may be part of a future XEP.
#### Error case: Display name rejected
See the error cases in the "Change display name" section.
### Establish a Session
Verb: `read-messages`
In order to receive live messages, a Participant sends `<presence/>` to a Group:
```xml
<presence
to="group@chats.example"
from="user1@users.example/client-123"
id="session-1"/>
```
The Group then queries the client's XEP-0030 Service Discovery information to confirm it supports GC3:
```xml
<iq
to="user1@users.example/client-123"
from="group@chats.example"
id="info-1"
type="get">
<query xmlns="http://jabber.org/protocol/disco#info"/>
</iq>
```
The client then replies with its disco#info response:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
id="info-1"
type="result">
<query xmlns="http://jabber.org/protocol/disco#info">
<!-- ... -->
<feature var="urn:xmpp:gc3:0"/>
<!-- ... -->
</query>
</iq>
```
If the server detects the `urn:xmpp:gc3:0` feature var, it can safely assume that the client intended to establish a session.
**Implementation note:** A Group MAY optimize this query using the mechanisms described in XEP-0115, XEP-0390 or similar mechanisms, so clients MUST NOT rely on the disco#info request actually arriving.
#### Success
If successful, the resource from which the presence stanza originated now has a Session with the Group and will receive live messages. As confirmation, the Group replies with a `<presence/>` stanza sent from the participant JID of the participant:
```xml
<presence
to="user1@users.example/client-123"
from="group@chats.example/45ae790b-41d8-494a-8b2a-192a602c5416"
id="session-1"/>
```
If the Group already has a Session with the given resource, it SHOULD treat this request as if it had been preceded by session teardown.
### Send a Message to a Group
Verb: `broadcast-message`
To send a message to a group, a Participant sends a `<message/>` stanza to the Group's address:
```xml
<message
to="group@chats.example"
from="user1@users.example/client-123"
type="groupchat"
id="msg-1">
<body>Hello World!</body>
</message>
```
#### Success
In the successful case, the Group broadcasts the message to all Participants' Sessions, including the Session of the original sender (if any).
Before broadcasting the message, the Server modifies the message stanza in the following way:
- The @from MUST be replaced with the sending Participant's *Participant JID*.
- The @to MUST be set to the full JID of the recipients session.
- A XEP-0359 Stanza ID MUST be added to the message. The assigned ID MUST be usable to retrieve the message from the Group's XEP-0313 Message Archive. If the sender supplied a `<stanza-id/>` element in their message with a `by` attribute matching the Group's address, the message MUST be rejected (see error cases below).
- A XEP-0172 Nickname element MUST be added to the message, containing the nickname of the sender. If the sender supplied a `<nick/>` element in their message, the message MUST be rejected (see error cases below).
However, the server MUST NOT change the `id` of the message stanza.
```xml
<message
from="group@chats.example/45ae790b-41d8-494a-8b2a-192a602c5416"
to="user2@users.example/other-client"
type="groupchat"
id="msg-1">
<body>Hello World!</body>
<nick xmlns='http://jabber.org/protocol/nick'>Yours Truly</nick>
<stanza-id
xmlns='urn:xmpp:sid:0'
by='group@chats.example'
id='66e5eb58-c746-443e-8336-28ab46180d75'/>
</message>
<!-- ... -->
<message
from="group@chats.example/45ae790b-41d8-494a-8b2a-192a602c5416"
to="user1@users.example/client-123"
type="groupchat"
id="msg-1">
<body>Hello World!</body>
<nick xmlns='http://jabber.org/protocol/nick'>Yours Truly</nick>
<occupant-id xmlns="urn:xmpp:occupant-id:0" id="45ae790b-41d8-494a-8b2a-192a602c5416" />
<stanza-id
xmlns='urn:xmpp:sid:0'
by='group@chats.example'
id='66e5eb58-c746-443e-8336-28ab46180d75'/>
</message>
```
**Note:** A Session is *not* a requirement in order to be able to send messages to the Group. Any Participant's resource may send messages to the Group at any time, even if they currently do not have a Session established to receive live messages.
#### Error case: Forbidden contents
If the sender includes contents which are not allowed in general, the server MUST reply with a `<not-acceptable/>` error:
```xml
<message
from="group@chats.example"
to="user1@users.example/client-123"
type="error"
id="msg-1">
<error type="modify">
<not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</message>
```
This error MUST be returned whenever the sender includes data in the `<message/>` which would attempt to impersonate the Group or another Participant, for example a stray `<nick/>`, `<stanza-id/>` (with `by` matching the Group's address), `<occupant-id/>` or `<event/>` element.
**Note:** The `<occupant-id/>` element is forbidden in relayed stanzas, even though it is not used in the protocol in that position. This is to avoid confusion.
#### Error case: Not enough permissions
If the Sender's bare JID is a Participant, but lacks the necessary permissions to broadcast to the Group, the Server MUST return a `type="auth"` `<forbidden/>` error, with the `<permission-denied/>` application-defined condition:
```xml
<message
from="group@chats.example"
to="user1@users.example/client-123"
type="error"
id="msg-1">
<error type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<permission-denied xmlns="urn:xmpp:gc3:0"/>
</error>
</message>
```
Future specifications MAY extend the `<permission-denied/>` element with properly namespaced children which further detail the reason for the rejection of the message.
Note that the decision whether a message is allowed to be sent MAY depend on the structural contents of the message. For example, an Announcement Group might allow XEP-0444 Reaction payloads, but not ordinary messages with a `<body/>`.
However, the `<permission-denied/>` application defined condition MUST NOT be used in cases where the sementic contents of a message lead to a rejection, for example if a badword filter rejected the contents of the `<body/>`. This also applies to future extensions of the protocol.
### Change display name
Verb: `change-own-display-name`
To change the display name within the Group, a Participant sends a `type="set"` IQ request to the Group with the `<nick/>` element as only child:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
id="nick-1"
type="set">
<nick xmlns='http://jabber.org/protocol/nick'>Scrooge</nick>
</iq>
```
#### Success
If the change is successful, the Group broadcasts a message to all Sessions (including the Session of the resource which requested the nick change, if such a Session exists):
```xml
<message
to="user1@users.example/client-123"
from="group@chats.example/45ae790b-41d8-494a-8b2a-192a602c5416"
type="groupchat">
<event xmlns="urn:xmpp:gc3:0" type="display-name-changed"/>
<nick xmlns='http://jabber.org/protocol/nick'>Scrooge</nick>
<stanza-id by="group@chats.example" id="495e62fd-4013-4e62-8cc0-4cd045797c41" />
</message>
```
**Note:** The message announcing the nickname change is archived into the Group's XEP-0313 Message Archive and thus has a Stanza ID.
**Note:** Groups may apply normalization or other non-destructive modifications to the display name. Clients SHOULD thus use the display name included in the IQ reply or the announcement message, respectively, instead of their own record of what the user set as display name.
And then sends the IQ response with the display name as payload:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
id="nick-1"
type="result">
<nick xmlns='http://jabber.org/protocol/nick'>Scrooge</nick>
</iq>
```
#### Error case: Display name not compatible
If the display name cannot be used because of technical constraints, for example because the Group is bridged to another network with more restrictive rules, the Group MUST reject the request with a `type="modify"` `<not-acceptable/>` error:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
id="nick-1"
type="error">
<error type="modify">
<not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
```
**Note:** This error MUST also be returned in reply to a join request with an unacceptable display name.
#### Error case: Display name violates Group policy
If the Group or Server has rules (such as badword filters) which constrain the choice of display name and a Participant attempts to set a display name which violates these rules, the Group MUST return a `type="modify"` `<policy-violation/>` error:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
id="nick-1"
type="error">
<error type="modify">
<policy-violation xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
```
**Note:** This error MUST also be returned in reply to a join request with an unacceptable display name.
**Note:** This error condition MUST NOT be used for cases where the restriction on the display name originates from technical compatibility reasons. For that, the `<not-acceptable/>` error condition MUST be used, as described above.
#### Error case: Display name already in use
If the requested display name is already in use by another participant, the Group MUST return a `type="modify"` `<conflict/>` error:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
id="nick-1"
type="error">
<error type="modify">
<conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
```
**Note:** This error MUST also be returned in reply to a join request with an already-in-use display name.
**Note:** Servers MAY choose to use fuzzy comparison methods (such as PRECIS or Stringprep profiles) to determine whether a display name is identical to another display name.
### Send an IQ request to another participant
Verb: `relay-iq`
To send an IQ stanza to Participant B, Participant A sends a stanza to Participant B's Participant JID. For example, to request the XEP-0084 Avatar of another Participant:
```xml
<iq
to="group@chats.example/c9978c7e-9dca-4c70-808c-9ea07d4ee646"
from="user1@users.example/client-123"
type="get"
id='avatar-1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<items node='urn:xmpp:avatar:data'/>
</pubsub>
</iq>
```
#### Success
If the Group allows mediation of IQ requests, it forwards the IQ request to the **bare JID** of the target Participant:
```xml
<iq
to="user2@users.example"
from="group@chats.example/45ae790b-41d8-494a-8b2a-192a602c5416"
type="get"
id='group-generated-id'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<items node='urn:xmpp:avatar:data'/>
</pubsub>
</iq>
```
Since forwarded IQs are always sent to the bare JID, the user's server will reply, which will then be forwarded. For example, if it replies with a `<forbidden/>` error:
```xml
<iq
to="group@chats.example/45ae790b-41d8-494a-8b2a-192a602c5416"
from="user2@users.example"
type="error"
id='group-generated-id'>
<error type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
```
Which is in turn relayed by the Group to the sender:
```xml
<iq
to="user1@users.example/client-123"
from="group@chats.example/c9978c7e-9dca-4c70-808c-9ea07d4ee646"
type="error"
id='group-generated-id'>
<error type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
```
If the Participant replies with an error IQ and that error IQ contains an application-specific condition matching `<relay-denied/>`, the group MUST silently remove that application-specific condition.
#### Error case: IQ relay not allowed
If the Group or the Server forbids relaying IQs in general, it MUST reply with a `type="cancel"` `<forbidden/>` error, which includes the `<relay-denied/>` application-specific condition:
```xml
<iq
to="user1@users.example/client-123"
from="group@chats.example/c9978c7e-9dca-4c70-808c-9ea07d4ee646"
type="error"
id='avatar-1'>
<error type="cancel">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<relay-denied xmlns="urn:xmpp:gc3:0"/>
</error>
</iq>
```
The application-specific condition is important and MUST be taken into account by clients which receive IQ error responses in order to distinguish IQ errors returned by the Group and IQ errors returned by the target.
#### Error case: Not enough permissions to use IQ relay
If the sending Participant does not have sufficient permissions to send an IQ request to the receiving Participant, the Group MUST reply with a `type="auth"` `<forbidden/>` error, which includes the `<relay-denied/>` application-specific condition:
```xml
<iq
to="user1@users.example/client-123"
from="group@chats.example/c9978c7e-9dca-4c70-808c-9ea07d4ee646"
type="error"
id='avatar-1'>
<error type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<relay-denied xmlns="urn:xmpp:gc3:0"/>
</error>
</iq>
```
The application-specific condition is important and MUST be taken into account by clients which receive IQ error responses in order to distinguish IQ errors returned by the Group and IQ errors returned by the target.
### Tear down a Session
Teardown of a Session is always allowed (provided a Session exists), hence this action has no Verb associated with it.
If a resource wishes to terminate a Session with a Group, it sends `type="unavailable"` presence to the Group.
Note that a client's server will send this presence automatically when the connection of that client with the server closes.
```xml
<presence
to="group@chats.example"
from="user1@users.example/client-123"
type="unavailable"
id="session-2"/>
```
#### Success case
When the session is terminated successfully, the Group replies with an unavailable presence, mirroring the ID (if any) of the presence which started the teardown:
```xml
<presence
to="user1@users.example/client-123"
from="group@chats.example"
type="unavailable"
id="session-2"/>
```
**Note:** If the session teardown was initiated due to a client going offline, a client's server may reply with a `type="error"` stanza to this presence. Groups MUST silently ignore this reply.
#### Group-initiated teardown
A Group might, in some cases, tear down a session on its own, such as when a participant (voluntarily or involuntarily) leaves the group.
In that case, it sends the same `type="unavailable"` presence stanza:
```xml
<presence
to="user1@users.example/client-123"
from="group@chats.example"
type="unavailable"
id="session-3"/>
```
### Leave a Group
Leaving a Group is always allowed for Participants. Hence, no verb is associated with this action.
To leave a group, a Participant sends a leave request:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
type="set"
id="leave-1">
<leave xmlns="urn:xmpp:gc3:0"/>
</iq>
```
#### Success
Upon success, the Group, in this order:
1. Unilaterally terminates all Sessions with the Participant (see above), including the session of the resource which requested to leave the Group (if and only if such a session exists).
The order in which the Sessions are terminated is unspecified.
3. Unsubscribes from the presence of the Participant.
4. Unsubscribes the Participant from the Group's presence.
5. Sends the IQ response.
6. Broadcasts a `left` event to all remaining sessions.
```xml
<presence
to="user1@users.example/client-123"
from="group@chats.example"
type="unavailable">
<leave xmlns="urn:xmpp:gc3:0"/>
</presence>
<presence
to="user1@users.example/other-client"
from="group@chats.example"
type="unavailable">
<leave xmlns="urn:xmpp:gc3:0"/>
</presence>
<!-- .. -->
<presence
to="user1@users.example"
from="group@chats.example"
type="unsubscribe"/>
<presence
to="user1@users.example"
from="group@chats.example"
type="unsubscribed"/>
<iq
to="user1@users.example/client-123"
from="group@chats.example"
type="result"
id="leave-1">
<leave xmlns="urn:xmpp:gc3:0"/>
</iq>
<message
to="group@chats.example"
from="user2@users.example/other-client"
type="result">
<event xmlns="urn:xmpp:gc3:0" type="left"/>
<nick xmlns='http://jabber.org/protocol/nick'>Yours Truly</nick>
<occupant-id xmlns="urn:xmpp:occupant-id:0" id="45ae790b-41d8-494a-8b2a-192a602c5416" />
<stanza-id by="group@chats.example" id="401922f4-fb16-43fe-b173-09dcfa772d1b" />
</message>
<!-- .. -->
```
## Core Protocol: Moderation and Permission Management
### Changing Affiliations
XMPP entities may be allowed to change affiliations. The specific verb of this action depends on the current affiliation of the target entity (`promote-to-*`, `demote-to-*`, `invite`, `ban`, `reinstate`).
Affiliations can be managed in two different ways: Either by using the Participant ID or by using the bare JID. This is in order to support several use cases:
- Moderators should be able to act on non-Participants if they learn about a particular XMPP entity acting unsuitably for a Group.
- It should be possible to set affiliations for domains, which then affect all users on that Domain.
- It should be possible to change affiliations without knowing the bare JID of a Participant.
In order to request a change of affiliation for a bare JID, an entity sends a `<set-entity-affiliation/>` request with:
- the `jid` attribute set to the bare JID for which the affiliation should be set
- the `affiliation` attribute set to the affiliation to assign
```xml
<iq to="group@chats.example"
from="user1@users.example/client-123"
type="set"
id="affiliate-1">
<set-entity-affiliation xmlns="urn:xmpp:gc3:0"
jid="bad-actor.example"
affiliation="outcast" />
</iq>
```
In order to request a change of affiliation for a Participant ID, an entity sends a `<set-participant-affiliation/>` request with:
- the `participant` attribute set to the Participant ID for which the affiliation should be set
- the `affiliation` attribute set to the affiliation to assign
```xml
<iq to="group@chats.example"
from="user1@users.example/client-123"
type="set"
id="affiliate-1">
<set-participant-affiliation xmlns="urn:xmpp:gc3:0"
participant="14aef044-3978-4f27-b727-bb0289848984"
affiliation="outcast" />
</iq>
```
**TODO:** Make table with verbs required for affiliation changes. /jsc
#### Success
If the affiliation change is allowed, the Group immediately modifies the affiliation of the entity.
If the entity for which the affiliation was changed is a Participant, the Group MUST broadcast a message containing information about the affiliation change to all active Sessions and stores it in MAM:
```xml
<message
to="user1@users.example/client-123"
from="group@chats.example/14aef044-3978-4f27-b727-bb0289848984"
type="groupchat">
<event xmlns="urn:xmpp:gc3:0" type="affiliation-change">
<actor><!-- see Common Protocol --></actor>
<old-affiliation>member</old-affiliation>
<new-affiliation>outcast</new-affiliation>
</event>
<!-- stanza-id and nick elements go here; see Common Protocol -->
</message>
```
**Note:** This message MUST be sent even if the Participant's affiliation was changed through `<set-entity-affiliation/>`.
If the Affiliation change results in the Participant losing the `become-participant` or `join` verbs, they MUST immediately be removed from the Group.
Finally, the Group responds to the requester with an empty IQ result:
```xml
<iq to="group@chats.example"
from="user1@users.example/client-123"
type="result"
id="affiliate-1"/>
```
#### Affiliation Changes on Domains
When an Affiliation is set for a domain JID, all current Participants retain their current Affiliation, even those which are on the affected domain. They get neither promoted nor demoted. This is for two reasons:
- Avoiding unexpected side effects
- Simplifying the permission calculations
Entities on the domain which are not currently participants and for which Affiliations have been set explicitly also retain their current Affiliation.
Entities on the domain for which no Affiliations have been set explicitly and which are no Participants at the time of the Affiliation change on the domain implicitly gain the Affiliation of the domain.
## Protocol for Owners
### Create a Group
Verb: `create-group`
There are two flows to create a new Group on a Server.
The first flow lets the Server automatically assign the address of the Group. In that case, the client addresses the request to the server's address and includes an empty `<create/>` element:
```xml
<iq
to="chats.example"
from="user1@users.example/client-123"
type="set"
id="create-1">
<create xmlns="urn:xmpp:gc3:0" />
</iq>
```
In the second flow, the client chooses the address. In that case, the client addresses the request to the desired Group's address and includes an empty `<create/>` element:
```xml
<iq
to="my-group@chats.example"
from="user1@users.example/client-123"
type="set"
id="create-1">
<create xmlns="urn:xmpp:gc3:0" />
</iq>
```
If a Server supports Groups on the Server JID itself (for example, if the server is at `chats.example`, it might support hosting a Group at `chats.example` (without localpart)), it MUST NOT create such a group in response to a `<create/>` request. Instead, such groups may only be created through a separate administrative action. A `<create/>` request would otherwise be ambiguous.
#### Success
On success, the Server replies with an IQ with the `<created/>` element:
```xml
<iq
to="user1@users.example/client-123"
from="chats.example"
type="set"
id="create-1">
<created xmlns="urn:xmpp:gc3:0">
<address>eq7bvyvajpxaw2sr@chats.example</address>
</created>
</iq>
```
The address MUST NOT be included in the response if the client requested a specific address:
```xml
<iq
to="user1@users.example/client-123"
from="my-group@chats.example"
type="set"
id="create-1">
<created xmlns="urn:xmpp:gc3:0" />
</iq>
```
The entity which created the Group is assigned the `owner` affiliation.
#### Error case: Requested address already in use
If the requester attempted to create a Group which already exists or used to exist, the server MUST reply with a `type="modify"` `<conflict/>` error:
```xml
<iq
to="user1@users.example/client-123"
from="chats.example"
type="error"
id="create-1">
<error type="modify">
<conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
```
This error MUST be returned even if the group has been destroyed or has been moved. The common error responses defined below MUST NOT be used in this case.
### Destroy a Group
Verb: `destroy-group`
To destroy a Group, an Owner sends a destruction request to the Group, which is an IQ of type `set` with a `<destroy/>` payload:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
type="set"
id="destroy-1">
<destroy xmlns="urn:xmpp:gc3:0" />
</iq>
```
#### Success
On success, the Server executes the following steps:
1. Send an inline destruction notice to all currently active sessions.
2. Terminate all sessions as described in "Group-initiated teardown".
3. Unsubscribe from the presence of all Participants.
4. Unsubscribe all Participants from the Group's presence.
5. Reply to the IQ request.
The destruction notice is a `<message/>` with an `<event type="destroyed"/>`:
```xml
<message
to="user1@users.example/client-123"
from="group@chats.example"
type="groupchat">
<event xmlns="urn:xmpp:gc3:0" type="destroyed">
<actor>
<nick xmlns='http://jabber.org/protocol/nick'>Yours Truly</nick>
<occupant-id xmlns="urn:xmpp:occupant-id:0" id="45ae790b-41d8-494a-8b2a-192a602c5416"/>
</actor>
</event>
<stanza-id by="group@chats.example" id="af3d8826-5fa1-4f66-858b-136b98d4d5e3"/>
</message>
```
Then the server terminates all sessions (**not** included in examples here, see the other section for that) **and afterwards** sends the presence unsubscription requests and notifications:
```xml
<presence
to="user1@users.example"
from="group@chats.example"
type="unsubscribe"/>
<presence
to="user1@users.example"
from="group@chats.example"
type="unsubscribed"/>
```
Finally, it confirms execution by returning the IQ result:
```xml
<iq
to="group@chats.example"
from="user1@users.example/client-123"
type="result"
id="destroy-1">
<destroyed xmlns="urn:xmpp:gc3:0" />
</iq>
```
## Additional Protocol for the Compatibility Profile
If a Server or Group **does *not* provide** the Compatibility Profile, it MUST reply to any XEP-0045 protocol with a `type="cancel"` `<feature-not-implemented/>` error with the `<core-profile-only xmlns="urn:xmpp:gc3:0"/>` application-defined condition and the rest of this section does not apply.
If a Server or Group **does provide** the Compatibility Profile, it MUST behave like a XEP-0045 service, with the translation rules described in this section.
However, a GC3 Group SHOULD NOT implement the following protocol flows and SHOULD reject all attempts to use them with a `type="cancel"` `<feature-not-implemented/>` error with the `<gc3-service xmlns="urn:xmpp:gc3:0"/>` application-defined condition:
- TODO: enumerate XEP-0045 sections which are not allowed.
### Mapping of GC3 Participants to XEP-0045 Occupants
Unlike GC3, XEP-0045 does not have built-in long-lived participation. Some implementations (particularly client implementations) have thus resorted to using the member list as a source of "participants" in addition to the currently online users.
*Participants* are, however, not mapped to XEP-0045 members, because in XEP-0045, members are generally more privileged than non-members. Instead, *Participants* are mapped to XEP-0045 Occupants.
**TODO:** define presence broadcast in XEP-0045; needs definition in GC3 first. we may show GC3 participants without active session as `<show>xa</show>` or so. /jsc
**TODO:** somehow mix nickname registrations into all this. ideally, a Participant implies a nickname registration, but a nickname registration does not imply a participant (somehow), while still reserving the nickname. /jsc
#### Mapping of Display Names to XEP-0045 Nicknames
GC3 implementations MUST use a human-readable value derived from a Participant's display name for the XEP-0045 Nickname (= resource of the occupant JID).
That implies that the generated string MUST conform to ResourcePrep as defined in RFC 6122.
GC3 implementations MUST choose either of the following two options for a mapping:
1. Either: Enforce ResourcePrep restrictions on all Participant's display names
2. Or: Enforce ResourcePrep restrictions on all Participant's display names, except that codepoints unassigned in Unicode 3.2 are replaced with an implementation-defined substitution (which may be empty). Conflicts which arise from this substitution MUST be resolved by adding an implementation-defined suffix to the modified name.
### Effects of Joining and Leaving via XEP-0045 only
If a resource of a non-Participant joins a Group using the XEP-0045 join flow, the entity becomes a *XEP-0045 Participant* (see Glossary!).
The GC3 join flow is implicitly executed and a *Participant ID* is allocated for the XEP-0045 Participant. The Participant ID MUST be used as Occupant ID in XEP-0045-related exchanges. A XEP-0045 Session is established for the resource which initiated the join.
When the last XEP-0045 Session of a XEP-0045 Participant sends `type="unavailable"` presence to the Group, the Participant leaves the Group.
### Effects of mixing GC3 and XEP-0045 Sessions on the same Participant
First of all, if a resource which has a XEP-0045 Session established attempts to use GC3 protocol, or if a resource which has a (normal GC3) Session established attempts to use XEP-0045 protocol, Groups MUST return a `type="cancel"` `<not-acceptable/>` error with the `<protocol-mismatch xmlns="urn:xmpp:gc3:0:compat"/>` application-defined condition.
If a resource of a XEP-0045 Participant attempts to do a GC3 join, that join succeeds immediately and returns the Participant ID already generated for the XEP-0045 Participant. The XEP-0045 Participant is "upgraded" to a full Participant, that is, the extra rules for being a XEP-0045 Participant do not apply anymore.
If a client of a Participant executes a XEP-0045 join, the Participant stays a normal Participant. If the XEP-0045 join requested a different nickname than the display name set on the Participant, the Group MUST handle this like a XEP-0045 nickname conflict.
**TODO:** Figure out if we can force a different nickname. A quick skim of XEP-0045 only brought up surprise protocol which I could swear hadn't been there forever when I looked yesterday. /jsc
If a client of a Participant attempts to do a GC3 leave while XEP-0045 Sessions are established for that Participant, all GC3 Sessions are terminated and the leave operation is executed, except for the broadcast of the `left` event. The Participant is "downgraded" to a XEP-0045 Participant.
The termination of a XEP-0045 Session has no effect on Participants beyond a normal session termination (but it *does* have extra effects on XEP-0045 Participants, see above).
### Send a private message to another Participant
Relaying direct messages through the Group is not supported in the Core Profile, but only in the Compatibility Profile.
It is also only supported if a Participant's Session opted into it by publishing the `urn:xmpp:gc3:0:compat:muc-pm` feature var. The Group will translate between XEP-0045 direct messages and GC3 direct messages.
When performing error handling, the permissions for sending messages MUST be checked before considering whether the recipient is able to receive messages. Otherwise, the Group would leak information about the recipient.
#### Sending via GC3
To send a private message to another Participant when joined via the GC3 protocol, a sending Participant sends a `<message/>` stanza with a `type` not equal to `groupchat`, addressed to the Participant JID of the recipient Participant:
```xml
<message
from="user1@users.example/client-123"
to="group@chats.example/c9978c7e-9dca-4c70-808c-9ea07d4ee646"
type="normal"
id="pm-1">
<body>Hi there, wanna know a secret?</body>
</message>
```
Note that the Group will send error replies if and only if the message has an `id` attribute. Otherwise, messages are discarded silently on error.
#### Sending via XEP-0045
See XEP-0045.
Note that the Group will send error replies if and only if the message has an `id` attribute. Otherwise, messages are discarded silently on error.
#### Success
If the Group allows private messages and:
- either the recipient is joined via XEP-0045,
- or the sender is joined via XEP-0045 and the receiver has opted into direct messages via the `urn:xmpp:gc3:0:compat:muc-pm` feature var
it accepts the message and relays it to the target Participant. See "Receive a private message from another Participant" for details.
##### Error case: Message relay not allowed
If the Group or the Server forbids relaying messages in general, it MUST reply with a `type="cancel"` `<forbidden/>` error, which includes the `<relay-denied/>` application-specific condition:
```xml
<message
to="user1@users.example/client-123"
from="group@chats.example/c9978c7e-9dca-4c70-808c-9ea07d4ee646"
type="error"
id="pm-1">
<error type="cancel">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<relay-denied xmlns="urn:xmpp:gc3:0"/>
</error>
</message>
```
The application-specific condition is important and MUST be taken into account by clients which receive IQ error responses in order to distinguish IQ errors returned by the Group and IQ errors returned by the target.
##### Error case: Not enough permissions to use message relay
If the sending Participant does not have sufficient permissions to send a message to the receiving Participant, the Group MUST reply with a `type="auth"` `<forbidden/>` error, which includes the `<relay-denied/>` application-specific condition:
```xml
<message
to="user1@users.example/client-123"
from="group@chats.example/c9978c7e-9dca-4c70-808c-9ea07d4ee646"
type="error"
id="pm-1">
<error type="auth">
<forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<relay-denied xmlns="urn:xmpp:gc3:0"/>
</error>
</message>
```
The application-specific condition is important and MUST be taken into account by clients which receive IQ error responses in order to distinguish IQ errors returned by the Group and IQ errors returned by the target.
##### Error case: Recipient cannot receive direct messages
If the recipient is not joined via XEP-0045 and does not expose the `urn:xmpp:gc3:0:compat:muc-pm` feature, the Group MUST reject the message with a `type="cancel"` `<feature-not-implemented/>` error, with the `<relay-denied/>` application-defined condition.
```xml
<message
to="user1@users.example/client-123"
from="group@chats.example/c9978c7e-9dca-4c70-808c-9ea07d4ee646"
type="error"
id="pm-1">
<error type="cancel">
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<relay-denied xmlns="urn:xmpp:gc3:0"/>
</error>
</message>
```
The application-specific condition is important and MUST be taken into account by clients which receive IQ error responses in order to distinguish IQ errors returned by the Group and IQ errors returned by the target.
If the recipient has no active sessions at all at the present time, Groups MAY reply with a `type="wait"` `<service-unavailable/>` error including the `<relay-denied/>` condition.
### Receive a private message from another Participant
Please see the notes in the "Send a private message to another Participant" section.
#### Receiving via GC3
Direct messages are modified for delivery to all GC3 Sessions of the target Participant in the following way:
- The @from MUST be replaced with the sending Participant's *Participant JID*.
- The @to MUST be set to the full JID of the recipients Session.
- A XEP-0359 Stanza ID MUST NOT be added to the message. If the sender supplied a `<stanza-id/>` element in their message with a `by` attribute matching the Group's address, the message MUST be rejected (see error cases above).
- A XEP-0172 Nickname element MUST be added to the message, containing the nickname of the sender. If the sender supplied a `<nick/>` element in their message, the message MUST be rejected (see error cases above).
- Add XEP-0334 `<no-store/>` and `<no-copy/>` hints.
However, the server MUST NOT change the `id` of the message stanza.
```xml
<message
to="user2@users.example/other-client"
from="group@chats.example/45ae790b-41d8-494a-8b2a-192a602c5416"
type="normal"
id="pm-1">
<x xmlns="urn:xmpp:gc3:0:compat:muc-pms"/>
<no-copy xmlns="urn:xmpp:hints"/>
<no-store xmlns="urn:xmpp:hints"/>
<body>Hi there, wanna know a secret?</body>
<nick xmlns='http://jabber.org/protocol/nick'>Someone Else</nick>
</message>
<!-- repeated for all other Sessions of the Participant -->
```
#### Receiving via XEP-0045
See XEP-0045.
## Extensions
Future extensions may need to specify additional events. Such extensions MUST add the `<event type="custom"/>` element and MUST embed all additional information in exactly one child element inside the `<event/>` element.
In addition to that extension-specific child element, the event MAY contain the `<actor/>` element of GC3 if needed by the extension.
## Interactions with other Specifications
### XEP-0045 (Multi-User Chats)
Please see the "Additional Protocol for the Compatibility Profile" section.
### XEP-0115 and XEP-0390 (Entity Capabilities)
Clients SHOULD implement either of these specifications in order to avoid the disco#info round-trip if the Group is part of the roster.
Servers SHOULD implement both of these specifications for the same reason.
### XEP-0352 (Client State Indication)
Servers implementing XEP-0352 SHOULD NOT cause CSI flushes for messages with the `<event/>` element.
### XEP-0410 (MUC Self-Ping)
MUC Self-Ping is not necessary for GC3, but it may be used by clients in the context of the Compatibility Profile (i.e. the XEP-0045 interface to a GC3 Group).
If a Group offers the Compatibility Profile and a non-joined resource sends a XEP-0045-formatted request, it MUST reply with a `type="cancel"` `<not-acceptable/>` error in cases where otherwise the `<not-joined/>` application-defined error condition would be emitted (see "Error Cases" in the "Common Protocol" section).
This ensures compatibility to XEP-0045 clients which implement XEP-0410.
## Security Considerations
## Privacy Considerations
- What to do about presence subscriptions messing with PEP permissions??
## Internationalization Considerations
## IANA Considerations
## Design Considerations
### Use of type="groupchat" for administrative messages
- Avoid client-side archiving
- Archive server side(!)
- Easier client implementation catching stuff
### Support of direct messages only if XEP-0045 clients are involved
- this seems like an arbitrary restriction, but on the other hand we don't really want to carry MUC-PMs along forever. They have nasty issues.
- Maybe we can rewrite this in terms of whichever direct-message-exchange protocol we can come up with in the future?
- Do we accept complexity for the transitional period until XEP-0045 is gone? If so, we could require a service component which can act as a proxy... could be useful for GC3 DMs, too.
### `<event type=".."/>` vs. `<.. xmlns="urn:xmpp:gc3:0:event"/>`
- We should definitely reconsider this one
## Thanks