This JEP defines an XMPP protocol extension for exchanging user avatars.
WARNING: This Standards-Track JEP is Experimental. Publication as a Jabber Enhancement Proposal does not imply approval of this proposal by the Jabber Software Foundation. Implementation of the protocol described herein is encouraged in exploratory implementations, but production systems should not deploy implementations of this protocol until it advances to a status of Draft.
Status: Experimental
Type: Standards Track
Number: 0084
Version: 0.6
Last Updated: 2005-04-13
JIG: Standards JIG
Approving Body: Jabber Council
Dependencies: XMPP Core, JEP-0030, JEP-0060
Supersedes: JEP-0008
Superseded By: None
Short Name: avatar
Wiki Page: <http://wiki.jabber.org/index.php/User Avatar (JEP-0084)>
Email: stpeter@jabber.org
JID: stpeter@jabber.org
Email: pgmillard@jabber.org
JID: pgmillard@jabber.org
Email: temas@jabber.org
JID: temas@jabber.org
Email: julian@jabber.org
JID: julian@jabber.org
This Jabber Enhancement Proposal is copyright 1999 - 2005 by the Jabber Software Foundation (JSF) and is in full conformance with the JSF's Intellectual Property Rights Policy <http://www.jabber.org/jsf/ipr-policy.shtml>. This material may be distributed only subject to the terms and conditions set forth in the Creative Commons Attribution License (<http://creativecommons.org/licenses/by/2.5/>).
The preferred venue for discussion of this document is the Standards-JIG discussion list: <http://mail.jabber.org/mailman/listinfo/standards-jig>.
The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 3920) and XMPP IM (RFC 3921) specifications contributed by the Jabber Software Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this JEP has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Many communication applications allow for the association of a small image or icon with a user of that application. Usually, such an "avatar" is not intended to be an accurate picture of the user's actual physical appearance, but rather a representation (often fanciful) of the user's desired self-image or a transient state of the user (such as a mood or activity). This proposal outlines a way to incorporate avatars into current Jabber/XMPP systems by layering this functionality on top of Publish-Subscribe [1] (pubsub).
Pubsub was chosen as the base layer for avatars because of the need to publish a large amount of data to any number of users. Pubsub provides a straightforward mechanism for any user to subscribe to the avatar source and receive notifications from the publisher. The protocol defined herein uses two pubsub nodes: one node for "metadata" about the avatar state (called the "metadata node") and one for the avatar data itself (called the "data node"). This separation of metadata from data conserves bandwidth and enables both the publisher and the subscriber to cache the avatar data. (For example, a user might toggle between two or three avatars, in which case the user's contacts can display a locally cached version of the images without having to retrieve the full image each time.)
This JEP also allows storage of avatar data at a URL accessible via HTTP (see RFC 2616 [2]). This can be helpful as a fallback mechanism if a pubsub-aware data repository is not available. It also makes it possible for avatar images to be hosted on public websites (e.g., an end-user-oriented community site) and retrieved from that site rather than handled directly by the publishing client in any fashion.
This JEP also enables XMPP applications to optionally integrate with third-party services that host user avatars (e.g., online gaming systems and virtual worlds).
This JEP addresses the following use cases for avatar publishers:
This JEP addresses the following use cases for avatar subscribers:
The root or "wrapper" element for all avatar-related communications is the <avatar/> element qualified by the 'http://jabber.org/protocol/avatar' namespace. There are four allowable child elements of the <avatar/> root element, as described below.
The <data/> child element is used to communicate avatar data:
<data id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' type='image/png' bytes='12345' height='64' width='64'> IMAGE DATA </data>
The <data/> element MUST possess the following attributes:
The value of the 'type' attribute MAY be any IANA-registered content type of type "image" or "video". [4] Support for the "image/png" content type is REQUIRED. Support for the "image/gif" and "image/jpeg" content types is RECOMMENDED. Support for any other content type is OPTIONAL.
The value of the 'id' attribute MUST be the SHA1 (RFC 3174 [5]) hash of the image data, and the same value MUST be used as the ItemID of the pubsub item for the avatar data (see below).
The <data/> element MUST contain content that is appropriate for the specified content type:
Support for the <data/> element is REQUIRED.
The <info/> child element is used to communicate avatar metadata:
<info id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' url='http://www.jabbercentral.org/avatars/happy.png' type='image/png' bytes='12345' height='64' width='64'/>
The <info/> child element MUST be empty.
The <info/> child element MUST possess the following attributes:
The <info/> element MUST possess at least one of the following attributes, and MAY possess both:
In addition, the <info/> element MAY possess the following attribute:
The <avatar/> root element MAY contain more than one <info/> element. Each element MUST specify metadata for the same avatar but in alternate formats (e.g., "image/png", "image/gif", and "image/jpeg"), and one of the formats MUST be "image/png" in order to help ensure interoperability.
Support for the <info/> element is REQUIRED.
The <pointer/> child element is used to point to an avatar that is not published via pubsub or HTTP, but rather is provided by a third-party service such as an online gaming system or virtual world:
<avatar xmlns='http://jabber.org/protocol/avatar'> <pointer> <x xmlns='http://example.com/virtualworlds'> <game>Ancapistan</game> <character>Kropotkin</character> </x> </pointer> </avatar>
The <pointer/> element MAY possess the following attributes if the publishing application has the relevant information:
The content of the <pointer/> element MUST be a properly-namespaced child element that specifies information about how to retrieve the avatar from the third-party service. The structure for any such child element is out of scope for this JEP.
Even if the <pointer> element is included, it MUST be preceded by at least one instance of the <info/> element so that implementations that do not support the <pointer/> element can display a "fallback" format of the avatar (at a minimum, "image/png").
Support for the <pointer/> element is OPTIONAL.
The <stop/> child element is used to signal that avatar publishing has been disabled:
<avatar xmlns='http://jabber.org/protocol/avatar'> <stop/> </avatar>
The <stop/> element MUST be empty and MUST NOT possess any attributes.
Support for the <stop/> element is REQUIRED.
In order to publish notifications related to its avatar, the avatar publisher MUST first create a node for its avatar metadata:
<iq type='set' from='juliet@capulet.com/chamber' to='pubsub.shakespeare.lit' id='create1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <create node='avatar/info/juliet@capulet.com'/> <configure/> </pubsub> </iq>
<iq type='result' from='pubsub.shakespeare.lit' to='juliet@capulet.com/chamber' id='create1'/>
The avatar publisher SHOULD also publish information about its metadata node to its XMPP server via the "disco publish" protocol specified in Service Discovery [7], so that subscribers to its avatar data can discover the metadata node even when the publisher is offline.
<iq type='set' from='juliet@capulet.com/chamber' id='dset1'> <query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/avatar'> <item jid='pubsub.shakespeare.lit' node='avatar/info/juliet@capulet.com' action='update'/> </query> </iq>
There are two allowable sources from which subscribers retrieve avatar data:
If a data node is used, obviously the publisher needs to create a data node in addition to the already-created metadata node:
<iq type='set' from='juliet@capulet.com/chamber' to='pubsub.shakespeare.lit' id='create2'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <create node='avatar/data/juliet@capulet.com'/> <configure/> </pubsub> </iq>
<iq type='result' from='pubsub.shakespeare.lit' to='juliet@capulet.com/chamber' id='create2'/>
Before updating the avatar metadata node, the publisher MUST make sure that the avatar data is available at the data node or URL. When publishing the avatar data to the data node, the publisher MUST ensure that the value of the item 'id' attribute is the SHA1 hash of the image data (this can be used by the subscriber to determine if a cached copy is still valid).
The following example illustrates the XML structure to be sent when publishing avatar data to the data node.
<iq type='set' from='juliet@capulet.com/chamber' to='pubsub.shakespeare.lit' id='publish1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='avatar/data/juliet@capulet.com'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <avatar xmlns='http://jabber.org/protocol/avatar'> <data id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' type='image/png' bytes='12345' height='64' width='64'> qANQR1DBwU4DX7jmYZnncm... </data> </avatar> </item> </publish> </pubsub> </iq>
<iq type='result' from='pubsub.shakespeare.lit' to='juliet@capulet.com/chamber' id='publish1'/>
Whenever the publisher wishes to change its current avatar, it MUST update the metadata node.
The following example shows metadata specifying avatar data that is available in only one format ("image/png") and accessible only at a pubsub data node:
<iq type='set' from='juliet@capulet.com/chamber' to='pubsub.shakespeare.lit' id='publish2'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='avatar/info/juliet@capulet.com'> <item id='current'> <avatar xmlns='http://jabber.org/protocol/avatar'> <info id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' type='image/png' bytes='12345' height='64' width='64'/> </avatar> </item> </publish> </pubsub> </iq>
Subscribers to the avatar would then receive an update from the metadata node:
<message to='romeo@montague.net' from='pubsub.shakespeare.lit'> <x xmlns='http://jabber.org/protocol/pubsub#event'> <items node='avatar/info/juliet@capulet.com'> <item id='current'> <avatar xmlns='http://jabber.org/protocol/avatar'> <info id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' type='image/png' bytes='12345' height='64' width='64'/> </avatar> </item> </items> </x> </message>
The following example shows metadata specifying avatar data that is available in only one format ("image/gif") and accessible only at an HTTP URL:
<iq type='set' from='juliet@capulet.com/chamber' to='pubsub.shakespeare.lit' id='publish2'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='avatar/info/juliet@capulet.com'> <item id='current'> <avatar xmlns='http://jabber.org/protocol/avatar'> <info id='222f4b3c50d7b0df729d299bc6f8e9ef9066971f' url='http://www.jabbercentral.org/avatars/happy.gif' type='image/gif' bytes='23456' height='64' width='64'/> </avatar> </item> </publish> </pubsub> </iq>
Subscribers to the avatar would then receive an update from the metadata node:
<message to='romeo@montague.net' from='pubsub.shakespeare.lit'> <x xmlns='http://jabber.org/protocol/pubsub#event'> <items node='avatar/info/juliet@capulet.com'> <item id='current'> <avatar xmlns='http://jabber.org/protocol/avatar'> <info id='222f4b3c50d7b0df729d299bc6f8e9ef9066971f' url='http://www.jabbercentral.org/avatars/happy.gif' type='image/gif' bytes='23456' height='64' width='64'/> </avatar> </item> </items> </x> </message>
The following example shows metadata specifying avatar data that is available in multiple formats, each of which is accessible at both an HTTP URL and a pubsub data node:
<iq type='set' from='juliet@capulet.com/chamber' to='pubsub.shakespeare.lit' id='publish3'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='avatar/info/juliet@capulet.com'> <item id='current'> <avatar xmlns='http://jabber.org/protocol/avatar'> <info id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' url='http://www.jabbercentral.org/avatars/happy.png' type='image/png' bytes='12345' height='64' width='64'/> <info id='222f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' url='http://www.jabbercentral.org/avatars/happy.gif' type='image/gif' bytes='23456' height='64' width='64'/> <info id='333f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' url='http://www.jabbercentral.org/avatars/happy.mng' type='image/mng' bytes='78912' height='64' width='64'/> </avatar> </item> </publish> </pubsub> </iq>
Subscribers to the avatar would then receive an update from the metadata node:
<message to='romeo@montague.net' from='pubsub.shakespeare.lit'> <x xmlns='http://jabber.org/protocol/pubsub#event'> <items node='avatar/info/juliet@capulet.com'> <item id='current'> <avatar xmlns='http://jabber.org/protocol/avatar'> <info id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' url='http://www.jabbercentral.org/avatars/happy.png' type='image/png' bytes='12345' height='64' width='64'/> <info id='222f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' url='http://www.jabbercentral.org/avatars/happy.gif' type='image/gif' bytes='23456' height='64' width='64'/> <info id='333f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' url='http://www.jabbercentral.org/avatars/happy.mng' type='image/mng' bytes='78912' height='64' width='64'/> </avatar> </item> </items> </x> </message>
In order to temporarily disable any avatar images, the publishing entity publishes an empty <stop/> element to the metadata node:
<iq type='set' from='juliet@capulet.com/chamber' to='pubsub.shakespeare.lit' id='publish3'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <publish node='avatar/info/juliet@capulet.com'> <item id='current'> <avatar xmlns='http://jabber.org/protocol/avatar'> <stop/> </avatar> </item> </publish> </pubsub> </iq>
Other clients can see if avatar support is available by sending a Service Discovery items request to the other client and looking for the avatar item. The request SHOULD be sent to the bare JID (<user@host>) of the other user (but may be sent to a full JID), further specified by a disco node of "http://jabber.org/protocol/avatar". (Sending the request to the bare JID enables one to discover whether an offline user has published disco information regarding avatars.)
<iq type='get' from='romeo@montague.net/orchard' to='juliet@capulet.com' id='items1'> <query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/avatar'/> </iq>
The result contains an item with the JID of the pubsub service where the publisher's avatar metadata (but not the avatar data itself) is published, along with the specific node for that metadata:
<iq type='result' from='juliet@capulet.com' to='romeo@montague.net/orchard' id='items1'> <query xmlns='http://jabber.org/protocol/disco#items' node='http://jabber.org/protocol/avatar'> <item jid='pubsub.shakespeare.lit' node='avatar/info/juliet@capulet.com'/> </query> </iq>
The subscriber application SHOULD then send a disco#info request to the node in order to determine its identity.
In order to receive notifications of changes to the publisher's avatar, a subscriber MUST subscribe to the metadata node maintained by the publisher.
<iq type='set' from='romeo@montague.net/orchard' to='pubsub.shakespeare.lit' id='sub1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <subscribe node='avatar/info/juliet@capulet.com' jid='romeo@montague.net'/> </pubsub> </iq>
<iq type='result' from='pubsub.shakespeare.lit' to='romeo@montague.net/orchard' id='sub1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <entity node='avatar/info/juliet@capulet.com' jid='romeo@montague.net' affiliation='none' subscription='subscribed'/> </pubsub> </iq>
The subscriber will now receive notifications published to the metadata node by the avatar publisher.
Alternatively, the subscriber MAY retrieve the current avatar metadata from the pubsub service:
<iq type='get' from='romeo@montague.net/orchard' to='pubsub.shakespeare.lit' id='ps-items1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='avatar/info/juliet@capulet.com' max_items='1'/> </pubsub> </iq>
<iq type='result' from='pubsub.shakespeare.lit' to='romeo@montague.net/orchard'' id='ps-items1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='avatar/info/juliet@capulet.com'> <item> <avatar xmlns='http://jabber.org/protocol/avatar'> <info id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f' jid='pubsub.shakespeare.lit' node='avatar/data/juliet@capulet.com' type='image/png' bytes='12345' height='64' width='64'/> </avatar> </item> </items> </pubsub> </iq>
If the <avatar/> element sent to the metadata node possesses a 'jid' attribute (optionally supplemented by a 'node' attribute), the avatar data is hosted at a pubsub service. Therefore, in order to retrieve the avatar image data, the requesting entity can send a request to the specified JID or JID+node, including an 'id' attribute that matches the value provided in the metadata result.
<iq type='get' from='romeo@montague.net/orchard' to='pubsub.shakespeare.lit' id='ps-items2'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='avatar/data/juliet@capulet.com'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'/> </items> </pubsub> </iq>
The result contains the avatar image data:
<iq type='result' from='pubsub.shakespeare.lit' id='ps-items2'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='avatar/data/juliet@capulet.com'> <item id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> <avatar xmlns='http://jabber.org/protocol/avatar'> <data id='111f4b3c50d7b0df729d299bc6f8e9ef9066971f'> type='image/png' bytes='12345' height='64' width='64'> qANQR1DBwU4DX7jmYZnncm... </data> </avatar> </item> </items> </pubsub> </iq>
If the <avatar/> element sent to the metadata node possesses a 'url' attribute, the avatar data is hosted at a URL. Therefore, in order to retrieve the avatar image data, the requesting entity can send an HTTP request to the specified URL.
Certain restrictions are placed upon the image. First, the image height and width SHOULD be between thirty-two (32) and ninety-six (96) pixels. The suggested size is sixty-four (64) pixels high and sixty-four (64) pixels wide. Images SHOULD be square, but this is not required. Finally, images SHOULD use less than eight (8) kilobytes of data.
There are no security features or concerns related to this proposal.
This JEP makes use of IANA-registered content types, but requires no interaction with the Internet Assigned Numbers Authority (IANA) [9].
The Jabber Registrar [10] shall include 'http://jabber.org/protocol/avatar' in its registry of protocol namespaces.
<?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='http://jabber.org/protocol/avatar' xmlns='http://jabber.org/protocol/avatar' elementFormDefault='qualified'> <xs:element name='avatar'> <xs:complexType> <xs:choice> <xs:element ref='data'/> <xs:sequence> <xs:element ref='info' maxOccurs='unbounded'/> <xs:element ref='pointer' minOccurs='0' maxOccurs='unbounded'/> </xs:sequence> <xs:element name='stop' type='empty'/> </xs:choice> </xs:complexType> </xs:element> <xs:element name='data'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:string'> <xs:attribute name='bytes' type='xs:string' use='required'/> <xs:attribute name='type' type='xs:string' use='required'/> <xs:attribute name='height' type='xs:string' use='required'/> <xs:attribute name='id' type='xs:string' use='required'/> <xs:attribute name='width' type='xs:string' use='required'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='info'> <xs:complexType> <xs:simpleContent> <xs:extension base='empty'> <xs:attribute name='bytes' type='xs:string' use='required'/> <xs:attribute name='type' type='xs:string' use='required'/> <xs:attribute name='height' type='xs:string' use='required'/> <xs:attribute name='id' type='xs:string' use='required'/> <xs:attribute name='jid' type='xs:string' use='optional'/> <xs:attribute name='node' type='xs:string' use='optional'/> <xs:attribute name='url' type='xs:string' use='optional'/> <xs:attribute name='width' type='xs:string' use='required'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='pointer'> <xs:complexType> <xs:sequence> <xs:any namespace='##other'/> </xs:sequence> <xs:attribute name='bytes' type='xs:string' use='optional'/> <xs:attribute name='type' type='xs:string' use='optional'/> <xs:attribute name='height' type='xs:string' use='optional'/> <xs:attribute name='id' type='xs:string' use='optional'/> <xs:attribute name='width' type='xs:string' use='optional'/> </xs:complexType> </xs:element> <xs:simpleType name='empty'> <xs:restriction base='xs:string'> <xs:enumeration value=''/> </xs:restriction> </xs:simpleType> </xs:schema>
1. JEP-0060: Publish-Subscribe <http://www.jabber.org/jeps/jep-0060.html>.
2. RFC 2616: Hypertext Transport Protocol -- HTTP/1.1 <http://www.ietf.org/rfc/rfc2616.txt>.
3. By "accessible via HTTP" is meant that the data is available at an http: or https: URI.
4. The IANA registry of content types is located at <http://www.iana.org/assignments/media-types/>.
5. RFC 3174: US Secure Hash Algorithm 1 (SHA1) <http://www.ietf.org/rfc/rfc3174.txt>.
6. RFC 3548: The Base16, Base32, and Base64 Data Encodings <http://www.ietf.org/rfc/rfc3548.txt>.
7. JEP-0030: Service Discovery <http://www.jabber.org/jeps/jep-0030.html>.
8. JEP-0054: vcard-temp <http://www.jabber.org/jeps/jep-0054.html>.
9. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.
10. The Jabber Registrar maintains a list of reserved Jabber protocol namespaces as well as registries of parameters used in the context of protocols approved by the Jabber Software Foundation. For further information, see <http://www.jabber.org/registrar/>.
END