Google Driveの変更通知をGoogle Cloud Functionsで受け取る


この記事でやりたいこと

Google Driveで変更(ex. ファイルの追加や削除など)が発生したら、Google Cloud Functionsに通知する方法を説明する記事である。

Google Apps Scriptなどで実現する場合、 1分間隔でポーリングするの方法 でも同様のことは行えるかもしれないが、Drive API - Push Notificationを使用すれば、 Google Driveのディレクトリ内の変更発生時に以下の方法で指定したURLをリクエストをしてくれる APIが存在する。今回は、それを使う。ポーリングしなくてもいい。最高。

使用するもの

  • Google Cloud Functions
  • Python

Step1. Google Cloud Functionsでfunctionを作成する

トリガーを HTTP とする、functionを作成する。今回の例ではNode.jsを使用するが、後述するHTTP tagをレスポンスできればどの言語でも問題ないハズ。

とりあえず、そのまま作成する

Step2. URLを所有していることを登録する

Drive APIでPush Notificationしてもらうためには、URLを所有していることを証明しなければならない。

Google Search Consoleから行う。

確認方法として、HTML タグ を選択する。HTMLタグはコピーしておく。

Step3. functionでHTMLタグをレスポンスするようにする

functionに戻って、先程コピーしたHTMLタグをレスポンスするように ソースコードを書き換える。その際、

<html><head>先程のHTMLタグ</head></html>

とすることを忘れないようにする。

デプロイする。

Step4. URLを確認してもらう

functionへ行った変更が行われたら、
Search Consoleまで戻ってきて、確認を実施する。

問題がなければ、以下のように所有権を証明できた旨の表示が行われる

Step5. GCPプロジェクト上でドメインを確認する

通知を送信するために、ドメインの所有権を証明をGCPプロジェクト上で行う必要がある。以下のドメイン確認のページに向かう。

そして、functionのトリガーとなるURLを追加する

Step6-1. サービスアカウントを作る

Drive APIで通知先となるURLを登録するためには、アクセストークンを発行する必要がある。そのため、Google Driveにアクセスできるサービスアカウントを作成する。

まず、サービスアカウントの作成画面に向かう。

作成途中で、 キーを作成 することが出来るので、JSONタイプのキーをダウンロードする。

Step6-2. アクセストークンを取得する

以下のPythonのコードスニペットを使って、アクセストークンを取得する

access_token.py
from oauth2client.service_account import ServiceAccountCredentials
from oauth2client.client import OAuth2Credentials
credentials = ServiceAccountCredentials.from_json_keyfile_name(
      'key.json', scopes=['https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file', 'https://www.googleapis.com/auth/drive.readOnly'])
res = credentials.get_access_token()
print(res.access_token)

access_token.py と同じディレクトリ内に、先程落としてきたjsonを key.json とリネームして実行すれば良い。なお、実行のためには以下のパッケージなどをインストールしておく必要があるため、適宜対応する。

必要であれば以下で通すPATHは .bash_profile 等で通すように設定しておくと良い。

$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py
$ export PATH="$HOME/Library/Python/2.7/bin:$PATH"
$ pip install --upgrade oauth2client
$ python access_token.py # 上記のコードスニペット。実行すると、アクセストークンが出力される。

参考

Step 7. ディレクトリ変更時のURL通知を登録する

Drive APIによる通知では、以下の2つの変更の通知を受け取ることが出来る。

今回はドライブ全体の変更を受け取ることにする。

まずは、pageTokenの位置を取得する。

start_page_token.py
import requests
token = 'XXXXX' # アクセストークン
header = {
    'Authorization': f'Bearer {token}',
    'Content-Type': 'application/json'
}
r = requests.get(url='https://www.googleapis.com/drive/v3/changes/startPageToken', headers=header)
print(r.text)

表示される startPageToken を控えて、
以下のコードスニペットに、必要な箇所を穴埋めする。

changes_watch.py
import uuid
import requests
import json
channel_id = str(uuid.uuid4())
SCOPES = ['https://www.googleapis.com/auth/drive.file',
         'https://www.googleapis.com/auth/drive.readonly',
         'https://www.googleapis.com/auth/drive']
token = 'XXXXXXXXXXXXXXXXXXXXXX' # 先程のアクセストークンを貼り付ける
header = {
    'Authorization': f'Bearer {token}',
    'Content-Type': 'application/json'
}
body = {
    "id": channel_id,
    "type": "web_hook",
    "address": f'{XXXXXXXXXXXXXXXXXX}' # functionのトリガーとなるURL
}
page_token = '0000' # 先程控えた pageToken
r = requests.post(url=f'https://www.googleapis.com/drive/v3/changes/watch?pageToken={page_token}', data=json.dumps(body), headers=header)

以上を実行することで、 マイドライブ配下で、何かしら変更が発生すると、functionが実行される 様になる。GCPのログで、functionが起動されていることを確認してみてください。