本指南提供了各种实现 Webhook 的示例以及 Webhook 问题排查建议。
设置会话参数
以下示例展示了如何设置会话参数。
Go
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
请参阅 Webhook 快速入门。Java
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Python
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
返回 fulfillment 响应
以下示例展示了如何返回 fulfillment 响应。
Go
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
请参阅 Webhook 快速入门。Java
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Python
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
根据需要设置表单参数
以下示例展示了如何将参数标记为必需。
Java
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
验证表单参数
以下示例展示了如何验证表单参数。
Java
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Python
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
记录会话 ID
以下示例展示了如何记录来自 webhook 请求的 session ID。
Python
如需向 Dialogflow CX 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
问题排查
Webhook 调用的生命周期
Webhook 调用始终由 Dialogflow CX 发起,并通过 HTTPS 发送到 Web 服务器。通用 Web 服务 webhook 调用源自属于 Google 的互联网 IP 地址,并且可以访问公共互联网中可用的 Web 服务器(webhook 服务器)。另一方面,Service Directory webhook 始终从内部Google Cloud 地址启动,并且只能访问 Google Cloud内专用网络中的 webhook 服务器。
用于调试网络钩子的实用日志
调试 webhook 问题通常涉及收集 Cloud Logging Dialogflow CX 日志和 webhook 服务器日志。如果 webhook 服务器是使用 Cloud Run functions 实现的,则其日志将位于 Cloud Logging 中。否则,日志通常会驻留在 webhook 服务器运行的位置。
标准网络钩子日志包含一个带有 UUID 的 detectIntentResponseId 字段,该字段可用于跟踪网络钩子服务器中的特定调用。启用 Cloud Logging 后,此日志会存在于 Dialogflow CX Cloud Logging 日志中。
常见的 webhook 问题
在 Dialogflow CX 日志中可以找到的一些 webhook 调用错误包括:
网络钩子服务器主机名解析错误
Dialogflow CX 查找了通用网络钩子的主机名,但该主机名在 DNS 中不存在。确保主机名已在公共 DNS 中注册。如果主机名是新的,则记录可能需要一些时间才能传播。Cloud Logging 消息:State: URL_ERROR, Reason: ERROR_DNS。
Webhook 服务器返回客户端错误
除了 ERROR_DNS 之外,此状态表示来自 webhook 服务器的 4xx 响应。这可能是未经授权的状态(401 - ERROR_AUTHENTICATION),也可能是未在网络钩子服务器中找到网址(404 - ERROR_NOT_FOUND)。Cloud Logging 消息:State: URL_ERROR。
Dialogflow 代理在 webhook 服务器返回响应之前超时
Dialogflow CX 在 Web 服务器完成之前达到了 webhook 超时限制。这里有两种可能的方法:减少 webhook 服务器处理时间,或增加 Dialogflow CX 等待 webhook 的时间。缩短处理时间通常会带来最佳结果,但在许多情况下,这并非易事。请注意,Webhook 有最大超时限制,并且最终调用方或用户需要等待更长时间才能从代理获得答案,然后才能提高此设置。Cloud Logging 消息:State: URL_TIMEOUT, Reason: TIMEOUT_WEB。
gRPC 在 webhook 服务器返回响应之前超时
在 webhook 调用完成之前,已达到 Dialogflow CX API 调用中 gRPC 设置的时间限制。此限制通常在集成级别设置,与 Dialogflow CX 参数和网络钩子超时限制无关。如需详细了解 gRPC 截止期限,请参阅 https://grpc.io/docs/guides/deadlines/。Cloud Logging 消息:State: URL_REJECTED, Reason: REJECTED_DEADLINE_EXCEEDED。
Dialogflow 无法联系 webhook 服务器
由于网络连接错误,无法访问 webhook 服务器,或者已建立连接,但 webhook 服务器返回了 HTTP 状态 5xx,表示在处理请求时出现问题。确保 Dialogflow CX 可以在网络层级访问 webhook 服务器地址。如果请求出现在 webhook 服务器日志中,请找出调用返回 5xx 错误的原因。Cloud Logging 消息:State: URL_UNREACHABLE。
跟踪 webhook 调用
您可以使用会话 ID、detectIntentResponse ID、Cloud Run functions 的跟踪记录 ID 以及调用的时间戳,在 Dialogflow CX 和网络钩子服务器之间关联标准网络钩子调用。您可以使用调用的时间戳和设计时在 webhook 定义中指定的会话参数值来执行灵活的 webhook 跟踪。如需详细了解标准和灵活的 webhook 请求,请参阅 Webhook。
会话 ID 会显示在 WebhookRequest 的 sessionInfo.session 字段中。此会话 ID 对于每个对话都应该是唯一的,它可以帮助您比较使用相同会话 ID 的请求的智能体日志和网络钩子日志。上一部分记录会话 ID 展示了如何从网络钩子记录会话 ID。
此外,如果您在 Cloud Run functions 或类似的 Google Cloud 无服务器选项上托管 webhook,则可以使用日志条目中的 trace 字段作为日志过滤条件。单次执行函数会产生多个具有相同跟踪值的日志条目。
下一个示例同时使用会话 ID 和跟踪值,将特定 Dialogflow CX 智能体错误日志与相应的 Cloud Run functions webhook 日志条目相关联。该示例针对已启用 Cloud Logging 的代理使用 Cloud Logging 过滤条件。
1. 过滤 Dialogflow CX 日志,以查找特定代理的错误日志
使用以下 Cloud Logging 过滤条件,过滤 Dialogflow CX 日志,以查找特定智能体的错误日志:
labels.location_id="global"
labels.agent_id="AGENT_ID"
severity=ERROR
Webhook 日志错误条目如下所示:
{
"insertId": "-j4gkkre31e2o",
"jsonPayload": {
"code": 14,
"message": "Error calling webhook 'https://us-central1-PROJECT_ID.cloudfunctions.net/function-webhook': State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500"
},
"labels": {
"agent_id": "e9e01392-1351-42dc-9b15-b583fb2d2881",
"environment_id": "",
"location_id": "global",
"session_id": "07c899-a86-78b-a77-569625b37"
},
"logName": "projects/PROJECT_ID/logs/dialogflow-runtime.googleapis.com%2Frequests",
"receiveTimestamp": "2024-10-28T21:49:04.288439054Z",
"resource": {
"labels": {
"project_id": "PROJECT_ID"
},
"type": "global",
},
"severity": "ERROR",
"timestamp": "2024-10-28T21:49:04.132548Z"
}
请注意包含会话 ID 的 labels.session_id 字段。
您将在下一步中使用会话 ID。
2. 按会话 ID 过滤 Cloud Run functions 日志
使用以下 Cloud Logging 过滤条件,按会话 ID 过滤 Cloud Run functions 日志:
resource.type = "cloud_run_revision"
resource.labels.service_name = "CLOUD_RUN_FUNCTION_NAME"
resource.labels.location = "CLOUD_RUN_FUNCTION_REGION"
textPayload="Debug Node: session ID = SESSION_ID"
生成的日志对应于在提供的会话期间生成的 webhook 日志。例如:
{
"insertId": "671c42940007ebebdbb1d56e",
"labels": {
"execution_id": "pgy8jvvblovs",
"goog-managed-by": "cloudfunctions",
"instance_id": "004940b3b8e3d975a4b11a4ed7d1ded4ce3ed37467ffc5e2a8f13a1908db928f8200b01cc554a5eda66ffc9d23d76dd75cec1619a07cb5751fa2e8a93bc6cfc3df86dfa0650a"
},
"logName": "projects/PROJECT_ID/logs/run.googleapis.com%2Fstdout",
"receiveTimestamp": "2024-10-26T01:15:00.523313187Z",
"resource": {
"labels": {
"configuration_name": "function-webhook",
"location": "us-central1",
"project_id": "PROJECT_ID",
"revision_name": "function-webhook-00001-jiv",
"service_name": "function-webhook",
},
"type": "cloud_run_revision"
},
"spanId": "6938366936362981595",
"trace": "d1b54fbc8945dd59bdcaed37d7d5e185",
"textPayload": "Debug Node: session ID = 07c899-a86-78b-a77-569625b37",
"timestamp": "2024-10-26T01:15:00.519147Z"
}
请记下 trace 字段,下一步中会用到。
3. 过滤特定跟踪记录的 Cloud Functions 函数日志
使用以下 Cloud Logging 过滤条件来过滤特定跟踪记录的 Cloud Function 日志:
resource.type = "cloud_run_revision"
resource.labels.service_name = "CLOUD_RUN_FUNCTION_NAME"
resource.labels.location = "CLOUD_RUN_FUNCTION_REGION"
trace="projects/PROJECT_ID/traces/TRACE_ID"
其中 TRACE_ID 是跟踪记录的最后一部分。例如,projects/PROJECT_ID/traces/e41eefc1fac48665b442bfa400cc2f5e 的 TRACE_ID 为 e41eefc1fac48665b442bfa400cc2f5e。
结果是执行与第 1 步中的会话 ID 和第 2 步中的跟踪记录关联的 webhook 请求期间生成的 webhook 服务器日志。日志将如下所示。
{
"insertId": "671c42940008465e29f5faf0",
"httpRequest": {
"requestMethod": "POST",
"requestUrl": "https://us-central1-TEST_PROJECT.cloudfunctions.net/function-webhook",
"requestSize": "2410",
"status": 200,
"responseSize": "263",
"userAgent": "Google-Dialogflow",
"remoteIp": "8.34.210.1",
"serverIp": "216.239.36.1",
"latency": "0.166482342s",
"protocol": "HTTP/1.1"
},
"resource": {
"type": "cloud_run_revision",
"labels": {
"project_id": "PROJECT_ID",
"service_name": "function-webhook",
"location": "us-central1",
"revision_name": "function-webhook-00001-jiv",
"configuration_name": "function-webhook"
}
},
"timestamp": "2024-10-26T01:15:00.352197Z",
"severity": "INFO",
"labels": {
"instanceId": "004940b3b813af8a656c92aac1bd07ffad5165f1353e1e346b6161c14bcde225f68f4a88ceedc08aa9020f387b1b59471f73de45f2882a710ced37dea921f05ad962347690be",
"goog-managed-by": "cloudfunctions"
},
"logName": "projects/test-project-12837/logs/run.googleapis.com%2Frequests",
"trace": "projects/test-project-12837/traces/d1b54fbc8945dd59bdcaed37d7d5e185",
"receiveTimestamp": "2024-10-26T01:15:00.548931586Z",
"spanId": "604a07f7b33b18db",
"traceSampled": true
}