在對話中儲存資料 (Dialogflow)

在 Dialogflow 中探索

按一下「繼續」,將我們的「儲存資料」範例匯入 Dialogflow。接著,請按照下列步驟部署及測試範例:

  1. 輸入虛擬服務專員名稱,並為範例建立新的 Dialogflow 代理程式。
  2. 代理程式匯入完成後,按一下「Go to agent」
  3. 從主要導覽選單中,前往「Fulfillment」
  4. 啟用「Inline Editor」(內嵌編輯器),然後按一下「Deploy」(部署)。編輯器包含程式碼範例。
  5. 在主要導覽選單中,前往「Integrations」(整合),然後按一下「Google Assistant」(Google 助理)
  6. 在出現的互動視窗中,啟用「Auto-preview changes」,按一下「Test」,開啟動作模擬工具。
  7. 在模擬工具中輸入 Talk to my test app 即可測試範例!
繼續

想要提供優質的使用者體驗,通常可以在對話切換或與使用者進行的多個對話之間儲存資料。如果您在單一對話中提供實用的重新提示、儲存不同工作階段的遊戲分數,或為使用者記住少量資訊,這項功能就十分實用。

視您是否需要在對話或跨對話中儲存資料而定,上述要求會略有不同。如要在對話中儲存資料,可以使用 AppResponse 物件的 conversationToken 欄位。

如要儲存不同對話的資料,請改為按照下列步驟操作:

  1. 判斷使用者是否已完成驗證或訪客身分。
  2. 使用 AppResponse 物件的 userStorage 欄位儲存或存取使用者資料。

在對話切換之間節省資料

conversationToken 欄位是包含不透明權杖的字串,每回合要輪流給動作執行該動作。例如,如果您將 AppResponse 中第一次回合的對話值設為 "count=1",則動作的第二回合時,動作收到的 AppRequest 會在對話的 conversationToken 中納入 "count=1"

系統一律會在對話開始時,將憑證初始化為空白字串。如果使用 Actions on Google Node.js 用戶端程式庫,可以使用 conv.data 將對話權杖視為 JSON 物件介面,其中 convConversation 的執行個體。

以下範例說明如何在 AppResponseconversationToken 欄位中儲存計數器:

Node.js

conv.data.firstNum = firstNum;
conv.ask(`Got it, the first number is ${firstNum}.`);
conv.ask(`What's the second number?`);

Java

ResponseBuilder responseBuilder = getResponseBuilder(request);
responseBuilder.getConversationData().put("firstNum", firstNum);
responseBuilder.add("Got it, the first number is " + firstNum + ".");
responseBuilder.add("What's the second number?");
return responseBuilder.build();

JSON

請注意,以下 JSON 說明使用 outputContexts 而不是 conversationToken 的 Webhook 回應。

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Got it, the first number is 23."
            }
          },
          {
            "simpleResponse": {
              "textToSpeech": "What's the second number?"
            }
          }
        ]
      }
    }
  },
  "outputContexts": [
    {
      "name": "projects/save-data-df-js/agent/sessions/ABwppHGfFkWJdHKPpBEYiGkhdoakWmYj_2sZa4o8pbGG9nj4q5_GfDTtNEXOY34mLX8G4o_d7oZdUW9bnBZC/contexts/_actions_on_google",
      "lifespanCount": 99,
      "parameters": {
        "data": "{\"firstNum\":23}"
      }
    }
  ]
}

JSON

請注意,以下 JSON 說明 Webhook 回應。

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Got it, the first number is 23."
              }
            },
            {
              "simpleResponse": {
                "textToSpeech": "What's the second number?"
              }
            }
          ]
        }
      }
    }
  ],
  "conversationToken": "{\"data\":{\"firstNum\":23}}"
}

如需實際使用範例,請參閱提供實用的提示和失敗機制最佳做法指南。

在不同對話之間儲存資料

AppResponse 物件的 userStorage 欄位是一個字串,包含動作提供的不透明權杖,這類權杖是由特定使用者儲存在特定使用者的對話中。舉例來說,遊戲可以將使用者的最高分數儲存在 userStorage 中,並在使用者每次開始新對話時,在歡迎訊息中使用其值。

判斷及處理使用者驗證狀態

使用者的驗證狀態可以是 GUESTVERIFIED,在每次對話開始時,Actions on Google 都會根據對話開始時的各種指標設定使用者的驗證狀態。舉例來說,如果使用者在行動裝置上登入 Google 助理,驗證狀態則為 VERIFIED

以下是使用者獲得 GUEST 驗證狀態的可能原因:

  • 使用者已關閉個人化搜尋結果
  • 使用者停用了網路和應用程式活動設定。請注意,部分使用者可能會在網域層級停用這項設定。
  • 如果裝置已啟用 Voice Match,但比對失敗,或使用者不使用語音叫用 Google 助理,例如長按 Google Home,即可啟動 Google 助理。
  • 使用者未登入。

使用 userStorage 儲存資料前,請務必先檢查使用者的驗證狀態,或啟動帳戶連結流程,避免訪客使用者與會失敗的功能互動。

如果使用 Node.js 適用的 Actions on Google 用戶端程式庫,可使用 conv.user.storage 將使用者儲存空間做為 JSON 物件介面,其中 convConversation 的執行個體。以下範例說明如何在 AppResponseuserStorage 欄位中儲存計數器:

Node.js

app.intent('Save Sum', (conv) => {
  if (conv.user.verification === 'VERIFIED') {
    conv.user.storage.sum = conv.data.sum;
    conv.close(`Alright, I'll store that for next time. See you then.`);
  } else {
    conv.close(`I can't save that right now, but we can add ` +
      `new numbers next time!`);
  }
});

Java

@ForIntent("Save Sum")
public ActionResponse saveSum(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  Integer sum = ((Double) request.getConversationData().get("sum")).intValue();
  String verificationStatus = request.getUser().getUserVerificationStatus();
  if (verificationStatus.equals("VERIFIED")) {
    responseBuilder.getUserStorage().put("sum", sum);
    responseBuilder.add("Alright, I'll store that for next time. See you then.");
  } else {
    responseBuilder.add("I can't save that right now, but we can add new numbers next time!");
  }
  responseBuilder.endConversation();
  return responseBuilder.build();
}

Node.js

if (conv.user.verification === 'VERIFIED') {
  conv.user.storage.sum = conv.data.sum;
  conv.close(`Alright, I'll store that for next time. See you then.`);
} else {
  conv.close(`I can't save that right now, but we can add ` +
    `new numbers next time!`);
}

Java

ResponseBuilder responseBuilder = getResponseBuilder(request);
Integer sum = ((Double) request.getConversationData().get("sum")).intValue();
String verificationStatus = request.getUser().getUserVerificationStatus();
if (verificationStatus.equals("VERIFIED")) {
  responseBuilder.getUserStorage().put("sum", sum);
  responseBuilder.add("Alright, I'll store that for next time. See you then.");
} else {
  responseBuilder.add("I can't save that right now, but we can add new numbers next time!");
}
responseBuilder.endConversation();
return responseBuilder.build();

JSON

請注意,以下 JSON 說明 Webhook 回應。

{
  "payload": {
    "google": {
      "expectUserResponse": false,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Alright, I'll store that for next time. See you then."
            }
          }
        ]
      },
      "userStorage": "{\"data\":{\"sum\":68}}"
    }
  }
}

JSON

請注意,以下 JSON 說明 Webhook 回應。

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "simpleResponse": {
            "textToSpeech": "Alright, I'll store that for next time. See you then."
          }
        }
      ]
    }
  },
  "conversationToken": "{\"data\":{\"firstNum\":23,\"sum\":68}}",
  "userStorage": "{\"data\":{\"sum\":68}}"
}

如需實際使用範例,請參閱「運用使用者偏好設定個人化對話」最佳做法指南。

注意事項:在存取 userStorage 前取得同意聲明。某些國家/地區的法規規定,開發人員必須先取得使用者的同意聲明,才能存取 userStorage 中或儲存特定資訊 (例如個人資訊)。如果您在上述國家/地區經營業務,想要存取或將這類資訊儲存至 userStorage,則必須使用確認輔助程式向使用者徵求同意聲明並取得同意聲明,才能開始在 userStorage 中儲存這類資訊。

使用者儲存空間到期

當 Google 助理可以比對使用者的身分時,userStorage 的內容將永遠不會過期,且只有使用者或動作本身可以清除。

當 Google 助理無法比對使用者的身分時,會在對話結束時清除 userStorage 的內容。以下列舉一些 Google 助理無法比對使用者的身分的情況:

  • 找不到相符的 Voice Match,
  • 使用者已停用個人資料。

清除 userStorage 欄位的內容

只要將 AppResponseresetUserStorage 欄位設為 true,即可清除動作中 userStorage 欄位的內容。如果您將 userStorage 的值設為空白字串,userStorage 的值會在下一個對話轉彎時維持不變。這可避免在內容未變更的情況下傳回整個 userStorage

如果您使用的是 Node.js 適用的 Actions on Google 用戶端程式庫,可以將 conv.user.storage 的值設為 {} (空白物件)。

Node.js

app.intent('Forget Number', (conv) => {
  conv.user.storage = {};
  conv.ask(`Alright, I forgot your last result.`);
  conv.ask(`Let's add two new numbers. What is the first number?`);
});

Java

@ForIntent("Forget Number")
public ActionResponse forgetNumber(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  responseBuilder.getUserStorage().clear();
  responseBuilder.add("Alright, I forgot your last result.");
  responseBuilder.add("Let's add two new numbers. What is the first number?");
  return responseBuilder.build();
}

Node.js

conv.user.storage = {};
conv.ask(`Alright, I forgot your last result.`);
conv.ask(`Let's add two new numbers. What is the first number?`);

Java

ResponseBuilder responseBuilder = getResponseBuilder(request);
responseBuilder.getUserStorage().clear();
responseBuilder.add("Alright, I forgot your last result.");
responseBuilder.add("Let's add two new numbers. What is the first number?");
return responseBuilder.build();

JSON

請注意,以下 JSON 說明 Webhook 回應。

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Alright, I forgot your last result."
            }
          },
          {
            "simpleResponse": {
              "textToSpeech": "Let's add two new numbers. What is the first number?"
            }
          }
        ]
      },
      "userStorage": "{\"data\":{}}"
    }
  }
}

JSON

請注意,以下 JSON 說明 Webhook 回應。

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Alright, I forgot your last result."
              }
            },
            {
              "simpleResponse": {
                "textToSpeech": "Let's add two new numbers. What is the first number?"
              }
            }
          ]
        }
      }
    }
  ],
  "userStorage": "{\"data\":{}}"
}

使用者可在叫用的動作中查看 userStorage 欄位的內容。您也可以從特定動作中移除儲存的使用者資料,讓服務不再記住您的資訊。

  1. 開啟手機上的「Google 助理」應用程式。
  2. 輕觸導覽匣圖示。

  3. 在「探索」分頁中,找出您要查看或清除使用者儲存空間的動作,然後輕觸該動作即可開啟詳細資料頁面。
  4. 捲動至頁面底部。
    • 如要查看 userStorage 欄位的內容,請輕觸「[查看已儲存的資料]」
    • 如要移除已儲存的使用者資料,請輕觸「不再記住我的『$action』