FunctionsとSchedulerを使ってSlackにアップロードした画像をGoogle Photos のアルバムに保存してみる
本業や趣味でGCP, Actions on Google, Androidなどを触っている fish です🐟
今回はCloud Functions と Cloud Schedulerを使って、Slackにアップロードした画像をGoogle Photosのアルバムに保存するサンプルの紹介をしたいと思います。
このサンプルは Firebase Meetup #9 Cloud Functions Day でお話した「Cloud Functions と Cloud Scheduler で作るお手軽バッチ処理」と同じ内容となります。登壇ではお話できなかった実装の方法を紹介したいと思います。
大体のながれ
- Cloud Functions から Slack APIを叩いてSlackにアップロードしている画像を取得
- 画像をGoogle Photos APIを使いGoogle Photosのアルバムにアップロード
- Cloud SchedulerとCloud Pub/Subを使用しCloud Functionsを定期実行
使用技術
- Slack API
- Google Photos API
- OAuth 2.0 to Access Google APIs
- Google Cloud Scheduler
- Google Cloud Pub/Sub
- Cloud Functions for Firebase
実装の流れ
- Google Photos APIの準備
- Slack API で使用する TokenとChannel ID を取得
- サンプルアプリの実装とデプロイ
- Functionsの実行
Google Photos APIの準備
こちらを参考にGoogle Photos API の有効化とサービスアカウントを作成し認証に必要なAPI Key を取得する。コマンドラインを開き下記の環境変数を作成する。今回はGoogle Photosのアルバムに書き込み行いたいのでScopeには photoslibrary を指定する。
$ CLIENT_ID=取得したclient id
$ CLIENT_SECRET=取得したclient secret
$ REDIRECT_URI=urn:ietf:wg:oauth:2.0:oob
$ SCOPE=https://www.googleapis.com/auth/photoslibrary
Google Photosのアルバムに書き込みを許可するための認証ページにアクセスする。ブラウザから下記のURLにアクセス。アクセスすると認証ページが書き込みをしたいアカウントを選択し許可する。許可したあとに表示されるコードをコピーする。
https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=$SCOPE&access_type=offline
取得したコードを環境変数に保存する。
$ AUTHORIZATION_CODE=取得したコードを入れる
Google PhotosへアクセスするためのTokenを取得する。なおこちらのTokenは1時間で有効期限が切れるので切れたらRefresh Tokenを使い新しいTokenを取得する。
$ curl -s --data "code=$AUTHORIZATION_CODE" --data "client_id=$CLIENT_ID" --data "client_secret=$CLIENT_SECRET" --data "redirect_uri=$REDIRECT_URI" --data "grant_type=authorization_code" --data "access_type=offline" https://www.googleapis.com/oauth2/v4/token// 結果
{
"access_token": "xxx",
"expires_in": 3600,
"refresh_token": "abcdef",
"scope": "https://www.googleapis.com/auth/photoslibrary",
"token_type": "Bearer"
}// Tokenの保存
$ ACCESS_TOKEN=xxxxxxxx
$ REFRESH_TOKEN=abcdef// 有効期限がきれたら下記のコマンドで再取得
$ curl -s --data "refresh_token=$REFRESH_TOKEN" --data "client_id=$CLIENT_ID" --data "client_secret=$CLIENT_SECRET" --data "grant_type=refresh_token" https://www.googleapis.com/oauth2/v4/token
APIからアルバムを作成しアルバムIDを取得する。
$ curl -s -X POST -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-type: application/json" -d '{ "album": { "title":"slack_photos" } }' https://photoslibrary.googleapis.com/v1/albums{
"id": "xxxx", //アルバムIDを控えておく
"title": "slack_photos",
"productUrl": "",
"isWriteable": true
}
今回のサンプルでは client_id, client_secret, refresh_token, album_idの4つを使用します。
Slack API で使用する TokenとChannel ID を取得
- https://api.slack.com/custom-integrations/legacy-tokens からTokenを取得する
- https://api.slack.com/methods/channels.list から画像を取得したチャンネルのChannel ID を取得する
今回のサンプルでは TokenとChannel IDを使用します。
サンプルアプリの実装とデプロイ
こちらからサンプルアプリをCloneします。このサンプルアプリにあるFirebaseの設定ファイルにご自身の設定を入れます。
下記コマンドで、client_id, client_secret, refresh_token, album_id, SlackのTokenとChannel IDをFirebase Functionsの環境変数に設定します。
$ firebase functions:config:set slack.token=""
$ firebase functions:config:set slack.channel=""
$ firebase functions:config:set google.refresh_token=""
$ firebase functions:config:set google.client_id=""
$ firebase functions:config:set google.client_secret=""
$ firebase functions:config:set photos.album_id=""
$ firebase deploy --only functions
下記コマンドでデプロイをします。このFunctionsはCloud Pub/Sub のトピックに slack-to-googlephotos が作成されると実行されます。
$ npm run deploy
Functionsの実行
Cloud Schedulerを使って定期実行する。
$ gcloud beta scheduler jobs create pubsub Saver --schedule "0 */3 * * *" --time-zone Asia/Tokyo --description "Upload photo to GooglePhotos" --topic slack-to-googlephotos --message-body "{"count":1}"
Cloud Schedulerの設定について詳しく知りたい場合は こちら をご参照ください。
定期実行ではなく1回だけ実行したい場合は直接Pub/Subのトピックを作成します。
$ gcloud pubsub topics publish slack-to-googlephotos --message "{"count":1}"
Functionsを実行しGoogle Photosのアルバムに画像がアップロードされたら成功です。
このサンプルの注意事項
- 今回のサンプルではファイル一覧結果の1ファイルのみアップロード対象にしています
- 画像以外のアップロードには対応していません
- Google Photos API を通じてアップロードした画像はオリジナルクオリティになるのでGoogle PhotosやGoogle Driveの料金プラン(容量制限)にご注意ください