Open8
Google CloudとGoogle Driveの連携
Google Drive上のファイルのパスを取得するコード
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
def dig_parents(id, creds) -> list[str]:
service = build('drive', 'v3', credentials=creds)
item = service.files().get(fileId=id, fields="id,name,kind,parents").execute()
name = item.get("name")
parents = item.get("parents")
if parents is None:
return [(id, name)]
if len(parents) != 1:
raise Exception("Unpexpected parents count.")
parent_id = parents[0]
return dig_parents(parent_id, creds) + [(id, name)]
if __name__ == "__main__":
file_id = sys.argv[1]
flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
parents = dig_parents(file_id, creds)
print(parents)
Google Driveの変更を検知する
以下を作成する。
- 受信用URL (Webhook call back receiver)
- 監視対象のリソースエンドポイントのチャネル
- ファイル単位や変更全体などの単位でリソースを指定する
チャネルの作成
https://www.googleapis.com/{apiName}/{apiVersion}/{resourcePath}/watch
の形式に従ってURLを組み立て、POSTリクエストのボディで作成するチャネルを指定する。
変更全体を監視する場合は
https://www.googleapis.com/drive/v3/changes/watch
Cloud FunctionでGoogle Driveの更新通知を受け取る場合
- CloudFuncitonをデプロイ
- チャネルを作成
1. CloudFuncitonをデプロイ
例えば下記。
ドキュメントに記載があるように、通知は POST
で送信され、ボディは空になっている。
changes
リソースを監視する場合、X-Goog-Resource-State
は常にchanges
となり、どういう変更がされたかまでは特定できない。
import functions_framework
@functions_framework.http
def hello_http(request):
print(request.headers)
return 'OK'
2. チャネルを作成
Pythonなら下記でできる。
def register_channel2(creds):
service = build('drive', 'v3', credentials=creds)
# start_page_tokenの取得
response = service.changes().getStartPageToken().execute()
start_page_token = response.get("startPageToken")
if start_page_token is None:
raise Exception("Invalid start page token")
# チャネルの登録
response = service.changes().watch(
pageToken=start_page_token,
body={
"address": "{CloudFunctionのURL}",
"type": "web_hook", # web_hook を指定
"id": str(uuid4()), # 任意の一意な文字列
}
).execute()
print(response)
- changesのwatchでは変更があったことしかわからないので、changes.listで何の変更があったかを確認する必要がある。
- Cloud Functionsで確認するためには、Cloud FunctionsにアタッチされているSAにGoogle Drive上の対象のフォルダを共有しておく必要がある。
- 共有されていないフォルダの変更でもpush通知がされてしまうので注意が必要
- changes.listをしても何の変更がされたかまではわからない
参考: https://qiita.com/kccs_kai-morita/items/6c5844dc78ce630ebb94
Drive Activity API を使う必要があるかも?