XEP-0045: Multi-User Chat

Abstract:This specification defines an XMPP protocol extension for multi-user text chat, whereby multiple XMPP users can exchange messages in the context of a room or channel, similar to Internet Relay Chat (IRC). In addition to standard chatroom features such as room topics and invitations, the protocol defines a strong room control model, including the ability to kick and ban users, to name room moderators and administrators, to require membership or passwords in order to join the room, etc.
Author:Peter Saint-Andre
Copyright:© 1999 - 2009 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status:Draft
Type:Standards Track
Version:1.24
Last Updated:2008-07-16

NOTICE: The protocol defined herein is a Draft Standard of the XMPP Standards Foundation. Implementations are encouraged and the protocol is appropriate for deployment in production systems, but some changes to the protocol are possible before it becomes a Final Standard.


Table of Contents


1. Introduction
2. Scope
3. Requirements
4. Terminology
    4.1. General Terms
    4.2. Room Types
    4.3. Dramatis Personae
5. Roles and Affiliations
    5.1. Roles
       5.1.1. Privileges
       5.1.2. Changing Roles
    5.2. Affiliations
       5.2.1. Privileges
       5.2.2. Changing Affiliations
6. Entity Use Cases
    6.1. Discovering Component Support for MUC
    6.2. Discovering Rooms
    6.3. Querying for Room Information
    6.4. Querying for Room Items
    6.5. Querying a Room Occupant
    6.6. Discovering Client Support for MUC
7. Occupant Use Cases
    7.1. Entering a Room
       7.1.1. Groupchat 1.0 Protocol
       7.1.2. Basic MUC Protocol
       7.1.3. Presence Broadcast
       7.1.4. Default Roles
       7.1.5. Non-Anonymous Rooms
       7.1.6. Semi-Anonymous Rooms
       7.1.7. Password-Protected Rooms
       7.1.8. Members-Only Rooms
       7.1.9. Banned Users
       7.1.10. Nickname Conflict
       7.1.11. Max Users
       7.1.12. Locked Room
       7.1.13. Nonexistent Room
       7.1.14. Room Logging
       7.1.15. Discussion History
       7.1.16. Managing Discussion History
    7.2. Exiting a Room
    7.3. Changing Nickname
    7.4. Changing Availability Status
    7.5. Inviting Another User to a Room
       7.5.1. Direct Invitation
       7.5.2. Mediated Invitation
    7.6. Converting a One-to-One Chat Into a Multi-User Conference
    7.7. Occupant Modification of the Room Subject
    7.8. Sending a Private Message
    7.9. Sending a Message to All Occupants
    7.10. Registering with a Room
    7.11. Getting Member List
    7.12. Discovering Reserved Room Nickname
    7.13. Requesting Voice
8. Moderator Use Cases
    8.1. Modifying the Room Subject
    8.2. Kicking an Occupant
    8.3. Granting Voice to a Visitor
    8.4. Revoking Voice from a Participant
    8.5. Modifying the Voice List
    8.6. Approving Voice Requests
9. Admin Use Cases
    9.1. Banning a User
    9.2. Modifying the Ban List
    9.3. Granting Membership
    9.4. Revoking Membership
    9.5. Modifying the Member List
    9.6. Granting Moderator Privileges
    9.7. Revoking Moderator Privileges
    9.8. Modifying the Moderator List
    9.9. Approving Registration Requests
10. Owner Use Cases
    10.1. Creating a Room
       10.1.1. General Considerations
       10.1.2. Creating an Instant Room
       10.1.3. Creating a Reserved Room
       10.1.4. Requesting a Unique Room Name
    10.2. Subsequent Room Configuration
       10.2.1. Notification of Configuration Changes
    10.3. Granting Ownership Privileges
    10.4. Revoking Ownership Privileges
    10.5. Modifying the Owner List
    10.6. Granting Administrative Privileges
    10.7. Revoking Administrative Privileges
    10.8. Modifying the Admin List
    10.9. Destroying a Room
11. Error and Status Codes
    11.1. Error Codes
    11.2. Status Codes
12. Internationalization Considerations
13. Security Considerations
    13.1. User Authentication and Authorization
    13.2. End-to-End Encryption
    13.3. Privacy
    13.4. Anonymity
    13.5. Denial of Service
14. IANA Considerations
15. XMPP Registrar Considerations
    15.1. Protocol Namespaces
    15.2. Service Discovery Category/Type
    15.3. Service Discovery Features
    15.4. Well-Known Service Discovery Nodes
    15.5. Field Standardization
       15.5.1. muc#register FORM_TYPE
       15.5.2. muc#request FORM_TYPE
       15.5.3. muc#roomconfig FORM_TYPE
       15.5.4. muc#roominfo FORM_TYPE
    15.6. Status Codes Registry
       15.6.1. Process
       15.6.2. Initial Submission
    15.7. URI Query Types
       15.7.1. join
       15.7.2. invite
16. Business Rules
    16.1. Addresses
    16.2. Message
    16.3. Presence
    16.4. IQ
17. Implementation Notes
    17.1. Services
       17.1.1. Allowable Traffic
    17.2. Clients
       17.2.1. IRC Command Mapping
18. XML Schemas
    18.1. http://jabber.org/protocol/muc
    18.2. http://jabber.org/protocol/muc#user
    18.3. http://jabber.org/protocol/muc#admin
    18.4. http://jabber.org/protocol/muc#owner
    18.5. http://jabber.org/protocol/muc#unique
19. Acknowledgements

Appendices
    A: Document Information
    B: Author Information
    C: Legal Notices
    D: Relation to XMPP
    E: Discussion Venue
    F: Requirements Conformance
    G: Notes
    H: Revision History


1. Introduction

Traditionally, instant messaging is thought to consist of one-to-one chat rather than many-to-many chat, which is called variously "groupchat" or "text conferencing". Groupchat functionality is familiar from systems such as Internet Relay Chat (IRC) and the chatroom functionality offered by popular consumer IM services. The Jabber community developed and implemented a basic groupchat protocol as long ago as 1999. This "groupchat 1.0" protocol provided a minimal feature set for chat rooms but was rather limited in scope. This specification (Multi-User Chat or MUC) builds on the older "groupchat 1.0" protocol in a backwards-compatible manner but provides advanced features such as invitations, room moderation and administration, and specialized room types.

2. Scope

This document addresses common requirements related to configuration of, participation in, and administration of individual text-based conference rooms. All of the requirements addressed herein apply at the level of the individual room and are "common" in the sense that they have been widely discussed within the Jabber community or are familiar from existing text-based conference environments outside of Jabber (e.g., Internet Relay Chat as defined in RFC 1459 [1] and its successors: RFC 2810 [2], RFC 2811 [3], RFC 2812 [4], RFC 2813 [5]).

This document explicitly does not address the following:

This limited scope is not meant to disparage such topics, which are of inherent interest; however, it is meant to focus the discussion in this document and to present a comprehensible protocol that can be implemented by Jabber client and component developers alike. Future specifications may of course address the topics mentioned above.

3. Requirements

This document addresses the minimal functionality provided by existing multi-user chat services in Jabber. For the sake of backwards-compatibility, this document uses the original "groupchat 1.0" protocol for this baseline functionality, with the result that:

The additional features and functionality addressed in this document include the following:

  1. native conversation logging (no in-room bot required)
  2. enabling users to request membership in a room
  3. enabling occupants to view an occupant's full JID in a non-anonymous room
  4. enabling moderators to view an occupant's full JID in a semi-anonymous room
  5. allowing only moderators to change the room subject
  6. enabling moderators to kick participants and visitors from the room
  7. enabling moderators to grant and revoke voice (i.e., the privilege to speak) in a moderated room, and to manage the voice list
  8. enabling admins to grant and revoke moderator privileges, and to manage the moderator list
  9. enabling admins to ban users from the room, and to manage the ban list
  10. enabling admins to grant and revoke membership privileges, and to manage the member list for a members-only room
  11. enabling owners to limit the number of occupants
  12. enabling owners to specify other owners
  13. enabling owners to grant and revoke administrative privileges, and to manage the admin list
  14. enabling owners to destroy the room

In addition, this document provides protocol elements for supporting the following room types:

  1. public or hidden
  2. persistent or temporary
  3. password-protected or unsecured
  4. members-only or open
  5. moderated or unmoderated
  6. non-anonymous or semi-anonymous

The extensions needed to implement these requirements are qualified by the 'http://jabber.org/protocol/muc' namespace (and the #owner, #admin, and #user fragments on the main namespace URI).

4. Terminology

4.1 General Terms

Affiliation
A long-lived association or connection with a room; the possible affiliations are "owner", "admin", "member", and "outcast" (naturally it is also possible to have no affiliation); affiliation is distinct from role. An affiliation lasts across a user's visits to a room.
Ban
To remove a user from a room such that the user is not allowed to re-enter the room (until and unless the ban has been removed). A banned user has an affiliation of "outcast".
Bare JID
The <user@host> by which a user is identified outside the context of any existing session or resource; contrast with Full JID and Room JID.
Full JID
The <user@host/resource> by which an online user is identified outside the context of a room; contrast with Bare JID and Room JID.
GC
The minimal "groupchat 1.0" protocol [7] developed within the Jabber community in 1999; MUC is backwards-compatible with GC.
History
A limited number of message stanzas sent to a new occupant to provide the context of current discussion.
Invitation
A special message sent from one user to another asking the recipient to join a room.
IRC
Internet Relay Chat.
Kick
To temporarily remove a participant or visitor from a room; the user is allowed to re-enter the room at any time. A kicked user has a role of "none".
Logging
Storage of discussions that occur within a room for public retrieval outside the context of the room.
Member
A user who is on the "whitelist" for a members-only room or who is registered with an open room. A member has an affiliation of "member".
Moderator
A room role that is usually associated with room admins but that may be granted to non-admins; is allowed to kick users, grant and revoke voice, etc. A moderator has a role of "moderator".
MUC
The multi-user chat protocol for text-based conferencing specified in this document.
Occupant
Any Jabber user who is in a room (this is an "abstract class" and does not correspond to any specific role).
Outcast
A user who has been banned from a room. An outcast has an affiliation of "outcast".
Participant
An occupant who does not have administrative privileges; in a moderated room, a participant is further defined as having voice (in contrast to a visitor). A participant has a role of "participant".
Private Message
A message sent from one occupant directly to another's room JID (not to the room itself for broadcasting to all occupants).
Role
A temporary position or privilege level within a room, distinct from a user's long-lived affiliation with the room; the possible roles are "moderator", "participant", and "visitor" (it is also possible to have no defined role). A role lasts only for the duration of an occupant's visit to a room.
Room
A virtual space that Jabber users figuratively enter in order to participate in real-time, text-based conferencing with other users.
Room Administrator
A user empowered by the room owner to perform administrative functions such as banning users; however, is not allowed to change defining room features. An admin has an affiliation of "admin".
Room ID
The node identifier portion of a Room JID, which may be opaque and thus lack meaning for human users (see Business Rules for syntax); contrast with Room Name.
Room JID
The <room@service/nick> by which an occupant is identified within the context of a room; contrast with Bare JID and Full JID.
Room Name
A user-friendly, natural-language name for a room, configured by the room owner and presented in Service Discovery queries; contrast with Room ID.
Room Nickname
The resource identifier portion of a Room JID (see Business Rules for syntax); this is the "friendly name" by which an occupant is known in the room.
Room Owner
The Jabber user who created the room or a Jabber user who has been designated by the room creator or owner as someone with owner privileges (if allowed); is allowed to change defining room features as well as perform all administrative functions. An owner has an affiliation of "owner".
Room Roster
A Jabber client's representation of the occupants in a room.
Server
A Jabber server that may or may not have associated with it a text-based conferencing service.
Service
A host that offers text-based conferencing capabilities; often but not necessarily a sub-domain of a Jabber server (e.g., conference.jabber.org).
Subject
A temporary discussion topic within a room.
Visit
A user's "session" in a room, beginning when the user enters the room (i.e., becomes an occupant) and ending when the user exits the room.
Visitor
In a moderated room, an occupant who does not have voice (in contrast to a participant). A visitor has a role of "visitor".
Voice
In a moderated room, the privilege to send messages to all occupants.

4.2 Room Types

Fully-Anonymous Room
A room in which the full JIDs or bare JIDs of occupants cannot be discovered by anyone, including room admins and room owners; such rooms are NOT RECOMMENDED or explicitly supported by MUC, but are possible using this protocol if a service implementation offers the appropriate configuration options; contrast with Non-Anonymous Room and Semi-Anonymous Room.
Hidden Room
A room that cannot be found by any user through normal means such as searching and service discovery; antonym: Public Room.
Members-Only Room
A room that a user cannot enter without being on the member list; antonym: Open Room.
Moderated Room
A room in which only those with "voice" may send messages to all occupants; antonym: Unmoderated Room.
Non-Anonymous Room
A room in which an occupant's full JID is exposed to all other occupants, although the occupant may choose any desired room nickname; contrast with Semi-Anonymous Room and Fully-Anonymous Room.
Open Room
A room that anyone may enter without being on the member list; antonym: Members-Only Room.
Password-Protected Room
A room that a user cannot enter without first providing the correct password; antonym: Unsecured Room.
Persistent Room
A room that is not destroyed if the last occupant exits; antonym: Temporary Room.
Public Room
A room that can be found by any user through normal means such as searching and service discovery; antonym: Hidden Room.
Semi-Anonymous Room
A room in which an occupant's full JID can be discovered by room admins only; contrast with Fully-Anonymous Room and Non-Anonymous Room.
Temporary Room
A room that is destroyed if the last occupant exits; antonym: Persistent Room.
Unmoderated Room
A room in which any occupant is allowed to send messages to all occupants; antonym: Moderated Room.
Unsecured Room
A room that anyone is allowed to enter without first providing the correct password; antonym: Password-Protected Room.

4.3 Dramatis Personae

Most of the examples in this document use the scenario of the witches' meeting held in a dark cave at the beginning of Act IV, Scene I of Shakespeare's Macbeth, represented here as the "darkcave@chat.shakespeare.lit" chatroom. The characters are as follows:

Table 1: Dramatis Personae

Room Nickname Full JID Affiliation
firstwitch crone1@shakespeare.lit/desktop Owner
secondwitch wiccarocks@shakespeare.lit/laptop Admin
thirdwitch hag66@shakespeare.lit/pda None

5. Roles and Affiliations

There are two dimensions along which we can measure a user's connection with or position in a room. One is the user's long-lived affiliation with a room -- e.g., a user's status as an owner or an outcast. The other is a user's role while an occupant of a room -- e.g., an occupant's position as a moderator with the ability to kick visitors and participants. These two dimensions are distinct from each other, since an affiliation lasts across visits, while a role lasts only for the duration of a visit. In addition, there is no one-to-one correspondence between roles and affiliations; for example, someone who is not affiliated with a room may be a (temporary) moderator, and a member may be a participant or a visitor in a moderated room. These concepts are explained more fully below.

5.1 Roles

The following roles are defined:

Table 2: Roles

Name Support
Moderator REQUIRED
None N/A (the absence of a role)
Participant REQUIRED
Visitor RECOMMENDED

Roles are temporary in that they do not necessarily persist across a user's visits to the room and MAY change during the course of an occupant's visit to the room. An implementation MAY persist roles across visits and SHOULD do so for moderated rooms (since the distinction between visitor and participant is critical to the functioning of a moderated room).

There is no one-to-one mapping between roles and affiliations (e.g., a member could be a participant or a visitor).

A moderator is the most powerful occupant within the context of the room, and can to some extent manage other occupants' roles in the room. A participant has fewer privileges than a moderator, although he or she always has the right to speak. A visitor is a more restricted role within the context of a moderated room, since visitors are not allowed to send messages to all occupants.

Roles are granted, revoked, and maintained based on the occupant's room nickname or full JID rather than bare JID. The privileges associated with these roles, as well as the actions that trigger changes in roles, are defined below.

Information about roles MUST be sent in all presence stanzas generated or reflected by the room and thus sent to occupants.

5.1.1 Privileges

For the most part, roles exist in a hierarchy. For instance, a participant can do anything a visitor can do, and a moderator can do anything a participant can do. Each role has privileges not possessed by the next-lowest role; these privileges are specified in the following table as defaults (an implementation MAY provide configuration options that override these defaults).

Table 3: Privileges Associated With Roles

Privilege None Visitor Participant Moderator
Present in Room No Yes Yes Yes
Receive Messages No Yes Yes Yes
Receive Occupant Presence No Yes Yes Yes
Presence Broadcasted to Room No Yes* Yes Yes
Change Availability Status No Yes Yes Yes
Change Room Nickname No Yes* Yes Yes
Send Private Messages No Yes* Yes Yes
Invite Other Users No Yes* Yes* Yes
Send Messages to All No No** Yes Yes
Modify Subject No No* Yes* Yes
Kick Participants and Visitors No No No Yes
Grant Voice No No No Yes
Revoke Voice No No No Yes***

* Default; configuration settings MAY modify this privilege.

** An implementation MAY grant voice by default to visitors in unmoderated rooms.

*** A moderator MUST NOT be able to revoke voice privileges from an admin or owner.

5.1.2 Changing Roles

The ways in which an occupant's role changes are well-defined. Sometimes the change results from the occupant's own action (e.g., entering or exiting the room), whereas sometimes the change results from an action taken by a moderator, admin, or owner. If an occupant's role changes, a MUC service implementation MUST change the occupant's role to reflect the change and communicate the change to all occupants. Role changes and their triggering actions are specified in the following table.

Table 4: Role State Chart

> None Visitor Participant Moderator
None -- Enter moderated room Enter unmoderated room Admin or owner enters room
Visitor Exit room or be kicked by a moderator -- Moderator grants voice Admin or owner grants moderator privileges
Participant Exit room or be kicked by a moderator Moderator revokes voice -- Admin or owner grants moderator privileges
Moderator Exit room Admin or owner changes role to visitor * Admin or owner changes role to participant or revokes moderator privileges * --

* A moderator MUST NOT be able to revoke moderator privileges from an occupant who is equal to or above the moderator in the hierarchy of affiliations.

Note: Certain roles are typically implicit in certain privileges. For example, an admin or owner is automatically a moderator, so if an occupant is granted admin status then the occupant will by that fact be granted moderator privileges; similarly, when an occupant is made a member in a moderated room, the occupant automatically has a role of participant. However, the loss of admin status does not necessarily mean that the occupant is no longer a moderator (since a "mere" participant can be a moderator). Therefore, the roles that are gained when an occupant is granted a certain affiliation are stable, whereas the roles that are lost when an occupant loses a certain affilitation are no hardcoded and are left up to the implementation. Since a client cannot predict what the role will be after revoking a certain affiliation, if it wants to remove both admin/owner privileges and the moderator role at the same time then it must specifically request the role change in addition to the affiliation change.

5.2 Affiliations

The following affiliations are defined:

  1. Owner
  2. Admin
  3. Member
  4. Outcast
  5. None (the absence of an affiliation)

Support for the Owner affiliation is REQUIRED. Support for the Admin, Member, and Outcast affiliations is RECOMMENDED. (The "None" affiliation is the absence of an affiliation.)

These affiliations are long-lived in that they persist across a user's visits to the room and are not affected by happenings in the room. In addition, there is no one-to-one mapping between these affiliations and an occupant's role within the room. Affiliations are granted, revoked, and maintained based on the user's bare JID.

If a user without a defined affiliation enters a room, the user's affiliation is defined as "none"; however, this affiliation does not persist across visits (i.e., a service does not maintain a "none list" across visits).

The member affiliation provides a way for a room owner or admin to specify a "whitelist" of users who are allowed to enter a members-only room. When a member enters a members-only room, his or her affiliation does not change, no matter what his or her role is. The member affiliation also provides a way for users to effectively register with an open room and thus be lastingly associated with that room in some way (one result may be that the user's nickname is reserved in the room).

An outcast is a user who has been banned from a room and who is not allowed to enter the room.

Information about affiliations MUST be sent in all presence stanzas generated or reflected by the room and sent to occupants.

5.2.1 Privileges

For the most part, affiliations exist in a hierarchy. For instance, an owner can do anything an admin can do, and an admin can do anything a member can do. Each affiliation has privileges not possessed by the next-lowest affiliation; these privileges are specified in the following table.

Table 5: Privileges Associated With Affiliations

Privilege Outcast None Member Admin Owner
Enter Open Room No Yes* Yes Yes Yes
Register with Open Room No Yes N/A N/A N/A
Retrieve Member List No No** Yes Yes Yes
Enter Members-Only Room No No Yes* Yes Yes
Ban Members and Unaffiliated Users No No No Yes Yes
Edit Member List No No No Yes Yes
Edit Moderator List No No No Yes** Yes**
Edit Admin List No No No No Yes
Edit Owner List No No No No Yes
Change Room Definition No No No No Yes
Destroy Room No No No No Yes

* As a default, an unaffiliated user enters a moderated room as a visitor, and enters an open room as a participant. A member enters a room as a participant. An admin or owner enters a room as a moderator.

** An admin or owner MUST NOT be able to revoke moderation privileges from another admin or owner.

5.2.2 Changing Affiliations

The ways in which a user's affiliation changes are well-defined. Sometimes the change results from the user's own action (e.g., registering as a member of the room), whereas sometimes the change results from an action taken by an admin or owner. If a user's affiliation changes, a MUC service implementation MUST change the user's affiliation to reflect the change and communicate that to all occupants. Affiliation changes and their triggering actions are specified in the following table.

Table 6: Affiliation State Chart

> Outcast None Member Admin Owner
Outcast -- Admin or owner removes ban Admin or owner adds user to member list Owner adds user to admin list Owner adds user to owner list
None Admin or owner applies ban -- Admin or owner adds user to member list, or user registers as member (if allowed) Owner adds user to admin list Owner adds user to owner list
Member Admin or owner applies ban Admin or owner changes affiliation to "none" -- Owner adds user to admin list Owner adds user to owner list
Admin Owner applies ban Owner changes affiliation to "none" Owner changes affiliation to "member" -- Owner adds user to owner list
Owner Owner applies ban Owner changes affiliation to "none" Owner changes affiliation to "member" Owner changes affiliation to "admin" --

6. Entity Use Cases

A MUC implementation MUST support Service Discovery [7].

6.1 Discovering Component Support for MUC

A Jabber entity may wish to discover if a service implements the Multi-User Chat protocol; in order to do so, it sends a service discovery information ("disco#info") query to the component's JID:

Example 1. User Queries Chat Service for MUC Support via Disco

<iq from='hag66@shakespeare.lit/pda'
    id='disco1'
    to='chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
    

The service MUST return its identity and the features it supports:

Example 2. Service Returns Disco Info Results

<iq from='chat.shakespeare.lit'
    id='disco1'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='conference'
        name='Macbeth Chat Service'
        type='text'/>
    <feature var='http://jabber.org/protocol/muc'/>
  </query>
</iq>
    

Note: Because MUC is a superset of the old "groupchat 1.0" protocol, a MUC service SHOULD NOT return a <feature var='gc-1.0'/> entry in a disco#info result.

6.2 Discovering Rooms

The service discovery items ("disco#items") protocol enables a user to query a service for a list of associated items, which in the case of a chat service would consist of the specific chat rooms hosted by the service.

Example 3. User Queries Chat Service for Rooms

<iq from='hag66@shakespeare.lit/pda'
    id='disco2'
    to='chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
    

The service SHOULD return a full list of the rooms it hosts.

Example 4. Service Returns Disco Item Results

<iq from='chat.shakespeare.lit'
    id='disco2'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='heath@chat.shakespeare.lit'
          name='A Lonely Heath'/>
    <item jid='darkcave@chat.shakespeare.lit'
          name='A Dark Cave'/>
    <item jid='forres@chat.shakespeare.lit'
          name='The Palace'/>
    <item jid='inverness@chat.shakespeare.lit'
          name='Macbeth&apos;s Castle'/>
  </query>
</iq>
    

If the full list of rooms is large (see XEP-0030 for details), the service MAY return only a partial list of rooms. If it does so, it SHOULD include a <set/> element (as defined in Result Set Management [8]) to indicate that the list not the full result set.

Example 5. Service Returns Limited List of Disco Item Results

<iq from='rooms.shakespeare.lit'
    id='disco-rsm-1'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='alls-well-that-ends-well@rooms.shakespeare.lit'/>
    <item jid='as-you-like-it@rooms.shakespeare.lit'/>
    <item jid='cleopatra@rooms.shakespeare.lit'/>
    <item jid='comedy-of-errors@rooms.shakespeare.lit'/>
    <item jid='coriolanus@rooms.shakespeare.lit'/>
    <item jid='cymbeline@rooms.shakespeare.lit'/>
    <item jid='hamlet@rooms.shakespeare.lit'/>
    <item jid='henry-the-fourth-one@rooms.shakespeare.lit'/>
    <item jid='henry-the-fourth-two@rooms.shakespeare.lit'/>
    <item jid='henry-the-fifth@rooms.shakespeare.lit'/>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <first index='0'>alls-well-that-ends-well@rooms.shakespeare.lit</first>
      <last>henry-the-fifth@rooms.shakespeare.lit</last>
      <count>37</count>
    </set>
  </query>
</iq>
    

6.3 Querying for Room Information

Using the disco#info protocol, a user may also query a specific chat room for more detailed information about the room. A user SHOULD do so before entering a room in order to determine the privacy and security profile of the room configuration (see the Security Considerations for details).

Example 6. User Queries for Information about a Specific Chat Room

<iq from='hag66@shakespeare.lit/pda'
    id='disco3'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
    

The room MUST return its identity and SHOULD return the features it supports:

Example 7. Room Returns Disco Info Results

<iq from='darkcave@chat.shakespeare.lit'
    id='disco3'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='conference'
        name='A Dark Cave'
        type='text'/>
    <feature var='http://jabber.org/protocol/muc'/>
    <feature var='muc_passwordprotected'/>
    <feature var='muc_hidden'/>
    <feature var='muc_temporary'/>
    <feature var='muc_open'/>
    <feature var='muc_unmoderated'/>
    <feature var='muc_nonanonymous'/>
  </query>
</iq>
    

Note: Because MUC is a superset of the old "groupchat 1.0" protocol, a MUC room SHOULD NOT return a <feature var='gc-1.0'/> entry in a disco#info result. The room SHOULD return the materially-relevant features it supports, such as password protection and room moderation (these are listed fully in the feature registry maintained by the XMPP Registrar; see also the XMPP Registrar section of this document).

A chatroom MAY return more detailed information in its disco#info response using Service Discovery Extensions [9], identified by inclusion of a hidden FORM_TYPE field whose value is "http://jabber.org/protocol/muc#roominfo". Such information might include a more verbose description of the room, the current room subject, and the current number of occupants in the room:

Example 8. Room Returns Extended Disco Info Results

<iq from='darkcave@chat.shakespeare.lit'
    id='disco3a'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='conference'
        name='A Dark Cave'
        type='text'/>
    <feature var='http://jabber.org/protocol/muc'/>
    <feature var='muc_passwordprotected'/>
    <feature var='muc_hidden'/>
    <feature var='muc_temporary'/>
    <feature var='muc_open'/>
    <feature var='muc_unmoderated'/>
    <feature var='muc_nonanonymous'/>
    <x xmlns='jabber:x:data' type='result'>
      <field var='FORM_TYPE' type='hidden'>
        <value>http://jabber.org/protocol/muc#roominfo</value>
      </field>
      <field var='muc#roominfo_description' label='Description'>
        <value>The place for all good witches!</value>
      </field>
      <field var='muc#roominfo_changesubject' label='Whether Occupants May Change the Subject'>
        <value>true</value>
      </field>
      <field var='muc#roominfo_contactjid' label='Contact Addresses'>
        <value>crone1@shakespeare.lit</value>
      </field>
      <field var='muc#roominfo_subject' label='Subject'>
        <value>Spells</value>
      </field>
      <field var='muc#roomconfig_changesubject' label='Subject can be modified'>
        <value>true</value>
      </field>
      <field var='muc#roominfo_occupants' label='Number of occupants'>
        <value>3</value>
      </field>
      <field var='muc#roominfo_ldapgroup' label='Associated LDAP Group'>
        <value>dc=lit,dc=shakespeare,cn=witches</value>
      </field>
      <field var='muc#roominfo_lang' label='Language of discussion'>
        <value>en</value>
      </field>
      <field var='muc#roominfo_logs' label='URL for discussion logs'>
        <value>http://www.shakespeare.lit/chatlogs/darkcave/</value>
      </field>
      <field var='muc#roominfo_pubsub' label='Associated pubsub node'>
        <value>xmpp:pubsub.shakespeare.lit?;node=the-darkcave-node</value>
      </field>
    </x>
  </query>
</iq>
    

Some extended room information may be dynamically generated (e.g., the URL for discussion logs, which may be based on service-wide configuration). Other information may be based on the room configuration, which is why any field defined for the muc#roomconfig FORM_TYPE can be included in the extended service discovery fields (as shown above for the muc#roomconfig_changesubject field).

Note: The foregoing extended service discovery fields for the 'http://jabber.org/protocol/muc#roominfo' FORM_TYPE may be supplemented in the future via the mechanisms described in the Field Standardization section of this document.

6.4 Querying for Room Items

A user MAY also query a specific chat room for its associated items:

Example 9. User Queries for Items Associated with a Specific Chat Room

<iq from='hag66@shakespeare.lit/pda'
    id='disco4'
    to='darkcave@chat.shakespeare.lit'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
    

An implementation MAY return a list of existing occupants if that information is publicly available, or return no list at all if this information is kept private.

Example 10. Room Returns Disco Item Results (Items are Public)

<iq from='darkcave@chat.shakespeare.lit'
    id='disco4'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='darkcave@chat.shakespeare.lit/firstwitch'/>
    <item jid='darkcave@chat.shakespeare.lit/secondwitch'/>
  </query>
</iq>
    

Note: These <item/> elements are qualified by the disco#items namespace, not the muc namespace; this means that they cannot possess 'affiliation' or 'role' attributes, for example.

Example 11. Room Returns Empty Disco Item Results (Items are Private)

<iq from='darkcave@chat.shakespeare.lit'
    id='disco4'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
    

6.5 Querying a Room Occupant

If a non-occupant attempts to send a disco request to an address of the form <room@service/nick>, a MUC service SHOULD return the request to the entity and specify a <bad-request/> error condition. If an occupant sends such a request, the service MAY pass it through the intended recipient; see the Implementation Guidelines section of this document for details.

6.6 Discovering Client Support for MUC

A Jabber user may want to discover if one of the user's contacts supports the Multi-User Chat protocol. This is done using Service Discovery.

Example 12. User Queries Contact Regarding MUC Support

<iq from='hag66@shakespeare.lit/pda'
    id='disco5'
    to='wiccarocks@shakespeare.lit/laptop'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
    

The client SHOULD return its identity and the features it supports:

Example 13. Contact Returns Disco Info Results

<iq from='wiccarocks@shakespeare.lit/laptop'
    id='disco5'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    <identity
        category='client'
        type='pc'/>
    ...
    <feature var='http://jabber.org/protocol/muc'/>
    ...
  </query>
</iq>
    

A user may also query a contact regarding which rooms the contact is in. This is done by querying the contact's full JID (<user@host/resource>) while specifying the well-known Service Discovery node 'http://jabber.org/protocol/muc#rooms':

Example 14. User Queries Contact for Current Rooms

<iq from='hag66@shakespeare.lit/pda'
    id='rooms1'
    to='wiccarocks@shakespeare.lit/laptop'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#items'
         node='http://jabber.org/protocol/muc#rooms'/>
</iq>
    

Example 15. Contact Returns Room Query Results

<iq from='wiccarocks@shakespeare.lit/laptop'
    id='rooms1'
    to='hag66@shakespeare.lit/pda'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#items'
         node='http://jabber.org/protocol/muc#rooms'>
    <item jid='darkcave@chat.shakespeare.lit'/>
    <item jid='characters@conference.shakespeare.lit'/>
  </query>
</iq>
    

Optionally, the contact MAY include its roomnick as the value of the 'name' attribute:

    ...
    <item jid='darkcave@chat.shakespeare.lit'
          name='secondwitch'/>
    ...
    

7. Occupant Use Cases

The main actor in a multi-user chat environment is the occupant, who can be said to be located "in" a multi-user chat room and to participate in the discussions held in that room (for the purposes of this specification, participants and visitors are considered to be "mere" occupants, since they possess no administrative privileges). As will become clear, the protocol elements proposed in this document to fulfill the occupant use cases fall into three categories:

  1. existing "groupchat 1.0" protocol for minimal functionality

  2. straightforward applications of the "groupchat 1.0" protocol, for example to handle some of the errors related to new room types

  3. additional protocol elements to handle functionality not covered by "groupchat 1.0" (room invites, room passwords, extended presence related to room roles and affiliations); these are qualified by the 'http://jabber.org/protocol/muc#user' namespace

Note: All client-generated examples herein are presented from the perspective of the service, with the result that all stanzas received by a service contain a 'from' attribute corresponding to the sender's full JID as added by a normal Jabber router or session manager. In addition, normal IQ result stanzas sent upon successful completion of a request (as required by RFC 3920 [10]) are not shown.

7.1 Entering a Room

7.1.1 Groupchat 1.0 Protocol

In order to participate in the discussions held in a multi-user chat room, a Jabber user MUST first become an occupant by entering the room. In the old "groupchat 1.0" protocol, this was done by sending presence to <room@service/nick>, where "room" is the room ID, "service" is the hostname of the chat service, and "nick" is the user's desired nickname within the room:

Example 16. Jabber User Seeks to Enter a Room (Groupchat 1.0)

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'/>
      

In this example, a user with a full JID of "hag66@shakespeare.lit/pda" has requested to enter the room "darkcave" on the "chat.shakespeare.lit" chat service with a room nickname of "thirdwitch".

If the user does not specify a room nickname, the service MUST return a <jid-malformed/> error:

Example 17. No Nickname Specified

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <error type='modify'>
    <jid-malformed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
      

7.1.2 Basic MUC Protocol

Compliant multi-user chat services MUST accept the foregoing as a request to enter a room from any Jabber client that knows either the "groupchat 1.0" (GC) protocol or the multi-user chat (MUC) protocol; however, MUC clients SHOULD signal their ability to speak the MUC protocol by including in the initial presence stanza an empty <x/> element qualified by the 'http://jabber.org/protocol/muc' namespace (note the absence of the '#user' fragment):

Example 18. Jabber User Seeks to Enter a Room (Multi-User Chat)

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>
      

Note: If an error occurs in relation to joining a room, the service SHOULD include the MUC child element (i.e., <x xmlns='http://jabber.org/protocol/muc'/>) in the <presence/> stanza of type "error".

Before attempting to enter the room, a MUC-compliant client SHOULD first discover its reserved room nickname (if any) by following the protocol defined in the Discovering Reserved Room Nickname section of this document.

7.1.3 Presence Broadcast

If the service is able to add the user to the room, it MUST send presence from all the existing occupants' room JIDs to the new occupant's full JID, including extended presence information about roles in an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'role' attribute set to a value of "moderator", "participant", or "visitor", and with the 'affiliation' attribute set to a value of "owner", "admin", "member", or "none" as appropriate:

Example 19. Service Sends Presence from Existing Occupants to New Occupant

<presence
    from='darkcave@chat.shakespeare.lit/firstwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner' role='moderator'/>
  </x>
</presence>

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin' role='moderator'/>
  </x>
</presence>
      

In this example, the user from the previous example has entered the room, by which time two other people had already entered the room: a user with a room nickname of "firstwitch" (who is a room owner) and a user with a room nickname of "secondwitch" (who is a room admin).

The service MUST also send presence from the new occupant's room JID to the full JIDs of all the occupants (including the new occupant):

Example 20. Service Sends New Occupant's Presence to All Occupants

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
  </x>
</presence>

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
  </x>
</presence>

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
    <status code='110'/>
  </x>
</presence>
      

In this example, initial room presence is being sent from the new occupant (thirdwitch) to all occupants, including the new occupant. As shown in the last stanza, the presence sent by the room to a user from itself as an occupant SHOULD include a status code of 110 so that the user knows this presence refers to itself as an occupant.

The service MAY rewrite the new occupant's roomnick (e.g., if roomnicks are locked down). If the service does not accept the new occupant's requested roomnick but instead assigns a new roomnick, it MUST include a status code of "210" in the presence broadcast that it sends to the new occupant.

Example 21. Service Sends New Occupant's Presence to New Occupant

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
    <status code='110'/>
    <status code='210'/>
  </x>
</presence>
      

Note: The order of the presence stanzas sent to the new occupant is important. The service MUST first send the complete list of the existing occupants to the new occupant and only then send the new occupant's own presence to the new occupant. This helps the client know when it has received the complete "room roster".

After sending the presence broadcast (and only after doing so), the service may then send discussion history, live messages, presence updates, and other in-room traffic.

7.1.4 Default Roles

The following table summarizes the initial default roles that a service should set based on the user's affiliation (there is no role associated with the "outcast" affiliation, since such users are not allowed to enter the room).

Table 7: Initial Role Based on Affiliation

Room Type None Member Admin Owner
Moderated Visitor Participant Moderator Moderator
Unmoderated Participant Participant Moderator Moderator
Members-Only N/A * Participant Moderator Moderator
Open Participant Participant Moderator Moderator

* Entry is not permitted.

7.1.5 Non-Anonymous Rooms

If the room is non-anonymous, the service MUST send the new occupant's full JID to all occupants using extended presence information in an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with a 'jid' attribute specifying the occupant's full JID:

Example 22. Service Sends Full JID to All Occupants

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='none'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>

[ ... ]
      

If the user is entering a room that is non-anonymous (i.e., which informs all occupants of each occupant's full JID as shown above), the service SHOULD allow the user to enter the room but MUST also warn the user that the room is not anonymous. This SHOULD be done by including a status code of "100" in the initial presence that the room sends to the new occupant:

Example 23. Service Sends New Occupant's Presence to New Occupant

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
    <status code='100'/>
    <status code='110'/>
    <status code='210'/>
  </x>
</presence>
      

However, it MAY be done by sending a message of type "groupchat" to the new occupant containing an <x/> child with a <status/> element that has the 'code' attribute set to a value of "100":

Example 24. Service Warns New Occupant About Lack of Anonymity

<message
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='groupchat'>
  <body>This room is not anonymous.</body>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <status code='100'/>
  </x>
</message>
      

The inclusion of the status code assists clients in presenting their own notification messages (e.g., information appropriate to the user's locality).

7.1.6 Semi-Anonymous Rooms

If the room is semi-anonymous, the service MUST send presence from the new occupant to all occupants as specified above, but MUST include the new occupant's full JID only in the presence notifications it sends to occupants with a role of "moderator" and not to non-moderator occupants.

(Note: All subsequent examples include the 'jid' attribute for each <item/> element, even though this information is not sent to non-moderators in semi-anonymous rooms.)

7.1.7 Password-Protected Rooms

If the room requires a password and the user did not supply one (or the password provided is incorrect), the service MUST deny access to the room and inform the user that they are unauthorized; this is done by returning a presence stanza of type "error" specifying a <not-authorized/> error:

Example 25. Service Denies Access Because No Password Provided

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='auth'>
    <not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
      

Passwords SHOULD be supplied with the presence stanza sent when entering the room, contained within an <x/> element qualified by the 'http://jabber.org/protocol/muc' namespace and containing a <password/> child. Passwords are to be sent as cleartext; no other authentication methods are supported at this time, and any such authentication or authorization methods shall be defined in a separate specification (see the Security Considerations section of this document).

Example 26. User Provides Password On Entering a Room

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <password>cauldronburn</password>
  </x>
</presence>
      

7.1.8 Members-Only Rooms

If the room is members-only but the user is not on the member list, the service MUST deny access to the room and inform the user that they are not allowed to enter the room; this is done by returning a presence stanza of type "error" specifying a <registration-required/> error condition:

Example 27. Service Denies Access Because User Is Not on Member List

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='auth'>
    <registration-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
      

7.1.9 Banned Users

If the user has been banned from the room (i.e., has an affiliation of "outcast"), the service MUST deny access to the room and inform the user of the fact that he or she is banned; this is done by returning a presence stanza of type "error" specifying a <forbidden/> error condition:

Example 28. Service Denies Access Because User is Banned

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
      

7.1.10 Nickname Conflict

If the room already contains another user with the nickname desired by the user seeking to enter the room (or if the nickname is reserved by another user on the member list), the service MUST deny access to the room and inform the user of the conflict; this is done by returning a presence stanza of type "error" specifying a <conflict/> error condition:

Example 29. Service Denies Access Because of Nick Conflict

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
      

However, if the bare JID <localpart@domain.tld> of the present occupant matches the bare JID of the user seeking to enter the room, then the service SHOULD allow entry to the user, so that the user has two (or more) in-room "sessions" with the same roomnick, one for each resource. If a service allows more than one occupant with the same bare JID and the same room nickname, it SHOULD route in-room messages to all of the user's resources and allow all of the user's resources to send messages to the room; it is up to the implementation to determine how to appropriately handle presence from the user's resources and how to route private messages to all or only one resource (based on presence priority or some other algorithm).

How nickname conflicts are determined is up to the implementation (e.g., whether the service applies a case folding routine, a stringprep profile such as Resourceprep or Nodeprep, etc.).

7.1.11 Max Users

If the room has reached its maximum number of occupants, the service SHOULD deny access to the room and inform the user of the restriction; this is done by returning a presence stanza of type "error" specifying a <service-unavailable/> error condition:

Example 30. Service Informs User that Room Occupant Limit Has Been Reached

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='wait'>
    <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
      

Alternatively, the room could kick an "idle user" in order to free up space.

If the room has reached its maximum number of occupants and a room admin or owner attempts to join, the room SHOULD allow the admin or owner to join, up to some reasonable number of additional occupants, which number MAY be configurable.

7.1.12 Locked Room

If a user attempts to enter a room while it is "locked" (i.e., before the room creator provides an initial configuration and therefore before the room officially exists), the service MUST refuse entry and return an <item-not-found/> error to the user:

Example 31. Service Denies Access Because Room Does Not Exist

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
      

7.1.13 Nonexistent Room

If the room does not already exist when the user seeks to enter it, the service SHOULD create it; however, this is not required, since an implementation or deployment MAY choose to restrict the privilege of creating rooms. For details, see the Creating a Room section of this document.

7.1.14 Room Logging

If the user is entering a room in which the discussions are logged to a public archive (often accessible via HTTP), the service SHOULD allow the user to enter the room but MUST also warn the user that the discussions are logged. This SHOULD be done by including a status code of "170" in the initial presence that the room sends to the new occupant:

Example 32. Service Sends New Occupant's Presence to New Occupant

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
    <status code='100'/>
    <status code='110'/>
    <status code='170'/>
    <status code='210'/>
  </x>
</presence>
      

7.1.15 Discussion History

After sending initial presence as shown above, a room MAY send discussion history to the new occupant. (The room MUST NOT send any discussion history before it finishes sending room presence as specified in the Presence Broadcast section of this document.) Whether such history is sent, and how many messages comprise the history, shall be determined by the chat service implementation or specific deployment.

Example 33. Delivery of Discussion History

<message
    from='darkcave@chat.shakespeare.lit/firstwitch'
    to='hecate@shakespeare.lit/broom'
    type='groupchat'>
  <body>Thrice the brinded cat hath mew'd.</body>
  <delay xmlns='urn:xmpp:delay'
     from='crone1@shakespeare.lit/desktop'
     stamp='2002-10-13T23:58:37Z'/>
</message>

<message
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='hecate@shakespeare.lit/broom'
    type='groupchat'>
  <body>Thrice and once the hedge-pig whined.</body>
  <delay xmlns='urn:xmpp:delay'
     from='wiccarocks@shakespeare.lit/laptop'
     stamp='2002-10-13T23:58:43Z'/>
</message>

<message
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hecate@shakespeare.lit/broom'
    type='groupchat'>
  <body>Harpier cries 'Tis time, 'tis time.</body>
  <delay xmlns='urn:xmpp:delay'
     from='hag66@shakespeare.lit/pda'
     stamp='2002-10-13T23:58:49Z'/>
</message>
      

Discussion history messages MUST be stamped with Delayed Delivery [11] information qualified by the 'urn:xmpp:delay' namespace to indicate that they are sent with delayed delivery and to specify the times at which they were originally sent. (Note: The 'urn:xmpp:delay' namespace defined in XEP-0203 supersedes the older 'jabber:x:delay' namespace defined in Delayed Delivery [12]; until the status of XEP-0091 is changed to Obsolete, implementations SHOULD include both datetime formats.) The 'from' attribute SHOULD be the full JID of the original sender in non-anonymous rooms, but MUST NOT be in semi-anonymous rooms (where the 'from' attribute SHOULD be set to the JID of the room itself). The service SHOULD send all discussion history messages before delivering any "live" messages sent after the user enters the room.

7.1.16 Managing Discussion History

A user MAY want to manage the amount of discussion history provided on entering a room (perhaps because the user is on a low-bandwidth connection or is using a small-footprint client). This MUST be accomplished by including a <history/> child in the initial presence stanza sent when joining the room. There are four allowable attributes for this element:

Table 8: History Management Attributes

Attribute Datatype Meaning
maxchars int Limit the total number of characters in the history to "X" (where the character count is the characters of the complete XML stanzas, not only their XML character data).
maxstanzas int Limit the total number of messages in the history to "X".
seconds int Send only the messages received in the last "X" seconds.
since dateTime Send only the messages received since the datetime specified (which MUST conform to the DateTime profile specified in XMPP Date and Time Profiles [13]).

The service MUST send the smallest amount of traffic that meets any combination of the above criteria, taking into account service-level and room-level defaults. The service MUST send complete message stanzas only (i.e., it MUST not literally truncate the history at a certain number of characters, but MUST send the largest number of complete stanzas that results in a number of characters less than or equal to the 'maxchars' value specified). If the client wishes to receive no history, it MUST set the 'maxchars' attribute to a value of "0" (zero).

The following examples illustrate the use of this protocol.

Example 34. User Requests Limit on Number of Messages in History

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <history maxstanzas='20'/>
  </x>
</presence>
      

Example 35. User Requests History in Last 3 Minutes

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <history seconds='180'/>
  </x>
</presence>
      

Example 36. User Requests All History Since the Beginning of the Unix Era

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <history since='1970-01-01T00:00:00Z'/>
  </x>
</presence>
      

Obviously the service SHOULD NOT return all messages sent in the room since the beginning of the Unix era, and SHOULD appropriately limit the amount of history sent to the user based on service or room defaults.

Example 37. User Requests No History

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'>
  <x xmlns='http://jabber.org/protocol/muc'>
    <history maxchars='0'/>
  </x>
</presence>
      

7.2 Exiting a Room

In order to exit a multi-user chat room, an occupant sends a presence stanza of type "unavailable" to the <room@service/nick> it is currently using in the room.

Example 38. Occupant Exits a Room

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/thirdwitch'
    type='unavailable'/>
    

The service MUST then send presence stanzas of type "unavailable" from the departing occupant's room JID to the full JIDs of the departing occupant and of the remaining occupants:

Example 39. Service Sends Presence Related to Departure of Occupant

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='none'/>
    <status code='110'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='none'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='wiccarocks@shakespeare.lit/laptop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='none'/>
  </x>
</presence>
    

Presence stanzas of type "unavailable" reflected by the room MUST contain extended presence information about roles and affiliations; the 'role' attribute SHOULD be set to a value of "none" to denote that the individual is no longer an occupant.

The occupant MAY include normal <status/> information in the unavailable presence stanzas; this enables the occupant to provide a custom exit message if desired:

Example 40. Custom Exit Message

<presence
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/oldhag'
    type='unavailable'>
  <status>gone where the goblins go</status>
</presence>
    

Normal presence stanza generation rules apply as defined in XMPP IM [14], so that if the user sends a general unavailable presence stanza, the user's server will broadcast that stanza to the <room@service/nick> to which the user's client has sent directed presence.

It is possible that a user may not be able to gracefully exit the room by sending unavailable presence directly to the room. If the user goes offline without sending unavailable presence, the user's server is responsible for sending unavailable presence on behalf of the user (in accordance with RFC 3921). If the user's server goes offline or connectivity is lost between the user's server and the MUC service to which the user is connected (e.g., in federated communications), the MUC service is responsible for monitoring error stanzas it receives in order to determine if the user has gone offline. If the MUC service determines that the user has gone offline, it must treat the user as if the user had itself sent unavailable presence.

Note: If the room is not persistent and this occupant is the last to exit, the service is responsible for destroying the room.

7.3 Changing Nickname

A common feature of multi-user chat rooms is the ability for an occupant to change his or her nickname within the room. In MUC this is done by sending updated presence information to the room, specifically by sending presence to a new room JID in the same room (changing only the resource identifier in the room JID).

Example 41. Occupant Changes Nickname

<presence
    from='hag66@shakespeare.lit/pda'
    to='darkcave@chat.shakespeare.lit/oldhag'/>
    

The service then sends two presence stanzas to the full JID of each occupant (including the occupant who is changing his or her room nickname), one of type "unavailable" for the old nickname and one indicating availability for the new nickname.

The unavailable presence MUST contain the following as extended presence information in an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace:

This enables the recipients to correlate the old roomnick with the new roomnick.

Example 42. Service Updates Nick

<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='crone1@shakespeare.lit/desktop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          nick='oldhag'
          role='participant'/>
    <status code='303'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='wiccarocks@shakespeare.lit/laptop'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          nick='oldhag'
          role='participant'/>
    <status code='303'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/thirdwitch'
    to='hag66@shakespeare.lit/pda'
    type='unavailable'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          nick='oldhag'
          role='participant'/>
    <status code='303'/>
    <status code='110'/>
  </x>
</presence>

<presence
    from='darkcave@chat.shakespeare.lit/oldhag'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/oldhag'
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
  </x>
</presence>
<presence
    from='darkcave@chat.shakespeare.lit/oldhag'
    to='hag66@shakespeare.lit/pda'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member'
          jid='hag66@shakespeare.lit/pda'
          role='participant'/>
    <status code='110'/>
  </x>
</presence>
    

If the user attempts to change his or her room nickname to a room nickname that is already in use by another user (or that is reserved by another user affiliated with the room, e.g., a member or owner), the service MUST deny the nickname change request and inform the user of the conflict; this is done by returning a presence stanza of type "error" specifying a <conflict/> error condition:

Example 43. Service Denies Nickname Change Because of Nick Conflict

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
    

However, if the bare JID <localpart@domain.tld> of the present occupant matches the bare JID of the user seeking to change his or her nickname, then the service MAY allow the nickname change. See the Nickname Conflict section of this document for details.

If the user attempts to change his or her room nickname but room nicknames are "locked down", the service MUST deny the nickname change request and return a presence stanza of type "error" specifying a <not-acceptable/> error condition:

Example 44. Service Denies Nickname Change Because Roomnicks Are Locked Down

<presence
    from='darkcave@chat.shakespeare.lit'
    to='hag66@shakespeare.lit/pda'
    type='error'>
  <x xmlns='http://jabber.org/protocol/muc'/>
  <error type='cancel'>
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</presence>
    

The user SHOULD then discover its reserved nickname as specified in the Discovering Reserved Room Nickname section of this document.

7.4 Changing Availability Status

In multi-user chat systems such as IRC, one common use for changing one's room nickname is to indicate a change in one's availability (e.g., changing one's room nickname to "thirdwitch|away"). In Jabber, availability is of course noted by a change in presence (specifically the <show/> and <status/> elements), which can provide important context within a chatroom. An occupant changes availability status within the room by sending the updated presence to its <room@service/nick>.

Example 45. Occupant Changes Availability Status

<presence
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/oldhag'>
  <show>xa</show>
  <status>gone where the goblins go</status>
</presence>
    

The service then sends a presence stanza from the occupant changing his or her presence to the full JID of each occupant, including extended presence information about the occupant's role and full JID to those with privileges to view such information:

Example 46. Service Passes Along Changed Presence to All Occupants

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'>
  <show>xa</show>
  <status>gone where the goblins go</status>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='admin'
          jid='wiccarocks@shakespeare.lit/laptop'
          role='moderator'/>
  </x>
</presence>

[ ... ]
    

7.5 Inviting Another User to a Room

7.5.1 Direct Invitation

A method for sending a direct invitation (not mediated by the room itself) is defined in Direct MUC Invitations [15]. Sending the invitation directly can help to work around communications blocking on the part of the invitee (which might refuse communication with entities not in its roster).

7.5.2 Mediated Invitation

It can be useful to invite another user to a room in which one is an occupant. To do this, a MUC client MUST send XML of the following form to the <room@service> itself (the reason is OPTIONAL and the message MUST be explicitly or implicitly of type "normal"):

Example 47. Occupant Sends an Invitation by Way of Room

<message
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='hecate@shakespeare.lit'>
      <reason>
        Hey Hecate, this is the place for all good witches!
      </reason>
    </invite>
  </x>
</message>
      

The <room@service> itself MUST then add a 'from' address to the <invite/> element whose value is the bare JID, full JID, or room JID of the invitor and send the invitation to the invitee specified in the 'to' address (the service MAY include a message body explaining the invitation or containing the reason, for the sake of older clients; in addition, the room SHOULD add the password if the room is password-protected):

Example 48. Room Sends Invitation to Invitee on Behalf of Invitor

<message
    from='darkcave@chat.shakespeare.lit'
    to='hecate@shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite from='crone1@shakespeare.lit/desktop'>
      <reason>
        Hey Hecate, this is the place for all good witches!
      </reason>
    </invite>
    <password>cauldronburn</password>
  </x>
</message>
      

If the room is members-only, the service MAY also add the invitee to the member list. (Note: Invitation privileges in members-only rooms SHOULD be restricted to room admins; if a member without privileges to edit the member list attempts to invite another user, the service SHOULD return a <forbidden/> error to the occupant; for details, see the Modifying the Member List section of this document.)

If the invitor supplies a non-existent JID, the room SHOULD return an <item-not-found/> error to the invitor.

The invitee MAY choose to formally decline (as opposed to ignore) the invitation; and this is something that the sender may want to be informed about. In order to decline the invitation, the invitee MUST send a message of the following form to the <room@service> itself:

Example 49. Invitee Declines Invitation

<message
    from='hecate@shakespeare.lit/broom'
    to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <decline to='crone1@shakespeare.lit'>
      <reason>
        Sorry, I'm too busy right now.
      </reason>
    </decline>
  </x>
</message>
      

Example 50. Room Informs Invitor that Invitation Was Declined

<message
    from='darkcave@chat.shakespeare.lit'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <decline from='hecate@shakespeare.lit'>
      <reason>
        Sorry, I'm too busy right now.
      </reason>
    </decline>
  </x>
</message>
      

It may be wondered why the invitee does not send the decline message directly to the invitor. The main reason is that certain implementations MAY choose to base invitations on room JIDs rather than bare JIDs (so that, for example, an occupant could invite someone from one room to another without knowing that person's bare JID). Thus the service MUST handle both the invites and declines.

7.6 Converting a One-to-One Chat Into a Multi-User Conference

Sometimes it is desirable to convert a one-to-one chat into a multi-user conference. The process flow is shown in the following examples.

First, two users begin a one-to-one chat.

Example 51. A One-to-One Chat

<message
    from='crone1@shakespeare.lit/desktop'
    to='wiccarocks@shakespeare.lit/laptop'
    type='chat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice the brinded cat hath mew'd.</body>
</message>

<message
    from='wiccarocks@shakespeare.lit/laptop'
    to='crone1@shakespeare.lit/desktop'
    type='chat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice and once the hedge-pig whined.</body>
</message>
    

Now the first person decides to include a third person in the discussion, so she (or, more precisely, her client) does the following:

  1. Creates a new multi-user chatroom
  2. Optionally sends history of the one-to-one chat to the room
  3. Sends an invitation to the second person and the third person, including a <continue/> element (optionally including a 'thread' attribute).

Note: The new room SHOULD be non-anonymous, MAY be an instant room as specified in the Creating an Instant Room section of this document, and MAY have a unique room name received from the service as specified in the Requesting a Unique Room Name section of this document.

Note: If the one-to-one chat messages included a <thread/> element, the person who creates the room SHOULD include the ThreadID with the history messages, specify the ThreadID in the invitations as the value of the <continue/> element's 'thread' attribute, and include the ThreadID in any new messages sent to the room. Use of ThreadIDs is RECOMMENDED because it helps to provide continuity between the one-to-one chat and the multi-user chat.

Example 52. Continuing the Discussion I: User Creates Room

<presence
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit/firstwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>

<presence
    from='darkcave@chat.shakespeare.lit/firstwitch'
    to='crone1@shakespeare.lit/desktop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner' role='moderator'/>
    <status code='110'/>
  </x>
</presence>
    

Example 53. Continuing the Discussion II: Owner Sends History to Room

<message
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit'
    type='groupchat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice the brinded cat hath mew'd.</body>
  <delay xmlns='urn:xmpp:delay'
     from='crone1@shakespeare.lit/desktop'
     stamp='2004-09-29T01:54:37Z'/>
</message>

<message
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit'
    type='groupchat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice and once the hedge-pig whined.</body>
  <delay xmlns='urn:xmpp:delay'
     from='wiccarocks@shakespeare.lit/laptop'
     stamp='2004-09-29T01:55:21Z'/>
</message>
    

Note: Use of the Delayed Delivery protocol enables the room creator to specify the datetime of each message from the one-to-one chat history (via the 'stamp' attribute), as well as the JID of the original sender of each message (via the 'from' attribute). The room creator SHOULD send the complete one-to-one chat history before inviting additional users to the room, and SHOULD also send as history any messages appearing in the one-to-one chat interface after joining the room and before the second person joins the room; if the one-to-one history is especially large, the sending client may want to send the history over a few seconds rather than all at once (to avoid triggering rate limits). The service SHOULD NOT add its own delay elements (as described in the Discussion History section of this document) to prior chat history messages received from the room owner.

Example 54. Continuing the Discussion III: Owner Sends Invitations, Including Continue Flag

<message
    from='crone1@shakespeare.lit/desktop'
    to='darkcave@chat.shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite to='wiccarocks@shakespeare.lit/laptop'>
      <reason>This coven needs both wiccarocks and hag66.</reason>
      <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
    </invite>
    <invite to='hag66@shakespeare.lit'>
      <reason>This coven needs both wiccarocks and hag66.</reason>
      <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
    </invite>
  </x>
</message>
    

Note: Since the invitor's client knows the full JID of the person with whom the invitor was having a one-to-one chat, it SHOULD include the full JID (rather than the bare JID) in the invitation.

The invitations are delivered to the invitees:

Example 55. Invitations Delivered

<message
    from='darkcave@chat.shakespeare.lit'>
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite from='crone1@shakespeare.lit'>
      <reason>This coven needs both wiccarocks and hag66.</reason>
      <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
    </invite>
  </x>
</message>

<message
    from='darkcave@chat.shakespeare.lit'>
    to='hag66@shakespeare.lit'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <invite from='crone1@shakespeare.lit'>
      <reason>This coven needs both wiccarocks and hag66.</reason>
      <continue thread='e0ffe42b28561960c6b12b944a092794b9683a38'/>
    </invite>
  </x>
</message>
    

When the client being used by <wiccarocks@shakespeare.lit/laptop> receives the invitation, it SHOULD auto-join the room or prompt the user whether to join (subject to user preferences) and then seamlessly convert the existing one-to-one chat window into a multi-user conferencing window:

Example 56. Invitee Accepts Invitation, Joins Room, and Receives Presence and History

<presence
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/secondwitch'>
  <x xmlns='http://jabber.org/protocol/muc'/>
</presence>

<presence
    from='darkcave@chat.shakespeare.lit/firstwitch'
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='owner' role='moderator'/>
  </x>
</presence>

<presence
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='wiccarocks@shakespeare.lit/laptop'>
  <x xmlns='http://jabber.org/protocol/muc#user'>
    <item affiliation='member' role='participant'/>
  </x>
</presence>

<message
    from='darkcave@chat.shakespeare.lit'
    to='wiccarocks@shakespeare.lit/laptop'
    type='groupchat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice the brinded cat hath mew'd.</body>
  <delay xmlns='urn:xmpp:delay'
     from='crone1@shakespeare.lit/desktop'
     stamp='2004-09-29T01:54:37Z'/>
</message>

<message
    from='darkcave@chat.shakespeare.lit'
    to='wiccarocks@shakespeare.lit/laptop'
    type='groupchat'>
  <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
  <body>Thrice and once the hedge-pig whined.</body>
  <delay xmlns='urn:xmpp:delay'
     from='wiccarocks@shakespeare.lit/laptop'
     stamp='2004-09-29T01:55:21Z'/>
</message>
    

Note: The fact that the messages come from the <room@service> itself rather than <room@service/nick> is a clue to the receiving client that these messages are prior chat history, since any message from a room occupant will have a 'from' address equal to the sender's room JID.

7.7 Occupant Modification of the Room Subject

If allowed in accordance with room configuration, a mere occupant MAY be allowed to change the subject in a room. For details, see the Modifying the Room Subject section of this document.

7.8 Sending a Private Message

Since each occupant has a unique room JID, an occupant MAY send a "private message" to a selected occupant via the service by sending a message to the occupant's room JID. The message type SHOULD be "chat" and MUST NOT be "groupchat", but MAY be left unspecified (i.e., a normal message). This privilege SHOULD be allowed to any occupant (even a visitor in a moderated room).

Example 57. Occupant Sends Private Message

<message
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/firstwitch'
    type='chat'>
  <body>I'll give thee a wind.</body>
</message>
    

The service is responsible for changing the 'from' address to the sender's room JID and delivering the message to the intended recipient's full JID.

Example 58. Recipient Receives the Private Message

<message
    from='darkcave@chat.shakespeare.lit/secondwitch'
    to='crone1@shakespeare.lit/desktop'
    type='chat'>
  <body>I'll give thee a wind.</body>
</message>
    

If the sender attempts to send a private message of type "groupchat" to a particular occupant, the service MUST refuse to deliver the message (since the recipient's client would expect in-room messages to be of type "groupchat") and return a <bad-request/> error to the sender:

Example 59. Occupant Attempts to Send a Message of Type "Groupchat" to a Particular Occupant

<message
    from='wiccarocks@shakespeare.lit/laptop'
    to='darkcave@chat.shakespeare.lit/firstwitch'
    type='groupchat'>
  <body>I'll give thee a wind.</body>
</message>

<message
    from='darkcave@chat.shakespeare.lit'
    to='wiccarocks@shakespeare.lit/laptop'
    type='error'>
  <body>I'll give thee a wind.</body>
  <error type='modify'>
    <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</message>
    

If the sender attempts to send a private message to a room JID that does not exist, the service MUST return an <item-not-found/> error to the sender.

If the sender is not an occupant of the room in which the intended recipient is visiting, the service MUST return a <not-acceptable/> error to the sender.

7.9 Sending a Message to All Occupants

An occupant sends a message to all other occupants in the room by sending a message of type "groupchat" to the <room@service> itself (a service MAY ignore or reject messages that do not have a