使用者和開發人員的 Google 登入提供最簡單輕鬆的使用者體驗,包括連結帳戶及建立帳戶。您的動作可在對話期間要求存取使用者的 Google 個人資料,包括使用者名稱、電子郵件地址和個人資料相片。
您可以使用這類設定檔資訊,在動作中打造個人化的使用者體驗。如果您的應用程式在其他平台上有應用程式,而且這些平台都使用 Google 登入功能,您也可以找出現有使用者帳戶並建立連結,然後建立新帳戶,然後建立與使用者直接溝通的管道。
如要透過 Google 登入功能執行帳戶連結作業,請先要求使用者同意存取其 Google 個人資料。然後,您可以使用其設定檔中的資訊 (例如電子郵件地址) 識別系統中的使用者。
實作 Google 登入帳戶連結
請按照下列各節的步驟,將 Google 登入帳戶連結新增至您的動作。
設定專案
如要將專案設為使用 Google 登入帳戶連結功能,請按照下列步驟操作:
- 開啟「Actions Console」並選取專案。
- 按一下「開發」分頁標籤,然後選擇「帳戶連結」。
- 啟用「帳戶連結」旁的切換鈕。
- 在「建立帳戶」部分中,選取「是」。
在「連結類型」中,選取「Google 登入」。
開啟「客戶資訊」,並記下「Google 核發給您的用戶端 ID」的值。
點按「儲存」。
設計驗證流程的語音使用者介面
檢查使用者是否已通過驗證,並啟動帳戶連結流程
- 在 Actions 主控台中開啟 Actions Builder 專案。
- 建立新的場景,以便在動作中開始連結帳戶:
- 按一下「Scenes」。
- 按一下「add」圖示 (+) 即可新增場景。
- 在新建立的場景中,按一下「Conditions」(條件) 圖示 add。
- 新增條件,檢查與對話相關聯的使用者是否為已驗證的使用者。如果檢查失敗,您的動作就無法在對話期間執行帳戶連結,而是應改回提供不需要帳戶連結的功能。
- 在「Condition」(條件) 下方的
Enter new expression
欄位中,輸入下列邏輯:user.verificationStatus != "VERIFIED"
- 在「轉換」下方,選取不需要連結帳戶的場景,或不需要訪客專屬功能的進入點。
- 在「Condition」(條件) 下方的
- 按一下「條件」的「新增」圖示 add。
- 新增條件,在使用者沒有相關聯的身分時觸發帳戶連結流程。
- 在「Condition」(條件) 下方的
Enter new expression
欄位中,輸入下列邏輯:user.verificationStatus == "VERIFIED"
- 在「轉換」下方,選取「帳戶連結」系統場景。
- 點按「儲存」。
- 在「Condition」(條件) 下方的
儲存後,名為 <SceneName>_AccountLinking
的帳戶連結系統場景就會新增至專案中。
自訂帳戶連結情境
- 在「場景」下方,選取帳戶連結系統場景。
- 按一下「Send 提示」,然後新增簡短句子,說明動作需要存取其身分的原因 (例如「如要儲存偏好設定」)。
- 點按「儲存」。
- 在「條件」下方,按一下「如果使用者成功完成帳戶連結」。
- 設定使用者同意連結帳戶時,流程的後續步驟。 舉例來說,呼叫 Webhook 以處理任何所需的自訂商業邏輯,然後切換回原始場景。
- 點按「儲存」。
- 在「條件」下方,按一下「如果使用者取消或關閉帳戶連結」。
- 如果使用者不同意連結帳戶,請設定流程。例如,傳送已確認的訊息,然後重新導向至提供不需要連結帳戶的功能的場景。
- 點按「儲存」。
- 在「條件」下方,按一下「如果發生系統或網路錯誤」。
- 設定若帳戶連結流程因系統或網路錯誤而無法順利完成時,流程該如何繼續。 例如,傳送已確認的訊息,然後重新導向至提供不需要連結帳戶的功能的場景。
- 點按「儲存」。
在後端存取設定檔資訊
使用者授權您的動作存取其 Google 設定檔後,您會在每個後續動作要求中收到一個 Google ID 權杖,其中包含使用者的 Google 個人資訊。
如要存取使用者的個人資料,您必須先按照下列步驟驗證並解碼權杖:
- 針對您的語言使用 JWT 解碼程式庫來解碼權杖,並使用 JWK 或 PEM 格式的 Google 公開金鑰 (提供 JWK 或 PEM 格式) 來驗證權杖的簽名。
- 確認權杖的核發者 (已解碼權杖中的
iss
欄位) 為https://accounts.google.com
,且目標對象 (已解碼權杖中的aud
欄位) 是 Google 核發至您動作的用戶端 ID 值,該值會在 Actions 控制台中指派給您的專案。
以下是已解碼權杖的範例:
{ "sub": 1234567890, // The unique ID of the user's Google Account "iss": "https://accounts.google.com", // The token's issuer "aud": "123-abc.apps.googleusercontent.com", // Client ID assigned to your Actions project "iat": 233366400, // Unix timestamp of the token's creation time "exp": 233370000, // Unix timestamp of the token's expiration time "name": "Jan Jansen", "given_name": "Jan", "family_name": "Jansen", "email": "jan@gmail.com", // If present, the user's email address "locale": "en_US" }
如果使用 Node.js 適用的 Actions on Google Fulfillment 程式庫,該程式庫會為您驗證權杖並解碼,然後讓您存取設定檔內容,如以下程式碼片段所示。
... const app = conversation({ // REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT clientId: CLIENT_ID, }); ... // Invoked on successful completion of account linking flow, check if we need to // create a Firebase user. app.handle('linkAccount', async conv => { let payload = conv.headers.authorization; if (payload) { // Get UID for Firebase auth user using the email of the user const email = payload.email; if (!conv.user.params.uid && email) { try { conv.user.params.uid = (await auth.getUserByEmail(email)).uid; } catch (e) { if (e.code !== 'auth/user-not-found') { throw e; } // If the user is not found, create a new Firebase auth user // using the email obtained from Google Assistant conv.user.params.uid = (await auth.createUser({email})).uid; } } } });
處理資料存取要求
如要處理資料存取要求,只要驗證由 Google ID 權杖宣告的使用者已存在於資料庫中即可。下列程式碼片段示範如何檢查使用者訂單是否已存在於 Firestore 資料庫中:
... app.handle('Place_Order', async conv => { const order = conv.session.params.order; const userDoc = dbs.user.doc(conv.user.params.uid); const orderHistory = userDoc.collection("orderHistory"); if (orderHistory) { // Order history exists, so the user already placed an order. // Update counter for order type. await orderHistory.doc(order).update({ count: admin.firestore.FieldValue.increment(1)}); } else { // First order they place await orderHistory.doc(order).set({ option: order, count: 1}); options.forEach(opt => { if (opt != order) { orderHistory.doc(opt).set({ option: opt, count: 0}); } }); } return conv.add(`Your ${order} has been placed. ` + 'Thanks for using Boba Bonanza, see you soon!'); });