在对话中保存数据 (Dialogflow)

在 Dialogflow 中探索

点击继续,将我们的“保存数据”示例导入 Dialogflow 中。然后,按照以下步骤部署和测试该示例:

  1. 输入代理名称并为示例创建新的 Dialogflow 代理。
  2. 代理导入完成后,点击转至代理 (Go to agent)。
  3. 在主导航菜单中,前往 Fulfillment
  4. 启用内嵌编辑器,然后点击部署。编辑器包含示例代码。
  5. 在主导航菜单中,点击 Integrations(集成),然后点击 Google Assistant
  6. 在显示的模态窗口中,启用 Auto-preview changes,然后点击 Test 打开 Actions 模拟器。
  7. 在模拟器中,输入 Talk to my test app 以测试示例!
继续

为了提供出色的用户体验,通常能够在两次对话之间或与用户的多次对话之间保存数据。如果您要在单个对话中提供有用的重新提示、保存跨会话的游戏得分或记住用户的一小段信息,则此功能非常有用。

根据您是需要在对话中还是跨对话之间保存数据,相关要求会略有不同。如需在对话中保存数据,您可以使用 AppResponse 对象的 conversationToken 字段。

如需保存各对话的数据,请改为执行以下步骤:

  1. 确定用户是已验证用户还是访客。
  2. 使用 AppResponse 对象的 userStorage 字段存储或访问用户数据。

在两轮对话的间隙保存数据

conversationToken 字段是一个字符串,其中包含一个不透明令牌,该令牌会在每一轮对话回合中重新分发给 Action。例如,如果您在对话的第一轮将 AppResponse 中的值设置为 "count=1",则您的 Action 在对话第二轮中收到的 AppRequest 会在其 conversationToken 中包含 "count=1"

令牌始终在对话开始时初始化为空字符串。如果您使用 Actions on Google Node.js 客户端库,则可以使用 conv.data 以 JSON 对象的形式与对话令牌进行交互,其中 conv 是您的 Conversation 实例。

以下示例展示了如何在 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 字段是一个字符串,其中包含由 Action 提供的不透明令牌,该令牌跨对话针对特定用户保存。例如,游戏可以在 userStorage 中保存用户的最高得分,并在用户每次发起新对话时在欢迎消息中使用该得分。

确定和处理用户验证状态

用户的验证状态可以是 GUESTVERIFIED 值。在每次对话开始时,Actions on Google 会根据对话开始时提供的各种指示来设置用户的验证状态。例如,在移动设备上登录 Google 助理的用户的验证状态为 VERIFIED

以下是可能导致用户验证状态为 GUEST 的原因:

  • 用户关闭了个人信息相关结果功能。
  • 用户停用了自己的网络与应用活动记录。请注意,部分用户可能在网域级别停用了此设置。
  • 设备启用了 Voice Match,但匹配失败,或者用户在不使用语音(例如长按 Google Home)的情况下调用了 Google 助理。
  • 用户未登录。

在使用 userStorage 存储数据或启动帐号关联流程之前,请务必检查用户的验证状态,以防止访客用户与会失败的功能互动。

如果您使用的是 Node.js 版 Actions On Google 客户端库,则可以使用 conv.user.storage 以 JSON 对象的形式与用户存储空间连接,其中 conv 是您的 Conversation 实例。以下示例展示了如何在 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 的内容永不过期,只有用户或 Action 本身可以清除这些内容。

当 Google 助理无法将某个身份与用户匹配时,会在对话结束时清除 userStorage 的内容。以下是 Google 助理无法将身份与用户进行匹配的一些示例情况:

  • Voice Match 已设置,但不匹配。
  • 用户停用了个人数据。

清除 userStorage 字段的内容

您可以将 AppResponseresetUserStorage 字段设置为 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 中移除您存储的用户数据。

  1. 在手机上打开 Google 助理应用。
  2. 点按抽屉式导航栏图标。

  3. Explore(探索)标签页中,找到要查看或清除用户存储空间的 Action,然后点按它以打开详情页面。
  4. 滚动到页面底部。
    • 如需查看 userStorage 字段的内容,请点按[查看存储的数据]
    • 如要移除存储的用户数据,请点按不再允许$action记住我