How to Access Blogger using PHP and GData Format

If you were like me, you wanted to be able to access Blogger using your own interface. Unfortunately, many Blogger API’s out there still using Atom API, which will be deprecated soon. Google plans to change it using Blogger GData API.

What is Blogger GData API? This is what the guidelines said,

The Blogger data API allows client applications to view and update Blogger content in the form of Google data API (“GData”) feeds. Your client application can use GData to create new blog posts, edit or delete existing posts, and query for posts that match particular criteria.

I will show you how to do that with PHP, using curl and simpleXML functions. So, make sure you have them installed in your PHP.

Authentication

You should know that at the time of this writing there are two versions of Blogger: the current version, in which users have Blogger-specific accounts, and the new version that’s in beta, in which users use their non-Blogger-specific Google accounts. This Google account is also used for other Google Service like Google Groups, Google Base and etc.

This tutorial assumes that you use current versions of Blogger, means that we don’t need Google account to authenticate our requests. So we only need HTTP basic authentication to make any request to server.

Getting BlogID

First off, we’re going to need blogID to make some requests to Blogger server. I cann’t find in the guidelines how to do that directly. So this is how to work around that.

According to the guidelines, you can get a feed listing the blogs for a particular user by sending an authenticated GET request to the following URL,

http://www.blogger.com/feeds/default/blogs

The metafeed response would be something like this,

<entry>
  <id>http://www.blogger.com/feeds/userID/blogs/blogID</id>
  <published>2006-08-02T07:55:26.191-08:00</published>
  <updated>2006-08-02T07:55:52.309-08:00</updated>

  <title type='text'>My Diary</title>
  <summary type='html'>Being the journal of Elizabeth Bennet</summary>
  <link rel='alternate' type='text/html'
    href='http://liz.blogspot.com/index.html'>
  </link>
  <link rel='http://schemas.google.com/g/2005#feed'
    type='application/atom+xml'
    href='http://www.blogger.com/feeds/blogID/posts/full'>
  </link>
  <link rel='http://schemas.google.com/g/2005#post'
    type='application/atom+xml'
    href='http://www.blogger.com/feeds/blogID/posts/full'>
  </link>
  <link rel='self' type='application/atom+xml'
    href='http://www.blogger.com/feeds/userID/blogs/blogID>
  </link>
  <author>
    <name>Elizabeth Bennet</name>
    <email>[email protected]</email>
  </author>
</entry>

Since we’re only interested in getting blogID, the first <id> .. </id> tag is our main concern. This is how we do this in PHP,

    function getBlogID($username,$password)
    {
      $ch = curl_init("http://www.blogger.com/feeds/default/blogs");
      curl_setopt($ch, CURLOPT_GET,1);
      curl_setopt($ch, CURLOPT_USERPWD, "{$username}:{$password}");
      curl_setopt($ch, CURLOPT_HEADER,0);
      curl_setopt($ch, CURLOPT_HTTPAUTH,CURLAUTH_BASIC);
      curl_setopt($ch, CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
      $xmlstr = curl_exec($ch);
      $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);

      if ( $http_code == '200' )
      {
        $xml = simplexml_load_string($xmlstr);
        $_entryid = explode("/",$xml->entry->id);
        return $_entryid[count($_entryid)-1];
      }
      else
      {
        return "Unable to connect to server";
      }
    }

    echo getBlogID('myusername','mypassword');

Change myusername and mypassword into your own username and password for Blogger. We will use this blogID for other requests like add, edit, view or delete post.

Posting a blog

You can post a new blog by sending the POST request to the appropriate Blogger URL,

POST http://www.blogger.com/feeds/blogID/posts/full

with the POST field defined in the following format,

<entry xmlns='http://www.w3.org/2005/Atom'>
  <title type='text'>This is my title</title>
  <content type='xhtml'>
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p>This is my <em>content</em>, you can put HTML format here.</p>
    </div>
  </content>
</entry>

Here is the code for doing that in PHP,

    function postBlog($username,$password,$title,$msg)
    {
      $blogID = getBlogID($username,$password);

      $xmlstr = "
<entry xmlns='http://www.w3.org/2005/Atom'>
  <title type='text'>$title</title>
  <content type='xhtml'>
      $msg
  </content>
</entry>
      ";

      $ch = curl_init("http://www.blogger.com/feeds/$blogID/posts/full");
      curl_setopt($ch, CURLOPT_POST,1);
      curl_setopt($ch, CURLOPT_USERPWD, "{$username}:{$password}");
      curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: application/atom+xml"));
      curl_setopt($ch, CURLOPT_HEADER,1);
      curl_setopt($ch, CURLOPT_HTTPAUTH,CURLAUTH_BASIC);
      curl_setopt($ch, CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
      curl_setopt($ch, CURLOPT_POSTFIELDS,$xmlstr);

      curl_exec($ch);
      $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
      if ( $http_code == '201' ) {
        echo "Post success";
      } else {
        echo "Post failed";
      }
    }

    postBlog("myusername","mypassword","This is my title","<p>This is my <em>content</em>, you can put HTML format here.</p>");

Send a query

GData lets you request a set of entries that match specified criteria, such as requesting blog posts created or updated in a given date range, or requesting blog posts containing a specified string. For more information about the query parameters for GData queries (such as updated-min and updated-max), see the Google Data APIs Protocol document.

For example, to get the blog listing from the first index up to two entries, you can send GET request to the following URL,

GET http://www.blogger.com/feeds/blogID/posts/full?start-index=1&max-results=2

the response to this request might look like this,

<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'>
  <id>http://www.blogger.com/feeds/83989983/posts/full</id>
  <updated>2006-10-12T23:04:11.220-07:00</updated>
  <title type='text'>My Blog</title>
  <link rel='alternate' type='text/html' href='http://myblog.blogspot.com'></link>
  <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.blogger.com/feeds/83989983/posts/full'></link>
  <link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='http://www.blogger.com/feeds/83989983/posts/full'></link>
  <link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/83989983/posts/full?start-index=1'></link>
  <author>
    <name>Mr. Author</name>
  </author>
  <generator version='6.00' uri='www.blogger.com'>Blogger</generator>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>2</openSearch:itemsPerPage>
  <entry>
    <id>http://www.blogger.com/feeds/83989983/posts/full/116075233967881293</id>
    <published>2006-10-13T08:12:19.663-07:00</published>
    <updated>2006-10-13T08:12:19.730-07:00</updated>
    <title type='text'>What a good thing</title>
    <content type='xhtml'>
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>This is my post</p>
      </div>
    </content>
    <link rel='alternate' type='text/html' href='http://myblog.blogspot.com/2006/10/what-good-thing.html'></link>
    <link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/83989983/posts/full/116075233967881293'></link>
    <link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/83989983/posts/full/116075233967881293'></link>
    <author><name>Mr. Author</name></author>
  </entry>
  <entry>
    <id>http://www.blogger.com/feeds/83989983/posts/full/116075233967881294</id>
    <published>2006-10-13T08:12:19.663-07:00</published>
    <updated>2006-10-13T08:12:19.730-07:00</updated>
    <title type='text'>Really nice thing</title>
    <content type='xhtml'>
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>This is my nextpost</p>
      </div>
    </content>
    <link rel='alternate' type='text/html' href='http://myblog.blogspot.com/2006/10/really-nice-thing.html'></link>
    <link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/83989983/posts/full/116075233967881294'></link>
    <link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/83989983/posts/full/116075233967881294'></link>
    <author><name>Mr. Author</name></author>
  </entry>
</feed>

Here is how you can do it in PHP,

    function sendQuery($username,$password,$start,$maxresults)
    {
      $blogID = getBlogID($username,$password);

      $ch = curl_init("http://www.blogger.com/feeds/$blogID/posts/full?start-index=$start&max-results=$maxresults");
      curl_setopt($ch, CURLOPT_GET,1);
      curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
      curl_setopt($ch, CURLOPT_HEADER,0);
      curl_setopt($ch, CURLOPT_HTTPAUTH,CURLAUTH_BASIC);
      curl_setopt($ch, CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
      $xmlstr = curl_exec($ch);

      $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
      if ( $http_code == '200' )
      {
        $resp = simplexml_load_string($xmlstr);
        return $resp;
      }
      else
      {
        echo "Failed to send query.";
        return false;
      }
    }

    if ( $resp = sendQuery("myusername","mypassword",1,2) )
    {
      foreach ($resp->entry as $ent ) {
        echo "<a href=\"{$ent->link[0][href]}\">{$ent->title}</a>","<br />";
        echo $ent->content->div->asXML() , "<br />";
      }
    }

You can find more type of query in GData protocol guidelines, including how to edit and delete entry. Perhaps on the next tutorial i will teach you how to do it. Till then, have a nice try.

🙂

Join the Conversation

5 Comments

  1. Hey!

    You have just made my day. I spent about 3 days looking for a straightforward explaination of how to do this and here it is. Appearantly I was looking for some of the wrong things and of course some right things (found javascript version that was rediculously slow and complicated (2000 lines of code to do what you did with 200) Once again thank you for the tute.

    I owe you one!

  2. Tremendous Explanation that I was searching for quite
    some days…

    Thanks dude…..

  3. Loads of thanks to you, now I can understand nearly all the GData Api’s and How they work just because you explained this here,
    I have a Big problem, I’m using you class from phpclasses and i am able to post a simple text post but when I try to post xhtml content blogger returns status code 400 (400 BAD REQUEST Invalid request URI or header, or unsupported nonstandard parameter.)
    It would be great if you can help me with that and also your blogger class is’nt properly parsing blogid from the metafeed which can be corrected by stripping blogid from the
    $idText = split(‘-‘,$bloginfo[‘blogid’]);
    $bloginfo[‘blogid’] = $idText[2];
    Now bloginfo will contain the blogid 🙂
    But i still need help with that xhtml posting seeems like some encoding problems . Waitng for your reply ..

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.