Google Docs SpreadSheetにAPIを利用してデータを追加してみよう(without zend gdata)


こんにちは。ラクスルエンジニアインターンのカンです。
食欲の秋になり、ランチがどんどんボリューム系に傾いている傾向を見せる中、
今回はGoogle Docs SpreadSheet APIを利用して新しいデータを追加する方法について書きたいと思います。

PHPでGoogle Docsをいじるときは基本的にはZend FrameworkのGdata APIを利用しますが、
ラクスルでは諸事情のため、使うことができませんでした。
従って、以下ではCURLを利用してProtocolを使ってデータを追加してみようと思います。

1.認証

SpreadSheetにアクセスためには、まずGoogleAccountで認証を行う必要があります。
今回はClientLoginを利用することにします。

※注意
昔書いたコードであるためClientLoginを使用していますが、2015年5月27日から廃止になりました。
OAuth2.0の方をおすすめします。

また、認証を行うアカウントがSpreadSheetに対して観覧、編集権限を持っていなければなりません。

以下にサンプルコードを示します。

/*
  'accountType' => 認証タイプで。HOSTEDはApps、GOOGLEはGoogleAccountの認証です。
                   デフォルトはHOSTED_OR_GOOGLE(両方認証)です。
  'service'     => 利用するサービス。Spreadsheets Data APIであるため'wise'になります。
                   詳しくは
             https://developers.google.com/gdata/faq?hl=ja#Authenticationを
                   参照してください。
*/
  $url = 'https://www.google.com/accounts/ClientLogin';
  $fields = array(
    'Email' => 'アカウントEmail',
    'Passwd' => 'パスワード',
    'accountType' => 'HOSTED_OR_GOOGLE', 
    'service' => 'wise',
    'source' => 'pfbc'
  );

  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl, CURLOPT_POST, true);
  curl_setopt($curl, CURLOPT_POSTFIELDS, $fields);
  $response = curl_exec($curl);
  $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  curl_close($curl);

  if ($status == 200) {
    echo 'auth status is 200' . PHP_EOL;
    //認証成功後、認証トークンを保存します
    if (stripos($response, 'auth=') !== false) {
      preg_match("/auth=([a-z0-9_\-]+)/i", $response, $matches);
      $token = $matches[1];
    }
  }


statusが200なら認証に成功したこととなります。

2.Idを取得する

編集しようとするgoogle docsのspreadsheetに接続するとURLが
https://docs.google.com/a/raksul.com/spreadsheets/d/[SpreadsheetId]/edit#gid=[gid]
のようになります。

データを追加するためには、認証以外にも上のURLに含まれているSpreadsheetId, WorksheetIdが必要になります。

SpreadsheetId

dとeditの間にある「SpreadsheetId」の部分がSpreadsheetIdとなります。

SheetId

URLのgidの部分でSheetの区別しているわけですが、APIではこのまま利用はできません。
利用するためには

  1.gidから最初の3桁を取得します
  2.31578とXORを行います
  3.36進数に変換します

出た36進数の数字がSheetIdです。
因みに、gidが0ならod6となります。(31578の36進数表現)
基本的に最初に生成されたシートのgidは0です。

この方法以外にも
Protocolを利用してSpreadSheetの情報を取得し、SheetIdを知る方法もあります。

3.追加する

SpreadsheetIdもSheetIdも取得したので、追加を行います。
APIを利用する目に、最初の行に識別できるようなコラム名を書く必要があります。
その行が気になるのなら、行隠し機能を利用するといいですね。

SpreadsheetIdとSheetIdを利用してSpreadsheetに追加する

追加するためにはXML形式でPOST Requestを送る必要があります。

下にサンプルソースを添付します


  //KeyがColumnの名前、Valueがデータになります。
  $data = array(
    'name' => 'Jane Doe',
    'age'  => '22'
  );
  $url = 'https://spreadsheets.google.com/feeds/list/[SpreadsheetId]/[worksheetid]/private/full';
  $headers = array(
    'Content-Type: application/atom+xml',
    'Authorization: GoogleLogin auth=' . $token, //認証のところで保存したトークンです
    'GData-Version: 3.0'
  );
  $fields = '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">';

  foreach ($data as $key => $value) {
    $fields .= "<gsx:$key><![CDATA[$value]]></gsx:$key>";
  }
  $fields .= '</entry>';

  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($curl, CURLOPT_POST, true);
  curl_setopt($curl, CURLOPT_POSTFIELDS, $fields);
  $response = curl_exec($curl);
  $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

  echo 'add status is ' . $status . PHP_EOL;
  curl_close($curl);

実行後、Response Statusが201なら、スプレッドシートにデータが追加されたことが確認できます。

Spreadsheetに追加した結果

4.終わりに

普段はラクスル内でのコーディングをしていたので
GoogleとAPIを通じてやりとりができるということは新鮮な経験でした。
今回は簡単な行の追加だけでしたが、Google Sheets API Documentを参考すると
追加だけではなく削除や修正することもできます。

・ 参考サイト

http://blog.flect.co.jp/labo/2013/07/google-spreadsh-7b42.html(SheetIdについて)