Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Dialogflow CX Flexible Webhook Receiving Null JSON Instead of Request Data

I'm having an issue with Dialogflow CX flexible webhooks where everything appears to be configured correctly, but my webhook receives null JSON instead of the actual request data.

My Dialogflow CX agent successfully calls my Cloud Function webhook, but when I check the function logs, I see:

=== WEBHOOK CALLED ===
Method: POST
Request JSON: null

Instead of getting the expected payload with text, sessionInfo, fulfillmentInfo, etc., I'm getting nothing.

My Setup

I'm running this in australia-southeast1 with a Python Cloud Function. The webhook is configured as a flexible webhook with this request body:

{
  "text": "$request.text",
  "sessionInfo": "$request.sessionInfo", 
  "fulfillmentInfo": "$request.fulfillmentInfo",
  "pageInfo": "$request.pageInfo",
  "languageCode": "$request.languageCode",
  "intent": "$request.intent"
}

What I've Tried

Authentication: Added the Cloud Functions invoker role for allUsers - the webhook gets called successfully now.

Webhook URL: When I test the exact same endpoint with curl using a Dialogflow-formatted payload, it works perfectly and returns the expected response.

Intent Recognition: The intent matches with 100% confidence and triggers the correct route.

Route Configuration: My custom route is positioned first, webhook is enabled and selected correctly.

Agent Publishing: Made sure all changes are published and live.

Fresh Start: Even created a completely new agent and got the same result.

The Dialogflow execution logs show the webhook call was successful:

  • Status: OK

  • Latency: around 200ms

  • Function executed properly

But in the diagnostic info, I see "webhookPayloads": [{}] which suggests Dialogflow is sending an empty payload.

Direct Testing Works

When I curl the webhook directly with this payload:

curl -X POST [my-function-url] \
  -H "Content-Type: application/json" \
  -H "User-Agent: Google-Dialogflow" \
  -d '{"text": "Help me", "sessionInfo": {"session": "test"}}'

It works perfectly and returns the proper fulfillmentResponse.

My Question

Has anyone seen this before? Is there something I'm missing in the flexible webhook configuration? I'm wondering if this could be a regional issue with australia-southeast1 or if there's some step I'm overlooking.

 

Solved Solved
0 1 247
1 ACCEPTED SOLUTION

Hi @mitbo,

Welcome to Google Cloud Community!

The issue is that the $request.* syntax you're using in your flexible webhook body is not how you access these top-level structures when defining a flexible webhook. Instead, you need to use the system functions available for flexible webhooks.

The $request object as a whole (like in $request.text or $request.sessionInfo) isn't directly available in the way you're trying to use it for constructing the flexible payload. Dialogflow's diagnostic info showing "webhookPayloads": [{}] confirms that Dialogflow itself is sending an empty JSON object because it couldn't resolve the $request.* references into actual values when building the custom payload.

When you use $request.text, Dialogflow is looking for a system function or parameter named request and then trying to access a property text on it. In the context of defining a flexible webhook body, this $request object (as you'd see it in a standard webhook payload) is not directly exposed for deconstruction in this manner. Instead, you use dedicated system functions like $session, $page, $intent, $fulfillment, and more specific ones like $detectIntentResponse.queryResult.text.

The variables $session, $intent, $page, and $fulfillment will expand into their respective JSON objects. For specific primitive values like the query text or language code, you use the more detailed paths like $detectIntentResponse.queryResult.text.

Was this helpful? If so, please accept this answer as “Solution”. If you need additional assistance, reply here within 2 business days and I’ll be happy to help.

View solution in original post

1 REPLY 1

Hi @mitbo,

Welcome to Google Cloud Community!

The issue is that the $request.* syntax you're using in your flexible webhook body is not how you access these top-level structures when defining a flexible webhook. Instead, you need to use the system functions available for flexible webhooks.

The $request object as a whole (like in $request.text or $request.sessionInfo) isn't directly available in the way you're trying to use it for constructing the flexible payload. Dialogflow's diagnostic info showing "webhookPayloads": [{}] confirms that Dialogflow itself is sending an empty JSON object because it couldn't resolve the $request.* references into actual values when building the custom payload.

When you use $request.text, Dialogflow is looking for a system function or parameter named request and then trying to access a property text on it. In the context of defining a flexible webhook body, this $request object (as you'd see it in a standard webhook payload) is not directly exposed for deconstruction in this manner. Instead, you use dedicated system functions like $session, $page, $intent, $fulfillment, and more specific ones like $detectIntentResponse.queryResult.text.

The variables $session, $intent, $page, and $fulfillment will expand into their respective JSON objects. For specific primitive values like the query text or language code, you use the more detailed paths like $detectIntentResponse.queryResult.text.

Was this helpful? If so, please accept this answer as “Solution”. If you need additional assistance, reply here within 2 business days and I’ll be happy to help.