Search code examples
gdata-apigdatagoogle-docs-apiputzend-gdata

Google Documents List API - How to Publish a Document


I'm utterly lost as to how one can programmatically publish a Google Document (specifically a spreadsheet).

I've read the Google Documents List API Protocol Guide and have found this:

http://code.google.com/apis/documents/docs/3.0/developers_guide_protocol.html#GettingRevisions

The next section of the article begins with 'Publishing documents by publishing a single revision' and this is where I found this example:

PUT /feeds/default/private/full/resource_id/revisions/revision_number
GData-Version: 3.0
Authorization: <your authorization header here>
Content-Length: 722
Content-Type: application/atom+xml

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd='http://schemas.google.com/g/2005'
       xmlns:docs="http://schemas.google.com/docs/2007" gd:etag="W/"DkIBR3st7ImA9WxNbF0o."">
  <id>https://docs.google.com/feeds/id/resource_id/revisions/1</id>
  <updated>2009-08-17T04:22:10.440Z</updated>
  <app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-06T03:25:07.799Z</app:edited>
  <title>Revision 1</title>
  <content type="text/html" src="https://docs.google.com/feeds/download/documents/Export?docId=doc_id&amp;revision=1"/>
  <link rel="alternate" type="text/html"
      href="https://docs.google.com/Doc?id=doc_id&amp;revision=1"/>
  <link rel="self" type="application/atom+xml"
      href="https://docs.google.com/feeds/default/private/full/resource_id/revisions/1"/>
  <author>
    <name>user</name>
    <email>user@gmail.com</email>
  </author>
  <docs:publish value="true"/>
  <docs:publishAuto value="false"/>
</entry>

I have been retrieving document list feeds and CRUDing worksheets but I cannot get the publishing to work nor do I understand how it is supposed to work. My basic setup for establishing a connection to my feed and preparing the data to be PUT is as follows:

<?php
set_include_path($_SERVER['DOCUMENT_ROOT'].'/library/');

require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);


$theId = 'my-worksheet-id';

$user = "my-gmail-account-name";
$pass = "my-gmail-account-password";
$service = Zend_Gdata_Docs::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);

$service = new Zend_Gdata($client);


$xml = "<entry  xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'
        xmlns:docs='http://schemas.google.com/docs/2007' gd:etag='W/\"DkIBR3st7ImA9WxNbF0o.\"'>

        <id>https://docs.google.com/feeds/id/spreadsheet:$theId/revisions/1</id>
        <updated>2009-08-17T04:22:10.440Z</updated>
        <app:edited xmlns:app='http://www.w3.org/2007/app'>2009-08-06T03:25:07.799Z</app:edited>
        <title>Revision 1</title>
        <content type='text/html' src='https://docs.google.com/feeds/download/documents/Export?docId=$theId&amp;revision=1'/>
        <link rel='alternate' type='text/html'
            href='https://docs.google.com/Doc?id=$theId&amp;revision=1'/>
        <link rel='self' type='application/atom+xml'
            href='https://docs.google.com/feeds/default/private/full/spreadsheet:$theId/revisions/1'/>
        <author>
            <name>$user</name>
            <email>$user</email>
        </author>
        <docs:publish value='true'/>
        <docs:publishAuto value='false'/>
      </entry>";

$putURL = "http://docs.google.com/feeds/default/private/full/spreadsheet:".$theId."/revisions/0";
$data = $service->put($xml, $putURL);
?>

Which results in a

Fatal error: Uncaught exception 'Zend_Gdata_App_HttpException' with message 'Expected response code 200, got 400 Invalid request URI

Can someone help me out? Has anyone successfully published a Google Document programmatically?


Solution

  • Assuming the document has already been created and has a document id of XXXX

    What you need to do is send a "PUT" request with specific headers, and XML (an entry describing your document) as the body, to a specific URL.

    Since you are not changing any content of the doc (only the meta-data), your target URL will look like this...

    https://docs.google.com/feeds/default/private/full/XXXX/revisions/0

    The first thing you need to do is authenticate with the proper Google service.

    $client = Zend_Gdata_ClientLogin::getHttpClient(GDOC_LOGIN, GDOC_PASS,'writely');
    

    Use the returned object to grab your auth token.

    $auth_token = $client->getClientLoginToken();
    

    In Zend/Gdata/App.php is a helper function for executing the PUT request. Prepare parameters for this method like so...

    $method = "PUT";
    $url ="https://docs.google.com/feeds/default/private/full/XXXX/revisions/0";
    $headers['GData-Version'] = '3.0';
    $headers['If-Match'] = '*';
    $headers['Authorization'] = "GoogleLogin auth = $auth_token";
    $headers['Content-Length'] = '380';
    $headers['Content-Type'] = 'application/atom+xml';
    $body = <<<XML
    <?xml version='1.0' encoding='UTF-8'?>
    <entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007"
        xmlns:gd="http://schemas.google.com/g/2005">
      <category scheme="http://schemas.google.com/g/2005#kind"
          term="http://schemas.google.com/docs/2007#spreadsheet"/>
        <docs:publish value="true"/>
        <docs:publishAuto value="true"/>
    </entry>
    XML;
    $contentType = "application/atom+xml";
    $remainingRedirects = 99;
    

    Then call the helper function...

    $app = new Zend_Gdata_App();
    $app->performHttpRequest($method, $url, $headers, $body, $contentType, $remainingRedirects);
    

    Good luck! Let me know if this helps!