1. はじめに
何十億もの企業や個人が Gmail やその他の G Suite サービスを使用して、コミュニケーションやデータの処理を行っています。Google は、これらのサービスの情報にプログラムでアクセスするための G Suite API を提供しています。また、API を使用して日常のワークフローを簡単に自動化できます。このラボでは、受信したメールに含まれるメールを自動的に分類し、そのカテゴリを Google スプレッドシートに保存する強力な Gmail 拡張機能を作成します。この拡張機能は、G Suite の RESTful API、Google Cloud Functions、その他の Google Cloud Platform サービスを使用します。
作業内容
このラボでは、G Suite API やその他の Google Cloud Platform サービスに接続された Cloud Functions の関数をいくつか構築し、デプロイします。これらの関数は、次の処理を行います。
- Gmail や Google スプレッドシートのデータへの安全なアクセスを承認する
- 受信メールに添付された画像を抽出する
- Cloud Vision API を使用してこれらの画像を分類する
- これらのカテゴリ、送信者のアドレス、添付ファイルの名前を Google スプレッドシートに書き込む
学習内容
- G Suite RESTful API の基本
- Google Cloud Functions とその他の Google Cloud Platform サービスの基本
- Google Cloud Functions を使用してプログラムで Gmail にアクセスする方法
必要なもの
- Gmail と Google スプレッドシートにアクセスできる Google アカウント。まだ作成していない場合は、こちらで作成してください。
- JavaScript/Node.js に関する基本的な知識。
2. 最初にすべきこと
API を有効にする
このラボでは、次の Google プロダクト/サービスを使用します。
- Google Cloud Functions
- Google Cloud Pub/Sub
- Google Cloud Vision API
- Google Cloud Datastore
- Gmail API
- Google Sheets API
Google Cloud Functions
Google Cloud Functions は Google のサーバーレス Functions as a Service プラットフォームで、個々のコード スニペット(「関数」)をシンプルかつスケーラブルな方法で実行できます。
Google Cloud Functions を有効にするには、画面の左上にあるハンバーガー メニューをクリックして左側のナビゲーション サイドバーを開きます。
ナビゲーション メニューで [Cloud Functions] を見つけてクリックします。[API を有効にする] をクリックして、プロジェクトで Google Cloud Functions を有効にします。
Google Cloud Pub/Sub
Google Cloud Pub/Sub は、データ ストリーミングとイベント配信のためのシンプルでスケーラブルな基盤です。このラボでは、Gmail と Google Cloud Functions の間の配送業者として機能します。
Google Cloud Pub/Sub を有効にするには、左側のナビゲーション サイドバーを開き、[Pub/Sub] を見つけてクリックします。[API を有効にする] をクリックして、プロジェクトで Google Cloud Pub/Sub を有効にします。
Google Cloud Datastore
Google Cloud Datastore は、スケーラブルで分散型のサーバーレス データベースです。
Google Cloud Datastore を有効にするには、左側のナビゲーション サイドバーで [Datastore] を見つけてクリックします。新しいページで [Datastore モードを選択] をクリックします。
このラボでは、任意のデータベースのロケーションを使用できます。[データベースを作成] をクリックして、Google Cloud Datastore を有効にします。完了するまで数分かかる場合があります。
Google Cloud Vision
Google Cloud Vision API は強力な ML サービスで、事前トレーニング済みモデルを使用して画像から分析情報を引き出します。
Google Cloud Vision API を有効にする方法については、以下の手順をご覧ください。
Gmail API、Google Sheets API、Google Cloud Vision API を有効にする
繰り返しになりますが、左側のナビゲーション サイドバーを開いて [API とサービス。[ライブラリ] をクリックします。[API と API の検索[サービス] フィールドに「Gmail」と入力します。検索結果で [Gmail API] を選択し、[有効にする] をクリックします。
[API ライブラリ] ページに戻ります。Google Sheets API を検索し、有効にします。
この手順を繰り返します。Cloud Vision API を検索して有効にします。
Google Cloud Shell を開く
このラボでは、Google Cloud Shell を使用してほとんどの操作を行います。Cloud Shell を使用すると、ブラウザからコマンドラインで直接 Google Cloud Platform リソースにアクセスできるため、ローカルマシンを使用せずにリソースを管理できます。
Google Cloud Shell を開くには、上部の青い水平バーにある「Cloud Shell をアクティブにする」ボタンをクリックします。
画面の下部に新しいパネルが表示されます。
[コードエディタの起動] ボタンをクリックして、Cloud Shell コードエディタを起動します。
Cloud Shell コードエディタが新しいウィンドウで開きます。
コードをダウンロードする
Cloud Shell で次のコマンドを実行して、プロジェクトのクローンを作成します。
git clone https://github.com/googlecodelabs/gcf-gmail-codelab.git cd gcf-gmail-codelab
新しいフォルダ gcf-gmail-codelab
が Cloud Shell コードエディタに表示されます。
3. アーキテクチャの概要
このラボのワークフローは次のとおりです。
- ユーザーが Gmail のプッシュ通知を設定する: 新しいメッセージが受信トレイに届くたびに、Gmail から Cloud Pub/Sub に通知が送信されます。
- Cloud Pub/Sub が新しいメッセージ通知を Google Cloud Functions に配信します。
- 新しいメッセージの通知を受信すると、Cloud Functions インスタンスが Gmail に接続し、新しいメッセージを取得します。
- メールに画像が添付されている場合、Cloud Functions インスタンスが Cloud Vision API を呼び出して添付ファイルを分析します。
- Cloud Functions インスタンスが任意の Google スプレッドシートを更新し、メッセージの送信者と添付ファイルのダウンロード場所を指定します。
4. Gmail へのアクセスを承認する
メールを自動的に読み取るように Cloud Functions の関数を設定する前に、Gmail へのアクセスを承認する必要があります。Google に OAuth クライアントを登録し、関連するクライアント ID を作成する必要があります。
OAuth クライアントを登録する
Google Cloud コンソールの左側のナビゲーション メニューで、[API とサービス。[OAuth 同意画面] をクリックします。
[Application name] に名前(GCF + Gmail Codelab など)を入力します。その他の設定は変更せずに、ページを下にスクロールして [保存] をクリックします。
関連するクライアント ID を作成する
[認証情報] タブに切り替えます。[認証情報を作成] をクリックし、[OAuth クライアント ID] を選択します。タイプとして [ウェブ アプリケーション] を選択し、名前を付けて(ここでも GCF + Gmail Codelab を使用できます)、[作成] をクリックします。[制限] フィールドは空欄のままにしておきます。
ポップアップ ウィンドウで返されたクライアント ID とクライアント シークレットを書き留めます。ページに表示されているクライアントの名前をクリックすると、これらの値を再度表示できます。
認可プロセスを実行する
サンプルコードでは、auth/index.js
に auth_init
と auth_callback
の 2 つの Cloud Functions の関数が指定されています。この関数が連携し、先ほど作成したクライアント ID とクライアント シークレットを使用して、認証プロセスを実行します。
コードを調べるには、Cloud Shell コードエディタで auth/index.js
を開きます。
認証プロセスでは、アクセス トークンと更新トークンの 2 種類のトークンが返されます。
- アクセス トークンは有効期間の短い ID で、そのトークンを所有する全員にデータへのアクセスが許可されます。
auth_callback
は、これらを Cloud Datastore に保存します。 - 更新トークンは新しいアクセス トークンを取得するために使用され、その有効期間は大幅に長くなります。
通常、トークンは暗号化されるか、アクセス トークンとは別に保存されます。
Cloud Shell コードエディタで auth/env_vars.yaml
を編集します。YOUR-GOOGLE-CLIENT-ID
と YOUR-GOOGLE-CLIENT-SECRET
は実際の値に置き換えます。詳細については、前のステップをご覧ください。YOUR-GOOGLE-CLIENT-CALLBACK-URL
と YOUR-PUBSUB-TOPIC
の値は変更しないでください。
auth/env_vars.yaml
を編集したら、Cloud Shell で次のコマンドを実行して Cloud Functions をデプロイします。
cd ~ cd gcf-gmail-codelab/auth # Deploy Cloud Function auth_init gcloud functions deploy auth_init --runtime=nodejs8 --trigger-http --env-vars-file=env_vars.yaml # Deploy Cloud Function auth_callback gcloud functions deploy auth_callback --runtime=nodejs8 --trigger-http --env-vars-file=env_vars.yaml
Cloud Functions のデプロイには数分かかる場合があります。プロンプトが表示されたら、Cloud SDK にベータ版コマンドをインストールする権限を付与します。
次に、Google Cloud コンソールに移動し、左側のナビゲーション メニューで [Cloud Functions] をクリックします。Cloud Functions のリストで auth_callback
をクリックし、[トリガー] タブに切り替えます。
ページの URL をコピーします。Cloud Functions ページに戻り、Cloud Functions のリストで auth_init
をクリックします。[全般] タブで [編集] をクリックします。[環境変数、ネットワーキング、タイムアウトなど] をクリックし、GOOGLE_CALLBACK_URL
の値を先ほどコピーした URL に置き換えます。
[デプロイ] をクリックして変更を適用します。この手順を繰り返して、auth_callback
も更新します。
最後に、左側のナビゲーション メニューを開き、[API とサービス >ドメインの所有権の証明。承認済みドメインを追加するには、[ドメインを追加] をクリックします。たとえば、先ほどコピーした URL が
https://us-central1-my-project.cloudfunctions.net/auth_callback
承認済みドメインとして次のものを追加する必要があります。
us-central1-my-project.cloudfunctions.net
[ドメインを追加] をクリックして確定します。
[認証情報] ページに戻ります。OAuth クライアントの名前をクリックし、コピーした URL を承認済みのリダイレクト URI として追加します。Enter キーを押して確定します。
URL から /auth_callback
の部分を削除し、残りを承認済みの JavaScript 生成元として追加します。たとえば、URL が
https://us-central1-my-project.cloudfunctions.net/auth_callback
オリジンとして以下を追加する必要があります。
https://us-central1-my-project.cloudfunctions.net/
Enter キーを押して確定し、[保存] をクリックして変更を適用します。
5. Gmail のプッシュ通知を設定する
承認プロセスに成功すると、auth_callback
は自動的に Gmail API を呼び出してプッシュ通知を設定します。
Gmail プッシュ通知を受信するには、Pub/Sub トピックを作成する必要があります。トピックのサブスクライバーには、Gmail から受信メッセージが届くと自動的に通知が表示されます。
Pub/Sub トピックを作成するには、Google Cloud コンソールに移動して [Pub/Sub] >[トピック] をクリックします。[トピックを作成] をクリックします。トピックの名前(gmail-watch
など)を入力し、[作成] をクリックします。さらに、Pub/Sub トピックにメッセージを送信する権限を Gmail に付与する必要があります。作成したトピックのコンテキスト メニュー(縦に並んだ 3 つの点)をクリックし、[権限] を選択します。[メンバーを追加] をクリックし、新しいメンバーとして gmail-api-push@system.gserviceaccount.com
を指定して、Pub/Sub >Pub/Sub パブリッシャー最後に、[保存] をクリックして変更を適用します。
Cloud Functions の auth_callback
関数を更新して、使用する Pub/Sub トピックを指定します。左側のナビゲーション メニューで [Cloud Functions] をクリックし、Cloud Functions のリストから auth_callback
を選択します。[全般] タブで [編集] をクリックします。[その他] をクリックし、PUBSUB_TOPIC
の値を、先ほど作成した Pub/Sub トピックの名前に置き換えます。[保存] をクリックして変更を適用します。
これで、Gmail プッシュ通知を承認して設定する準備ができました。新しい変更が完了するまで待ってから、[Cloud Functions] ページに戻り、Cloud Functions のリストで auth_init
を選択して、[トリガー] タブに切り替えます。URL をクリックすると、[Google でログイン] ページにリダイレクトされます。
所有している Gmail アカウントを使用してログインします。新しいメールがアカウントの受信トレイに到着すると、プッシュ通知がトリガーされます。ログインすると、次のようなページが表示されます。
[許可] をクリックしてアクセスを承認します。auth_callback
が認証プロセスを完了し、アクセス トークンを保存して、Gmail のプッシュ通知を設定します。この処理が完了すると、ブラウザに「Successfully set up Gmail push notifications
」というメッセージが表示されます。
この Codelab では、@google-cloud/express-oauth2-handlers
パッケージを使用して、認証ワークフローを自動化します。詳細については、GitHub のリポジトリをご覧ください。
6. 着信メッセージを処理する
前述したように、作成した Pub/Sub トピックのサブスクライバーは、新しいメッセージが受信トレイに到着すると通知を受け取ります。pubsub/index.js
は、Cloud Functions の関数 watchGmailMessages
を指定します。この関数は、トピックのサブスクライバーとしてデプロイされると、新しいメッセージを読み取り、添付された画像を分類して、それらのカテゴリを Google スプレッドシートにエクスポートします。
コードを調べるには、Cloud Shell コードエディタで pubsub/index.js
を開きます。
メッセージの取得
Gmail のプッシュ通知には、通知が関連付けられているメールアドレスと履歴 ID が含まれています。わかりやすくするため、この Codelab では、プッシュ通知が届いたときに Gmail API に最新のメッセージを取得します。適切な結果を得るには、代わりに履歴 ID を使用してメッセージを検索してください。
// Look up the most recent message. const listMessagesRes = await gmail.users.messages.list({ userId: email, maxResults: 1 }); const messageId = listMessagesRes.messages[0].id; // Get the message using the message ID. const message = await gmail.users.messages.get({ userId: email, id: messageId }); return message;
添付ファイルの画像を分析する
メッセージに画像が添付されている場合、watchGmailMessages
は Cloud Vision API を呼び出して画像にアノテーションを付けます。この Codelab では、Cloud Vision API に画像を分類して複数の画像タグを返すよう指示します。たとえば、青空の画像が渡されると、Cloud Vision API はタグ blue、sky、nature を返します。
watchGmailMessages
は、Node.js 用の Cloud Vision API ライブラリを使用して Cloud Vision API を呼び出します。
// Tag the attachment using Cloud Vision API const analyzeAttachment = async (data, filename) => { var topLabels = ['', '', '']; if (filename.endsWith('.png') || filename.endsWith('.jpg')) { const [analysis] = await visionClient.labelDetection({ image: { content: Buffer.from(data, 'base64') } }); const labels = analysis.labelAnnotations; topLabels = labels.map(x => x.description).slice(0, 3); } return topLabels; };
Google スプレッドシートを更新
watchGmailMessages
は、この分析結果を Google スプレッドシートにエクスポートします。このファイルには、送信者の名前、添付ファイルの名前、添付ファイルの画像(存在する場合)のタグが含まれます。
まず、Google スプレッドシートを作成します。Google スプレッドシートを開き、[Start a new spreadsheet] の [空白] テンプレートをクリックします。シートの ID をコピーします。たとえば、ブラウザで次のようなアドレスがあるとします。
https://docs.google.com/spreadsheets/d/abcdefghij01234567890/edit#gid=0
スプレッドシートの ID は abcdefghij01234567890
です。Cloud Shell コードエディタで、gcf-gmail-codelab/pubsub/env_vars.yaml
を更新し、YOUR-GOOGLE-SHEET-ID
を独自の値に置き換えます。
watchGmailMessages
は、Google Sheets API に接続して情報を追加します。
const updateReferenceSheet = async (from, filename, topLabels) => { await googleSheets.spreadsheets.values.append({ spreadsheetId: SHEET, range: SHEET_RANGE, valueInputOption: 'USER_ENTERED', requestBody: { range: SHEET_RANGE, majorDimension: 'ROWS', values: [ [from, filename].concat(topLabels) ] } }); };
最後に
Cloud Shell コードエディタで gcf-gmail-codelab/pubsub/env_vars.yaml
を開き、YOUR-GOOGLE-CLIENT-ID
、YOUR-GOOGLE-CLIENT-SECRET
、YOUR-GOOGLE-CALLBACK-URL
を独自の値に置き換えます。これらの値は Google Cloud コンソールで確認できます。左側のナビゲーション メニューで [Cloud Functions] を開き、Cloud Functions のリストで auth_init
を選択して [環境変数] セクションを探します。
コードをデプロイする
次のコマンドを実行して、Cloud Functions の関数をデプロイします。
cd ~ cd gcf-gmail-codelab/pubsub gcloud functions deploy watchGmailMessages --runtime=nodejs8 --trigger-topic=gmail-watch --env-vars-file=env_vars.yaml
Cloud Pub/Sub トピックに gmail-watch
以外の名前を付けた場合は、上記のコマンドの gmail-watch
をトピックの名前に置き換えてください。Cloud Functions の関数のデプロイには数秒かかることがあります。
7. 試してみる
お疲れさまでした。画像が添付されたメールを自分に送信します。数秒後、作成した Google スプレッドシートが入力した情報で自動的に更新されます。