Dialogflow

connect a call to a [Google Dialogflow](https://cloud.google.com/dialogflow) bot.

The dialogflow verb streams the caller’s audio to a Google Dialogflow agent and plays the agent’s spoken replies back to the caller. Three agent types are supported, selected by the model parameter:

modelProductBuilt inNotes
es (default)Dialogflow ESDialogflow ES consoleLegacy intent-based agents; one agent per GCP project
cxDialogflow CXConversational Agents consoleFlow-based and generative Playbook agents. Supports client-side tool calls
cesCX Agent Studio”Go to CX Agent Studio” in the consoleA newer, separate product with its own API

Agents built in the Conversational Agents console (Google markets it under the “Customer Engagement Suite” umbrella) speak the CX API — use model: "cx" for them, not ces.

Examples

Connecting to a Dialogflow ES agent:

1{
2 "verb": "dialogflow",
3 "project": "my-gcp-project",
4 "lang": "en-US",
5 "credentials": "{\"type\":\"service_account\",\"project_id\":\"my-gcp-project\",\"private_key\":\"-----BEGIN PRIVATE KEY-----\\n...\"}",
6 "welcomeEvent": "welcome",
7 "eventHook": "/dialogflow-event",
8 "actionHook": "/dialogflow-action"
9}

Connecting to a Dialogflow CX (Playbook) agent with client-side tools:

1{
2 "verb": "dialogflow",
3 "model": "cx",
4 "project": "my-gcp-project",
5 "agent": "99e7b4c8-259c-4de4-b9da-cb44dc42b792",
6 "region": "us-central1",
7 "lang": "en-US",
8 "credentials": "{\"type\":\"service_account\",\"project_id\":\"my-gcp-project\",\"private_key\":\"-----BEGIN PRIVATE KEY-----\\n...\"}",
9 "events": ["intent", "transcription", "tool-calls", "start-play", "stop-play"],
10 "eventHook": "/dialogflow-event",
11 "toolHook": "/dialogflow-tool",
12 "actionHook": "/dialogflow-action"
13}

The agent value is the uuid from the agent’s resource name (projects/my-gcp-project/locations/us-central1/agents/99e7b4c8-...), shown in the Conversational Agents console URL.

Parameters

credentials
stringRequired

The service account key in JSON string form (i.e. JSON.stringify the key file’s contents). The service account needs the Dialogflow API Client role (roles/dialogflow.client).

lang
stringRequired

Language for speech recognition, e.g. en-US.

project
stringRequired

The GCP project ID hosting the agent, e.g. my-gcp-project.

actionHook
string

A webhook invoked when the operation completes.
See below for specified request parameters.

agent
string

The Dialogflow agent ID (uuid), e.g. 99e7b4c8-259c-4de4-b9da-cb44dc42b792. Required when model is cx or ces.

bargein
boolean

If true, kill playback immediately when the user begins speaking.

environment
string

The Dialogflow CX environment to use, e.g. production. Omit to use the draft environment.

eventHook
string

A webhook to invoke when a Dialogflow event occurs, such as an intent being detected or a speech transcription being returned.
The response to the event hook may contain a new Jambonz application to execute.

events
array

Which event types to receive on the eventHook, e.g. ["intent", "transcription", "tool-calls"]. Defaults to all supported events for the selected model. See the event list.

model
string

The agent type: es (default) | cx | ces. See the table above.

noInputEvent
string

Name of the Dialogflow event to send in query when no input timeout expires. Default: actions_intent_NO_INPUT.

noInputTimeout
number

Number of seconds of no speech detected after which to reprompt. Default: 20.

passDtmfAsTextInput
boolean

If true, pass user DTMF entries as text inputs to the Dialogflow bot.

region
string

The GCP region hosting the agent, e.g. us-central1 (the default for CX/CES). The matching regional API endpoint (us-central1-dialogflow.googleapis.com) is used automatically — a CX agent created in a region is not reachable via the global endpoint.

thinkingMusic
string

A URL to a .wav or .mp3 file to play as filler music while the Dialogflow back-end is executing.

toolHook
string

A webhook invoked when a Dialogflow CX agent requests a client-side tool call, e.g. /dialogflow-tool. Respond with the tool result to resume the conversation. See Client-side tool calls.

tts
object

If provided, audio prompts will be played using text-to-speech rather than the Dialogflow-provided audio clips.

tts.gender
string

(Google only) MALE, FEMALE, or NEUTRAL.

tts.language
stringRequired

Language code to use.

tts.vendor
string

Speech vendor to use: Google, AWS (alias: Polly), or default (for application default).

tts.voice
string

Voice to use. Note that the voice list differs depending on whether you are using AWS or Google. Defaults to application setting, if provided.

welcomeEvent
string

An event to send to Dialogflow when first connecting; e.g., to trigger a welcome prompt. The agent must define a handler for this event — Playbook agents typically do not (sending one returns a Google “No handler is defined for the event” error); they respond to the caller’s first spoken turn instead.

welcomeEventParams
object

An object containing parameters to send with the welcome event, e.g. {"customer_tier": "gold"}.

actionHook properties

The actionHook webhook will contain the following additional parameters:

  • dialogflowResult: the completion reason:
    • redirect - a new application was returned from an event webhook
    • completed - an intent with end interaction set to true was received from dialogflow
    • caller hungup - the caller hung up

eventHook properties

The eventHook webhook contains two parameters: event (the event name) and data (the event payload). Supported events:

  • intent: dialogflow detected an intent
  • transcription: a speech transcription was returned from dialogflow
  • dtmf: a dtmf key was pressed by the caller
  • start-play: an audio segment returned from dialogflow started to play
  • stop-play: an audio segment returned from dialogflow completed playing
  • no-input: the no input timer elapsed with no input detected from the caller
  • tool-calls: the agent requested one or more client-side tool calls (CX/CES; informational — use toolHook to answer them)

A transcription event (CX):

1{
2 "event": "transcription",
3 "data": {
4 "recognition_result": {
5 "message_type": "TRANSCRIPT",
6 "transcript": "hi, I need a flight",
7 "is_final": true,
8 "confidence": 0.98,
9 "language_code": "en-us"
10 }
11 }
12}

A start-play event (the path is the agent audio jambonz is playing):

1{
2 "event": "start-play",
3 "data": {"path": "/tmp/4f3a2b1c-..._3.wav"}
4}

Please refer to this tutorial for a detailed example.

Client-side tool calls (Dialogflow CX)

Dialogflow CX agents (including generative Playbook agents) can define client-side Function tools — tools with no server backend, where your application executes the action and returns the result. When the agent needs one, it stops speaking and waits. jambonz handles the round trip through the toolHook.

A tool’s description must not be empty in the Dialogflow console. Dialogflow passes the description to the model as that action’s documentation — with no description the tool is never offered to the model, and the agent silently escalates instead of calling it.

1. The agent requests a tool. jambonz POSTs to your toolHook:

1{
2 "event": "tool-call",
3 "tool_call": {
4 "tool": "projects/my-gcp-project/locations/us-central1/agents/99e7b4c8-.../tools/4f58a625-...",
5 "action": "getGeolocation",
6 "input_parameters": {}
7 },
8 "call_sid": "df01a-...",
9 "direction": "inbound",
10 "from": "+15083084809",
11 "to": "+15082084810"
12}

input_parameters carries the arguments the agent gathered from the conversation. For example, a flight-search tool called after the caller has given a destination and date arrives populated:

1{
2 "event": "tool-call",
3 "tool_call": {
4 "tool": "projects/.../tools/e85ff4ee-...",
5 "action": "getFlights",
6 "input_parameters": {
7 "origin_airport_code": "JFK",
8 "destination_airport_code": "CDG",
9 "destination_city_name": "Paris",
10 "travel_date": "2026-12-05",
11 "timezone_difference_minutes": 360,
12 "flight_duration_minutes": 450
13 }
14 }
15}

2. Your application executes the tool and responds to the webhook with the result — a raw JSON object, not a list of verbs:

1{
2 "outputParameters": {
3 "flights": [
4 {"flight_number": "CA101", "origin": "JFK", "destination": "CDG",
5 "departure_time": "08:30", "arrival_time": "21:45", "price_usd": 640},
6 {"flight_number": "CA205", "origin": "JFK", "destination": "CDG",
7 "departure_time": "17:10", "arrival_time": "06:25", "price_usd": 545}
8 ]
9 }
10}

or, to report a failure so the agent can react gracefully:

1{"error": "flight search service unavailable"}

3. jambonz returns the result to Dialogflow and the agent resumes speaking — e.g. “I have two flights for you: flight CA101 leaves JFK at 8:30… which of these flights would you like to book?”

A complete toolHook handler:

1app.post('/dialogflow-tool', (req, res) => {
2 const {tool_call} = req.body;
3 switch (tool_call.action) {
4 case 'getGeolocation':
5 // no input_parameters: return the caller's location
6 return res.json({
7 outputParameters: {city: 'New York', country_code: 'us', postcode: '10001'}
8 });
9 case 'getFlights': {
10 const {origin_airport_code, destination_airport_code, travel_date} = tool_call.input_parameters;
11 const flights = searchFlights(origin_airport_code, destination_airport_code, travel_date);
12 return res.json({outputParameters: {flights}});
13 }
14 default:
15 return res.json({error: `no handler for tool '${tool_call.action}'`});
16 }
17});

Notes:

  • A reliable sign a tool call is pending: an intent event arrives with a tool_call response message and no audio is played — the agent produced no speech because it is waiting on you.
  • Without a toolHook, tool calls are surfaced via the tool-calls event only (informational) and the conversation waits for caller input.
  • Timing measured on a live agent: caller stops speaking → tool call ≈ 2-3s; tool result → agent resumes speaking ≈ 2-4s.

call transfer in Dialogflow

Call transfer from a dialogflow bot is achieved by responding to an eventHook with event intent by returning a new jambonz application containing a dial verb. Of course, this should only be done if the intent is signaling a request for a call transfer.

Indicating a desire to transfer the call to a live agent can be done in a couple of different ways in the dialogflow editor:

  1. By adding a Dialogflow Phone Gateway Response to the intent, with a Transfer Call action.
  2. By adding a custom payload in a response to the intent, with arbitrary JSON content that you define and which should include the telephone number (or registered user, or sip endpoint) to transfer to.

Note: option 1 only works when transferring to a US number, because the dialogflow editor only accepts US destinations. To transfer to non-US destinations, use option 2.

In either case, your application is responsible for having an eventHook that parses the intent (found in the data property of the webhook content) in order to check if call transfer is being requested, and if so responding with a new jambonz application.

For instance, when the Dialogflow Phone Gateway Response is used (option 1 above), the code snippet below shows where to find the transfer number in the intent data provided in the eventHook.

1const evt = req.body;
2if (evt.event === 'intent') {
3 const qo = evt.data.query_result;
4 const transfer = qo.fulfillment_messages.find((fm) => {
5 return fm.platform === 'TELEPHONY' && fm.telephony_transfer_call;
6 });
7 if (transfer) {
8 // a transfer has been requested
9 // transfer.telephony_transfer_call.phone_number has the phone number to transfer to
10 }
11}