Googleドライブへのアップロード

本記事はFixstars Solutions Incの許可を得て転載したものです。
転載元:http://www.fixstars.com/en/news/?p=451


はじめに

  1. FlashAirにtestfile.jpgを設置します。
  2. FlashAirでLuaを実行するを参考に、Luaスクリプト実行方法をCONFIGファイルに指定します。

導入

このチュートリアルでは、LUAとGoogle device APIを使ってGoogleドライブへイメージデータをアップロードする方法を紹介いたします。これはFlashAirのような限られた入力機能を持つものから実行するアイデアになります。残念ながらすべての設定が完了するまでは入力機能デバイスが必要となりますが、一度設定が完了したら、ヘッドレス運用で無制限にアップロードすることができます。


手順

1. Googleでプロジェクトを設定

  1. GoogleのAPI Consoleを開き、”プロジェクトを選択”をクリックします。 Googleでプロジェクトを設定
  2. ”+”をクリックします。 Googleでプロジェクトを設定
  3. “プロジェクト名”を入力し”作成”をクリックします。 Googleでプロジェクトを設定
    • 例: “My Project 1”
  4. プロジェクトの作成が終了したら、画面上部の”プロジェクトを選択”をクリックします。 Googleでプロジェクトを設定
  5. 作成したプロジェクト名をクリックします。 Googleでプロジェクトを設定
  6. 左ナビゲーションの”ライブラリ”をクリックし、”Drive API”をクリックします。 Googleでプロジェクトを設定
  7. Google Drive API画面に切り替わったら、”有効にする”をクリックします。 Googleでプロジェクトを設定
  8. “認証情報を作成”をクリックします。 Googleでプロジェクトを設定
  9. プロジェクトへの認証情報の追加画面が表示されます。”必要な設定を決定します”と”アクセスするデータの種類”を入力し、”必要な認証情報”をクリックします。 Googleでプロジェクトを設定
  10. “名前”を入力し、”クライアントIDの作成”クリックします。 Googleでプロジェクトを設定
    • 例: “flashair”
  11. “ユーザーに表示するサービス名”を入力し、”次へ”クリックします。 Googleでプロジェクトを設定
    • 例: “Lua Upload”
  12. “完了”をクリックします。 Googleでプロジェクトを設定
  13. 認証情報が作成されました。OAuth 2.0 クライアントIDの”flashair”をクリックします。 Googleでプロジェクトを設定
  14. アプリの情報を控えます。これらの情報は取扱に注意し、他人と共有しないようにしてください。 Googleでプロジェクトを設定
    • クライアント ID
    • クライアント シークレット

2. 使用デバイスの承認

セットアップでは、Googleに2段階のプロセスでデバイスを承認させる必要があります。まず、「accounts.google.com/o/oauth2/device/code」にPOSTリクエストの送信が必要です。Content-Typeに「application/x-www-form-urlencoded」を入れて、client_id(上の手順で作成したOAuthクライアントID内の「クライアントID」を入れる)とscope(「https://docs.google.com/feeds」を入れてください)の2つのフィールドを付与します。この作業のためにいくつかのツールの使用が考えられますが、GoogleChrome拡張機能「postman」がすごく使いやすいでしょう。

例:

POST /o/oauth2/device/code HTTP/1.1
Host: accounts.google.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

client_id={Your client ID}
scope=http://docs.google.com/feeds/

postmanのHeaders設定

使用デバイスの承認

postmanのBody設定

使用デバイスの承認

注:Googleではscopeに「https://www.googleapis.com/auth/drive」を使用するように指示していますが、「Invalid_scope:Not authorized to request the scop」で返ってきます。代わりに/feeds/を使用すると、Googleドライブの許可が付与されます。

レスポンスには、user_codeとverification_urlが含まれるでしょう。そのurl(おそらくhttps://www.google.com/device)へ移動し、user_codeを入力します。すると、device_codeも返ってきます。

レスポンス例:

"device_code": {Device code},
"user_code": {Your user code},
"verification_url": "https://www.google.com/device",
"expires_in": 1800,
"interval": 5

使用デバイスの承認

ウェブブラウザからhttps://www.google.com/deviceにアクセスすると、端末の接続画面が表示されます。

取得したuser_codeを入力し、”次へ”をクリックします。

使用デバイスの承認

“許可”をクリックします。

使用デバイスの承認

Googleドライブの許可が付与されました。

使用デバイスの承認

3. 永続リフレッシュトークンの取得

これまですべて適切に承認されてもまだ、使用しようとしているアプリのリフレッシュトークンを取得する必要があります。Googleドライブにアップロードできる一時的な「認証」トークンとは別のトークンを取得します。Googleにはたくさんのトークンがあります。リフレッシュトークンを取得するには、以下のようなPOSTリクエストを送信します。

POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

client_id={Your full client ID}
client_secret={Your client secret}
code={Your device code}
grant_type=http://oauth.net/grant_type/device/1.0

postmanのBody設定

使用デバイスの承認

あなたは以下のような形で受信します:

"access_token": {Your access token here},
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": {Your refresh token here}

使用デバイスの承認

最後に、ヘッドレス運用のアップロードスクリプトを作成します!私たちに本当に必要なトークンは、リフレッシュトークンです。アクセストークンは動作が短く有効期限が切れます。リフレッシュトークンを使えば、必要な時(許可が長く続かない場合がかなりある)に新しいアクセスコードを取得できます。

refresh_tokenを控えておきます。

4. Luaのインポート必須事項

取得しているすべての必要な情報を含むローカル変数を使い、以下のコードを作成します。

コード例:

/GoogleDriveUpload.lua
-- Basic account info
local client_id = "{Your full client ID}"
local client_secret = "{Your client secret}"
local refresh_token = "{Your refresh token}"
-- For refresh
local scope = "https://docs.google.com/feeds"
local response_type = "code"
local access_type = "offline"

5. リフレッシュトークンを使用して再認証

何かをアップロードする前に、サーバーに再認証する必要があるので、まずはgetAuth()関数と一緒に入れてみましょう。本手法では、(必要なパラメータとしての)長さを考えHTTPリクエストを作成し、送信するメッセージを設定します。 「配列」としてレスポンスが来ますが、それは実際にLuaがJSONへデコードすることができない、最初で唯一の大きな文字列です。ですが便利なことに、JSONライブラリを入れる前にテーブルでそれを解析し、新しいアクセストークンを取得するために使用することができます。

関数例:

local function getAuth()
  -- Set our message
  local mes="client_id="..client_id
  mes=mes.."&client_secret="..client_secret
  mes=mes.."&refresh_token="..refresh_token
  mes=mes.."&grant_type=refresh_token"

  local length = string.len(mes)
  print("Sending: ["..mes.."]")
  print "\n"
  b, c, h = fa.request{
    url = "https://accounts.google.com/o/oauth2/token",
    headers = {
        ["Content-Type"] = "application/x-www-form-urlencoded",
        ["Content-Length"] = length,
    },
    method = "POST",
    body=mes,
  }

  local tempTable = {}

  tempTable = cjson.decode(b)

  access_token = tempTable["access_token"]
end

6. アップロード用Lua関数

これで新しいアクセストークンを取得して、アップロードの準備が整いました!別のHTTP POSTリクエストでssl.httpsを使用して行います。アップロードするイメージファイルを用意し、認証コードを設定して行います。

例:

local function uploadTest(token)
  filePath="testfile.jpg"
  local fileSize = lfs.attributes(filePath,"size")
  b, c, h = fa.request{
    url = "https://www.googleapis.com/upload/drive/v2/files",
    headers = {
      ["Content-Type"] = "image/jpeg",
      ["Content-Length"] = fileSize, -- calculate file size
      ["authorization"] = "Bearer "..token,
      ["uploadType"]="media"
    },
    method = "POST",
    --NOTE: You probably want to set your own file here,
    --or maybe even pass it as a parameter!
    file=filePath
  }
end

ここまでの例を掲載順に組み合わせて最後に以下の2つの関数コードを付け足して実行すれば、Googleドライブへファイルがアップロードされるでしょう(accounts.google.comを参照してください)。

最後に動かす関数コード:

getAuth()
uploadTest(access_token)

7. 実行結果

実行結果


サンプルコード

リポジトリを見る(GitHub)

このサイトのサンプルコードは二条項BSDライセンスで提供されています。