This is another question which came to me from a client, and I think the answer might be helpful for a lot of folks.
Here is the challenge: You want to use the text response you write in your Dialogflow console to be available to the webhook code.
Here are three reasons for doing this (there may be others too):
- maintain the WYSIWYG (what you see is what you get) for your copy editors, who are usually not programmers. They write the copy inside the Dialogflow console, and you just use it from your webhook code
- implement some kind of templating system where you write the copy in the text response and populate the dynamic stuff in the webhook
- let the copy editors choose the error messages which should be displayed if the webhook cannot do its job
What is sent to the webhook
Before we can discuss how to use the copy from the Dialogflow console from inside your webhook, you should first understand exactly what is sent to the webhook.
In Dialogflow, at the end of each intent you will notice that you can add responses.
Now, these responses can be a combination of the following:
- zero or more "Text Response" blocks - and each block may have multiple individual response, plus
- zero or more "Custom Payload" blocks
For example, the image below shows a Response section of an intent which has two Text Response blocks and one Custom Payload block. The first Text Response block has 2 individual responses, while the second Text Response block has 3 individual responses.
So what is sent to the webhook?
Here is what Dialogflow does:
- it chooses a random individual response from the first Text Response block
- then it chooses a random individual response from the second Text Response block
- after that, it sends the complete response in the first (and only) Custom payload block
- if there were more custom payload blocks, everything in those payload blocks will also be sent to the webhook
How does the webhook receive this data?
In other words, a big clump of JSON heads towards the webhook each time a webhook is invoked. In that JSON, how can we find what is coming from the Response section?
The image below shows the complete JSON coming in to the webhook:
Notice the following:
- there is a section called fulfillment in the JSON received by the webook
- the fulfillment object has a field called speech - which randomly selects an individual response amongst the 5 possible responses (2 from Text Response block 1 and 3 from Text Response block 2)
- the fulfillment object also has a JSON array called messages
- messages array has one individual response chosen at random from each of the three response blocks
- the block corresponding to the randomly chosen messages are in the same order as in the console
- complete payload is sent from the custom payload block
If the webhook is invoked a second time after a few minutes, this is the JSON which is sent over:
Notice the following:
- the "speech" field has changed value
- the randomly selected individual responses from Text Response block 1 and Text Response block 2 have changed
How to use this from the webhook
Now that you know the pattern of the JSON coming in to the webhook, you should be able to use this in your webhook code.
For example, if I were using the inline editor to write some NodeJS code, I will simply call the request.body.result.fulfillment object and inspect the messages inside.
Now with this in mind, let us revisit the three reasons we wanted to implement this.
WYSIWYG for your copy editors
Have your copy editors write down the responses in the Dialogflow console. In this case, you will use the default speech received by your webhook inside the fulfillment object and simply set it as the speech field coming back in the response JSON.
A good use case for this approach is the following: you have collected some data from the user successfully. After the webhook saves the data, you want to display some appropriate message to the user. Note that in this case, the response coming back from the webhook can use the copy from the console without any modifications.
Another possibility is to use a templating language inside your console, such as the Liquid templates that Shopify uses.
The copy editors will specify the template, and the webhook might fetch the values from a data store and populate the fields in the template.
Suppose your webhook does a lookup of a product code and finds that the code is invalid. Or perhaps the product is not in stock. At the same time, you might also have specified a template for the response (as described in the previous section) if the product was found.
Here we have a situation where we might choose to use the first Text Response block for the success case, and a second Text Response block to write out the error message. If the product lookup code fails to fetch the product, it will look at the response in the second element of the messages array and use it to show an appropriate failure message.
Update for API v2 (added June 2018)
In response to the question left in the comments section: the basic ideas discussed in this article still hold for API v2. The main difference is the structure of the JSON sent to the webhook.
Here are some tips to adapt this article to API v2:
- Read up on the v1 to v2 API migration guide.
- Understand the structure of the new JSON sent over to the webhook.
- The field in the JSON which you read from has changed from "result" to "queryResult"
- The field in the JSON you write to has also changed. Where you used the fields "speech" and "displayText" before, you now use the field "fulfillmentText" in your response JSON.
- If you need a specific example, I also have added a mini-course written in Python where I have migrated my tutorial code from v1 API to v2 API.
How do you tackle this challenge? Let me know in the comments below.