1. 簡介
數十億企業和個人使用 Gmail 和其他 G Suite 服務進行通訊及處理資料。Google 提供 G Suite API,協助您以程式輔助方式存取這些服務中的資訊,並輕鬆自動化日常工作流程。在本實驗室中,您將建構強大的 Gmail 擴充功能,自動將來信分類,並將這些類別儲存至 Google 試算表。這項擴充功能會使用 G Suite 的 RESTful API、Google Cloud Functions 和其他 Google Cloud Platform 服務。
建構目標
在本實驗室中,您將建構及部署幾個 Cloud Functions,並連結至 G Suite API 和其他 Google Cloud Platform 服務。這些函式會執行下列作業:
- 授權安全存取 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 的無伺服器函式即服務平台,可讓您以簡單且可擴充的方式執行個別程式碼片段 (「函式」)。
如要啟用 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」。在新頁面中,按一下「Select Datastore Mode」(選取 Datastore 模式)。

本實驗室可使用任何資料庫位置。按一下「建立資料庫」啟用 Google Cloud Datastore,這項作業可能需要幾分鐘才能完成。
Google Cloud Vision
Google Cloud Vision API 是一項功能強大的機器學習服務,可使用預先訓練模型從圖片中取得洞察資訊。
請參閱下列操作說明,瞭解如何啟用 Google Cloud Vision API。
啟用 Gmail API、Google Sheets API 和 Google Cloud Vision API
再次開啟左側導覽側欄,然後找到「API 和服務」。按一下「圖書館」。在「搜尋 API 和服務」欄位中輸入「Gmail」。在搜尋結果中選取「Gmail API」,然後按一下「啟用」。
返回「API Library」(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
您應該會在 Cloud Shell 程式碼編輯器中看到新資料夾 gcf-gmail-codelab。
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 Function 自動讀取電子郵件前,請先授權存取 Gmail。您必須向 Google 註冊 OAuth 用戶端,並建立相關聯的用戶端 ID。
註冊 OAuth 用戶端
在 Google Cloud 控制台的左側導覽選單中,找到「API 和服務」。按一下「OAuth 同意畫面」。

在「應用程式名稱」欄位中輸入名稱,例如「GCF + Gmail Codelab」。其他設定維持不變,然後捲動至頁面底部,按一下「儲存」。
建立相關聯的用戶端 ID
切換至「憑證」分頁標籤。按一下「建立憑證」,然後選擇「OAuth 用戶端 ID」。選取「網頁應用程式」類型,為其命名 (您可以在這裡再次使用「GCF + Gmail Codelab」),然後按一下「建立」。暫時將「限制」欄位留空。
記下彈出式視窗中傳回的用戶端 ID 和用戶端密鑰。如要再次查看這些值,請在頁面上按一下用戶端名稱:

執行授權程序
在程式碼範例中,auth/index.js 會指定兩個 Cloud Functions (auth_init 和 auth_callback),這兩個函式會搭配您剛建立的用戶端 ID 和用戶端密碼,共同執行授權程序。
如要檢查程式碼,請在 Cloud Shell 程式碼編輯器中開啟 auth/index.js。
授權程序會傳回兩種權杖:存取權杖和更新權杖。
- 存取權杖是短期身分證明,可授予持有者範圍受限的資料存取權;
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 安裝 Beta 版指令的權限。
接著前往 Google Cloud 控制台,然後點選左側導覽選單中的「Cloud Functions」。在 Cloud Functions 清單中點選 auth_callback,然後切換至「觸發條件」分頁。


複製網頁上的網址。返回「Cloud Functions」頁面,然後點選 Cloud Functions 清單中的 auth_init。在「一般」分頁中,按一下「編輯」。按一下「環境變數、網路、逾時等」,然後將 GOOGLE_CALLBACK_URL 的值替換為您剛複製的網址。

按一下「Deploy」(部署) 即可套用變更。重複上述程序,更新 auth_callback。
最後,開啟左側導覽選單,然後依序點選「API 和服務」>「網域驗證」。如要新增已授權的網域,請按一下「新增網域」。舉例來說,如果您先前複製的網址如下:
https://us-central1-my-project.cloudfunctions.net/auth_callback
請將下列項目新增為已授權網域:
us-central1-my-project.cloudfunctions.net
按下「新增網域」確認。

返回「憑證」頁面。按一下 OAuth 用戶端名稱,然後將複製的網址新增為「已授權的重新導向 URI」。按下 Enter 鍵確認。
從網址中移除 /auth_callback 部分,然後將其餘部分新增為「已授權的 JavaScript 來源」。舉例來說,如果網址如下:
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」 >「Topics」(主題)。按一下「建立主題」。輸入主題名稱 (例如 gmail-watch),然後點選「建立」。此外,您必須授予 Gmail 權限,才能將訊息傳送至 Pub/Sub 主題:按一下剛建立主題的環境選單 (三個垂直點),然後選擇「權限」;按一下「新增成員」,將 gmail-api-push@system.gserviceaccount.com 指定為新成員,並授予「Pub/Sub」>「Pub/Sub 發布者」角色;最後,按一下「儲存」套用變更。
更新 Cloud Function auth_callback,指定要使用的 Pub/Sub 主題。按一下左側導覽選單中的「Cloud Functions」,然後在 Cloud Functions 清單中選取 auth_callback。在「一般」分頁中,按一下「編輯」。按一下「更多」,然後將 PUBSUB_TOPIC 的值替換為您剛建立的 Pub/Sub 主題名稱。按一下「儲存」即可套用變更。
現在可以授權及設定 Gmail 推播通知。等待新變更完成,然後返回「Cloud Functions」頁面,在 Cloud Functions 清單中選取 auth_init,然後切換至「觸發條件」分頁標籤。按一下網址,系統會將您重新導向「使用 Google 帳戶登入」頁面:

使用您擁有的 Gmail 帳戶登入。只要帳戶收件匣收到新郵件,就會觸發推播通知。登入後,您會看到下方的頁面:

按一下「允許」授權存取。auth_callback會完成授權程序、儲存存取權杖,並為你設定 Gmail 推播通知。程序完成後,瀏覽器中會顯示 Successfully set up Gmail push notifications 訊息。
本程式碼研究室會使用 @google-cloud/express-oauth2-handlers 套件,自動執行授權工作流程。詳情請參閱 GitHub 上的存放區。
6. 處理收到的訊息
如先前所述,您建立的 Pub/Sub 主題有任何訂閱者,都會在收件匣收到新訊息時收到通知。pubsub/index.js 指定的 Cloud Function (watchGmailMessages) 部署為主題的訂閱者後,會讀取新訊息、分類附加圖片,並將這些類別匯出至 Google 試算表。
如要檢查程式碼,請在 Cloud Shell 程式碼編輯器中開啟 pubsub/index.js。
正在擷取訊息
Gmail 推播通知會包含與通知相關聯的電子郵件地址和記錄 ID。為簡化作業,本程式碼研究室會在收到即時通知時,直接向 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 為圖片加上註解。在本程式碼研究室中,您將要求 Cloud Vision API 分類圖片並傳回多個圖片標記;舉例來說,如果提供藍天的圖片,Cloud Vision API 可能會傳回「藍色」、「天空」和「自然」標記。
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 試算表,然後點選「開始建立新試算表」下方的「空白」範本。複製工作表的 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 函式:
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 函式可能需要幾秒鐘的時間。
7. 立即試用
恭喜,您已完成!傳送一封含圖片附件的電子郵件給自己。幾秒後,您建立的 Google 試算表就會自動更新您提供的資訊。