アシスタント用 Google ログインは、アカウントのリンクやアカウント作成に関するユーザー エクスペリエンスをシンプルかつ簡単にするもので、ユーザーとデベロッパーのどちらにとっても便利です。アクションは、ユーザーとの会話中に、ユーザーの Google プロフィール(ユーザーの名前、メールアドレス、プロフィール写真など)へのアクセスをリクエストできます。
これらのプロフィール情報をアクション内で使用して、ユーザーに合わせてパーソナライズしたエクスペリエンスを作り出すことができます。他のプラットフォームのアプリからでも、そのアプリが Google ログインを使用していれば、既存ユーザーのアカウントを検索してそのアカウントにリンクしたり、新しいアカウントを作成したり、ユーザーと直接やり取りする経路を確立したりすることができます。
Google ログインを使用してアカウント リンクを行うには、ユーザーの Google プロフィールにアクセスすることについてユーザーに同意を求めます。次に、メールアドレスなどのプロフィール情報を使用して、そのユーザーを既存システム内で識別します。
Google ログインによるアカウント リンクを実装する
以降のセクションの手順に従って、Google ログインによるアカウント リンクをアクションに追加します。
プロジェクトを構成する
プロジェクトで Google ログインによるアカウント リンクを使用するよう構成するには、次の手順に従います。
- Actions Console を開き、プロジェクトを選択します。
- [Develop](開発)タブをクリックして、[Account linking](アカウント リンク)を選択します。
- [アカウントのリンク] の横にあるスイッチを有効にします。
- [アカウントの作成] セクションで [はい] を選択します。
[Linking type](リンクタイプ)で、[Google Sign In](Google ログイン)を選択します。
[Client Information](クライアント情報)を開き、[Client ID issued by Google to your Actions](Google がアクションに対して発行したクライアント ID)の値をメモします。
[保存] をクリックします。
認証フローの音声ユーザー インターフェースを設計する
で確認できます。ユーザーが確認済みかどうかを確認し、アカウントのリンクのフローを開始する
- Actions Console で Actions Builder プロジェクトを開きます。
- アクションでアカウントのリンクを開始するための新しいシーンを作成します。
<ph type="x-smartling-placeholder">
- </ph>
- [Scenes] をクリックします。
- 追加(+)アイコンをクリックして新しいシーンを追加します。
- 新しく作成したシーンで、追加アイコン add をクリックします。 [Conditions] アイコンをクリックします。
- 会話に関連付けられたユーザーが
確認できます。チェックに失敗した場合、アクションはアカウントのリンクを実行できません
アクセスが許可されることが確認されると、
機能も用意されています。
- [Condition] の
Enter new expression
フィールドに、次のロジックを入力します。user.verificationStatus != "VERIFIED"
- [トランジション] で、アカウントのリンクを必要としないシーンを選択します。または、 ゲスト専用機能へのエントリ ポイントとなるシーン。
- [Condition] の
- [Conditions] の add アイコンをクリックします。
- ユーザーがまだリンクしていない場合にアカウントのリンクフローをトリガーする条件を追加します。
関連付けられます。
- [Condition] の下にある
Enter new expression
フィールドに、次のロジックを入力します。user.verificationStatus == "VERIFIED"
- [Transition] で、[Account Linking] システムシーンを選択します。
- [保存] をクリックします。
- [Condition] の下にある
保存後、<SceneName>_AccountLinking
という新しいアカウント リンク システムシーンが作成されます
がプロジェクトに追加されます。
アカウントのリンクシーンをカスタマイズする
- [Scenes] で、アカウント リンクのシステムシーンを選択します。
- [プロンプトを送信] をクリックし、ユーザーに説明する短い文を追加します。 アクションが ID にアクセスする必要がある理由(「設定を保存するため」など)。
- [保存] をクリックします。
- [条件] で [ユーザーがアカウントのリンクを正常に完了した場合] をクリックします。
- ユーザーがアカウントのリンクに同意した場合のフローの処理方法を構成します。 たとえば、Webhook を呼び出して、必要なカスタム ビジネス ロジックを処理します。 元のシーンに戻ります
- [保存] をクリックします。
- [条件] で、[ユーザーがアカウントのリンクをキャンセルまたは拒否した場合] をクリックします。
- ユーザーがリンクに同意しなかった場合のフローの進め方を設定します。 あります。たとえば、確認応答メッセージを送信し、シーンにリダイレクトします。 アカウントのリンクを必要としない機能を提供する。
- [保存] をクリックします。
- [条件] で [システムエラーまたはネットワーク エラーが発生した場合] をクリックします。
- アカウントのリンクのフローを実行できない場合のフローの進め方を設定する システムエラーまたはネットワークエラーのために完了した。 たとえば、確認応答メッセージを送信し、シーンにリダイレクトします。 アカウントのリンクを必要としない機能を提供する。
- [保存] をクリックします。
バックエンドでプロフィール情報にアクセスする
ユーザーがアクションに対して自分の Google プロフィールへのアクセスを許可すると、それ以降そのアクションのリクエストが発行されるたびに、ユーザーの Google プロフィール情報を含む Google ID トークンを受け取ります。
ユーザーのプロフィール情報にアクセスするには、まず次の手順に従ってトークンの検証とデコードを行う必要があります。
- ご使用の言語の JWT デコード ライブラリを使用して、 Google の公開鍵(JWK で入手可能)を使用して、 PEM 形式など)を使用してトークンの署名を検証します。
- トークンの発行者(デコードされたトークンの
iss
フィールド)がhttps://accounts.google.com
であることを確認します。 オーディエンス(デコードされたトークンのaud
フィールド)が プロジェクトに割り当てられているアクションに対して Google が発行するクライアント ID 確認できます。
デコードされたトークンの例を以下に示します。
{ "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 フルフィルメント ライブラリを使用する場合は、 トークンの検証とデコードが自動的に行われます。 プロフィールのコンテンツを変更する必要があります。
... 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!'); });