Google Drive push notifications を hubot で受ける


Google Driveの変更を通知する仕組みを活用して何かしたい。

特定のDriveフォルダの変更を通知させる

サービスアカウントの作成をする

  1. Google Developers Consoleからプロジェクトの選択またはプロジェクトの作成を実施
  2. APIと認証 > API でDrive APIを有効にする
  3. APIと認証 > 認証情報から新しいクライアントIDを作成を実施
    サービスアカウントで作成する
  4. 新しいP12キーを作成ボタンでP12キーを作成しダウンロードされたものを保管
  5. APIと認証 > プッシュ からプッシュを受けるドメインを追加しておく
    webmasterでドメインの所有者登録しておく必要あり

フォルダ共有

  • サービスアカウントのメールアドレスを通知したいDriveフォルダの共同編集者として登録する

プッシュを受けるサイト設定

  • hubotのrouterで受ける場合
  robot.router.post "/google/drive/notifications", (req, res) ->
    robot.logger.debug req
    # 何かしらの処理
    res.status(200).send 'ok'

プッシュ通知設定

  • ダウンロードしたp12キーをpemに変換する
openssl pkcs12 -in xxx.p12 -nocerts -passin pass:notasecret -nodes -out xxx.pem
  • watch apiで登録する
    coffeescriptで実施するサンプル
googleapis = require('googleapis')
drive = googleapis.drive({version: 'v2'})

SERVICE_ACCOUNT_EMAIL = '[email protected]'
SERVICE_ACCOUNT_KEY = 'xxx.pem'
SCOPE = [
  "https://www.googleapis.com/auth/drive",
  "https://www.googleapis.com/auth/drive.file",
  "https://www.googleapis.com/auth/drive.readonly",
  "https://www.googleapis.com/auth/drive.metadata.readonly",
  "https://www.googleapis.com/auth/drive.appdata",
  "https://www.googleapis.com/auth/drive.apps.readonly",
  "https://www.googleapis.com/auth/drive.metadata",
]

jwt = new googleapis.auth.JWT(SERVICE_ACCOUNT_EMAIL, SERVICE_ACCOUNT_KEY, null, SCOPE)
resource = {id: 'watch-001', type: 'web_hook', address: 'https://上記でプッシュ設定したドメイン/google/drive/notifications'}
jwt.authorize (err, tokens) ->
  if err
    console.log err
  else
    jwt.credentials = tokens
    drive.changes.watch {auth: jwt, resource: resource}, (err, resp) ->
    if err
      console.log err
    else
      console.log resp
  • 確認
    サービスアカウントに共有したフォルダ以下で何かしらのファイル変更を実施すると https://上記でプッシュ設定したドメイン/google/drive/notifications に通知が飛んでくる
2015-06-11T03:15:35.450146+00:00 heroku[router]: at=info method=POST path="/google/drive/notifications" host=xxx.herokuapp.com request_id=4660b262-e65b-42bc-bfad-06a9a290c292 fwd="xx.xx.xx.xx" dyno=web.1 connect=0ms service=6ms status=200 bytes=164