This guide provides various samples for implementing webhooks as well as webhook troubleshooting recommendations.
Set a session parameter
The following samples show how to set a session parameter.
Go
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
See the Webhooks quick start.Java
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Node.js
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Python
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Return a fulfillment response
The following samples show how to return a fulfillment response.
Go
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
See the Webhooks quick start.Java
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Node.js
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Python
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Set form parameters as required
The following samples show how to flag a parameter as required.
Java
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Node.js
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Validate a form parameter
The following samples show how to validate a form parameter.
Java
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Node.js
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Python
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Log session ID
The following sample shows how to log the session ID
from a webhook request.
Python
To authenticate to Dialogflow, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Troubleshooting
Life of a webhook call
Webhook calls are always initiated by Conversational Agents (Dialogflow CX) and go to a web server through HTTPS. Generic web service webhooks calls originate from an Internet IP address that belongs to Google and can reach web servers (webhook servers) that are available in the public Internet. On the other hand, Service Directory webhooks always start from an internal Google Cloud address and can only reach webhook servers in private networks within Google Cloud.
Useful logs for debugging webhooks
Debugging webhook issues usually involves gathering the Cloud Logging Dialogflow logs and the webhook server logs. If the webhook server is implemented using Cloud Run functions, its logs would be in Cloud Logging. Otherwise, the logs would typically reside where the webhook server runs.
Standard webhook logs contain a detectIntentResponseId
field with a UUID which can be
useful to trace a particular call in webhook servers. This log exists in
the Dialogflow Cloud Logging logs when
Cloud logging is enabled.
Common webhook issues
Some errors that can be found in the Dialogflow logs for webhooks calls are:
Webhook server hostname resolution error
Dialogflow looked up the hostname of a Generic webhook and
the hostname does not exist in the DNS. Make sure the hostname is registered
in the public DNS. If the hostname is new, it might take some time for the
record to propagate. Cloud Logging message:
State: URL_ERROR, Reason: ERROR_DNS
.
Webhook server returns a client-side error
Apart from ERROR_DNS
this state indicates a 4xx response from the webhook
server. This can be an unauthorized status (401 - ERROR_AUTHENTICATION
)
or that the URL was not found in the webhook server (404 - ERROR_NOT_FOUND
).
Cloud Logging message: State: URL_ERROR
.
Dialogflow agent times out before the webhook server returns a response
Dialogflow reached the webhook timeout limit before the web server
finished. The two possible approaches here are reducing the webhook server
processing time or increasing the time Dialogflow waits for the
webhook. Reducing the processing time usually brings best results although
it is non-trivial in many cases. Consider that there is maximum time out limit
for webhooks and that end callers or users would need to wait for longer to get
an answer from the agent before increasing this setting. Cloud Logging
message: State: URL_TIMEOUT, Reason: TIMEOUT_WEB
.
gRPC times out before the webhook server returns a response
The time limit set by gRPC in the Dialogflow API call was reached
before the webhook call finished. This limit is set usually at the integration
level and is independent of the Dialogflow parameters and webhook
timeout limits. For more information on gRPC deadlines see
https://grpc.io/docs/guides/deadlines/.
Cloud Logging
message: State: URL_REJECTED, Reason: REJECTED_DEADLINE_EXCEEDED
.
Dialogflow couldn't contact the webhook server
The webhook server couldn't be reached because of
a network error or the connection was established and the webhook server
returned HTTP status 5xx indicating an issue while it was processing the
request. Make sure Dialogflow can reach the webhook server address
at the networking level. If the request appears in the webhook server logs,
find why the call returned a 5xx error. Cloud Logging message:
State: URL_UNREACHABLE
.
Tracing webhook calls
A standard webhook call can be correlated between the Dialogflow and
a webhook server using the session ID, detectIntentResponse
ID, the trace ID
for Cloud Run functions and a timestamp of the call. Flexible webhook
tracing can be done using the timestamp of the call and the session parameter
values specified in the webhook definition at design time. For more information
on standard and flexible webhooks requests, see
Webhooks.
The session ID appears in the sessionInfo.session
field of the
WebhookRequest.
This session ID should be unique for each conversation,
and it can help you compare agent logs against webhook logs
for requests using the same session ID.
The previous Log session ID section
shows how to log the session ID from a webhook.
In addition, if you are hosting your webhook on
Cloud Run functions
or a similar Google Cloud serverless option,
you can use the trace
field from
log entries
as a log filter.
A single execution of a function results in multiple log entries
with the same trace value.
The next example uses both the session ID and the trace value to associate a particular Dialogflow agent error log with the corresponding Cloud Run functions webhook log entries. The example uses Cloud Logging Filters for an agent that has enabled Cloud Logging.
1. Filter Dialogflow logs for a particular agent's error logs
Use the following Cloud Logging filter to filter your Dialogflow logs for a particular agent's error logs:
labels.location_id="global"
labels.agent_id="AGENT_ID"
severity=ERROR
A webhook log error entry looks like the following:
{
"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"
}
Note the labels.session_id
field which contains the session ID.
You will use the session ID in the next step.
2. Filter Cloud Run functions logs by session ID
Use the following Cloud Logging filter to filter your Cloud Run functions logs by session ID:
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"
The resulting logs correspond to webhook logs made during the provided session. For example:
{
"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"
}
Note the trace
field which is used in the next step.
3. Filter Cloud Function logs for a particular trace
Use the following Cloud Logging filter to filter Cloud Function logs for a particular trace:
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"
where TRACE_ID
is the last segment of trace. For example the TRACE_ID
for projects/PROJECT_ID/traces/e41eefc1fac48665b442bfa400cc2f5e
is
e41eefc1fac48665b442bfa400cc2f5e
.
The result is the webhook server log generated during the execution of the webhook request associated with the session ID from step 1 and with the trace from step 2. The log would look like the following.
{
"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
}