muc — Multi-User-Chat support (XEP-0045)¶
This subpackage provides client-side support for XEP-0045.
New in version 0.5.
Changed in version 0.9: Nearly the whole public interface of this module has been re-written in 0.9 to make it coherent with the Modern IM interface defined by aioxmpp.im.
Using Multi-User-Chats¶
To start using MUCs in your application, you have to load the Service into the client, using summon().
- class aioxmpp.MUCClient(client, **kwargs)¶
Conversation Implementation for Multi-User Chats (XEP-0045).
This service provides access to Multi-User Chats using the conversation interface defined by aioxmpp.im.
Client service implementing the a Multi-User Chat client. By loading it into a client, it is possible to join multi-user chats and implement interaction with them.
Private Messages into the MUC are not handled by this service. They are handled by the normal p2p.Service.
- join(mucjid, nick, *, password=None, history=None, autorejoin=True)¶
Join a multi-user chat and create a conversation for it.
Parameters: - mucjid (JID.) – The bare JID of the room to join.
- nick (str) – The nickname to use in the room.
- password (str) – The password to join the room, if required.
- history (xso.History) – Specification for how much and which history to fetch.
- autorejoin (bool) – Flag to indicate that the MUC should be automatically rejoined after a disconnect.
Raises ValueError: if the MUC JID is invalid.
Returns: The Conversation and a future on the join.
Return type: tuple of Room and asyncio.Future.
Join a multi-user chat at mucjid with nick. Return a Room instance which is used to track the MUC locally and a aioxmpp.Future which becomes done when the join succeeded (with a None value) or failed (with an exception).
In addition, the on_conversation_added() signal is emitted immediately with the new Room.
It is recommended to attach the desired signals to the Room before yielding next (e.g. in a non-deferred event handler to the on_conversation_added() signal), to avoid races with the server. It is guaranteed that no signals are emitted before the next yield, and thus, it is safe to attach the signals right after join() returned. (This is also the reason why join() is not a coroutine, but instead returns the room and a future to wait for.)
Any other interaction with the room must go through the Room instance.
If the multi-user chat at mucjid is already or currently being joined, the existing Room and future is returned. The nick and other options for the new join are ignored.
If the mucjid is not a bare JID, ValueError is raised.
password may be a string used as password for the MUC. It will be remembered and stored at the returned Room instance.
history may be a History instance to request a specific amount of history; otherwise, the server will return a default amount of history.
If autorejoin is true, the MUC will be re-joined after the stream has been destroyed and re-established. In that case, the service will request history since the stream destruction and ignore the history object passed here.
If the stream is currently not established, the join is deferred until the stream is established.
Manage rooms:
- coroutine get_room_config(mucjid)¶
Query and return the room configuration form for the given MUC.
Parameters: mucjid (bare JID) – JID of the room to query Returns: data form template for the room configuration Return type: aioxmpp.forms.Data See also
- ConfigurationForm
- for a form template to work with the returned form
New in version 0.7.
- coroutine set_affiliation(mucjid, jid, affiliation, *, reason=None)¶
Change the affiliation of an entity with a MUC.
Parameters: Change the affiliation of the given jid with the MUC identified by the bare mucjid to the given new affiliation. Optionally, a reason can be given.
If you are joined in the MUC, Room.muc_set_affiliation() may be more convenient, but it is possible to modify the affiliations of a MUC without being joined, given sufficient privilegues.
Setting the different affiliations require different privilegues of the local user. The details can be checked in XEP-0045 and are enforced solely by the server, not local code.
The coroutine returns when the change in affiliation has been acknowledged by the server. If the server returns an error, an appropriate aioxmpp.errors.XMPPError subclass is raised.
- coroutine set_room_config(mucjid, data)¶
Set the room configuration using a XEP-0004 data form.
Parameters: - mucjid (bare JID) – JID of the room to query
- data (aioxmpp.forms.Data) – Filled-out configuration form
See also
- ConfigurationForm
- for a form template to generate the required form
A sensible workflow to, for example, set a room to be moderated, could be this:
form = aioxmpp.muc.ConfigurationForm.from_xso( (await muc_service.get_room_config(mucjid)) ) form.moderatedroom = True await muc_service.set_rooom_config(mucjid, form.render_reply())
New in version 0.7.
Changed in version 0.8: This class was formerly known as aioxmpp.muc.Service. It is still available under that name, but the alias will be removed in 1.0.
Changed in version 0.9: This class was completely remodeled in 0.9 to conform with the aioxmpp.im interface.
- class aioxmpp.muc.Service¶
Alias of MUCClient.
Deprecated since version 0.8: The alias will be removed in 1.0.
The service returns Room objects which are used to track joined MUCs:
- class aioxmpp.muc.Room(service, mucjid)¶
Conversation representing a single XEP-0045 Multi-User Chat.
Note
This is an implementation of AbstractConversation. The members which do not carry the muc_ prefix usually have more extensive documentation there. This documentation here only provides a short synopsis for those members plus the changes with respect to the base interface.
Changed in version 0.9: In 0.9, the Room interface was re-designed to match AbstractConversation.
The following properties are provided:
- features¶
The set of features supported by this MUC. This may vary depending on features exported by the MUC service, so be sure to check this for each individual MUC.
- jid¶
The (bare) aioxmpp.JID of the MUC which this Room tracks.
- me¶
A Occupant instance which tracks the local user. This is None until on_enter() is emitted; it is never set to None again, but the identity of the object changes on each on_enter().
- members¶
A copy of the list of occupants. The local user is always the first item in the list, unless the on_enter() has not fired yet.
These properties are specific to MUC:
- muc_active¶
A boolean attribute indicating whether the connection to the MUC is currently live.
This becomes true when joined first becomes true. It becomes false whenever the connection to the MUC is interrupted in a way which requires re-joining the MUC (this implies that if stream management is being used, active does not become false on temporary connection interruptions).
- muc_joined¶
This attribute becomes true when on_enter() is first emitted and stays true until on_exit() is emitted.
When it becomes false, the Room is removed from the bookkeeping of the MUCClient to which it belongs and is thus dead.
- muc_subject¶
The current subject of the MUC, as LanguageMap.
- muc_subject_setter¶
The nick name of the entity who set the subject.
- muc_autorejoin¶
A boolean flag indicating whether this MUC is supposed to be automatically rejoined when the stream it is used gets destroyed and re-estabished.
- muc_password¶
The password to use when (re-)joining. If autorejoin is None, this can be cleared after on_enter() has been emitted.
The following methods and properties provide interaction with the MUC itself:
- coroutine ban(member, reason=None, *, request_kick=True)¶
Ban an occupant from re-joining the MUC.
Parameters: request_kick is supported by MUC, but setting it to false has no effect: banned members are always immediately kicked.
See also
AbstractConversation.ban() for the full interface specification.
- coroutine kick(member, reason=None)¶
Kick an occupant from the MUC.
Parameters: Raises aioxmpp.errors.XMPPError: if the server returned an error for the kick command.
See also
AbstractConversation.kick() for the full interface specification.
- coroutine leave()¶
Leave the MUC.
- coroutine send_message(msg)¶
Send a message to the MUC.
Parameters: msg (aioxmpp.Message) – The message to send. There is no need to set the address attributes or the type of the message correctly; those will be overridden by this method to conform to the requirements of a message to the MUC. Other attributes are left untouched (except that autoset_id() is called) and can be used as desired for the message.
See also
AbstractConversation.send_message() for the full interface specification.
- coroutine send_message_tracked(msg)¶
Send a message to the MUC with tracking.
Parameters: msg (aioxmpp.Message) – The message to send. Warning
Please read General Remarks about Tracking and Memory Consumption. This is especially relevant for MUCs because tracking is not guaranteed to work due to how XEP-0045 is written. It will work in many cases, probably in all cases you test during development, but it may fail to work for some individual messages and it may fail to work consistently for some services. See the implementation details below for reasons.
The message is tracked and is considered DELIVERED_TO_RECIPIENT when it is reflected back to us by the MUC service. The reflected message is then available in the response attribute.
Note
Two things:
- The MUC service may change the contents of the message. An example of this is the Prosody developer MUC which replaces messages with more than a few lines with a pastebin link.
- Reflected messages which are caught by tracking are not emitted through on_message().
There is no need to set the address attributes or the type of the message correctly; those will be overridden by this method to conform to the requirements of a message to the MUC. Other attributes are left untouched (except that autoset_id() is called) and can be used as desired for the message.
See also
AbstractConversation.send_message_tracked() for the full interface specification.
Implementation details: Currently, we try to detect reflected messages using two different criteria. First, if we see a message with the same message ID (note that message IDs contain 120 bits of entropy) as the message we sent, we consider it as the reflection. As some MUC services re-write the message ID in the reflection, as a fallback, we also consider messages which originate from the correct sender and have the correct body a reflection.
Obviously, this fails consistently in MUCs which re-write the body and re-write the ID and randomly if the MUC always re-writes the ID but only sometimes the body.
- coroutine set_nick(new_nick)¶
Change the nick name of the occupant.
Parameters: new_nick (str) – New nickname to use This sends the request to change the nickname and waits for the request to be sent over the stream.
The nick change may or may not happen, or the service may modify the nickname; observe the on_nick_change() event.
See also
AbstractConversation.set_nick() for the full interface specification.
- coroutine set_topic(new_topic)¶
Change the (possibly publicly) visible topic of the conversation.
Parameters: new_topic (str) – The new topic for the conversation. Request to set the subject to new_topic. new_topic must be a mapping which maps LanguageTag tags to strings; None is a valid key.
- coroutine muc_request_voice()¶
Request voice (participant role) in the room and wait for the request to be sent.
The participant role allows occupants to send messages while the room is in moderated mode.
There is no guarantee that the request will be granted. To detect that voice has been granted, observe the on_role_change() signal.
New in version 0.8.
- coroutine muc_set_role(nick, role, *, reason=None)¶
Change the role of an occupant.
Parameters: Change the role of an occupant, identified by their nick, to the given new role. Optionally, a reason for the role change can be provided.
Setting the different roles require different privilegues of the local user. The details can be checked in XEP-0045 and are enforced solely by the server, not local code.
The coroutine returns when the role change has been acknowledged by the server. If the server returns an error, an appropriate aioxmpp.errors.XMPPError subclass is raised.
- coroutine muc_set_affiliation(jid, affiliation, *, reason=None)¶
Convenience wrapper around MUCClient.set_affiliation(). See there for details, and consider its mucjid argument to be set to mucjid.
The interface provides signals for most of the rooms events. The following keyword arguments are used at several signal handlers (which is also noted at their respective documentation):
- muc_actor = None
The UserActor instance of the corresponding UserExt, describing which other occupant caused the event.
Note that the muc_actor is in fact not a Occupant.
- muc_reason = None
- The reason text in the corresponding UserExt, which gives more information on why an action was triggered.
Note
Signal handlers attached to any of the signals below must accept arbitrary keyword arguments for forward compatibility. For details see the documentation on AbstractConversation.
- signal on_enter(presence, occupant, **kwargs)¶
Emits when the initial room Presence stanza for the local JID is received. This means that the join to the room is complete; the message history and subject are not transferred yet though.
The occupant argument refers to the Occupant which will be used to track the local user.
- signal on_message(msg, member, source, **kwargs)¶
A message occured in the conversation.
Parameters: - msg (aioxmpp.Message) – Message which was received.
- member (AbstractConversationMember) – The member object of the sender.
- source (MessageSource) – How the message was acquired
The notable specialities about MUCs compared to the base specification at AbstractConversation.on_message() are:
Carbons do not happen for MUC messages.
MUC Private Messages are not handled here; see MUCClient for MUC PM details.
MUCs reflect messages; to make this as easy to handle as possible, reflected messages are not emitted via the on_message() event if and only if they were sent with tracking (see send_message_tracked()) and they were detected as reflection.
See send_message_tracked() for details and caveats on the tracking implementation.
See also
AbstractConversation.on_message() for the full specification.
- signal on_presence_changed(member, resource, presence, **kwargs)¶
The presence state of an occupant has changed.
Parameters: - member (Occupant) – The member object of the affected member.
- resource (str or None) – The resource of the member which changed presence.
- presence (aioxmpp.Presence) – The presence stanza
resource is always None for MUCs and unavailable presence implies that the occupant left the room. In this case, only on_leave() is emitted.
See also
AbstractConversation.on_presence_changed() for the full specification.
- signal on_nick_changed(member, old_nick, new_nick, **kwargs)¶
The nickname of an occupant has changed
Parameters: The new nickname is already set in the member object. Both old_nick and new_nick are not None.
See also
AbstractConversation.on_nick_changed() for the full specification.
- signal on_topic_changed(member, new_topic, *, muc_nick=None, **kwargs)¶
The topic of the conversation has changed.
Parameters: - member (Occupant or None) – The member object who changed the topic.
- new_topic (LanguageMap) – The new topic of the conversation.
- muc_nick (str) – The nickname of the occupant who changed the topic.
The member is matched by nickname. It is possible that the member is not in the room at the time the topic chagne is received (for example on a join).
muc_nick is always the nickname of the entity who changed the topic. If the entity is currently not joined or has changed nick since the topic was set, member will be None, but muc_nick is still the nickname of the actor.
Note
on_topic_changed() is emitted during join, iff a topic is set in the MUC.
- signal on_join(member, **kwargs)¶
A new occupant has joined the MUC.
Parameters: member (Occupant) – The member object of the new member. When this signal is called, the member is already included in the members.
- signal on_leave(member, *, muc_leave_mode=None, muc_actor=None, muc_reason=None, **kwargs)¶
An occupant has left the conversation.
Parameters: When this signal is called, the member has already been removed from the members.
- signal on_muc_suspend()¶
Emits when the stream used by this MUC gets destroyed (see on_stream_destroyed()) and the MUC is configured to automatically rejoin the user when the stream is re-established.
- signal on_muc_resume()¶
Emits when the MUC is about to be rejoined on a new stream. This can be used by implementations to clear their MUC state, as it is emitted before any events like presence are emitted.
The internal state of Room is cleared before on_resume() is emitted, which implies that presence events will be emitted for all occupants on re-join, independent on their presence before the connection was lost.
Note that on a rejoin, all presence is re-emitted.
- signal on_exit(*, muc_leave_mode=None, muc_actor=None, muc_reason=None, **kwargs)¶
Emits when the unavailable Presence stanza for the local JID is received.
Parameters:
The following signals inform users about state changes related to other occupants in the chat room. Note that different events may fire for the same presence stanza. A common example is a ban, which triggers on_affiliation_change() (as the occupants affiliation is set to "outcast") and then on_leave() (with LeaveMode.BANNED mode).
- signal on_muc_affiliation_changed(member, *, muc_actor=None, muc_reason=None, **kwargs)¶
Emits when the affiliation of a member with the room changes.
occupant is the Occupant instance tracking the occupant whose affiliation changed.
There may be actor and/or reason keyword arguments which provide details on who triggered the change in affiliation and for what reason.
- signal on_muc_role_changed(member, *, muc_actor=None, muc_reason=None, **kwargs)¶
Emits when the role of an occupant in the room changes.
occupant is the Occupant instance tracking the occupant whose role changed.
There may be actor and/or reason keyword arguments which provide details on who triggered the change in role and for what reason.
- class aioxmpp.muc.LeaveMode¶
The different reasons for a user to leave or be removed from MUC.
- DISCONNECTED¶
The local client disconnected. This only occurs in events referring to the local entity.
- SYSTEM_SHUTDOWN¶
The remote server shut down.
- NORMAL¶
The leave was initiated by the occupant themselves and was not a kick or ban.
- KICKED¶
The user was kicked from the room.
- AFFILIATION_CHANGE¶
Changes in the affiliation of the user caused them to be removed.
- MODERATION_CHANGE¶
Changes in the moderation settings of the room caused the user to be removed.
- BANNED¶
The user was banned from the room.
Inside rooms, there are occupants:
- class aioxmpp.muc.Occupant(occupantjid, is_self, presence_state=<PresenceState available>, presence_status={}, affiliation=None, role=None, jid=None)¶
A tracking object to track a single occupant in a Room.
- direct_jid¶
The real JID of the occupant.
If the MUC is anonymous and we do not have the permission to see the real JIDs of occupants, this is None.
- nick¶
The nickname of the occupant.
- presence_state¶
The PresenceState of the occupant.
- presence_status¶
The LanguageMap holding the presence status text of the occupant.
- affiliation¶
The affiliation of the occupant with the room.
- role¶
The current role of the occupant within the room.
Forms¶
- class aioxmpp.muc.ConfigurationForm¶
This is a XEP-0004 form template (see aioxmpp.forms) for MUC configuration forms.
The attribute documentation is auto-generated from XEP-0045; see there for details on the semantics of each field.
New in version 0.7.
- allowinvites¶
boolean field muc#roomconfig_allowinvites
Whether to Allow Occupants to Invite Others
- allowpm¶
list-single field muc#roomconfig_allowpm
Roles that May Send Private Messages
- changesubject¶
boolean field muc#roomconfig_changesubject
Whether to Allow Occupants to Change Subject
- enablelogging¶
boolean field muc#roomconfig_enablelogging
Whether to Enable Public Logging of Room Conversations
- getmemberlist¶
list-multi field muc#roomconfig_getmemberlist
Roles and Affiliations that May Retrieve Member List
- lang¶
text-single field muc#roomconfig_lang
Natural Language for Room Discussions
- maxhistoryfetch¶
text-single field muc#maxhistoryfetch
Maximum Number of History Messages Returned by Room
- maxusers¶
list-single field muc#roomconfig_maxusers
Maximum Number of Room Occupants
- membersonly¶
boolean field muc#roomconfig_membersonly
Whether to Make Room Members-Only
- moderatedroom¶
boolean field muc#roomconfig_moderatedroom
Whether to Make Room Moderated
- passwordprotectedroom¶
boolean field muc#roomconfig_passwordprotectedroom
Whether a Password is Required to Enter
- persistentroom¶
boolean field muc#roomconfig_persistentroom
Whether to Make Room Persistent
- presencebroadcast¶
list-multi field muc#roomconfig_presencebroadcast
Roles for which Presence is Broadcasted
- publicroom¶
boolean field muc#roomconfig_publicroom
Whether to Allow Public Searching for Room
- pubsub¶
text-single field muc#roomconfig_pubsub
XMPP URI of Associated Publish-Subscribe Node
- roomadmins¶
jid-multi field muc#roomconfig_roomadmins
Full List of Room Admins
- roomdesc¶
text-single field muc#roomconfig_roomdesc
Short Description of Room
- roomname¶
text-single field muc#roomconfig_roomname
Natural-Language Room Name
- roomowners¶
jid-multi field muc#roomconfig_roomowners
Full List of Room Owners
- roomsecret¶
text-private field muc#roomconfig_roomsecret
The Room Password
- whois¶
list-single field muc#roomconfig_whois
Affiliations that May Discover Real JIDs of Occupants
XSOs¶
Generic namespace¶
User namespace¶
- class aioxmpp.muc.xso.UserExt(status_codes=[], destroy=None, decline=None, invites=[], items=[], password=None)[source]¶