OAuth 2.0 クライアントIDを用いてExecution API叩く方法はよく紹介されてるのですが、サービスアカウントを使ったものは見つからなかったので書いておこうと思います。
今回はAWS Lambdaで実行したかったのでpythonを使いました。
参考:
- OAuth 2.0 クライアントIDを用いたExecution APIの実行
- pythonをつかったサービスアカウントでの認証
はじめに
本当にExecution APIを使う必要があるか?考えましょう。
web applicationとしても公開できるので、認証しなくてもいいのであれば、そちらの方がおすすめです。
流れ
- 叩きたいGASの関数を書く
- 外から叩ける様に設定する
- Developer ConsoleでExecution APIを使える状態にする
- サービスアカウント発行
- pythonスクリプトでAPI叩く
- なりすましできるように設定
1-3. GASの作成からAPI公開まで
1-3の手順については、こちらの記事で詳しく説明されているので、参照してください。(自分の記事じゃないけど。@soundTrickerさんありがとうございます。)
4. サービスアカウント発行
google projectの認証情報ページにて、サービスアカウントの認証情報を含むjsonをダウンロードします
するとjsonをダウンロードできます
5. pythonスクリプト作成
mkdir gas_executor
pip install google-auth google-auth-httplib2 google-api-python-client -t gas_executor
- pythonスクリプト作成
ここでの注意点は、Execution APIはなりすましを行わないといけないらしいこと。
なりすまさないと、サービスアカウント自体の認証は通るけど、execute()部分で権限がなくて死ぬ。
サービスアカウントを使うときはだいたい、jsonに記載しているメアドをユーザーとして追加するといけるので、spreadsheetをそのメアドに共有したけど通らなかった
from google.oauth2 import service_account
from googleapiclient import discovery
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
SERVICE_ACCOUNT_FILE = '先ほどダウンロードしたjsonのパス'
SCRIPT_ID = '先ほどメモしたGASのScript ID'
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
delegated_credentials = credentials.with_subject("xxxx@gmail.com") # ← なりすましたいユーザーのメアド
service = discovery.build('script', 'v1', credentials=delegated_credentials)
request = {"function": "main", "devMode": "true"} # ← 関数名は自分が作ったもの
response = service.scripts().run(body=request, scriptId=SCRIPT_ID).execute()
参考: pythonを使ったサービスアカウントの認証(公式)
6. なりすましできるように設定
通称 domain wide delegation と呼ぶらしいんですが、これを設定すると特定のユーザーになりすませます。
多分G Suite使ってないと利用できません。
設定方法は Configure OAuth2 Service Accounts for Domain-wide Delegation をご参照ください
最後に
やってみると意外にめんどくさかったです。こんなに頑張って認証するなら、ウェブアプリケーションとして公開する方がいいかなぁというのが率直な感想です。
一番厄介なのは、domain wide delegationで、本当になりすまさないとできないんですかね?
ちゃんとは検証できてないですが、少なくともなりすませば通ることは確認できました。
他の方法知ってる方は教えてください。