This page shows how to use the buddycloud API to create, edit, use and delete places.
Places can be either personal or shared. Personal places are only usable by the owner (the person who created it), but it will be visible to all his followers. Shared places places can be used by anyone. It will be included in place searches and nearby views, and anyone may add it to their list of places (see My places) and thus be placed at it whenever they are physically present at the place.
Places can have many attributes, but the only required attribute is name, assigned by the user that created it. In addition, the buddycloud server will assign a few other attributes that cannot directly be specifed by the user:
id is assigned by the buddycloud server on creation. It is a unique handle used in all subsequent queries.revision is set to 0 on creation and incremented each time the place is edited. It is typically used to check for updates by clients that cache place details.population specifies how many people are at this place. It is only appliccable to shared places.Although only name is required, it is recommended to provide more information, especially for shared places, as this increases the chances of it being correctly found and used by others.
A place search looks for identical or similarly named shared places already define by other buddycloud users. If none found, a quick search of 3rd party services will be done. In order to minimize the search scope, it is recommended to supply country, region and city names if available.
IMPORTANT NOTE: Places found in 3rd party databases wil be returned with no ID and these places will need to be created before they can be used. See Create Place.
Client to server:
<iq type='get' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#search'> <place> <name>The Water Hole</name> <country>Chad</country> </place> </query> </iq>
Server to client:
<iq type="result" from="butler.buddycloud.com"> <query xmlns="http://buddycloud.com/protocol/place"> <place> <id>http://buddycloud.com/places/6431</id> <name>The Water Hole</name> <shared>true</shared> <lat>20.22</lat> <lon>20.0</lon> <street>Desert Street</street> <area>Middle of</area> <city>Nowhere</city> <region>The Desert</region> <country>Chad</country> <postalcode>202020</postalcode> </place> </query> </iq>
The only attribute needed to create a place is <name>. If a value for <shared> is not specified, it will default to false (personal). Clients need to await the result stanza and parse the place ID before the place can be used.
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#create'> <place> <name>Test Place</name> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#create'> <place> <id>http://buddycloud.com/places/27546</id> <name>Test Place</name> </place> </query> </iq>
Note: When creating a shared place, a name conflict may arise. If another shared place already exists with the same name, the server will return an error. In this case, the place to be created must specify the following attributes: country, city, street (including house number). If the existing place also have these attributes set, and they are identical, a second place cannot be created as a shared place, as it represents the same physical place. It may however be created as a personal place, as private places need not represent unique physical places.
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#create'> <place> <name>Another Test Place</name> <shared>true</shared> <area>Middle of</area> <city>Nowhere</city> <region>The Desert</region> <country>Chad</country> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#create'> <place> <id>http://buddycloud.com/places/22873</id> <name>Another Test Place</name> <shared>true</shared> <area>Middle of</area> <city>Nowhere</city> <region>The Desert</region> <country>Chad</country> </place> </query> </iq>
Note: When editing a personal place, declearing it shared, name conflicts may arise (see Create Place), if so, the server will return an error, and further attributes will have to be specified (e.g. region, city, area, street address) until the name conflict has been resolved.
The <revisionfield will be incremented on each succesful edit.
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#edit'> <place> <id>http://buddycloud.com/places/27546</id> <name>Test Place</name> <shared>false</shared> <area>Middle of</area> <city>Nowhere</city> <region>The Desert</region> <country>Chad</country> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#edit'> <place> <id>http://buddycloud.com/places/27546</id> <name>Test Place</name> <shared>false</shared> <area>Middle of</area> <city>Nowhere</city> <region>The Desert</region> <country>Chad</country> </place> </query> </iq>
My Places is the list of places at which the buddycloud location server will attempt to place you at whenever you are physically present there. In addition to places you have created yourself, it consists of shared places created by other buddycloud users tha you have added to your list (see Add place to "My Places".
Client to server:
<iq type='get' to='butler.buddycloud.com' id='getplacepostcreate'> <query xmlns='http://buddycloud.com/protocol/place#myplaces'> <options> <feature var='id' /> <feature var='name' /> <feature var='shared' /> </options> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com' id='getplacepostcreate'> <query xmlns="http://buddycloud.com/protocol/place#myplaces"> <place> <id>http://buddycloud.com/places/6431</id> <name>The Water Hole</name> <shared>true</shared> </place> <place> <id>http://buddycloud.com/places/27546</id> <name>Test Place</name> <shared>false</shared> </place> <place> <id>http://buddycloud.com/places/22873</id> <name>Another Test Place</name> <shared>true</shared> </place> </query> </iq>
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#add'> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#add'> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#add'> <place> <id>http://buddycloud.com/places/767</id> </place> </query> </iq>
Server to client:
<iq to="testsuite@buddycloud.com/testsuite" type="error" from="butler.buddycloud.com"> <query xmlns="http://buddycloud.com/protocol/place#add"> <place> <id>http://buddycloud.com/places/767</id> </place> </query> <error type="auth" code="401"> <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Place with ID 767 is private.</text> </error> </iq>
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#remove'> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#remove'> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Client to server:
<iq type='get' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place'> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Server to client:
<iq from='butler.buddycloud.com' type='result'> <query xmlns='http://buddycloud.com/protocol/place'> <place> <id>http://buddycloud.com/places/6431</id> <name>The Water Hole</name> <description>A water hole. Literally.</description> <shared>true</shared> <lat>20.2</lat> <lon>20.0</lon> <street>Desert Street</street> <area>Middle of</area> <city>Nowhere</city> <region>The Desert</region> <country>Chad</country> <postalcode>202020</postalcode> <population>0</population> <revision>0</revision> </place> </query> </iq>
Client to server:
<iq type='get' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place'> <options> <feature var='name' /> </options> <place> <id>http://buddycloud.com/places/22</id> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place'> <place> <name>Lisboa Bar</name> </place> </query> </iq>
Client to server:
<iq type='get' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place'> <place> <id>http://buddycloud.com/places/2</id> </place> </query> </iq>
Server to client:
<iq type="error" from="butler.buddycloud.com"> <query xmlns="http://buddycloud.com/protocol/place"> <place> <id>http://buddycloud.com/places/2</id> </place> </query> <error code="401" type="auth"> <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Place with ID 2 is private.</text> </error> </iq>
If a user has created a new place and is physically present at the place, he may wish to set it as his current place. If so, the buddycloud server will analyze his recent location query history and generate a pattern of cell towers and wifi access points that will enable it to automatically place the user here the next time he comes back. This stanza may also be used when the buddycloud location server, for some reason, has failed to place the user at a place, or has placed her at a wrong place. In that case new cell and wifi patterns will be generated, and old ones will be deleted.
Important note: Make sure to communicate to client users that functions that results in this stanza being sent is only triggerede when the user is actually physically present at the place which is set!
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#current'> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com' > <query xmlns="http://buddycloud.com/protocol/place#current"> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Server publishes current place to user's PEP geoloc node:
<iq from='user@buddycloud.com' id='items1' type='result'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='http://jabber.org/protocol/geoloc'> <item id='4D96A45D84D60'> <geoloc xmlns='http://jabber.org/protocol/geoloc' xml:lang='en'> <uri>http://buddycloud.com/places/6431</uri> <text>The Water Hole</text> <area>Middle of</area> <locality>Nowhere</locality> <region>The Desert</region> <country>Chad</country> <lat>20.2</lat> <lon>20.0</lon> <accuracy>200.0</accuracy> </geoloc> </item> </items> </pubsub> </iq>
<uri> instead of <id>, <text> instead of <name> and <locality> instead of <city> which stems from the use of XEP-0080 as node format.
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#next'> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#next'> <place> <id>http://buddycloud.com/places/6431</id> </place> </query> </iq>
Server publishes current place to user's PEP geoloc node:
<iq from='user@buddycloud.com' id='items1' type='result'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='http://jabber.org/protocol/geoloc-next'> <item id='4D96A45D84D60'> <geoloc xmlns='http://jabber.org/protocol/geoloc' xml:lang='en'> <uri>http://buddycloud.com/places/6431</uri> <text>The Water Hole</text> <area>Middle of</area> <locality>Nowhere</locality> <region>The Desert</region> <country>Chad</country> <lat>20.2</lat> <lon>20.0</lon> <accuracy>200.0</accuracy> </geoloc> </item> </items> </pubsub> </iq>
Note: The name submitted does not have to correspond to an existing place, and can thus be used very informally. E.g. "Some restaurant", "New York Tomorrow", "The Pub @ 8pm" are all valid next place names.
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#next'> <place> <name>Joe's Pizza @ 5pm</name> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#next'> <place> <name>Joe's Pizza @ 5pm</name> </place> </query> </iq>
Server publishes current place to user's PEP geoloc node:
<iq from='user@buddycloud.com' id='items1' type='result'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='http://jabber.org/protocol/geoloc-next'> <item id='4D96A45D84D60'> <geoloc xmlns='http://jabber.org/protocol/geoloc' xml:lang='en'> <text>Joe's Pizza @ 5pm</text> </geoloc> </item> </items> </pubsub> </iq>
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#delete'> <place> <id>http://buddycloud.com/places/4865</id> </place> </query> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#delete'> <place> <id>http://buddycloud.com/places/4865</id> </place> </query> </iq>
WARNING: Will delete all places created by the querying user. Clients should show big red confirmation dialogs before sending this!
Client to server:
<iq type='set' to='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#delete_all' /> </iq>
Server to client:
<iq type='result' from='butler.buddycloud.com'> <query xmlns='http://buddycloud.com/protocol/place#delete_all' /> </iq