Skip to content

Instantly share code, notes, and snippets.

@imaginator
Created December 27, 2010 08:45
Show Gist options
  • Select an option

  • Save imaginator/755971 to your computer and use it in GitHub Desktop.

Select an option

Save imaginator/755971 to your computer and use it in GitHub Desktop.
buddycloud channel API
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>untitled</title>
<meta name="generator" content="TextMate http://macromates.com/">
<meta name="author" content="Simon Tennant">
<!-- Date: 2010-12-27 -->
</head>
<body>
9.6 User is added to a "closed channel" by channel owner
9.7 User requests all channels he's subscribed to
9.8 User gets subscribers or affiliations of a pubsub node (channel followers)
9.9 User Unsubscribes from a channel
9.10 User removes user from a closed access channel
9.11 User (owner or moderator) blacklists another user from a channel
9.12 Channel owner can add/remove moderators of the channel
9.13 User publishes an item to a channel
9.14 User Deletes a channel entry
9.14.1 By moderator / owner
9.15 Owner deletes a channel
9.16 User gets "offline items" of a channel
9.17 Invite user to a pubSub -channel
10 Example how channel privilege request could happen
11 Walkthrough
11.1 User subscribes to the pubsub service
11.1.1 What happens when user subscribes to the pubsub service
11.2 User adds her roster to her channel
11.3 User publishes her mood
11.4 User publishes her first post on her channel
11.5 User joins to an open channel
11.6 User is set as moderator on a channel
11.7 User blocks a person on the open channel
11.8 User removes a post on the open channel
11.9 User unsubscribes from a channel
11.10 User get's blocked from a channel
-->
<!-- cut below here -->
<h2>API Notes</h2>
<ul>
<li>For debugging use PSI to send raw XMPP stanzas.<img border="0" height="302" src="https://sites.google.com/a/buddycloud.com/channels/_/rsrc/1293012728170/api/Screen%20shot%202010-12-22%20at%2011.09.53.png?height=302&amp;width=400" style="display:inline;float:right;margin-top:5px;margin-right:10px;margin-bottom:5px;margin-left:10px" width="400" /></li>
<li>Ensure that you are talking to the authoritative channel server for each domain.</li>
<li>Results can be sent using <a href="http://xmpp.org/extensions/xep-0059.html">result set management</a></li>
</ul>
<h2>Channel server basics</h2>
<h3>Create channel / Go online</h3>
<p>
Sending presence to the channel server tells the server that your client is online. It also creates a channel for the sending JID if one doesn't currently exist.
</p>
<code lang="XML">
<presence from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com"/>
</code>
<p>The server replies</p>
<code lang="XML">
<presence to="channeluser@example.com/ChannelCompatibleClient" from="channelserver.example.com">
<status>Small happy channel server!</status>
</presence>
</code>
<h3>Allow the channel server to when you are online</h3>
<p>Allow the channel server to subscribe to your presence</h3>
<code lang="XML">
<presence to='comptest.xmpp.lobstermonster.org' type='subscribed' />
</code>
<h3>Go offline</h3>
<p>Stop receiving channel updates</p>
<code lang="XML">
<presence from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="unavailable"/>
</code>
<h3>Retrieve your channel subscriptions</h3>
<p>get a list of subscribed channels</p>
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="get" id="13:01">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<subscriptions/>
<set xmlns="http://jabber.org/protocol/rsm">
<max>50</max>
</set>
</pubsub>
</iq>
</code>
<p>The server replies with your subscriptions <strong>and</strong> your role</p>
<code lang="XML">
<iq type="result" id="13:01" from="channelserver.example.com" to="channeluser@example.com/ChannelCompatibleClient">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<subscriptions>
<subscription node="/user/channeluser@example.com/geo/current" jid="channeluser@example.com" subscription="subscribed" affiliation="owner"/>
<subscription node="/user/channeluser@example.com/geo/previous" jid="channeluser@example.com" subscription="subscribed" affiliation="owner"/>
<subscription node="/user/channeluser@example.com/geo/future" jid="channeluser@example.com" subscription="subscribed" affiliation="owner"/>
<subscription node="/user/channeluser@example.com/mood" jid="channeluser@example.com" subscription="subscribed" affiliation="owner"/>
<subscription node="/user/charlesbrompton@example.com/channel" jid="channeluser@example.com" subscription="subscribed" affiliation="publisher"/>
<subscription node="/user/gulli@example.com/channel" jid="channeluser@example.com" subscription="subscribed" affiliation="publisher"/>
<subscription node="/user/nicola@example.com/channel" jid="channeluser@example.com" subscription="subscribed" affiliation="publisher"/>
<subscription node="/channel/breakfast" jid="channeluser@example.com" subscription="subscribed" affiliation="member"/>
<subscription node="/channel/fridge" jid="channeluser@example.com" subscription="subscribed" affiliation="publisher"/>
<subscription node="/channel/buddycloudsuggestions" jid="channeluser@example.com" subscription="subscribed" affiliation="moderator"/>
<subscription node="/channel/abuse" jid="channeluser@example.com" subscription="subscribed" affiliation="owner"/>
<set xmlns="http://jabber.org/protocol/rsm">
<first>/channel/goodnight</first>
<last>/channel/abuse</last>
<count>174</count>
</set>
</subscriptions>
</pubsub>
</iq>
</code>
<h3>Sync your channel messages</h3>
<p>The client sends the highest postID to the server</p>
<code lang="XML">
<presence from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com">
<set xmlns="http://jabber.org/protocol/rsm">
<after>1291048651903</after>
</set>
</presence>
</code>
<p>The server will lookup more recent posts and begin sending them (ideally with RSM enabled) to the client</p>
<code lang="XML">
<iq type="set" id="bc:HkXzD" from="channelserver.example.com" to="channeluser@example.com/ChannelCompatibleClient">
<event xmlns="http://jabber.org/protocol/pubsub#event">
<items node="/user/catherine@example.com/channel">
<item id="1285682065577">
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
<author>
<name>Catherine Filmgirl</name>
<jid xmlns="http://buddycloud.com/atom-elements-0">catherine@example.com</jid>
<affiliation xmlns="http://buddycloud.com/atom-elements-0">owner</affiliation>
</author>
<content type="text">I spent the weekend at the lake house and had a great time grilling and swimming. I really needed the break after last week.</content>
<published>2010-09-28T14:08:11Z</published>
<updated>2010-09-28T14:08:11Z</updated>
<id>/user/catherine@example.com/channel:1285682065577</id>
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<text>United States of America</text>
<country>United States of America</country>
</geoloc>
</entry>
</item>
<item id="1285682908733">
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
<author>
<jid xmlns="http://buddycloud.com/atom-elements-0">catherine@example.com</jid>
<affiliation xmlns="http://buddycloud.com/atom-elements-0">publisher</affiliation>
</author>
<content type="text">Cool Catherine! Next time you go to the lake house I'm coming with you.</content>
<published>2010-09-28T14:08:28Z</published>
<updated>2010-09-28T14:08:28Z</updated>
<id>/user/catherine@example.com/channel:1285682908733</id>
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<text>United States of America</text>
<country>United States of America</country>
</geoloc>
<thr:in-reply-to ref="1285682065577"/>
</entry>
</item>
<item id="1285682913618">
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
<author>
<name>Catherine Filmgirl</name>
<jid xmlns="http://buddycloud.com/atom-elements-0">nancy@example.com</jid>
<affiliation xmlns="http://buddycloud.com/atom-elements-0">publisher</affiliation>
</author>
<content type="text">You are always welcome to join me. Next trip is in three weeks time.</content>
<published>2010-09-28T14:08:33Z</published>
<updated>2010-09-28T14:08:33Z</updated>
<id>/user/catherine@example.com/channel:1285682913618</id>
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<text>United States of America</text>
<country>United States of America</country>
</geoloc>
<thr:in-reply-to ref="1285682065577"/>
</entry>
</item>
<item id="1285682915691">
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
<author>
<jid xmlns="http://buddycloud.com/atom-elements-0">mike@example.com</jid>
<affiliation xmlns="http://buddycloud.com/atom-elements-0">publisher</affiliation>
</author>
<content type="text">May I come too?</content>
<published>2010-09-28T14:08:35Z</published>
<updated>2010-09-28T14:08:35Z</updated>
<id>/user/catherine@example.com/channel:1285682915691</id>
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<text>United States of America</text>
<country>United States of America</country>
</geoloc>
<thr:in-reply-to ref="1285682065577"/>
</entry>
</item>
<item id="1285682934790">
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
<author>
<jid xmlns="http://buddycloud.com/atom-elements-0">catherine@example.com</jid>
<affiliation xmlns="http://buddycloud.com/atom-elements-0">owner</affiliation>
</author>
<content type="text">No.</content>
<published>2010-09-28T14:08:54Z</published>
<updated>2010-09-28T14:08:54Z</updated>
<id>/user/catherine@example.com/channel:1285682934790</id>
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<text>United States of America</text>
<country>United States of America</country>
</geoloc>
<thr:in-reply-to ref="1285682065577"/>
</entry>
</item>
</items>
</event>
</iq>
</code>
<h3>Delete/retract a channel post</h3>
<p>The client sends</p>
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="set" id="retractitem:32">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<retract node="/user/channeluser@example.com/channel" notify="1">
<item id="1291048772456"/>
</retract>
</pubsub>
</iq>
</code>
<p>Server replies</p>
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="set" id="18:23:1">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<publish node="/user/channeluser@example.com/channel">
<item>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
<updated>2010-11-29T16:39:38Z</updated>
<thr:in-reply-to ref="1291048772456"/>
<author>
<jid xmlns="http://buddycloud.com/atom-elements-0">channeluser@example.com</jid>
</author>
<content type="text">A test comment post</content>
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<text>Schwabing Ost, Germany</text>
<locality>Schwabing Ost</locality>
<country>Germany</country>
</geoloc>
</entry>
</item>
</publish>
</pubsub>
</iq>
</code>
<p>A retraction message is sent to all online clients</p>
<code lang="XML">
<message from="channelserver.example.com" id="bc:MGV3B" to="imranraza@example.com">
<event xmlns="http://jabber.org/protocol/pubsub#event">
<items node="/user/channeluser@example.com/channel">
<retract id="1291048772456"/>
</items>
</event>
</message>
</code>
<h3>Post to a channel</h3>
<p>Posting to a channel implies a role of "follower+post, moderator or producer"</p>
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="set" id="publish:20">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<publish node="/user/koski@buddycloud.com/channel">
<item>
<entry xmlns="http://www.w3.org/2005/Atom">
<published>2010-01-06T21:41:32Z</published>
<author>
<name>koski@buddycloud.com</name>
<jid xmlns="http://buddycloud.com/atom-elements-0">koski@buddycloud.com</jid>
</author>
<content type="text">Test</content>
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<text>Paris, France</text>
<locality>Paris</locality>
<country>France</country>
</geoloc>
</entry>
</item>
</publish>
</pubsub>
</iq>
</code>
<h3>Retrieve a channel post</h3>
<p>Online clients automatically receive new posts from the server</p>
<code lang="XML">
<iq type="set" id="bc:GfLwH" from="channelserver.example.com" to="31941515521289471453412508@anon.buddycloud.com/2906694851289471453813745">
<event xmlns="http://jabber.org/protocol/pubsub#event">
<items node="/user/channeluser@example.com/channel">
<item id="1291048810046">
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
<author>
<name>Dirk</name>
<jid xmlns="http://buddycloud.com/atom-elements-0">fahrertuer@example.com</jid>
<affiliation xmlns="http://buddycloud.com/atom-elements-0">moderator</affiliation>
</author>
<content type="text">A comment, wondering what all this testing does</content>
<published>2010-11-29T16:40:10Z</published>
<updated>2010-11-29T16:40:10Z</updated>
<id>/user/channeluser@example.com/channel:1291048810046</id>
<geoloc xmlns="http://jabber.org/protocol/geoloc">
<text>Bremen, Germany</text>
<locality>Bremen</locality>
<country>Germany</country>
</geoloc>
<thr:in-reply-to ref="1291048772456"/>
</entry>
</item>
</items>
</event>
</iq>
</code>
<h3>Retrieve channel metadata</h3>
<p>The client sends</p>
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="get" id="metadata1">
<query xmlns="http://jabber.org/protocol/disco#info" node="/user/channeluser@example.com/channel"/>
</iq>
</code>
<p>The server replies</p>
<code lang="XML">
<iq type="result" id="metadata1" from="channelserver.example.com" to="channeluser@example.com/ChannelCompatibleClient">
<query xmlns="http://jabber.org/protocol/disco#info" node="/user/channeluser@example.com/channel">
<identity category="pubsub" type="channel"/>
<feature var="http://jabber.org/protocol/pubsub"/>
<x xmlns="jabber:x:data" type="result">
<field var="FORM_TYPE" type="hidden">
<value>http://jabber.org/protocol/pubsub#meta-data</value>
</field>
<field var="pubsub#type" label="Payload type" type="text-single">
<value>http://www.w3.org/2005/Atom</value>
</field>
<field var="pubsub#title" label="A short name for the node" type="text-single">
<value>my awesome channel</value>
</field>
<field var="pubsub#description" label="A description of the node" type="text-single">
<value>the original home of awesomeness.</value>
</field>
<field var="pubsub#publish_model" label="Publish Model" type="text-single">
<value>publishers</value>
</field>
<field var="pubsub#access_model" label="Access Model" type="text-single">
<value>open</value>
</field>
<field var="pubsub#creation_date" label="Creation Date" type="text-single">
<value>2010-03-01T00:00:00Z</value>
</field>
<field var="pubsub#owner" label="Node owners" type="jid-multi">
<value>channeluser@example.com</value>
</field>
<field var="pubsub#default_affiliation" label="Default Affiliation" type="text-single">
<value>publisher</value>
</field>
<field var="pubsub#num_subscribers" label="Number of subscribers to this node" type="text-single">
<value>211</value>
</field>
<field var="x-buddycloud#rank" label="Rank" type="text-single">
<value>21</value>
</field>
<field var="x-buddycloud#popularity" label="Popularity" type="text-single">
<value>9070</value>
</field>
<field var="x-buddycloud#geoloc-text" label="Textual representation of location" type="text-single">
<value/>
</field>
<field var="x-buddycloud#geoloc-lat" label="Latitude" type="text-single">
<value>0.0</value>
</field>
<field var="x-buddycloud#geoloc-lon" label="Longitude" type="text-single">
<value>0.0</value>
</field>
</x>
</query>
</iq>
</code>
<h3>Retrieve channel followers</h3>
<p>Find out who is following a channel</p>
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="get" id="26:85">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
<affiliations node="/user/channeluser@example.com/channel"/>
<set xmlns="http://jabber.org/protocol/rsm">
<max>30</max>
</set>
</pubsub>
</iq>
</code>
<p>server replies with a list of users and their affiliations</p>
<code lang="XML">
<iq type="result" id="26:85" from="channelserver.example.com" to="channeluser@example.com/ChannelCompatibleClient">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
<affiliations node="/user/channeluser@example.com/channel">
<affiliation jid="1753416401288704184459819@anon.buddycloud.com" affiliation="member"/>
<!-- anon users are usually bosh based read-only web views -->
<affiliation jid="akioh@anotherdomain.com" affiliation="publisher"/>
</affiliations>
</pubsub>
</iq>
</code>
<h2>Follower management</h2>
<h3>Change the affiliation of a channel follower</h3>
Affiliation can be any of the roles described in <a href="http://open.buddycloud.com/channel-protocol#TOC-Channel-roles">http://open.buddycloud.com/channel-protocol#TOC-Channel-roles</a>.
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="set" id="subscription:86">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
<subscriptions node="/user/channeluser@example.com/channel">
<subscription jid="ajax53@example.com" subscription="none"/>
</subscriptions>
</pubsub>
</iq>
</code>
<p>The server replies</p>
<code lang="XML">
<iq type="result" id="subscription:86" from="channelserver.example.com" to="channeluser@example.com/ChannelCompatibleClient"/>
<message from="channelserver.example.com" id="bc:v2B2t" to="ajax53@example.com">
<event xmlns="http://jabber.org/protocol/pubsub#event">
<subscription jid="ajax53@example.com" subscription="none" node="/user/channeluser@example.com/channel" affiliation="none"/>
</event>
</message>
</code>
<h3>Remove channel posting rights</h3>
<p>set the user to just member (userspeak: "follower")</p>
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="set" id="19:88">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
<affiliations node="/user/channeluser@example.com/channel">
<affiliation jid="ChannelFollower@example.com" affiliation="member"/>
</affiliations>
</pubsub>
</iq>
</code>
<p>the server replies</p>
<code lang="XML">
<iq type="result" id="19:88" from="channelserver.example.com" to="channeluser@example.com/ChannelCompatibleClient"/>
</code>
<p>the server sends a message to all online users about the change</p>
<code lang="XML">
<message from="channelserver.example.com" id="bc:6M6nM" to="ChannelFollower@example.com">
<event xmlns="http://jabber.org/protocol/pubsub#event">
<affiliation jid="ChannelFollower@example.com" affiliation="member" node="/user/channeluser@example.com/channel" subscription="subscribed"/>
</event>
</message>
</code>
<h3>Un-follow a channel</h3>
<p>Unfollowing a channel just changes the subscription type to "none"</p>
<code lang="XML">
<iq from="channeluser@example.com/ChannelCompatibleClient" to="channelserver.example.com" type="set" id="subscription:92">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
<subscriptions node="/user/channeluser@example.com/channel">
<subscription jid="teapots@example.com" subscription="none"/>
</subscriptions>
</pubsub>
</iq>
</code>
<!-- s:cut above here -->
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment