Search and integrate Google Buzz Streams with PHP

Use PHP to process and integrate activity streams from Google Buzz with a web application

Google Buzz allows users to post real-time status updates, news, and content to their Google Account, and to subscribe to similar updates from others. Web application developers are able to access and search this content through the Google Buzz REST API. This article introduces the Google Buzz API and demonstrates it in the context of a PHP application, explaining how to search, retrieve, add, and edit different types of content on Google Buzz.

Vikram Vaswani, Founder, Melonfire

Photo of Vikram VaswaniVikram 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.



26 October 2010

Also available in Chinese Japanese Portuguese

Introduction

Frequently used acronyms

  • API: Application program interface
  • DOM: Document Object Model
  • HTTP: Hypertext Transfer Protocol
  • JSON: JavaScript Object Notation
  • REST: REpresentational State Transfer
  • URL: Uniform Resource Locator
  • XML: Extensible Markup Language

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&#39;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&#39;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.


Retrieving public posts

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 buzzStorage object, which specifies how local caching will occur. The Google Buzz PHP Client Library supports Alternative PHP Cache (APC), memcached, and file-based caching, represented by buzzApcStorage, buzzMemcacheStorage, and buzzFileStorage classes respectively.
  • A properly configured buzzOAuth object. This object is generated by the static buzzOAuth::performOAuthLogin() method, which accepts two arguments: a buzzStorage object, and a local user identifier. The buzzOAuth::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
Screen capture of a list of five public posts, including links to the posts

A quick word here about feed types. The Google Buzz API offers three feed types:

  1. 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
  2. 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
  3. 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.


Searching public posts

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
Screen capture of the result of a Google Buzz search for the word 'chocolate', shows three of 100 posts

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 alt parameter, which specifies the feed format ('atom' or 'json')
  • The max-results parameter, which specifies the maximum number of entries to retrieve
  • The max-comments parameter, which specifies the maximum number of comments to retrieve per entry
  • The lat and lon parameters, 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
Screen capture of the result of adding a new Google Buzz post: Added new post with ID: tag:google.com,2010:buzz:z13

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
Screen capture of the result of editing a Google Buzz post: Updated post with ID: tag:google.com,2010:buzz:z133

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
Screen capture of the result of deleting a Google Buzz post: Deleted post with ID: tag:google.com,2010:buzz:z13

Searching for users

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
Screen capture of the result of a Google Buzz person search with three sample entries

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.


Managing followers

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.


An example application

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 buzz object and uses its getPosts() 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
Screen capture of a Message web form for Google Buzz interaction; also shows three of 6 recent posts

Conclusion

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!

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into XML on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Open source
ArticleID=555182
ArticleTitle=Search and integrate Google Buzz Streams with PHP
publish-date=10262010