English | Site Directory

Activities Data API Developer's Guide: Protocol

The OpenSocial Activities data API allows client applications to publish and view information about users' activities, in the form of entries in AtomPub APIs with a Google data schema. Your client application can create and publish new entries, edit or delete existing entries, or request a list of entries.

Important: The OpenSocial Activities data API hasn't been released yet; this document is a preview of the developer's guide that we'll publish when we release the data API. All of the details are subject to change, but this preview should give you a general idea of what the API will be like.

Contents

  1. Audience
  2. Getting started
    1. About activities
    2. Registering your client
    3. Policies
  3. Authenticating to the Activities service
    1. AuthSub proxy authentication
    2. ClientLogin username/password authentication
  4. Creating entries
  5. Retrieving entries
    1. Retrieving a user-level feed
    2. Retrieving a source-level feed
  6. Updating entries
  7. Deleting entries

Audience

This document is intended for programmers who want to write client applications that can interact with any of Google's services that keep track of user activities, such as the "Updates from your friends" list at Orkut.

An Activities service is sometimes called a "domain"; in the URLs shown in this document, we use the placeholder term domain to indicate the part of the URL that varies from one service to another.

This document provides a series of examples of basic data API interactions using raw XML and HTTP, with explanations.

This document is intended for two different (though overlapping) groups of client developers. Both groups should read the whole document, but depending on your goal, you should focus on different parts of it:

  • If you're writing a client to publish information about user activities to one of Google's Activities services, then focus on the sections about creating, updating, and deleting entries.
  • If you're writing a client to consume activities feeds, then focus on the section about retrieving entries.

This document assumes that you understand the general ideas behind AtomPub and the Google data APIs protocol.

Getting started

About activities

An entry in an Activities feed represents an activity performed by a user. An entry specifies a user and a source, plus textual information and metadata about the event.

The user is the person who performed the activity; the source is the service that informed the Activities server that the activity had happened.

For example, a particular entry (posted to the feed by YouTube) might indicate that user liz@gmail.com uploaded a video file on YouTube. Here, liz@gmail.com is the user whose activity is being reported, and YouTube is the source of the activity. The fact that the activity consisted of uploading a video is given in the textual description.

The Google GUIs that display lists of activities are labeled as various kinds of "updates," such as "Updates from your friends." (Users can use those lists to view realtime updates showing their friends' activities on various sites across the web.) Therefore, if your client displays activities to your users, you should use the term "updates" in your GUI, rather than "activities." Note that an "update" in this sense is not the same as updating data by sending an HTTP PUT request.

Registering your client

To post user activities to the OpenSocial Activities API, you first need to register your application with Google.

Policies

Clients posting activities to any of Google's Activities services must abide by the following policies:

  • The Activities server detects and filters sources that post an unreasonable number of activities. Post only the most relevant or important activities for each user. A good guideline to follow is: would the user want to share this activity with their friends?
  • Posts must be about activities performed by users of your application or service. Don't post promotional messages or other messages that don't pertain to an actual user activity. If Google notices a client posting a promotional message or abusing the feeds, we will block that client from posting to our Activities services.
  • Titles must be under 140 characters long. We recommend using plain text for the title, and we'll scrub most HTML from it; in particular, no images or rich media are allowed. We may also limit the number of links in the title.
  • Posts can't include JavaScript.

Authenticating to the Activities service

To read from or write to a feed, your client needs to authenticate. It can authenticate using either of two approaches: AuthSub proxy authentication or ClientLogin username/password authentication.

For more information about authentication with Google data APIs in general, please see the authentication documentation.

AuthSub proxy authentication

AuthSub proxy authentication is used by web applications that need to authenticate their users to Google accounts. The website operator and the client code don't have access to the username and password for the Activities user; instead, the client obtains special AuthSub tokens that allow the client to act on a particular user's behalf. See the AuthSub documentation for more detailed information.

When a user first visits your application, they have not yet been authenticated. In this case, you need to display some information and a link directing the user to a Google page to authenticate your request for access to their activities.

The AuthSubRequest URL might look like this:

https://www.google.com/accounts/AuthSubRequest?scope=http%3A%2F%2Fdomain%2Factivities%2Ffeeds%2F&session=1&secure=0&next=http%3A%2F%2Fwww.example.com%2Fwelcome.html

The following query parameters are included in the AuthSubRequest URL:

scope
Indicates that the application is requesting a token to access Activities feeds. The scope string for Activities is http://domain/activities/feeds.
session
Indicates whether the token returned can be exchanged for a multi-use (session) token.
secure
Indicates whether the client is requesting a secure token.
next
The URL of the page that Google should redirect the user to after authentication.

After the user logs in, the AuthSub system redirects them to the URL you specified in the next query parameter of the AuthSubRequest URL. The AuthSub system appends an authentication token to that URL, as the value of the token query parameter. For example:

http://www.example.com/welcome.html?token=yourAuthToken

This token value represents a single-use AuthSub token. In this example, since session=1 was specified, this token can be exchanged for an AuthSub session token by calling the AuthSubSessionToken service with the single-use token in an Authorization header, as follows, where urlFromAuthSub is the URL that AuthSub appended the token to:

GET /accounts/AuthSubSessionToken HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="yourAuthToken"
User-Agent: Java/1.5.0_06
Host: https://www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
    

The AuthSubSessionToken service response includes a Token header that contains the session token and an Expiration header that indicates how long the token will remain valid. Your application can use the session token value in the Authorization header of subsequent interactions with Activities. Here's an example of an HTTP request, containing a non-secure token, that you might send to Activities:

GET feedURL HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="yourSessionToken"
User-Agent: Java/1.5.0_06
Host: ActivitiesServerURL
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
    

ClientLogin username/password authentication

Use ClientLogin authentication if your client is a standalone, single-user "installed" client (such as a desktop application). To request an authentication token using the ClientLogin mechanism, send a POST request to the following URL:

https://www.google.com/accounts/ClientLogin

The POST body should contain a set of query parameters that look like parameters passed by an HTML form, using the application/x-www-form-urlencoded content type. These parameters are:

Email
The user's email address.
Passwd
The user's password.
source
Identifies your client application. Should take the form companyName-applicationName-versionID. The examples use the name exampleCo-exampleApp-1.
service
The Activities service name is reader. (Other service names are listed in the Google data API knowledge base.)

If the authentication request fails, you'll receive an HTTP 403 Forbidden status code.

If it succeeds, then the response from the service is an HTTP 200 OK status code, plus three long alphanumeric codes in the body of the response: SID, LSID, and Auth. The Auth value is the authorization token that you'll send to Activities with your request, so keep a copy of that value. You can ignore the SID and LSID values.

Since all requests to private feeds require authentication, you have to set the Authorization header in all subsequent interactions with Activities, using the following format:

Authorization: GoogleLogin auth=yourAuthToken

Where yourAuthToken is the Auth string returned by the ClientLogin request.

For more information about ClientLogin authentication, including sample requests and responses, see the Account Authentication for Installed Applications documentation.

Creating entries

After successful authentication, your client can post entries describing user activities. However, a client can post only to a source-level feed, not to a user-level feed. For information about the types of feeds, see the Retrieving entries section of this document.

To post, first create an XML representation of the entry to publish. This XML needs to be in the form of an Atom <entry> element, which might look something like this:

<atom:entry xmlns:atom='http://www.w3.org/2005/Atom'>
  <atom:updated>2007-10-27T19:41: 51.574Z</atom:updated>
  <atom:category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/activities/2007#activities'/>
  <atom:title>Liz uploaded "My Date With Darcy" to YouTube.com</atom:title>
</atom:entry>

To publish this activity, send it to the feed's post URL as follows. First, place your Atom <entry> element in the body of a new POST request, using the application/atom+xml content type. Then send the request to the feed's post URL, which is in this format:

http://domain/activities/feeds/activities/user/userID/source/sourceID

The Activities server creates an entry using the data you sent, assigning the specified user and source to the activity; then it returns an HTTP 201 CREATED status code, along with a copy of the new post in the form of an <entry> element. The activity returned is the same one you sent, but it also contains various elements added by the Activities server, such as an <id> element.

If your request fails for some reason, the server may return a different status code. For information about the status codes, see the protocol reference document.

Retrieving entries

To retrieve a list of activities, your client requests an Activities feed by sending an HTTP GET request. The Activities server then returns a feed containing the appropriate activities.

There are two different kinds of feeds: user-level feeds, listing the activities associated with a specified user, and source-level feeds, listing the subset of a given user's activities that are associated with a specified source. Both contain the same kind of entries, where each entry describes an activity by a user.

Retrieving a user-level feed

To get a user-level feed, listing all the activities associated with a particular user, you send the following HTTP request to the Activities server (with the appropriate values in place of domain and userID, of course):

GET http://domain/activities/feeds/activities/user/userID

The server then returns an HTTP 200 OK status code and a standard Atom 1.0 feed containing all the activities. The following is an example of a feed with only one activity. Note that we've slightly edited the following example to make it a little more readable by humans; in particular, a real Activities feed contains actual IDs and URLs.

<atom:feed xmlns:atom='http://www.w3.org/2005/Atom'
    xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
    xmlns:gact='http://schemas.google.com/activities/2007'>
  <atom:id>http://www.google.com/activities/feeds/activities/user/userID/source/sourceID</atom:id>
  <atom:updated>1970-01-01T00:00:00.000Z</atom:updated>
  <atom:category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/activities/2007#activity'/>
  <atom:title>Feed title</atom:title>
  <atom:link rel='alternate' type='text/html' href='http://sourceID.com/123'/>
  <atom:link rel='http://schemas.google.com/g/2005#feed'
    type='application/atom+xml'
    href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID'/>
  <atom:link rel='http://schemas.google.com/g/2005#post'
    type='application/atom+xml'
    href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID'/>
  <atom:link rel='self' type='application/atom+xml'
    href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID'/>
  <atom:author>
    <atom:name>unknown</atom:name>
  </atom:author>
  <openSearch:totalResults>1</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>25</openSearch:itemsPerPage>
  <atom:entry>
    <atom:id>http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1</atom:id>
    <atom:updated>2007-10-27T19:41:51.574Z</atom:updated>
    <atom:category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/activities/2007#activity'/>
    <atom:title>Activity title</atom:title>
    <atom:link rel='self' type='application/atom+xml'
      href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1'/>
    <atom:link rel='edit' type='application/atom+xml'
      href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1'/>
    <gact:received>2007-10-27T19:41:51.478Z</gact:received>
  </atom:entry>
</atom:feed>

Also note that the entry doesn't contain XML elements that specifically represent a user or a source; your client can determine the user and source by examining the <link rel="self"> element.

Retrieving a source-level feed

A source-level feed lists all the activities associated with a particular source and a particular user.

Retrieving a source-level feed is the same as retrieving a user-level feed, except that you specify a source as well as a user in the feed URL:

GET http://domain/activities/feeds/activities/user/userID/source/sourceID

Updating entries

A client can modify an entry only in a source-level feed.

To edit an existing entry, first retrieve the entry, then modify it, then send a PUT request with the modified entry in the message body to the entry's edit URL.

Be sure that the <id> value in the entry you POST exactly matches the <id> of the existing entry.

The edit URL is highlighted in the following entry:

  <atom:entry>
    <atom:id>http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1</atom:id>
    <atom:updated>2007-10-27T19:41:51.574Z</atom:updated>
    <atom:category scheme='http://schemas.google.com/g/2005#kind'
      term='http://schemas.google.com/activities/2007#activity'/>
    <atom:title>Edited title</atom:title>
    <atom:link rel='self' type='application/atom+xml'
      href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1'/>
    <atom:link rel='edit' type='application/atom+xml'
      href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1'/>
    <gact:received>2007-10-27T19:41:51.478Z</gact:received>
  </atom:entry>

Note: To ensure forward compatibility, be sure that when you PUT an updated entry you preserve all the XML that was present when you retrieved the entry from the server. Otherwise, when we implement new stuff and include <new-awesome-feature> elements in the feed, your client won't return them when updating, and your users will miss out!

Troubleshooting Tip: Some firewalls block HTTP PUT messages. To get around this you can include the X-HTTP-Method-Override: PUT header in your requests.

Deleting entries

A client can delete an entry only in a source-level feed.

To delete an activity, send a DELETE request to the activity's edit URL. This is the same URL used to update entries.

Troubleshooting Tip: Some firewalls block HTTP DELETE messages. To get around this you can include the X-HTTP-Method-Override: DELETE header in your requests.

Back to top