Ever since its launch in February 2010, Google Buzz has created...well, quite a buzz. By allowing users to share rich content such as videos and photos, in addition to offering simple status updates, Buzz has quickly become one of Google's most popular services and the tight Gmail integration doesn't hurt either!
If you're a web developer, there's even more reason to get excited about Google Buzz. Like many other Google services, Google Buzz comes with a developer API that lets you put your hands right into the heart of the service and create your own mashups on top of it. And because the API uses REST, you can easily integrate it with most programming toolkits—including the one I use most often, PHP.
This article introduces you to the Google Buzz API, as it shows you how to integrate and use Google Buzz content with PHP applications. So come on and get started!
Understanding Google Buzz feeds
Before you start to develop applications with Google Buzz, you need to understand how it works. As with all REST-based services, things begin with an HTTP request to a designated resource. This HTTP request contains a query with one or more input parameters; the server replies to the query with an Atom or JSON feed. The HTTP "verb" used in the request—GET for reads, POST and PUT for writes, and DELETE for deletions—indicates the type of action required, and the HTTP status code returned by the server indicates whether or not the action was successful.
To see how this works, log into your Google Account and try requesting the URL https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@public in your favourite web browser. Remember to replace the string YOUR_ID in the URL with your Google ID; you can obtain this from your Google Profile URL, which is displayed in your Google Account Settings page. The response to this request (which you can view in the source code of the resulting page) will contain a list of your most recent Google Buzz posts, and might look something like Listing 1:
Listing 1. An example Google Buzz feed
<?xml version="1.0" encoding="UTF-8"?>
<feed gd:kind="buzz#activityFeed"
xmlns="http://www.w3.org/2005/Atom"
xmlns:activity="http://activitystrea.ms/spec/1.0/"
xmlns:buzz="http://schemas.google.com/buzz/2010"
xmlns:crosspost="http://purl.org/syndication/cross-posting"
xmlns:gd="http://schemas.google.com/g/2005"
xmlns:georss="http://www.georss.org/georss"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:poco="http://portablecontacts.net/ns/1.0"
xmlns:thr="http://purl.org/syndication/thread/1.0">
<link href="http://pubsubhubbub.appspot.com/" rel="hub"/>
<link
href="https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@public?alt=atom"
rel="self" type="application/atom+xml"/>
<title type="text">Google Buzz Public Feed</title>
<updated>2010-06-24T18:16:47.108Z</updated>
<id>tag:google.com,2010:buzz-feed:public:posted:YOUR_ID</id>
<generator uri="http://www.google.com/buzz">Google Buzz</generator>
<entry gd:kind="buzz#activity">
<title>Watching it rain and planning tomorrow's shopping</title>
<published>2010-06-18T14:13:51.000Z</published>
<updated>2010-06-18T14:13:51.400Z</updated>
<id>tag:google.com,2010:buzz:s12ard75xvreh35</id>
<link href="http://www.google.com/buzz/YOUR_ID/fqFn7S27Va4" rel="alternate"
type="text/html"/>
<link href="https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@self/
tag:google.com,2010:buzz:s12ard75xvreh35?alt=atom" rel="self"
type="application/atom+xml"/>
<link href="https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@self/
tag:google.com,2010:buzz:s12ard75xvreh35/@comments?alt=atom" rel="replies"
thr:count="0" thr:updated="2010-06-18T14:13:51.400Z"
type="application/atom+xml"/>
<author>
<poco:id>YOUR_ID</poco:id>
<poco:photoUrl/>
<name>Vikram Vaswani (Melonfire)</name>
<uri>http://www.google.com/profiles/YOUR_ID</uri>
<link href="" rel="photo" type="image/jpeg"/>
<activity:object-type>http://activitystrea.ms/schema/1.0/
person</activity:object-type>
</author>
<content type="text/html">Watching it rain and planning
tomorrow's shopping</content>
<activity:verb>http://activitystrea.ms/schema/1.0/post
</activity:verb>
<activity:object>
<activity:object-type>http://activitystrea.ms/schema/1.0/note
</activity:object-type>
<content type="text/html">Watching it rain and planning
tomorrow's shopping</content>
<buzz:original-content type="text"/>
<link href="http://www.google.com/buzz/YOUR_ID/fqFn7S27Va4"
rel="alternate" type="text/html"/>
</activity:object>
<source>
<activity:service>
<title>Buzz</title>
</activity:service>
</source>
<buzz:visibility>
<buzz:aclentry type="group">
<poco:id>tag:google.com,2010:buzz-group:@me:@public</poco:id>
<uri>https://www.googleapis.com/buzz/v1/people/@me/
@groups/@public?alt=atom</uri>
<poco:name>Public</poco:name>
</buzz:aclentry>
</buzz:visibility>
<link buzz:count="0" href="https://www.googleapis.com/buzz/v1/
activities/YOUR_ID/@self/tag:google.com,2010:buzz:s12ard75xvreh35/
@liked?alt=atom" rel="http://schemas.google.com/buzz/2010#liked"
type="application/poco+xml"/>
</entry>
<entry>
...
</entry>
</feed>
|
The Google Buzz API responds to REST requests with an Atom or JSON feed containing the requested data. Google Buzz offers a number of interesting feeds, including:
- The per-user activity feed, which contains all public posts by a particular user
- The global activity feed, which contains all public posts on Google Buzz
- The per-activity comments feed, which contains a list of user comments on a particular activity
- The per-user person feed, which contains a list of users followed by, and following, a particular user
Some of these feeds are publicly accessible and searchable; others are only available to the feed owner after successful authentication. Most feeds support both read and write operations with authentication; this means that an authenticated user can programmatically post new content to his or her public activity feed, or write comments on other user's public feeds through the Google Buzz API.
The feed itself is a standard Atom feed, with the outermost <feed> element containing <link> elements with URLs for the current page (and, where
applicable, next and previous pages) of the result set. The outermost <feed> element also encloses one or more <entry> elements, each representing a Google Buzz post. Each
entry contains descriptive metadata, including the post ID, title, author, publication
date, and URL. Each <entry> also contains an <author> element, which provides the profile ID, profile URL, photo URL, and name of the post author, and <link> elements, which provide URL links to the post comments feed or the "like" feed.
It's worth pointing out the <activity:> namespaced
elements, which provide specific information on the Google Buzz activity. The <activity:verb> element specifies the type of activity, while
the <activity:object> element specifies the content for the activity.
Before proceeding further, note that usage of Google Buzz content in third-party applications is governed by the Google Buzz Terms of Service. Your application should also comply with the Google Buzz Developer Policies and Branding Guidelines. It's worth your while to read over these documents before you start development, to ensure that you comply with all necessary rules. See Resources for links to these three guidelines.
Now that you know how to access Google Buzz activity feeds through the public REST API, look at doing the same thing from within a PHP application. One way is to use PHP's built-in XML processing extensions (SimpleXML, DOM, or XMLReader) to parse the Atom feed returned by Google Buzz and extract the relevant fragments of information from it. However, this can be very tedious, especially if you deal with large feeds or large volumes of namespaced information.
Two other, more convenient approaches exist:
- The Zend_Rest_Client component in the Zend Framework is designed specifically for developers trying to integrate PHP applications with REST-based web services. You use this client to perform GET, POST, PUT, and DELETE responses to a REST service endpoint. REST responses are returned as instances of Zend_Rest_Client_Response objects, making it easy to access individual response properties.
- The Google Buzz PHP Client Library is an open source client library designed specifically for use with Google Buzz feeds. This library also returns Google Buzz feeds as native PHP objects, simplifying data access.
To use the Google Buzz PHP Client Library, you will also need to register your web application with Google and obtain the necessary OAuth consumer secret for OAuth authentication. You'll find download links and instructions for both libraries in Resources. When you install these libraries, remember to update your PHP 'include_path' to reflect their location.
Which of these two options is better? At the moment, the Google Buzz PHP Client Library has an edge, because it also includes OAuth authentication support. This support significantly reduces the work involved in sending authenticated requests to the Google Buzz service. Expert users can still combine the Zend_Rest_Client library with the Zend_Oauth component to achieve the same result, but the process is slightly more complex. The examples in this article will therefore make use of the Google Buzz PHP Client Library, although the first few examples will also demonstrate use of the Zend_Rest_Client library for unauthenticated requests.
Listing 2 illustrates how to use the Google Buzz PHP Client Library to retrieve and parse a user's public activity feed (the same feed in Listing 1):
Listing 2. Listing public posts with the Buzz PHP client
<?php
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// fetch authenticated user's public feed
$result = $buzz->getPosts('@public', '@me');
// iterate through feed data
echo '<h1>' . $result->title . '</h1>';
echo count($result->posts) . ' post(s) found. <br/>';
echo '<ol>';
foreach ($result->posts as $post) {
echo '<li>';
echo isset($post->links['alternate'][0]->href) ?
'<a href="' . $post->links['alternate'][0]->href .
'">' . $post->title . '</a>' : $post->title;
echo ' (' . date("d M Y h:i", strtotime($post->published)) . ')';
echo '</li>';
}
echo '</ol>';
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
?>
|
Listing 2 begins by including the source files, and then creating a
new buzz object. This buzz
object serves as a central point for communication with the Google Buzz API, exposing
numerous methods to access Google Buzz data. To initialize the object, pass two
arguments to the constructor:
- A properly configured
buzzStorageobject, which specifies how local caching will occur. The Google Buzz PHP Client Library supports Alternative PHP Cache (APC), memcached, and file-based caching, represented bybuzzApcStorage,buzzMemcacheStorage, andbuzzFileStorageclasses respectively. - A properly configured
buzzOAuthobject. This object is generated by the staticbuzzOAuth::performOAuthLogin()method, which accepts two arguments: abuzzStorageobject, and a local user identifier. ThebuzzOAuth::performOAuthLogin()then takes care of performing OAuth authentication with the Google servers, displaying the appropriate prompts to the user to grant or deny the application access to the user's Google Buzz data, and performing necessary redirection.
Once you create the primary buzz object, you can use the object's
getPosts() method to access a user's activity
feed. This method accepts five arguments: the feed type, the user ID, and the numbers of comments, likes, and posts to include in the feed results. The return value of this method is a series of nested PHP objects, each representing an entry in the underlying Atom result feed. It now becomes quite easy to iterate over this object collection, extracting relevant information for display using standard object->property notation.
Figure 1 illustrates what the result looks like.
Figure 1. A list of public posts
A quick word here about feed types. The Google Buzz API offers three feed types:
- The user's public feed, which contains the user's public posts and is
referenced as
@public. This feed is usually located at https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@public - The user's consumption feed, which contains posts from users being followed and is referenced as
@consumption. This feed is usually located at https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@consumption - The user's personal feed, which contains the user's public and private posts and is referenced as
@personal. This feed is usually located at https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@personal
The consumption and personal feeds require authentication, while the public feed does not. The special user ID string @me can also be used as a convenient shortcut to refer to "the currently authenticated user", instead of the numeric Google ID.
Listing 3 produces a result equivalent to Listing 2 using the Zend_Rest_Client library:
Listing 3. Listing public posts with the Zend REST client
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');
try {
// get feed of user public activities
$client = new Zend_Rest_Client('https://www.googleapis.com/buzz/v1/
activities/YOUR_ID_HERE/@public');
$result = $client->get();
// iterate through returned feed
echo '<h1>' . $result->title . '</h1>';
echo count($result->entry) . ' post(s) found. <br/>';
echo '<ol>';
foreach ($result->entry as $entry) {
echo '<li>';
echo isset($entry->link[0][@href]) ? '<a href="' .
$entry->link[0][@href] . '">' . $entry->content .
'</a>' : $entry->content;
echo ' (' . date("d M Y h:i", strtotime($entry->published)) . ')';
echo '</li>';
}
echo "</ol>";
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
?>
|
Listing 3 first loads the Zend class libraries, and then initializes an instance of the Zend_Rest_Client class. Use this client to initialize an unauthenticated GET request for the user's public feed, as you did earlier in Listing 1. Notice that the feed URL in this case must contain the user's Google Profile ID. The returned Atom feed is then parsed and converted into a Zend_Rest_Client_Response object. As before, it now becomes quite easy to iterate over this object collection and extract the details of specific posts from it.
It would be unusual indeed if the Google Buzz API failed to include a search feature; after all, this is Google. And so, the API offers a public search feed, which can be used to search all public posts by all users and return those matching the specified search term. This public search feed is accessible at https://www.googleapis.com/buzz/v1/activities/search.
If you're using the Google Buzz PHP Client Library, you can simply invoke the search() method and pass it your query term. Listing 4 illustrates:
Listing 4. Searching posts with the Buzz PHP client
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Searching public activity feeds</title>
<style>
body {
font-family: Verdana;
}
li {
border-bottom: solid black 1px;
margin: 10px;
padding: 2px;
width: auto;
padding-bottom: 20px;
}
</style>
</head>
<body>
<form method="post"
action="<?php echo $_SERVER['PHP_SELF']; ?>">
Search for: <input type="text" name="q" />
<input type="submit" name="submit" value="Search">
</form>
<?php
if (isset($_POST['submit'])) {
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// fetch authenticated user's public feed
$result = $buzz->search($_POST['q']);
// iterate through feed data
echo '<h1>' . $result->title . '</h1>';
echo count($result->posts) . ' post(s) found. <br/>';
echo '<ol>';
foreach ($result->posts as $post) {
echo '<li>';
echo isset($post->links['alternate'][0]->href) ?
'<a href="' . $post->links['alternate'][0]->href .
'">' . $post->title . '</a><br/>' :
$post->title . '<br/>';
echo $post->person->name . ' (' .
date("d M Y h:i", strtotime($post->published)) . ')';
echo '</li>';
}
echo '</ol>';
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
}
?>
</body>
</html>
|
Listing 4 begins by displaying a web form for the user to enter one
or more search terms. Once this form is submitted, the script creates a new buzz
object and passes the search terms to the object's search()
method. This method generates the necessary REST request to the Google Buzz API and
converts the result feed into a collection of buzzPost objects. All that's left to do now is to loop over the collection, printing the content, author, and publication date of each.
Figure 2 illustrates the result of a search for chocolate.
Figure 2. The result of a Google Buzz search
Since the search feed is public, you can also query it using any unauthenticated HTTP client. Listing 5 illustrates by using the Zend_Rest_Client library to directly request the search feed URL and process the response:
Listing 5. Searching posts with the Zend REST client
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Searching public activity feeds</title>
<style>
body {
font-family: Verdana;
}
li {
border-bottom: solid black 1px;
margin: 10px;
padding: 2px;
width: auto;
padding-bottom: 20px;
}
</style>
</head>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
Search for: <input type="text" name="q" />
<input type="submit" name="submit" value="Search">
</form>
<?php
if (isset($_POST['submit'])) {
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');
try {
if (empty($_POST['q'])) {
throw new Exception('No search term provided');
}
// search all feeds
$url = 'https://www.googleapis.com/buzz/v1/activities/search?q=' .
urlencode($_POST['q']);
$client = new Zend_Rest_Client($url);
$result = $client->get();
// iterate through returned feed
// display results
echo '<h1>' . $result->title . '</h1>';
echo count($result->entry) . ' post(s) found. <br/>';
echo '<ol>';
foreach ($result->entry as $entry) {
echo '<li>';
echo '<a href="' . $entry->link[0][@href] . '">' .
$entry->content . '</a><br/>';
echo $entry->author->name;
echo ' (' . date("d M Y h:i", strtotime($entry->published)) . ')';
echo '</li>';
}
echo "</ol>";
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
}
?>
</body>
</html>
|
Listing 5 initializes a new REST client and uses it to send an
unauthenticated GET request to the public search feed. The user-supplied search
parameters are URL-encoded and appended to the request through the special q parameter. You use a foreach() loop to iterate over the resulting object collection, as in Listing 3, to produce output equivalent to that of Listing 4.
As with other Google feeds, the Google Buzz API allows developers to customize the output by adding the following parameters to the REST query:
- The
altparameter, which specifies the feed format ('atom' or 'json') - The
max-resultsparameter, which specifies the maximum number of entries to retrieve - The
max-commentsparameter, which specifies the maximum number of comments to retrieve per entry - The
latandlonparameters, which specify geographical filters for search results
It's also possible to attach advanced search query operators to the request URL. Look in the Google Buzz API Developers Guide (see Resources for a link) for a complete list of operators, with examples.
Adding, editing, and deleting posts
That takes care of listing and searching for posts. Now, how about adding, editing, and deleting them?
As a REST-compliant API, the Google Buzz API supports the use of regular HTTP verbs to indicate the type of action required. Therefore, to add a new post, you simply send an authenticated POST request to the feed URL, appending the post content to the request body. In a similar vein, to edit or delete a post, you send an authenticated PUT or DELETE request containing the post ID to the feed URL.
To make things simpler for developers, the Google Buzz PHP Client Library encapsulates the above tasks into two methods: updatePost() and deletePost(). To illustrate, consider Listing 6, which demonstrates how to add a new Google Buzz post with PHP:
Listing 6. Adding posts
<?php
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// add a new post
$object = new buzzObject('Adding this post through the Buzz API...woohoo!');
$post = buzzPost::createPost($object);
$result = $buzz->updatePost($post);
echo 'Added new post with ID: ' . $result->id;
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
?>
|
Your first order of business is to create a new buzz instance. Then, create a new buzzObject instance and initialize it with the content to be posted.
Then you convert this buzzObject into a Google Buzz entry
through the buzzPost::createPost() method, and use the
updatePost() method to POST the entire request packet to
the Google Buzz servers. Once the new post is created, the server sends back a 201 (Created) status code and a complete <entry> fragment representing the newly-added post.
Figure 3 illustrates the output of Listing 6:
Figure 3. The result of adding a new Google Buzz post
Editing a post is slightly different: you must first create a new post, and then set its ID to the ID of the post you wish to replace. Listing 7 illustrates:
Listing 7. Modifying posts
<?php
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// edit a post
$object = new buzzObject('Updating this post through the Buzz API...yeehaw!');
$post = buzzPost::createPost($object);
$post->id = 'tag:google.com,2010:buzz:z133';
$result = $buzz->updatePost($post);
echo 'Updated post with ID: ' . $result->id;
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
?>
|
In Listing 7, the code initializes a new buzzPost
object with the correct content, and sets its ID to the ID of the post to be edited.
The updatePost() method then sends a PUT request to the Google Buzz servers with the revised entry. If successful, the server will respond with a 201 (OK) status code and the revised <entry>. Figure 4 illustrates the likely output:
Figure 4. The result of editing a Google Buzz post
Deleting a post is comparatively simple: provide the post ID to the deletePost() method and the Google Buzz PHP Client Library will construct and transmit a DELETE request to the REST API. Listing 8 illustrates the process:
Listing 8. Deleting posts
<?php
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// delete a post
$id = 'tag:google.com,2010:buzz:z13';
$buzz->deletePost($id);
echo 'Deleted post with ID: ' . $id;
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
?>
|
Figure 5 displays the output:
Figure 5. The result of deleting a Google Buzz post
In addition to allowing you to search for keywords, the Google Buzz API also allows you to search for people by name. This is accomplished by sending an HTTP GET request to the URL https://www.googleapis.com/buzz/v1/people/search, appending the necessary search terms to it. The response to this request is an Atom or JSON feed containing a list of matching users, together with their name and Google ID.
Listing 9 illustrates how to do this using the Google Buzz PHP Client Library:
Listing 9. Searching for users with the Buzz PHP client
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Searching for people</title>
<style>
table {
border-collapse: yes;
}
tr {
border-bottom: solid black 1px;
}
td {
vertical-align: top;
border: solid black 1px;
}
li {
margin: 10px;
padding: 2px;
width: auto;
padding-bottom: 20px;
}
</style>
</head>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
Search for people: <input type="text" name="q" />
<input type="submit" name="submit" value="Search">
</form>
<?php
if (isset($_POST['submit'])) {
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// fetch authenticated user's public feed
$result = $buzz->searchPeople($_POST['q']);
// iterate through feed data
echo '<h1>Search Results</h1>';
echo '<table>';
foreach ($result as $person) {
echo '<tr>';
// display user full name and photo
echo '<td><img src="' . $person->thumbnailUrl .
'" /><br/>';
echo '<strong>' . $person->name .
'</strong></td><td>';
// fetch user's public feed
$result = $buzz->getPosts('@public',
$person->id, false, false, 3);
// iterate through feed data
echo 'Recent updates: <br/>';
echo '<ol>';
foreach ($result->posts as $post) {
echo '<li>';
$url = isset($post->links->self[0]->href) ?
$post->links->self[0]->href : '#';
echo '<a href="' . $url . '">' . $post->title . '</a>';
echo ' (' . date("d M Y h:i", strtotime($post->published)) . ')';
echo '</li>';
}
echo '</ol></td>';
echo '</tr>';
}
echo '</table>';
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
}
?>
</body>
</html>
|
Listing 9 asks the user to enter a person's name into a search form,
and then uses the searchPeople() method to query the Google
Buzz API for matching people. The return value of this method is a collection of buzzPerson objects, each of which contains information on the user:
first and last name, Google ID, Google Profile URL, photo URL, and other personal information. Listing 9 extracts this information and then uses the Google ID with the getPosts() method to retrieve the user's three most recent posts as well. All of this information is formatted in a readable web page, like the one in Figure 6.
Figure 6. The result of a Google Buzz person search
Listing 10 offers an alternative to Listing 9, using the Zend_Rest_Client library to accomplish the same result:
Listing 10. Searching for users with the Zend REST client
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Searching for people</title>
<style>
table {
border-collapse: yes;
}
tr {
border-bottom: solid black 1px;
}
td {
vertical-align: top;
border: solid black 1px;
}
li {
margin: 10px;
padding: 2px;
width: auto;
padding-bottom: 20px;
}
</style>
</head>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
Search for people: <input type="text" name="q" />
<input type="submit" name="submit" value="Search">
</form>
<?php
if (isset($_POST['submit'])) {
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');
try {
if (empty($_POST['q'])) {
throw new Exception('No search term provided');
}
// search people feed
$client = new Zend_Rest_Client('https://www.googleapis.com/buzz/v1/
people/search?q=' . urlencode($_POST['q']));
$result = $client->get();
// iterate through returned feed
// for each result, display user name and photo
echo '<h1>Search Results</h1>';
echo '<table>';
foreach ($result->entry as $entry) {
echo '<tr>';
echo '<td><img src="' . $entry->thumbnailUrl .
'" /><br/>';
echo $entry->displayName . '</td><td>';
// get feed of user's three most recent public posts
$client2 = new Zend_Rest_Client('https://www.googleapis.com/buzz/
v1/activities/' . $entry->id . '/@public?max-results=3');
$result2 = $client2->get();
echo 'Recent updates: <br/>';
echo '<ol>';
foreach ($result2->entry as $entry2) {
echo '<li>';
echo '<a href="' . $entry2->link[0][@href] . '">' .
$entry2->content . '</a>';
echo ' (' . date("d M Y h:i", strtotime($entry2->published)) . ')';
echo '</li>';
}
echo "</ol></td>";
echo '</tr>';
}
echo '</table>';
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
}
?>
</body>
</html>
|
Listing 10 uses the Zend_Rest_Client library to directly access the REST endpoint for the people search service, returning an object representation of an Atom feed. This object collection can be used as needed to extract relevant information. Note that the query term must be manually URL-encoded in this case.
Google Buzz allows users to "follow" each other. Following a user automatically makes their posts part of a user's consumption feed. The Google Buzz API makes this information available through follower and following feeds at the https://www.googleapis.com/buzz/v1/people/YOUR_ID/@groups/@followers and https://www.googleapis.com/buzz/v1/people/YOUR_ID/@groups/@following URLs respectively.
To obtain this information using the PHP client library, use the followers() and following() methods, which return buzzPerson object collections representing the user's followers and following. Listing 11 has an example:
Listing 11. Listing followers and following
<?php
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// get followers
$followers = $buzz->followers('@me');
echo '<h1>Currently being followed by:</h1>';
foreach ($followers as $person) {
displayUserBlock($person);
}
// get following
$following = $buzz->following('@me');
echo '<h1>Currently following:</h1>';
foreach ($following as $person) {
displayUserBlock($person);
}
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
// render user block
function displayUserBlock($person) {
// get object from global scope
global $buzz;
// display user full name
echo '<strong>' . $person->name . '</strong><br/>';
// fetch user's public feed
$result = $buzz->getPosts('@public', $person->id, false, false, 3);
// iterate through feed data
echo '<ol>';
foreach ($result->posts as $post) {
echo '<li>';
$url = isset($post->links->self[0]->href) ?
$post->links->self[0]->href : '#';
echo '<a href="' . $url . '">' . $post->title .
'</a>';
echo ' (' . date("d M Y h:i", strtotime($post->published)) . ')';
echo '</li>';
}
echo '</ol>';
}
?>
|
Listing 11 first uses the followers() method to retrieve a list of the authenticated user's followers. The return value of this method is a collection of buzzPerson objects, each of which is passed to the user-defined displayUserBlock() method. This method retrieves each follower's name and ID, and then uses the ID to make a second request, this time through the getPosts() method, to retrieve the follower's three most recent posts. This information is then formatted for display.
After this, use the following() method to retrieve a list of the users currently being followed by the authenticated user. The collection returned by this method is processed in a similar manner.
The Google Buzz API also makes it possible to programmatically follow or unfollow particular users. These API methods are reflected in the buzz object's follow() and unfollow() method, both of which accept a user ID and either add or drop that user from the authenticated user's follow queue.
Now that you know a little bit about how the Google Buzz API works, let's put together a simple web application that demonstrates how to use it interactively. Listing 12 updates Listing 2, creating an Add form and attaching Delete links to each post. These additions allows authenticated users to view their public feed, interactively add new posts to it, or delete existing ones from it—all without using the Google Buzz interface.
Listing 12. Listing user posts
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style>
body {
font-family: Verdana;
}
li {
margin: 10px;
padding: 2px;
width: auto;
padding-bottom: 20px;
}
</style>
</head>
<body>
<h1>Add New Post</h1>
<form method="post" action="add.php">
Message: <br/>
<textarea name="buzz" cols="60" rows="5"></textarea><br/>
<input type="submit" name="submit" value="Post!" />
</form>
<h1>Recent Posts</h1>
<?php
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// fetch authenticated user's public feed
$result = $buzz->getPosts('@public', '@me');
// iterate through feed data
echo count($result->posts) . ' post(s) found. <br/>';
echo '<ol>';
foreach ($result->posts as $post) {
echo '<li>';
echo isset($post->links['alternate'][0]->href) ?
'<a href="' . $post->links['alternate'][0]->href .
'">' . $post->title . '</a>' : $post->title;
echo ' (' . date("d M Y h:i", strtotime($post->published)) . ') ';
echo '<a href="delete.php?id=' . $post->id . '">[Delete this post]</a>';
echo '</li>';
}
echo '</ol>';
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
?>
</body>
</html>
|
Listing 12 is divided into two parts:
- The first part initializes a
buzzobject and uses itsgetPosts()method to retrieve the user's public feed. Each post is accompanied with a link that allows the user to delete the post through the delete.php script. The post ID is passed to the delete.php script as a standard GET parameter. - The second part contains an HTML form, which provides an input field for the user to enter a new post. Data submitted through the form is transferred to the add.php script through POST.
Listing 13 contains the add.php script, which receives input data
through POST and converts it to a buzzPost object. This
object is then transmitted to the Google Buzz service as a POST request through the
updatePost() method discussed earlier. Listing 13 shows the code:
Listing 13. Adding new posts
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
</head>
<body>
<?php
if (!isset($_POST['buzz'])) {
die('ERROR: Please enter some Buzz content!');
}
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// add a new post
$object = new buzzObject($_POST['buzz']);
$post = buzzPost::createPost($object);
$result = $buzz->updatePost($post);
echo 'Added new post with ID: ' . $result->id;
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
?>
</body>
</html>
|
Listing 14 contains the delete.php script, which receives the ID of the script to be deleted and passes this ID to the deletePost() method. This method constructs a DELETE request and hands it over to the Google Buzz API for execution. Here's the code:
Listing 14. Deleting posts
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
</head>
<body>
<?php
if (!isset($_GET['id'])) {
die('ERROR: Please provide a valid Buzz ID for deletion');
}
// include PHP client library
require_once 'buzz.php';
try {
// set up file store
$storage = new buzzFileStorage('/tmp/cache');
// get user ID
$uid = 1;
// perform authentication with Google
$auth = buzzOAuth::performOAuthLogin($storage, $uid);
// initialize Buzz object
$buzz = new buzz($storage, $auth);
// delete a post
$buzz->deletePost($_GET['id']);
echo 'Deleted post with ID: ' . $id;
} catch (Exception $e) {
echo 'ERROR:' . $e->getMessage();
}
?>
</body>
</html>
|
Figure 7 displays the output of Listing 12:
Figure 7. A web form for Google Buzz interaction
As these examples illustrate, the Google Buzz API and PHP Client Library make it possible to integrate Buzz posts and activity streams directly into a PHP application. The examples in this article merely touch the tip of the iceberg. You can do a lot more with Google Buzz, including:
- Creating private activities
- Mute, unmute and like posts
- Create and edit comments
- Create advanced search queries
As of this writing, the Google Buzz API is still under development, so you can expect even more goodies in the future!
In summary, the Google Buzz API provides a sophisticated, format-independent mechanism for developers to integrate public Buzz content into any web application. It's great for mashups, or to build your own custom interface to Google Buzz. Try it out sometime, and see what you come up with!
Learn
- The Google Buzz Terms of Service: Base your use of Google Buzz content in third-party applications on these Terms of Service.
- The Google Buzz Developer Policies and Branding Guidelines: Read how you can use Google Buzz and make your application comply with these policies and guidelines.
- Google Account: Register for your free account and get started.
- The Developer's Guide and REST reference: Explore the Google Buzz API and the common features of the API that use the RESTful calling style to access Atom or JSON data structures.
- Google OAuth authentication: Authorize a web application's requests for access to a user's data with Google's implementation of the OAuth protocol.
- Google authentication services: Register your web application for free.
- Install and use the Google Buzz PHP Client Library: Understand how to use this client library to work with Google Buzz data from your web server.
- Google Buzz API Developer Forum: Participate in discussions related to Google Buzz API development.
- The Google Social web blog: Track Google Buzz news.
- Programmer's Reference Guide: Read more about the Zend_Rest_Client library.
- Writing a REST Web Service and Client With Zend_Controller (Jon Lebensold, Zendcasts, April 2009): Learn how to build a REST web service and client in this screencast (38.50 minutes).
- XML area on developerWorks: Get the resources you need to advance your skills in the XML arena.
- My developerWorks: Personalize your developerWorks experience.
- IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
- XML technical library: See the developerWorks XML Zone for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks. Also, read more XML tips.
- developerWorks technical events and webcasts: Stay current with technology in these sessions.
- developerWorks on Twitter: Join today to follow developerWorks tweets.
- developerWorks podcasts: Listen to interesting interviews and discussions for software developers.
- developerWorks on-demand demos: Watch demos ranging from product installation and setup for beginners to advanced functionality for experienced developers.
Get products and technologies
- The Google Buzz PHP Client Library: Download and work with Google Buzz data on your server. The language of choice is PHP.
- The Zend Framework: Download and build more secure, reliable, and modern Web 2.0 apps and web services with widely available APIs.
- IBM product evaluation versions: Download or explore the online trials in the IBM SOA Sandbox and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
- XML zone discussion forums: Participate in any of several XML-related discussions.
- developerWorks blogs: Check out these blogs and get involved.

Vikram Vaswani is the founder and CEO of Melonfire, a consulting services firm with special expertise in open-source tools and technologies. He is also the author of the books Zend Framework: A Beginners Guide and PHP: A Beginners Guide.




