XMPP Schema

From Mugshot Developer Wiki

Jump to: navigation, search

This document is a little bit out of date, but is mostly accurate. Look at the file client/common/hippo/hippo-connection.c for the client-side source code and in wildfire/ for the Jive Wildfire plugin that sends it.

Our XMPP (aka Jabber) server is not usable as a plain chat server; its "identity system" is the Mugshot site instead of normal Jabber IDs, and its chat rooms are attached to Mugshot shares and groups. In other words we're repurposing an XMPP server to implement our own protocol.

We use this protocol to integrate the live social experience of Mugshot into the desktop and applications, when our design efforts suggest said integration makes sense.

Contents

Common elements

These are some elements that can be embedded in multiple different notifications; all of the notifications they are sent in currently have the namespace xmlns="http://dumbhippo.com/protocol/post" so these can be considered to be in that namespace as well.

user

Identifies a user of the system. If embedded in other tags, this can appear in abbreviated form with only the id attribute.

 <user id="ID"  name="NAME" smallPhotoUrl="URL"/>
ID 
GUID of user
NAME 
Human readable name of user
URL 
URL to use to display a small thumbnail of the user's identifying picture

resource

Used to refer to a resource such as an email address that identifies a person that is not a user of the system. If embedded in other tags, this can appear in abbreviated form with only the id attribute.

 <resource id="ID" name="NAME"/>
ID 
GUID of the resource
NAME 
Display form of the resource

group

Identifies a group of the system. If embedded in other tags, this can appear in abbreviated form with only the id attribute.

 <group id="ID" name="NAME" smallPhotoUrl=""/>
ID 
GUID of group
NAME 
Human readable name of the group
URL 
URL to use to display a small thumbnail of the group's identifying picture

post

Stores fixed information about a post.

  <post id="ID">
      <poster>POSTER_ID</poster>
      <href>HREF</href>
      <title>TITLE</title>
      <text>TEXT</text>
      <postDate>POSTDATE</postDate>
      [ <postInfo>POSTINFO</postInfo ]
      </postInfo>
      <recipients>
         RECIPIENTS = ( <user id="ID"/> | <resource id="ID"/> | <group id="ID"/> ) ...
      </recipients>
  </post>
POSTER_ID 
ID of the user posting the post
HREF 
URL of the link that was shared in this post
TITLE 
Title of the post
TEXT 
Descriptive body of the post
POSTDATE
Date of the post in Unix format (seconds since January 1, 1970)
POSTINFO
Optional chunk of XML information about the post in a form specific to a particular type of post.
RECIPIENTS
List of recipients of the post; these are <user/> <resource/> and <group/> elements in abbreviated form.

livepost

Represents information about a post that changes during the life of a post.

  <livepost id="ID">
      <recentViewers>
          RECENTVIEWERS = <viewer id="VIEWERID"/> ...
          [...]
      </recentViewers>
      <chattingUserCount>CHATTING_USER_COUNT></chattingUserCount>
      <totalViewers>TOTAL_VIEWERS</totalViewers>
  </livepost>
RECENTVIEWERS 
A small number of people who have recently viewed the post. (It's unclear why this has <viewer/> subelements rather than <user/> subelements.)
CHATTING_USER_COUNT 
Number of current participants in the chatroom for this post
TOTAL_VIEWERS 
Total number people who have ever looked at the post

Notifications sent from the server to clients

All of the following are sent inside <message/> element, of type 'headline', except for newPost, which is sent in a <message/> of type 'normal', so that it will be queued inside the XMPP server for later sending.

newPost

  <newPost xmlns="http://dumbhippo.com/protocol/post">
      <user/>
      [<user/> | <resource/> | <group/> ... ]
      <post/>
  </newpost>

livePostChanged

  <livePostChanged xmlns="http://dumbhippo.com/protocol/post">
      <livePost/>
  </livePostChanged>

mySpaceNameChanged

  <myspaceNameChanged xmlns="http://dumbhippo.com/protocol/myspace" name="NAME"/>

mySpaceContactComment

  <myspaceContactComment xmlns="http://dumbhippo.com/protocol/myspace"/>

hotness

  <hotness xmln="http://dumbhippo.com/protocol/hotness" value="HOTNESS"/>

activePostsChanged

  <activePostsChanged xmlns="http://dumbhippo.com/protocol/post">
     <post/>
     <livePost/> 
     [... (in pairs) ]
  </activePostsChanged>

prefs

  <prefs xmlns="http://dumbhippo.com/protocol/prefs">
     <prop key="KEY">VALUES</prop>
     [...]
  </prefs>


IQs

recentPosts

FIXME no docs yet

clientInfo

Request information about the required and available version of the client software for a particular platform.

  <iq type="get" id="N">
      <clientInfo xmlns="http://dumbhippo.com/protocol/clientinfo" platform="PLATFORM"/>
  </iq>

PLATFORM 
platform for which the client information should be retrieved. Currently, the supported values are 'windows' and 'x11'
  <iq type="result" id="N">
      <clientInfo xmlns="http://dumbhippo.com/protocol/clientinfo" 
           minimum="MINIMUM"
           current="CURRENT"
           download="DOWNLOAD"/>
  </iq>
MINIMUM
Minimum client version that is required for interoperation with the server. If the version of the client that is currently running is older than this, then the client should prompt the user for an upgrade and do nothing until the upgrade is completed.
CURRENT
The current version of the client available on the server. If the version of the client that is currently running is older than this, then the client should prompt the user for an upgrade, but may continue running until the download is complete or if the user does not upgrade immediately.

method

Generic call to perform an operation on the server. This is used only for one method currently, and that method doesn't actually do anything at the moment either. This approach should be considered deprecated.

  <iq type="set" id="N">
      <method xmlns="http://dumbhippo.com/protocol/servermethod" name="METHOD_NAME">
          <arg>VALUE</arg>...
      </method>
  </iq>
  <iq type="result" id="N"></iq>
METHOD_NAME
The name of the method to execute. Currently, only 'postClicked' is supported. 'postClicked' takes a single argument, the GUID of the post that the user clicked on.
VALUE
A string argument value to pass to the method.

hotness

  <iq type="get" id="N">
      <hotness xmlns="http://dumbhippo.com/protocol/hotness" type="getValue"/>
  </iq>
 
  <iq type="result" id="N">
      <hotness xmlns="http://dumbhippo.com/protocol/hotness" value="VALUE"/>
  </iq>

music

  <iq type="set" id="N">
      <music xmlns="http://dumbhippo.com/protocol/musc" type="musicChanged">
         <prop key="KEY">VALUE</prop>[...]
      </music>
  </iq>
  <iq type="result" id="N"></iq>
 
  KEY=type|format|name|artist|album|url|duration|fileSize|trackNumber|discIdentifier
  <iq type="set" id="N">
      <music xmlns="http://dumbhippo.com/protocol/music" type="primingTracks">
         <track>
             <prop key="KEY">VALUE</prop>[..]
         </track>[....]
      </music>
  </iq>
  <iq type="result" id="N"></iq>
  

(This is foul and disgusting to have the schema depend upon attribute values, no clue why separate element names aren't used)

addBlogComment


  <iq type="set" id="N">
     <addBlogComment xmlns="http://dumbhippo.com/protocol/myspace" type="addBlogComment">
        <commentId>COMMENT_ID</commentId>
        <posterId>POSTER_ID</posterId>
     </addBlogComment>
  </iq>
  <iq type="result" id="N"></iq>

(I have no clue why the type attribute mirrors the element name)

notifyContactComment =

  <iq type="set" id="N">
     <notifyContactComment xmlns="http://dumbhippo.com/protocol/myspace" type="notifyContactComment"
        name="NAME">
     </notifyContactComment>
  </iq>
  <iq type="result" id="N"></iq>

mySpaceInfo

  <iq type="get" id="N">
      <myspaceInfo xmlns="http://dumbhippo.com/protocol/myspace" type="getName"/>
  </iq>
 
  <iq type="result" id="N">
      <myspaceInfo xmlns="http://dumbhippo.com/protocol/myspaceInfo" mySpaceName="NAME">
  </iq>
  
  <iq type="get" id="N">
      <myspaceInfo xmlns="http://dumbhippo.com/protocol/myspace" type="getBlogComments"/>
  </iq>
 
  <iq type="result" id="N">
      <myspaceInfo xmlns="http://dumbhippo.com/protocol/myspaceInfo">
          <comment>
              <commentId>COMMENT_ID</commentId>
              <posterId>POSTER_ID</posterId>
          </comment>[...]
      </myspaceInfo>
  </iq>
  <iq type="get" id="N">
      <myspaceInfo xmlns="http://dumbhippo.com/protocol/myspace" type="getContacts"/>
  </iq>
 
  <iq type="result" id="N">
      <myspaceInfo xmlns="http://dumbhippo.com/protocol/myspaceInfo">
          <contact name="NAME" friendId="FRIEND_ID"/>
      </myspaceInfo>
  </iq>

prefs

 <iq type="get" id="N">
     <prefs xmlns="http://dumbhippo.com/protocol/prefs"/>
 </iq>
  <iq type="result" id="N">
      <prefs xmlns="http://dumbhippo.com/protocol/prefs">
         <prop key="KEY">VALUES</prop>
         [...]
      </prefs>
  </iq>

Chat Room Protocol

This is an adaption of the JEP-0045 Multi User chat protocol (http://www.jabber.org/jeps/jep-0045.html)

Client Joins Chat Room

Client sends a presence message to the room

<presence type="available" to="POST_ID@rooms.dumbhippo.com">
   <x xmlns="http://jabber.org/protocol/muc">
      <userInfo xmlns="http://dumbhippo.com/protocol/rooms" role="ROLE"/>
  </x>
</message>

ROLE=participant|visitor

If the same user joins a room multiple with different resources, these resources are combined into one "role" - if at least one resource has a role of "participant", then the user has a role of "participant", otherwise the user has a rule of "visitor".

If the client joining the chatroom causes the client to be present (with either role) for the first time, or the role to change, the presence message is echoed to all other room member clients:

<presence type="available" from="POST_ID@rooms.dumbhippo.com/USER_ID">
   <x xmlns="http://jabber.org/protocol/muc#user">
      <userInfo xmlns="http://dumbhippo.com/protocol/rooms" name="NAME" version="VERSION" role="ROLE"/>
   </x>
</presence>
USER_ID
GUID of the use newly joining the chatroom
NAME 
Human readable name of the user
VERSION 
User's version number (used when building URLs to headshot photos)
ROLE 
The role of the user, as above.

In the case of a change in role, the <presence type="available"/> message is simply resent with the new role. No intervening <presence type="unavailable"/> message is sent.

Room also sends <presence/> information for all other room members to the newly joined resource and a complete backlog of all past messages.

Client Leaves Chat Room

Client sends a presence message to the room

<presence type="available" to="POST_ID@rooms.dumbhippo.com"/>

If that causes the user to now be unavailable for the room, the room echos the message to all other room member clients:

<presence type="unavailable" from="POST_ID@rooms.dumbhippo.com/USER_ID"/>

If the user stays available but the users role changes, a <presence type="available/"> message is sent as discussed in the previous section.

Client adds a message to the chat room

Client sends the message to the room

<message to="POST_ID@rooms.dumbhippo.com">
    <body>BODY</body>
</message>
POST_ID 
GUID of the post this mesage is about
BODY 
Descriptive body of the new message

The room echos the message to all other client members of the room:

<message from="POST_ID@rooms.dumbhippo.com/USER_ID">
    <body>BODY</body>
    <messageInfo xmlns="http://dumbhippo.com/protocol/rooms"
        version="VERSION"
        name="NAME"
        timestamp="TIMESTAMP"
        serial="SERIAL"/>
</message>

USER_ID
The GUID of the user sending the message
NAME
The human readable name of the sending user
VERSION
The version of the sending user (used to build headshot URLs)
TIMESTAMP
The timestamp of the message, in milliseconds since the Unix epoch
SERIAL
The serial of the message: every message sent to the chatroom is assigned an integer serial in ascending order. This can be used to identify whether a message has been seen before or should be added to the list of messages displayed to the user.
Personal tools