Clone this wiki locally
Creating and sending presence stanzas can be done in four ways:
The first option is simply a plain presence stanza object. Any additional
information such as the
from attribute or
status element will need to be
added using the interfaces described below.
makePresence method accepts keyword parameters that match the stanza
object's interface, except that they are prefixed with a
p. For example,
to create a presence stanza from
firstname.lastname@example.org with a status of
"Curiouser and curiouser!" and a show type of
'xa' the following would
# Where xmpp is a SleekXMPP object xmpp.makePresence(email@example.com', pstatus='Curiouser and curiouser!', pshow='xa')
sendPresence method accepts the same keyword arguments as
makePresence and also queues the stanza to be sent to the XMPP server for
sendPresenceSubscription does not mirror the
keyword parameters of
makePresence. Instead, only
pnick are accepted. The
pnick option allows for adding an
nick element to the presence in accordance with
Using Presence Stanzas
Adding or removing a subscription is typically a four-step process:
- Send a presence stanza with type
- Receive a presence stanza of type
- Receive a presence stanza of type
- Send a presence stanza of type
If your program will be accepting subscriptions instead of initiating them, reverse the send and receive steps above.
Sending and replying to a presence subscription can be done using
xmpp.sendPresenceSubscription. In both cases, the
ptype keyword parameter must be set. If adding a
nick element to the
subscription request is desired,
xmpp.sendPresenceSubscription must be used.
# Where xmpp is a SleekXMPP object xmpp.sendPresence(firstname.lastname@example.org', ptype='subscribe') # -or- xmpp.sendPresenceSubscription(email@example.com', ptype='subscribe', pnick='Sleek')
Automatic Subscription Management
SleekXMPP already provides basic subscription management, but the automatic handling is to either accept or reject all subscription requests.
xmpp.auto_authorize controls how the agent responds to a
'subscribe' request. If
True, then a
'subscribed' response will be
False, then an
'unsubscribed' response will be sent to decline
the subscription. Setting
None will disable
xmpp.auto_subscribe is used when
xmpp.auto_authorize is set to
True then a
will be sent after accepting a subscription request.
- Accept and create bidirectional subscription requests:
xmpp.auto_authorize = True xmpp.auto_subscribe = True
- Accept only one-directional subscription requests:
xmpp.auto_authorize = True xmpp.auto_subscribe = False
- Decline all subscription requests:
xmpp.auto_authorize = False
- Use a custom subscription policy:
xmpp.auto_authorize = None
Custom Subscription Management
To create custom subscription management, the events
'presence_unsubscribed' must be listened for by event handlers.
Note: If your application will both send and receive subscription requests, you will need to keep a roster data structure that knows the status of all pending requests (the ClientXMPP implementation has such a roster object, but ComponentXMPP does not). Otherwise, you can create an infinite loop of two bots subscribing to the other's presence. If you only test with a human-facing client, most client programs will detect that situation and stop the cycle without reporting an error to you.
As an example, here is a sample snippet for custom subscription handling.
However, note that if you are using a server component, it is a good idea
to also set the
pfrom parameter when sending presence subscriptions.
Doing so allows you to support different subscription states for different
JIDs for the component, such as
# Where self is a SleekXMPP object, and self.backend is some arbitrary # object that you create depending on the needs of your application. # self.add_event_handler('presence_subscribe', self.subscribe) # self.add_event_handler('presence_subscribed', self.subscribed) # The unsubscribe and unsubscribed handlers will be similar. # If a component is being used, be sure to set the pfrom parameter # when sending presences if you are using multiple JIDs for the component, # such as firstname.lastname@example.org and email@example.com. def subscribe(self, presence): # If the subscription request is rejected. if not self.backend.allow_subscription(presence['from']): self.sendPresence(pto=presence['from'], ptype='unsubscribed') return # If the subscription request is accepted. self.sendPresence(pto=presence['from'], ptype='subscribed') # Save the fact that a subscription has been accepted, somehow. Here # we use a backend object that has a roster. self.backend.roster.subscribe(presence['from']) # If a bi-directional subscription does not exist, create one. if not self.backend.roster.sub_from(presence['from']): self.sendPresence(pto=presence['from'], ptype='subscribe') def subscribed(self, presence): # Store the new subscription state, somehow. Here we use a backend object. self.backend.roster.subscribed(presence['from']) # Send a new presence update to the subscriber. self.sendPresence(pto=presence['from'])
Presence probes (presence stanzas with a type of
'probe') are used to
discover the status of other XMPP agents. When a presence probe is received, a
presence stanza should be sent in reply that contains the agent's current state.
Some XMPP servers use presence probes to generate the initial burst of presence
stanzas to populate the roster when an agent connects.
Using presence probes can be done in two ways, either as a recipient or as a
sender of the probes. Receiving and handling a probe is done by listening for
'presence_probe' event, as so:
# Where self is a SleekXMPP object: # def __init__(self, ...): # ... # self.add_event_handler('presence_probe', self.handle_probe) def handle_probe(self, presence): sender = presence['from'] # Populate the presence reply with the agent's current status. self.sendPresence(pto=sender, pstatus="Busy studying XMPP", pshow="dnd")
It is a good idea for server components to respond to presence probes since the main XMPP server will usually not respond on its behalf.
Sending a presence probe can be done at any time. It can be especially useful for XMPP components that require some form of registration before interacting with other agents. If a client already has the component in its roster, then the component can receive a presence stanza before registration takes place, and then not receive a presence stanza after registration. By sending a presence probe after a client registers, the server component can be sure to get a new presence update once registration is completed. Issuing a presence probe is done like so:
# Where xmpp is a SleekXMPP object xmpp.sendPresence(firstname.lastname@example.org', ptype='probe')
Standard stanza interface. The JID of the presence stanza's sender.
Standard stanza interface. An
'id'value may be used to track and associate series of stanzas.
A number greater than or equal to zero. Most XMPP servers will route messages to connections with the highest priority. Setting the priority to
'0'is usually recommended for bots that will not interact directly with humans.
Free form, human readable text that describes the agent's status. For example,
"Ready for data", or
"Executing job". The status text will usually be displayed in a client's roster.
Standard stanza interface. The JID of the presence stanza's recipient.
Be careful, this attribute does not correspond exactly with the XML of a presence stanza since. The values that may be used with
'type'key maps to both the
typeattribute and the
showelement of a presence stanza.
A standard stanza interface method. If the presence has a type of
'unsubscribe', the reply presence will have a type of
The XEP-0045 plugin adds
support for the
<x xmlns="http://jabber.org/protocol/muc#user" />
element as part of presence stanzas. Not every possible subelement of
xmlns="http://jabber.org/protocol/muc#user" /> is supported, but interfaces
<item /> element are provided.
Provide the agent's affiliation with the chatroom. Possible values are:
''for no affiliation. Affiliations are persisted across visits to the chatroom and are useful for controlling who may enter the room.
If the chatroom is not anonymous, or the agent has sufficient privileges, then the JID for other members in the chatroom may be found from their presence updates using
The nickname used by a participant in the chatroom. It is equivalent to
Note: It is not possible to change the agent's room nick by modifying
presence['muc']['nick']. The nick must be set before joining the room.
The chatroom participant's role in the room. Possible values are:
''for no role. Roles are typically more temporary than affiliations and are used to control what room participants may do to manage the room's configuration and the roles of other participants.
The name of the chatroom. It is equivalent to
Note: It is not possible to change the room name by modifying