在 Dialogflow 中探索
点击继续,将我们的“保存数据”示例导入 Dialogflow 中。然后,按照以下步骤部署和测试该示例:
- 输入代理名称并为示例创建新的 Dialogflow 代理。
- 代理导入完成后,点击转至代理 (Go to agent)。
- 在主导航菜单中,前往 Fulfillment。
- 启用内嵌编辑器,然后点击部署。编辑器包含示例代码。
- 在主导航菜单中,点击 Integrations(集成),然后点击 Google Assistant。
- 在显示的模态窗口中,启用 Auto-preview changes,然后点击 Test 打开 Actions 模拟器。
- 在模拟器中,输入
Talk to my test app
以测试示例!
为了提供出色的用户体验,通常能够在两次对话之间或与用户的多次对话之间保存数据。如果您要在单个对话中提供有用的重新提示、保存跨会话的游戏得分或记住用户的一小段信息,则此功能非常有用。
根据您是需要在对话中还是跨对话之间保存数据,相关要求会略有不同。如需在对话中保存数据,您可以使用 AppResponse
对象的 conversationToken
字段。
如需保存各对话的数据,请改为执行以下步骤:
- 确定用户是已验证用户还是访客。
- 使用
AppResponse
对象的userStorage
字段存储或访问用户数据。
在两轮对话的间隙保存数据
conversationToken
字段是一个字符串,其中包含一个不透明令牌,该令牌会在每一轮对话回合中重新分发给 Action。例如,如果您在对话的第一轮将 AppResponse
中的值设置为 "count=1"
,则您的 Action 在对话第二轮中收到的 AppRequest
会在其 conversationToken
中包含 "count=1"
。
令牌始终在对话开始时初始化为空字符串。如果您使用 Actions on Google Node.js 客户端库,则可以使用 conv.data
以 JSON 对象的形式与对话令牌进行交互,其中 conv
是您的 Conversation
实例。
以下示例展示了如何在 AppResponse
的 conversationToken
字段中保存计数器:
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
字段是一个字符串,其中包含由 Action 提供的不透明令牌,该令牌跨对话针对特定用户保存。例如,游戏可以在 userStorage
中保存用户的最高得分,并在用户每次发起新对话时在欢迎消息中使用该得分。
确定和处理用户验证状态
用户的验证状态可以是 GUEST
或 VERIFIED
值。在每次对话开始时,Actions on Google 会根据对话开始时提供的各种指示来设置用户的验证状态。例如,在移动设备上登录 Google 助理的用户的验证状态为 VERIFIED
。
以下是可能导致用户验证状态为 GUEST
的原因:
- 用户关闭了个人信息相关结果功能。
- 用户停用了自己的网络与应用活动记录。请注意,部分用户可能在网域级别停用了此设置。
- 设备启用了 Voice Match,但匹配失败,或者用户在不使用语音(例如长按 Google Home)的情况下调用了 Google 助理。
- 用户未登录。
在使用 userStorage
存储数据或启动帐号关联流程之前,请务必检查用户的验证状态,以防止访客用户与会失败的功能互动。
如果您使用的是 Node.js 版 Actions On Google 客户端库,则可以使用 conv.user.storage
以 JSON 对象的形式与用户存储空间连接,其中 conv
是您的 Conversation
实例。以下示例展示了如何在 AppResponse
的 userStorage
字段中保存计数器:
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
的内容永不过期,只有用户或 Action 本身可以清除这些内容。
当 Google 助理无法将某个身份与用户匹配时,会在对话结束时清除 userStorage
的内容。以下是 Google 助理无法将身份与用户进行匹配的一些示例情况:
- Voice Match 已设置,但不匹配。
- 用户停用了个人数据。
清除 userStorage 字段的内容
您可以将 AppResponse
的 resetUserStorage
字段设置为 true,以清除 Action 的 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\":{}}" }
作为用户,您可以查看您调用的 Action 中 userStorage
字段的内容。您还可以阻止该服务记住您,从而从该特定 Action 中移除您存储的用户数据。
- 在手机上打开 Google 助理应用。
- 点按抽屉式导航栏图标。
- 在 Explore(探索)标签页中,找到要查看或清除用户存储空间的 Action,然后点按它以打开详情页面。
- 滚动到页面底部。
- 如需查看
userStorage
字段的内容,请点按[查看存储的数据]。 - 如要移除存储的用户数据,请点按不再允许$action记住我。
- 如需查看