muc — Multi-User-Chat support (XEP-0045)

This subpackage provides client-side support for XEP-0045.

New in version 0.5.

Using Multi-User-Chats

To start using MUCs in your application, you have to load the Service into the client, using summon().

class aioxmpp.muc.Service(client)

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.

join(mucjid, nick, *, password=None, history=None, autorejoin=True)

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).

It is recommended to attach the desired signals to the Room before yielding next, 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, ValueError is raised.

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.

coroutine set_affiliation(mucjid, jid, affiliation, *, reason=None)

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.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.

The service returns Room objects which are used to track joined MUCs:

class aioxmpp.muc.Room(service, mucjid)

Interface to a XEP-0045 multi-user-chat room.

mucjid

The (bare) structs.JID of the MUC which this Room tracks.

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).

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 Service to which it belongs and is thus dead.

this_occupant

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().

subject

The current subject of the MUC, as LanguageMap.

subject_setter

The nick name of the entity who set the subject.

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.

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:

occupants

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.

coroutine set_role(nick, role, *, reason=None)

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 kick has been acknowledged by the server. If the server returns an error, an appropriate aioxmpp.errors.XMPPError subclass is raised.

coroutine set_affiliation(jid, affiliation, *, reason=None)

Convenience wrapper around Service.set_affiliation(). See there for details, and consider its mucjid argument to be set to mucjid.

set_subject(subject)

Request to set the subject to subject. subject must be a mapping which maps LanguageTag tags to strings; None is a valid key.

Return the StanzaToken obtained from the stream.

leave()

Request to leave the MUC.

This sends unavailable presence to the bare mucjid. When the leave is completed, on_exit() fires.

See also

Method leave_and_wait()
A coroutine which calls leave() and returns when on_exit() is fired.
coroutine leave_and_wait()

Request to leave the MUC and wait for it. This effectively calls leave() and waits for the next on_exit() event.

send_tracked_message(body_or_stanza, *, timeout=datetime.timedelta(0, 120))

Send a tracked message. The first argument can either be a Message or a mapping compatible with body.

Return a MessageTracker which tracks the message. See the documentation of MessageTracker and MessageState for more details on tracking in general.

Tracking a MUC groupchat message supports tracking up to the DELIVERED_TO_RECIPIENT state. If a timeout is given, it must be a timedelta indicating the time span after which the tracking shall time out. timeout may be None to let the tracking never expire.

Warning

Some MUC implementations rewrite the id when the message is reflected in the MUC. In that case, tracking cannot succeed beyond the DELIVERED_TO_SERVER state, which is provided by the basic tracking interface.

To support these implementations, the timeout defaults at 120 seconds; this avoids that sending a message becomes a memory leak.

If the chat is exited in the meantime, the messages are set to UNKNOWN state. This also happens on suspension and resumption.

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):

actor = None
The UserActor instance of the corresponding UserItem, describing which other occupant caused the event.
reason = None
The reason text in the corresponding UserItem, which gives more information on why an action was triggered.
occupant = None
The Occupant object tracking the subject of the operation.

Signal handlers attached to any of the signals below must accept arbitrary keyword arguments for forward compatibility. If any of the above arguments is listed as positional in the signal signature, it is always present and handed as positional argument.

signal on_message(message, **kwargs)

Emits when a group chat Message message is received for the room. This is also emitted on messages sent by the local user; this allows tracking when a message has been spread to all users in the room.

The signal also emits during history playback from the server.

The occupant argument refers to the sender of the message, if presence has been broadcast for the sender. There are two cases where this might not be the case:

  1. if the signal emits during history playback, there might be no occupant with the given nick anymore.
  2. if the room is configured to not emit presence for occupants in certain roles, no Occupant instances are created and tracked for those occupants
signal on_subject_change(message, subject, **kwargs)

Emits when the subject of the room changes or is transmitted initially.

subject is the new subject, as a LanguageMap.

The occupant keyword argument refers to the sender of the message, and thus the entity who changed the subject. If the message represents the current subject of the room on join, the occupant may be None if the entity who has set the subject is not in the room currently. Likewise, the occupant may indeed refer to an entirely different person, as the nick name may have changed owners between the setting of the subject and the join to the room.

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_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_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(presence, occupant, mode, **kwargs)

Emits when the unavailable Presence stanza for the local JID is received.

mode indicates how the occupant got removed from the room, see the LeaveMode enumeration for possible values.

The occupant argument refers to the Occupant which is used to track the local user. If given in the stanza, the actor and/or reason keyword arguments are provided.

If autorejoin is false and the stream gets destroyed, or if the Service is unloaded from a node, this event emits with presence set to None.

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_join(presence, occupant, **kwargs)

Emits when a new occupant enters the room. occupant refers to the new Occupant object which tracks the occupant. The object will be indentical for all events related to that occupant, but its contents will change accordingly.

The original Presence stanza which announced the join of the occupant is given as presence.

signal on_leave(presence, occupant, mode, **kwargs)

Emits when an occupant leaves the room.

occupant is the Occupant instance tracking the occupant which just left the room.

mode indicates how the occupant got removed from the room, see the LeaveMode enumeration for possible values.

If the mode is not LeaveMode.NORMAL, there may be actor and/or reason keyword arguments which provide details on who triggered the leave and for what reason.

signal on_affiliation_change(presence, occupant, **kwargs)

Emits when the affiliation of an occupant 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_role_change(presence, occupant, **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.

signal on_status_change(presence, occupant, **kwargs)

Emits when the presence state and/or status of an occupant in the room changes.

occupant is the Occupant instance tracking the occupant whose status changed.

signal on_nick_change(presence, occupant, **kwargs)

Emits when the nick name (room name) of an occupant changes.

occupant is the Occupant instance tracking the occupant whose status changed.

Inside rooms, there are occupants:

class aioxmpp.muc.Occupant(occupantjid, presence_state=<PresenceState available>, presence_status={}, affiliation=None, role=None, jid=None)

A tracking object to track a single occupant in a Room.

occupantjid

The occupant JID of the occupant; this is the bare JID of the Room, with the nick of the occupant as resourcepart.

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.

jid

The actual JID of the occupant, if it is known.

XSOs

Generic namespace

class aioxmpp.muc.xso.GenericExt(*args, **kwargs)[source]
class aioxmpp.muc.xso.History(*, maxchars=None, maxstanzas=None, seconds=None, since=None)[source]

User namespace

class aioxmpp.muc.xso.UserExt(status_codes=[], destroy=None, decline=None, invites=[], items=[], password=None)[source]
class aioxmpp.muc.xso.Status(code)[source]
class aioxmpp.muc.xso.DestroyNotification(*args, **kwargs)[source]
class aioxmpp.muc.xso.Decline(*args, **kwargs)[source]
class aioxmpp.muc.xso.Invite(*args, **kwargs)[source]
class aioxmpp.muc.xso.UserItem(affiliation=None, jid=None, nick=None, role=None, reason=None)[source]
class aioxmpp.muc.xso.UserActor(*args, **kwargs)[source]
class aioxmpp.muc.xso.Continue(*args, **kwargs)[source]

Admin namespace

class aioxmpp.muc.xso.AdminQuery(*, items=[])[source]
class aioxmpp.muc.xso.AdminItem(affiliation=None, jid=None, nick=None, role=None, reason=None)[source]
class aioxmpp.muc.xso.AdminActor(*args, **kwargs)[source]

Owner namespace

class aioxmpp.muc.xso.OwnerQuery(*args, **kwargs)[source]
class aioxmpp.muc.xso.DestroyRequest(*args, **kwargs)[source]