I have an action set up in Dialogflow using webhook pointing to local server using ngrok tunnel. When using Dialogflow's "Test now" feature the webhook is working, the request is being sent to webhook and response is being received, but when testing in Simulator it says "Action isn't responding right now". In ngrok logs I can see the request being made to the endpoint the same as when using "Test now".
In the Simulator's logs it's showing "MalformedResponse: Failed to parse Dialogflow response into AppResponse".
Here's the fulfillment response as seen from Dialogflow's diagnostic info:
{
"payload": {
"google": {
"expectUserResponse": false,
"richResponse": {
"items": {
"simpleResponse": {
"textToSpeech": "test",
"displayText": "test"
}
}
}
}
}
}
Found a solution in this comment https://stackoverflow.com/a/55238042/2197296,
Turns out the simpleResponse element inside the items array has to be wrapped up in another array, like this:
"webhookPayload": {
"google": {
"richResponse": {
"items": [
{
"simpleResponse": {
"displayText": "test",
"textToSpeech": "test"
}
}
]
},
"expectUserResponse": false
}
},
Related
I am trying to setup a bot using dialogflow/webhook. my webhook returns the response for basic text message along with contextoutputs(esp. I am interested in parameters passed from webhooks). This works. But when i use the Basic card response of V2 along with outputcontext, Actions-on-google simulator says, "My test app isn't responding right now. Try again soon." But this works, if i remove outputcontext from the response. Please help
Steps Worked:
1. DialogFlow Testing
Basic Message (FulfillmentText) and contextoutput works fine
Card and contextOutput - not working
Card and followupEvent - Works
2. Actions on Google
Basic Message (FulfillmentText) and contextoutput works fine
Card and contextOutput - not working
Card and followupEvent - not working
Attached the response
{
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "This is sample Response"
}
},
{
"basicCard": {
"title": "testbot",
"formattedText": "This is sample Response",
"image": {
"url": "example.com/image.png",
"accessibilityText": "samplebot"
},
"buttons": [
{
"title": "example",
"openUrlAction": {
"url": "http://example.com"
}
}
]
}
}
]
}
}
},
"outputContexts": [{
"name": "projects/<projectid>/agent/sessions/<sessionid>/contexts/<contextname>",
"lifespanCount": 1,
"parameters": {
"param1": "123",
"param2": "456"
}
}]
}```
I assume you've used the sample code in your action. However, unless you changed the url fields, your action can not find the imageUrl and openUrlAction.
If you change url fields with actual(not "http://example.com") links, your app will respond properly.
Also make sure you've added necessary classes.
e.g.
const { dialogflow, BasicCard, Image, Button } = require('actions-on-google');
This problem is arising when using events. Say, after a particular event 'A' occurs, intent 'X' is called. 'X' has fulfillment webhook which tries to render a SimpleResponse response and a BasicCard response. But, in the simulator, only the SimpleResponse can be seen and not the BasicCard. There are no errors reported in the simulator also. Below is the JSON response:
{
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Sample Text1"
}
},
{
"basicCard": {
"title": "Sample Text2 ",
"formattedText": " Sample Text3",
"image": {
"url": "Sample working URL1"
},
"buttons": [
{
"title": "Sample Text4",
"openUrlAction": {
"url": "Sample working URL2"
}
}
]
}
}
]
}
}
}
}
Now what is surprising, the same JSON response renders both SimpleResponse as well as BasicCard response when another intent 'Y' is called by one of its utterance. 'Y' is also linked to a webhook fulfillment.
Any reason why?
I built a bot using Dialogflow and connected it to a local webhook (now accessing it through ngrok). I am able to receive the response from Dialogflow but I am unable to replay to it. I followed the JSON structure as shown here - Test response from webhook. But I am getting the following error in Dialogflow.
Webhook call failed. Error: Failed to parse webhook JSON response:
Cannot find field: messages in message
google.cloud.dialogflow.v2.Intent.Message.
Following is the reply that I sent to Dialogflow -
{
"messages":[
{
"speech":"Text response",
"type":0
}
]
}
Please tell me what should be the exact format of the reply that I should send to Dialogflow.
From v1 to v2, the response object almost change completely. For just simple text, you can use like:
{
"fulfillmentText": "Text response",
"fulfillmentMessages": [
{
"text": {
"text": ["Text response"]
}
}
],
"source": "<Text response>"
}
I faced same issue,resolved using below json on dialogflow :
I made a simple node program which accepts a post response and returns json of the format accepted by Dialogflow.You may send your request in any way you like. check on Fulfillment status tab :
The field messageswas renamed/refactored to fulfillmentMessages - "can not find" means that it is not a property in the definition.
This is some comparable result accepted by v2:
{
"fulfillmentText": "response text",
"fulfillmentMessages": [{"simpleResponses": {"simpleResponses": [ {
"textToSpeech": "response text",
"displayText": "response text"
}]}}]
}
Messages alone is not sufficient. Refer to Dialogflow V2 webhook fulfillment documentation for complete list of parameters expected and format of JSON.
Are you sure you are using V2 of the DialogFlow APIs?
Use the Webhook Playground to Get the appropriate response for either the Dialogflow API or the Actions SDK which is depricated but still works. There is also the yet newer and different API for the Google Actions Builder/SDK framework as per :
DiaglowFlow JSON Response:
{
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Webhook worked.",
"displayText": "Webhook worked."
}
}
]
}
}
}
}
Actions SDK Response:
{
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Webhook worked.",
"displayText": "Webhook worked."
}
}
]
}
},
"possibleIntents": [
{
"intent": "actions.intent.TEXT"
}
]
}
]
}
Action Builder/SDK. Note that the session id needs to be returned.
{
"session": {
"id": "example_session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "Hello World.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
}
}
Just started with the DialogFlow building an app. I have hosted a service in Java on cloud (not using the firebase). Basically, I receive the data from the agent and send the response back as Json. For simple query its working as expected. Like if I say "My name is X", the service will respond as "Hello X" and it will be played on the Response. The JSON response is sent as
{speech: "Hello X", type:"0"}
Now, I want to fetch the user location, so I want to ask the user the permission to access the location. I have a separate intent that does not have any training_Phrases. It has an Event actions_intent_PERMISSION.
I am sending the following response
{
"conversationToken": "[\"_actions_on_google_\"]",
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [
{
"simpleResponse": {
"textToSpeech": "PLACEHOLDER_FOR_PERMISSION"
}
}
]
}
},
"possibleIntents": [
{
"intent": "actions.intent.PERMISSION",
"inputValueData": {
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "To locate you",
"permissions": [
"NAME"
]
}
}
],
"speechBiasingHints": [
"$geo_city",
"$event_category",
"$event_date"
]
}
],
"responseMetadata": {
"status": {},
"queryMatchInfo": {
"queryMatched": true,
"intent": "1ec64dc5-a6f4-44f6-8483-633b8638c729"
}
}
}
But I am getting the response as 400 Bad request. Is there anything that I am doing wrong here or am I missing any thing?
There are three issues.
The first is that the actions_intent_PERMISSION event is sent in response to a permission request. So this should not be the intent that triggers the request.
Second, you're asking for the users name, but not their location. You want either the DEVICE_COARSE_LOCATION or DEVICE_PRECISE_LOCATION.
The third, and much bigger, issue is that the JSON you're sending is the format used by the Action SDK. Since you're using Dialogflow, you'll be using a different response format which is the basic Dialogflow response, plus Actions on Google specific content in the data.google JSON property.
Your response should look something more like this:
{
"data": {
"google": {
"expectUserResponse": true,
"systemIntent": {
"intent": "actions.intent.PERMISSION",
"data": {
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "To locate you",
"permissions": [
"NAME",
"DEVICE_PRECISE_LOCATION"
]
}
}
}
}
}
Dialogflow also has some other examples of requests and replies that should help for the other parts of your conversation.
I'm seeing a strange behavior. I send a basic card with some information but regardless the expectUserResponse json flag, the conversation is not closed in Google Assistant. How come? Is it a bug? Can someone confirm?
JSON that is returned that contains the card:
{
"data": {
"google": {
"expectUserResponse": false,
"systemIntent": {
"intent": "actions.intent.TEXT"
},
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Some text",
"displayText": "Some text"
}
},
{
"basicCard": {
"title": "A title",
"formattedText": "A long text",
"buttons": [
{
"title": "Title button",
"openUrlAction": {
"url": "http://www.google.com"
}
}
]
}
}
]
}
}
}
}
(From https://plus.google.com/102582215848134314158/posts/PG3NbHG9dsr)
The problem is that you're specifying systemIntent. This indicates what system Intent should be used to handle the response.
But you don't want to handle a response, as you've tried to indicate with "expectUserResponse": false.
Given the conflicting information - it chooses to honor the systemIntent setting and waits for the response.
The solution is to remove the systemIntent section completely. In general, unless you're requesting permission or one of the other helper Intents, you can leave this section out anyway since you're using API.AI.