Google APIからGoogle Fusion Tablesに触る

Google Fusion Tablesは、簡単に言うとオンラインで使えるデータベースです。これ、相当すごいと思います。夢広がりまくりです。SQLっぽいクエリを投げて、データを取得したり、追加したりなどなどできます。

特にGoogle Mapsとの連携が良くできていますが、今回は純粋にデータベースとして使ってみる試みです。詳しい手順は忘れたのでざっくりいきますが、極力絵は多めです。Googleの公式Webに説明は多くあるものの今一つつかみどころ無く、かなり苦労したためです。

APIキー取得

こちらから取得。
https://code.google.com/apis/console/

プロジェクト作成

こんな画面を出して、「CREATE PROJECT」の赤ボタンを押してプロジェクトを作ります。
f:id:Schima:20131127231400p:plain

API登録

作ったプロジェクトの中に進み、左のメニューの API & auth のAPIsを見ると、使えるAPIがずらっと一覧になっています。名前を見ているだけで夢が広がってきます。今回はFusion Tables APIをONにします。
f:id:Schima:20131127231540p:plain

アプリケーション登録

続いて左のメニューから Registered appsに進み、REGISTER APPを押してアプリケーションを登録します。これから作るプログラムをアプリケーションととらえ、そのプログラムからGoogleを使わせていただくための各種情報を頂戴します。

今回はWeb ApplicationでたぶんOK.
f:id:Schima:20131127232157p:plain

これで登録すると、こんな画面になります。まず使うのはBrowser Keyです。メモっておきます。また、あとでOAuth 2.0 ClientIDも必要になりますのでこちらも開いて確認しておきましょう。
f:id:Schima:20131127233252p:plain

Fusion Talbesの準備

新規作成

Google Driveを開いて、作成するときの「アプリの追加」を選ぶと、デフォルトのスプレッドシート等以外のドキュメントも作ることができます。ここからFusion Tablesを選択し、新規作成できる状態にします。
f:id:Schima:20131127233226p:plain
作成時はCreate empty tableで良いです。何か良いデータがあるなら既存のExcelファイルなどを上げても良さそうです。

データ入力

「若干操作しづらいスプレッドシート」といった感触で、気軽にデータを入れていくことができます。empty tableで始めると下の画像のような4列ができます。適当に入れてみましょう。
Locationについてはデータ型がLocationになっていて、geocodeを使うことで地名から緯度経度情報に変換できたりもします。Map of Locationのタブを押せばその位置がすぐに地図で確認できたりもします。やはりGoogle Maps連携が重視されていますね。
f:id:Schima:20131127233806p:plain

共有設定

APIからアクセスしやすいよう、右上の青いShareボタンから「リンクを知っている全員が閲覧できます」状態に変えます。
またこの際、このテーブルのIDも控えておきます。正攻法じゃない気はするのですが、表示されているリンクのdocid=***の部分がテーブルIDです。
f:id:Schima:20131127234109p:plain

JavaScriptからデータの取得

ようやくコードが書けます。手始めに全データを取得してみましょう。今回は適当なHTMLを書いて、その中のJavaScriptから実行させます。jQueryの力も借りています。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="content-language" content="ja">
    <title>FusionTables Test</title>

    <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
    <script src="https://apis.google.com/js/client.js"></script>
    <script src="https://www.google.com/jsapi"></script>

    <script type="text/javascript">
var apiKey = 'AIzaSyDB3OjI-xxxxxxxxxxxxxxxxxxxxxxxxxx';
var tableId = '1Le9Mv57xwsp7yyyyyyyyyyyyyyyyyyyyyyyyyyy';

function initialize(){
    var sql = 'SELECT * FROM ' + tableId;
    var url = 'https://www.googleapis.com/fusiontables/v1/query';
    url += '?key=' + apiKey;
    url += '&sql=' + encodeURIComponent(sql);

    $.ajax({
        url: url,
        dataType: 'json',
        success: function (data) {
            console.log(data);
            writeDataAsCsv(data);
        }
    });
}

function writeDataAsCsv(data){
    var text = '';
    text += data.columns.join(",") + "\n";
    $.each(data.rows, function(index, row){
        text += row.join(",") + "\n";
    });
    $('#container').html("<pre>" + text + "</pre>");
}
google.setOnLoadCallback(initialize);
    </script>
</head>

<body>
    <div id="container">
    </div>
</body>
</html>

HTMLをブラウザで見ます。少し待たされるかもしれませんが、こんな表示が出れば成功。

Text,Number,Location,Date
Hoge,1,Tokyo,2013-11-27
Fuga,2,Tottori,2013-12-25
Piyo,3,Wakkanai,2013-12-02

API(クエリ)の仕様については、このページなどが参考になります。
https://developers.google.com/fusiontables/docs/v1/using

JavaScriptからデータを追加

OAuthの追加

次は追加です。ただし追加(と削除)は取得に比べ、壁があります。上記のコードでクエリをINSERTに変えたりしても動きません。OAuthの認証が必要です。

(取得についても、「リンクを知っている全員が閲覧できます」状態でないのならOAuthが必要?)

はじめにアプリケーションの登録をしたときに、OAuthの項目もあり、ClientIDが示されていました。あれが必要です。Web Origin、Redirect Uriの欄があり、たぶん設定が必要?です。ここで示すURLにHTMLを置く必要があるようで、ローカルにHTMLを置いても認証がされませんでした。

ClientIDを使って、こんなコードを書けば認証ができます(Google謹製の例よりだいぶ端折っています)。scopesはFusion Tablesでは以下の値で固定で良いです。

var clientId = '903248181902-*************.apps.googleusercontent.com';
var scopes = 'https://www.googleapis.com/auth/fusiontables';

gapi.client.setApiKey(apiKey);
gapi.auth.authorize({
    client_id: clientId, 
    scope: scopes, 
    immediate: false
}, function(authResult) {
    if (authResult && !authResult.error) {
        alert("Auth was successful!");
    } else {
        alert("Auth was not successful");
    }
});

他のGoogleアカウントによる認証サービスでよく見るダイアログが現れ、承認すればアクセストークンが得られます。以後は gapi.auth.getToken().access_token からトークンを確認できます。このトークンをクエリと一緒に渡すことでアクセスが認められます。

行追加 (INSERT) のクエリを投げる

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="content-language" content="ja">
    <title>FusionTables Test</title>

    <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
    <script src="https://apis.google.com/js/client.js"></script>
    <script src="https://www.google.com/jsapi"></script>

    <script type="text/javascript">
var clientId = '903248181902-*************.apps.googleusercontent.com';
var apiKey = 'AIzaSyDB3OjI-***************';
var scopes = 'https://www.googleapis.com/auth/fusiontables';
var tableId = '1Le9Mv57xwsp7chNDE****************';

function initialize(){
    // OAuth2.0
    gapi.client.setApiKey(apiKey);
    gapi.auth.authorize({
        client_id: clientId, 
        scope: scopes, 
        immediate: false
    }, function(authResult) {
        if (authResult && !authResult.error) {
            alert("Auth was successful!");
        } else {
            alert("Auth was not successful");
            return;
        }
    });

    // 適当な追加するデータ
    var text = "Foobar";
    var number = 100;
    var loc = 'Beijing';
    var date = '2014-01-03';

    // Fusion Tablesに行を追加
    var sql = "INSERT INTO " + tableId;
    sql += " (Text,Number,Location,Date)";
    sql += " VALUES ('"+text+"','"+number+"','"+loc+"','"+date+"')";
    var url = 'https://www.googleapis.com/fusiontables/v1/query';
    url += '?access_token=' + gapi.auth.getToken().access_token;
    var data = 'key=' + apiKey;
    data += '&sql=' + encodeURIComponent(sql);

    $.ajax({
        url: url,
        type: 'POST',
        dataType: 'json',
        data: data,
        success: function (data, textStatus, xhr) {
            alert('送信成功');
        },
        error: function (xhr, textStatus, errorThrown) {
            alert('Fusion TableへのPOSTに失敗');
            console.log(errorThrown);
        }
    });
}

google.setOnLoadCallback(initialize);
    </script>
</head>

<body>
    <div id="container">
    </div>
</body>
</html>

送信成功、とアラートが出たら、Google DriveからFusion Tablesを見に行きましょう。無事行が追加されていればOKです。
f:id:Schima:20131128004206p:plain