Buddycloud is a open source/standards federated social network built on top of XMPP. For more information about the future of social networking please see the buddycloud website.
The first thing you must do is to discover your buddycloud server. Any attempted actions before the discovery will result in an error response.
socket.send( 'xmpp.buddycloud.discover', { /* "server": "channels.buddycloud.org" */ }, function(error, data) { console.log(error, data) } )
If a server is discovered the `data` will contain the channel server host, if not `error` will be populated to tell you that no server was found.
Providing a `server` key allows the user to short cut discovery by specifying the channel server they wish to use.
There is a default timeout of 8 seconds on the second part of the discovery process (where we ask components for features/identity). If a server is found before this time then xmpp-ftw will inform you immediately. This value can be changed server-side by calling the
setDiscoveryTimeoutmethod on a Buddycloud object.
For convenience, `xmpp-ftw-buddycloud` proxies disco requests for the user using the two events xmpp.buddycloud.discover.items and xmpp.buddycloud.discover.info ( xmpp.discover.items and xmpp.discover.info respectively).
These events are documented in service discovery. Note: these events do not require that the channel server is discovered first.
Presence must be sent to the buddycloud server in order to start receiving notifications. Default presence is set as 'online' with a priority of -1, and a status of 'buddycloud'.
For more advanced priority setting it is suggested that you use 'xmpp.presence'.
socket.send('xmpp.buddycloud.presence', {})
The first time you use a buddycloud server you should register with it in order to generate your personal nodes. Multiple registrations will not cause an error.
socket.send( 'xmpp.buddycloud.register', {}, function(error, data) { console.log(error, data) } )
A successful response will look as follows:
{ registered: true }
In the unlikely event of an error upon registration these will formatted in the same style as xmpp-ftw-register.
socket.send( 'xmpp.buddycloud.create', { "node": "/user/[email protected]/posts", /* "options": [] */ }, function(error, data) { console.log(error, data) } )
options should be formatted as a data form in order to add node configuration options at creation time.
If the node is successfully created `error` will be null and `data` will be true.
Deleting a node is covered later
socket.send( 'xmpp.buddycloud.publish', { "node": "/user/[email protected]/posts", "content": { "atom": { "content": "Posting from XMPP-FTW" }, "in-reply-to": { "ref": "1234-5678-9087-6543" } } }, function(error, data) { console.log(error, data) }
A successful post will result in the following response:
{ "id": "tag:[email protected],/user/[email protected]/posts,1" }
socket.send( 'xmpp.buddycloud.subscribe', { "node": "/user/[email protected]/posts" }, function(error, data) { console.log(error, data) } )
If a subscription is successful then the value of `data` will be as follows:
{ subscription: "subscribed" }
socket.send( 'xmpp.buddycloud.unsubscribe', { "node": "/user/[email protected]/posts" }, function(error, data) { console.log(error, data) } )
If there is no `error` then `data` will simply be true.
This method supports RSM.
socket.send( 'xmpp.buddycloud.subscriptions', { /* "node": "/user/[email protected]/posts", */ /* "owner": true, */ /* "ephemeral": true */ }, function(error, data) { console.log(error, data) } )
Setting owner to true will return information about all subscriptions to that node. This is provided you are the owner of the node, otherwise an error will be returned.
Setting ephemeral to true will retrieve subscriptions from ephemeral nodes only. Leaving it out will default to non-ephemeral nodes only. Note: This only applies to user subscriptions.
A successful response will then be as follows:
[ { node: "/user/[email protected]/posts", jid: { user: "lloyd", domain: "evilprofessor.co.uk" }, subscription: "subscribed" }, { node: "/user/[email protected]/posts", jid: { user: "lloyd", domain: "evilprofessor.co.uk" }, subscription: "pending" }, { node: "/user/[email protected]/posts", jid: { user: "megan", domain: "evilprofessor.co.uk" }, invitedBy: { user: "lloyd", domain: "evilprofessor.co.uk" }, subscription: "invited" } ]
As a node owner, or moderator, it is also possible to update the subscription state of a user as follows:
socket.send( 'xmpp.buddycloud.subscription', { "node": "/user/[email protected]/posts", "jid": "[email protected]", "subscription" : "none" }, function(error, data) { console.log(error, data) } )
On success the data argument will simply be true.
As a subscriber it is possible to invite another user to a node as follows:
socket.send( 'xmpp.buddycloud.subscription', { "node": "/user/[email protected]/posts", "jid": "[email protected]", "subscription" : "invited" }, function(error, data) { console.log(error, data) } )
On success the data argument will simply be true.
In the event of a subscription change all node subscribers are informed via the `xmpp.buddycloud.push.subscription` event:
{ node: "/user/[email protected]/posts", jid: { domain: "evilprofessor.co.uk", user: "megan" }, subscription: "subscribed", /* invitedBy: { domain: "evilprofessor.co.uk", user: "lloyd" } */ }
If required, and if supported by the server, a node owner, or moderator, will receive a subscription authorisation request as follows:
socket.on('xmpp.buddycloud.push.authorisation', function(data, callback) { console.log(data) callback( /* see below */ ) })
With the data in the following format:
{ id: "approve1", form: {} }
In order to reply to a subscription authorisation request the callback function should be used as follows (actual field data will depend on received data form):
[ { var: "pubsub#node", value: "/user/[email protected]/posts" }, { var: "pubsub#subscriber_jid": value: "[email protected]" }, { var: "pubsub#allow", value: "true" } ]
This method supports RSM.
socket.send( 'xmpp.buddycloud.affiliations', { /* "node": "/user/[email protected]/posts", */ /* "owner": true", */ /* "ephemeral": true */ }, function(error, data) { console.log(error, data) } )
Setting owner to true allows the user to get a list of all node affiliations provided they are the owner of the node (otherwise an error is returned.
Setting ephemeral to true will retrieve affiliations from ephemeral nodes only. Leaving it out will default to non-ephemeral nodes only. Note: This only applies to user affiliations.
A successful response will then be as follows:
[ { jid: { user: "lloyd", domain: "evilprofessor.co.uk" }, affiliation: 'owner' }, { jid: { user: "dev-kitty-1", domain: "evilprofessor.co.uk" }, affiliation: 'member' } ]
socket.send( 'xmpp.buddycloud.affiliation', { "node": "/user/[email protected]/posts", "jid": "[email protected]", "affiliation": "outcast" }, function(error, data) { console.log(error, data) } )
If the node is successfully created `error` will be null and `data` will be true.
Note: Whilst specification allows user to update several affiliation changes at once, only on per message is supported here. If required it can be added later.
The event name for these changes is `xmpp.buddycloud.push.affiliation`.
{ node: "/user/[email protected]/posts", jid: { domain: "evilprofessor.co.uk", user: "bad-person" }, affiliation: "none" }
Retrieve items from a buddycloud node. For information about how RSM is supported please see result set management.
socket.send( 'xmpp.buddycloud.retrieve', { "node": "/user/[email protected]/posts" }, function(error, data) { console.log(error, data) } )
Items are parsed using `xmpp-ftw-item-parser` although it is possible to inject your own parser. Additonal features of the item will be come available as this project adds support.
Unlike `xmpp-ftw-pubsub` items will always include a node key.
When an item is published to a node that your user is subscribed to then a message will be received with item details.
socket.on('xmpp.buddycloud.push.item', function(data) { console.log(data) })
The item itself is parsed by `xmpp-ftw-item-parser` and is held in the item key.
{ from: 'channels.evilprofessor.co.uk', node: '/user/[email protected]/posts', id: '201305301825', item: ...as parsed by xmpp-ftw-item-parser... }
Retrieve recent items for subscribed nodes by requesting using the following event name (this message supports RSM):
socket.send( 'xmpp.buddycloud.items.recent', { /* "max": 50, */ /* "since": "2013-07-01 16:02:00", */ /* "parentOnly": true */ }, function(error, data, rsm) { console.log(error, data, rsm) } )
Whilst both max and since are optional it is
suggested values are provided. max will default to
30 if not set, whilst since will default
to 1st January 2000 if not set. since will
accept any string which can be parsed by Date.parse()
. Setting
parentOnly with something that evaluates to true
will request only thread parents.
Output data has the following format:
[ { node: '/user/[email protected]/posts', id: 'item-1', entry: //... a parsed by xmpp-ftw-item-parser ...// }, { node: '/user/[email protected]/posts', id: 'item-3', entry: //... a parsed by xmpp-ftw-item-parser ...// }, { node: '/user/[email protected]/posts', id: 'item-5', entry: //... a parsed by xmpp-ftw-item-parser ...// }, ]
Very similar to the recent items retrieval, except that it does not attempt to retrieve items from every channel regardless of age. This function returns a feed as if all items are in a single feed (this message supports RSM):
socket.send( 'xmpp.buddycloud.items.feed', { /* "since": "2013-07-01 16:02:00", */ /* "parentOnly": true */ }, function(error, data, rsm) { console.log(error, data, rsm) } )
Whilst since are optional it is
suggested the value is provided. since will default
to 1st January 2000 if not set. since will
accept any string which can be parsed by Date.parse()
. Setting
parentOnly with something that evaluates to true
will request only thread parents.
Output data has the following format:
[ { node: '/user/[email protected]/posts', id: 'item-1', entry: //... a parsed by xmpp-ftw-item-parser ...// }, { node: '/user/[email protected]/posts', id: 'item-3', entry: //... a parsed by xmpp-ftw-item-parser ...// }, { node: '/user/[email protected]/posts', id: 'item-5', entry: //... a parsed by xmpp-ftw-item-parser ...// }, ]
Retrieve a full post thread as follows (RSM supported):
socket.send( 'xmpp.buddycloud.items.thread', { "node": "/user/[email protected]/posts", "id": "1234-5678-9012-3456" }, function(error, data, rsm) { console.log(error, data, rsm) } )
Responses then look like the following:
[ { id: '1234-5678-9012-3457', node: "/user/[email protected]/posts", entry: //... as parsed by xmpp-ftw-item-parser ...// } ]
Retrieve all replies to a post as follows (RSM supported):
socket.send( 'xmpp.buddycloud.items.replies', { "node": "/user/[email protected]/posts", "id": "1234-5678-9012-3456" }, function(error, data, rsm) { console.log(error, data, rsm) } )
Responses then look like the following:
[ { id: '1234-5678-9012-3457', entry: //... as parsed by xmpp-ftw-item-parser ...// node: "/user/[email protected]/posts", } ]
socket.send( 'xmpp.buddycloud.item.delete', { "node": "/user/[email protected]/posts", "id": "1" }, function(error, data) { console.log(error, data) } )
If the delete is successful then `data` will simply be true.
If an item is successfully deleted from a node then all subscribers will be notified of this event (configuration dependent).
socket.on('xmpp.buddycloud.push.retract', function(data) { console.log(data) })
With the payload as follows:
{ node: '/user/[email protected]/posts', id: '222' }
Node configuration follows that of the standard pubsub setup with simply the event name changed.
socket.send( 'xmpp.buddycloud.config.get', { "node": "/user/[email protected]/posts" }, function(error, data) { console.log(error, data) } )
socket.send( 'xmpp.buddycloud.config.set', { "node": "/user/[email protected]/posts", "form": [] }, function(error, data) { console.log(error, data) } )
If configuration update is sucessful then `data` will simply be true.
On update of a node's configuration then a notification will be sent to all node subscribers.
socket.on('xmpp.buddycloud.push.configuration', function(data) { console.log(data) })
With data looking as follows:
{ node: '/user/[email protected]/posts', configuration: [] }
configuration if provided will match the parsing of other data forms.
socket.send( 'xmpp.buddycloud.delete', { "node": "/user/[email protected]/posts" }, function(error, data) { console.log(error, data) } )
If the delete is successful then `data` will simply be true.
If a node is successfully deleted then all subscribers will be notified of this event (configuration dependent).
socket.on('xmpp.buddycloud.push.delete', function(data) { console.log(data) })
With the payload as follows:
{ node: '/user/[email protected]/posts' }
Media servers can be discovered using the method below. Domain is the domain on which the channel you wish to post to lives. Note: If you are attempting to post to a topic channel you will need to run the discovery against the parent domain (usually a case of just removing the subdomain).
socket.send( 'xmpp.buddycloud.disover.media-server', { "of": "evilprofessor.co.uk" }, function(error, data) { console.log(error, data) } )
If a media server component can not be found then the error message will be an item-not-found error. A successful response is as follows:
{ component: 'media.evilprofessor.co.uk', /* endpoint: 'https://api.evilprofessor.co.uk/media' */ }
The endpoint will only be provided if the media server advertises it.
There is a default timeout of 10 seconds on the second part of the media server discovery process (where we ask components for features/identity). If a server is found before this time then xmpp-ftw will inform you immediately. This value can be changed server-side by calling the
setMediaServerDiscoveryTimeoutmethod on a Buddycloud object.
If a media server has been discovered then xmpp-ftw-buddycloud will take over handling of HTTP verification requests from this server.
The HTTP verfication is detailed on the manual page and here we simply show the related events.
An incoming verification request is picked up as follows:
socket.on( 'xmpp.buddycloud.http.verify', function(data) { console.log(data) } )
This request can then either be confirmed or denied as follows. Approve:
socket.send( 'xmpp.buddycloud.http.confirm', { "to": "media.evilprofessor.co.uk", "id": "abc-123", "type": "iq", "request": { "url": "https://media.evilprofessor.co.uk/secret.txt", "method": "GET", "id": "request-1" } }, function(error, data) { console.log(error, data) } )
Deny:
socket.send( 'xmpp.buddycloud.http.deny', { "to": "media.evilprofessor.co.uk", "id": "abc-123", "type": "iq", "request": { "url": "https://media.evilprofessor.co.uk/secret.txt", "method": "GET", "id": "request-1" } }, function(error, data) { console.log(error, data) } )