Dialogflow v2 error “MalformedResponse 'final_response' must be set” - python

I am getting this error only when using the simulator/google assistant. When I use the Slack integration or test within DialogFlow then it works perfectly.
I checked this question about settings in DialogFlow, but that wasn't my issue. I checked this question but because I use python in my webhook, I can't be sure whether that would solve it for me or not.
I am doing the following:
First, the user invokes any one of my intents which are connected through a webhook to my python code. Call this intent1.
Second, I check to see what the response (response1) would be for intent1 in my code.
Third, I send response1 to another intent intent2 via a followup-event event2.
The reason why I'm doing this just for interest is that I'm allowing multiple types of conversation flows. The first being FAQs and the second being a directed conversation.
The JSON I'm sending back is:
"followupEventInput":{
"name":"EventName",
"parameters":{
"speech": str(speech)
}
}
EventName is event2.
speech is response1
I also tried adding this to the JSON, but it didn't change anything:
,"payload": {"google":{"expectUserResponse": False}}
The Debug from the simulator shows:
{
"response": "",
"expectUserResponse": false,
"conversationToken": "GidzaW11bG...",
"audioResponse": "//NExAASWK...",
"debugInfo": {
"assistantToAgentDebug": {
"curlCommand": "curl -v 'https://api.api.ai/api/integrations/google?token=2b0fcc112a9b40c48f7a7182a29f6b2f' -H 'Content-Type: application/json;charset=UTF-8' -H 'Google-Actions-API-Version: 2' -H 'Authorization: eyJhbGciOiJSUzI1NiIsImtpZCI6IjQxMjlkYjJlYTE4NjBkMmU4NzFlZTQ4NTA2Mjg3ZmIwNWIwNGNhM2YifQ.eyJhdWQiOiJkbmFmaXQtZmFxIiwiZXhwIjoxNTMwODU5MzIzLCJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJqdGkiOiJiNDcwZjdhODYyYWJiMzI0NjRjNGY5MmU4MTQ1ZWU5NTFlYTA1MWY5IiwiaWF0IjoxNTMwODU5MjAzLCJuYmYiOjE1MzA4NTg5MDN9.XMAmItiH9SEo1I24T5xEPvSfP7dPX21AYHvVqZZReayNoR396ZQ1JdHZiY9rwGfp49qSwn2ea9EDkNVCQ-PK8NIKdTdxG-L0HuhY7r8nEMfzO4PjJKU6bI-Ry1OwL3A90WGK0l8rwJpByHSfA1gTsS7PU983yyR51PCJFkVnd2KQfX1ZKPIqpcEzKkCvexh9mwOx8cH6iVYuBzmHctH1FRLqhzzRb9zcx3Qq2mDFB8cVbl8SluXLyV4hBeKSeFe-HnkWEzqE3zvgIbAZha2rAOMb2xx1ta_M86hmwET4woAB-hBlR77cyNZV49Y5GmFrF5DozvQWEw1GNoRxcZCLhA' -A 'Mozilla/5.0 (compatible; Google-Cloud-Functions/2.1; +http://www.google.com/bot.html)' -X POST -d '{\"user\":{\"userId\":\"ABwppHEpW9IVOkzk8egeV0A0NHO5Ug4wqLj3ney3hdwx_iPW4cMeayYws8m-fzoFiYksk7JsnDmi-g\",\"locale\":\"en-US\",\"lastSeen\":\"2018-07-05T15:54:50Z\"},\"conversation\":{\"conversationId\":\"1530859188209\",\"type\":\"ACTIVE\",\"conversationToken\":\"[]\"},\"inputs\":[{\"intent\":\"actions.intent.TEXT\",\"rawInputs\":[{\"inputType\":\"KEYBOARD\",\"query\":\"what are the best recipes for oranges\"}],\"arguments\":[{\"name\":\"text\",\"rawText\":\"what are the best recipes for oranges\",\"textValue\":\"what are the best recipes for oranges\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.MEDIA_RESPONSE_AUDIO\"},{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]}],\"requestType\":\"SIMULATOR\"}'",
"assistantToAgentJson": "{\"user\":{\"userId\":\"ABwppHEpW9IVOkzk8egeV0A0NHO5Ug4wqLj3ney3hdwx_iPW4cMeayYws8m-fzoFiYksk7JsnDmi-g\",\"locale\":\"en-US\",\"lastSeen\":\"2018-07-05T15:54:50Z\"},\"conversation\":{\"conversationId\":\"1530859188209\",\"type\":\"ACTIVE\",\"conversationToken\":\"[]\"},\"inputs\":[{\"intent\":\"actions.intent.TEXT\",\"rawInputs\":[{\"inputType\":\"KEYBOARD\",\"query\":\"what are the best recipes for oranges\"}],\"arguments\":[{\"name\":\"text\",\"rawText\":\"what are the best recipes for oranges\",\"textValue\":\"what are the best recipes for oranges\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.MEDIA_RESPONSE_AUDIO\"},{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"}]}],\"requestType\":\"SIMULATOR\"}"
},
"agentToAssistantDebug": {
"agentToAssistantJson": "{\n \"responseMetadata\": {\n \"status\": {\n \"code\": 10,\n \"message\": \"Failed to parse Dialogflow response into AppResponse because of empty speech response\",\n \"details\": [{\n \"#type\": \"type.googleapis.com/google.protobuf.Value\",\n \"value\": \"{\\\"id\\\":\\\"63a2647e-43fc-4c36-9067-5c48b51626bb\\\",\\\"timestamp\\\":\\\"2018-07-06T06:40:04.014Z\\\",\\\"lang\\\":\\\"en-us\\\",\\\"result\\\":{},\\\"status\\\":{\\\"code\\\":200,\\\"errorType\\\":\\\"success\\\"},\\\"sessionId\\\":\\\"1530859188209\\\"}\"\n }]\n }\n }\n}"
},
"sharedDebugInfoList": [
{
"name": "ResponseValidation",
"debugInfo": "",
"subDebugEntryList": [
{
"name": "MalformedResponse",
"debugInfo": "'final_response' must be set.",
"subDebugEntryList": []
}
]
}
]
},
"visualResponse": {
"visualElementsList": [],
"suggestionsList": [],
"agentLogoUrl": ""
},
"clientError": 0,
"is3pResponse": 1
}

The value of the agentToAssistantJson field includes the message "Failed to parse Dialogflow response into AppResponse because of empty speech response". As it suggests, whatever you're sending in your response is missing speech information.
You don't specify what Event2 is doing, what it is sending back, or what it is doing with the parameter (if anything), but the likely issue is that it isn't sending back anything. Just including the speech as a parameter doesn't do anything - parameters are just information, not replies.
While there are some uses for followup events, most of the time they aren't what you really want. If you want to reply with a message from the fulfillment - just reply with the message.

Related

Why does executing a webhook via the discord API return a 404 error?

Whilst trying to execute a webhook, I've been getting 404 errors. The url I'm using is exactly what the Discord docs tell me to use: https://discord.com/api/v10/webhooks/{webhook.id}/{webhook.token}. However, I've been able to successfully create and delete webhooks. Finally, to test this error, I waited about a day after creation to see if it took some time for the url to work, but this also turned up a 404 error.
When creating a webhook, I use this method. Upon doing so, it returns json containing something like this:
{
"name": "test webhook",
"type": 1,
"channel_id": "199737254929760256",
"token": "3d89bb7572e0fb30d8128367b3b1b44fecd1726de135cbe28a41f8b2f777c372ba2939e72279b94526ff5d1bd4358d65cf11",
"avatar": null,
"guild_id": "199737254929760256",
"id": "223704706495545344",
"application_id": null,
"user": {
"username": "test",
"discriminator": "7479",
"id": "190320984123768832",
"avatar": "b004ec1740a63ca06ae2e14c5cee11f3",
"public_flags": 131328
}
}
I used this bit of documentation to attempt to execute the webhook to send a message but to no avail. I use a url that uses the id and token in the json of the webhook, so with the JSON above, the url would look like this: https://discord.com/api/v10/webhooks/223704706495545344/3d89bb7572e0fb30d8128367b3b1b44fecd1726de135cbe28a41f8b2f777c372ba2939e72279b94526ff5d1bd4358d65cf11. I have checked to make sure that the program is using the right URL, and it is. What am I doing wrong to get the 404 error?
Thanks in advance.
You are using the API correctly from what I can tell, it's likely something that goes wrong when executing the webhook.
You can verify this by sending a get GET request to your webhook URL (for example by opening it in your browser), and see what response you get.
For example, a successful call for this URL would look like this:
https://discord.com/api/v10/webhooks/730533481892106727/aPKOoEoamLq9pVnKHT3gF-whSrtrsnkWlOA3xPQPMNBsK5vhe9PC82-e7bu3BEFESQfaw
{
"type": 1,
"id": "730533481892106727",
"name": "Spidey Bot",
"avatar": null,
"channel_id": "501452852364050123",
"guild_id": "413797995205889283",
"application_id": null,
"token": "aPKOoEoamLq9pVnKHT3gF-whSrtrsnkWlOA3xPQPMNBsK5vhe9PC82-e7bu3BEFESQfaw"
}
It seems like missing a forward-slash / will result in a 404, so that might be your issue.

How to read chrome console using python without selenium?

I would like to read chrome's js console using Python3 without any webdriver such as selenium (bot detection and stuff).
I've tried Chrome DevTools Protocol python libraries such as chromewhip, pychrome and PyChromeDevTools, but I'm unable to read any data from the console.
I want to read Runtime.consoleAPICalled or Log.entryAdded, but I don't know how to implement these callbacks as the documentation for these libraries doesn't specify any of that. Also there are no examples to be found either.
Does anyone know how to properly access these events or some other library which provides it?
#kundapanda could you at least post a snippet of the code that worked for you.
I want to read Runtime.consoleAPICalled or Log.entryAdded, but I don't
know how to implement these callbacks
The following assumes (per your question phrasing) that you're able to send and receive debug protocol messages on the stream that's open to the web debugger endpoint.
After you send debug protocol messages Runtime.enable and Log.enable messages, the Runtime.consoleAPICalled and Log.entryAdded "events" you are looking for are represented by messages you receive on the same debugging channel.
You may need to match the console event messages with the execution context (seen in the Runtime.enable response) by examining the executionContextId field in the received event messages. The log events are not associated with any single execution context. All of these "event" messages will have Id=0, which helps to recognize they're "event" messages and not response messages.
Here are a couple of sample messages received from Chrome (formatted as JSON with arbitrary field order):
Console API event message:
{
"method": "Runtime.consoleAPICalled",
"params":
{
"type": "warning",
"args": [
{ "type": "string",
"value": "Google Maps JavaScript API warning: NoApiKeys https://developers.google.com/maps/documentation/javascript/error-messages#no-api-keys"
}],
"executionContextId": 1,
"timestamp": 1618949706735.553,
"stackTrace":
{
"callFrames": [
{
"functionName": "TA.j",
"scriptId": "206",
"url": "https://maps.googleapis.com/maps-api-v3/api/js/44/10/util.js",
"lineNumber": 228,
"columnNumber": 26
} ]
}
}
},
"id": 0
}
Log event message:
{
"method":"Log.entryAdded",
"params":
{
"entry":
{
"source":"javascript",
"level":"warning",
"text":"The deviceorientation events are blocked by permissions policy. See https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md#sensor-features",
"timestamp":1.6189509536801208e+12
}
},
"id": 0
}

python google geolocation api using wifi mac

I'm trying to use Google's API for geolocation giving wifi data to determine location. This is their intro. And this is my code
#author: Keith
"""
import requests
payload = {
"considerIp": "false",
"wifiAccessPoints": [
{
"macAddress": "00:25:9c:cf:1c:ac",
"signalStrength": -43,
"signalToNoiseRatio": 0
},
{
"macAddress": "00:25:9c:cf:1c:ad",
"signalStrength": -55,
"signalToNoiseRatio": 0
}
],
'key':'<MyAPIKey>'
}
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate',
params=payload)
print(r.text)
This is the output
{
"location": {
"lat": 32.3643098,
"lng": -88.703656
},
"accuracy": 6061.0
}
The request ignored all of the payload except the key portion and just found the geolocation using my IP address. So I'm sending the json payload incorrectly. I know this is probably really simple, but I'm stuck and couldn't find an example of python being used with requests to do this type of API query. Thanks
Edit:
Picked up the cURL library and executed this command with success:
curl -d #your_filename.json -H "Content-Type: application/json" -i "https://www.googleapis.com/geolocation/v1/geolocate?key=<myapikey>"
and got the output I expected. I just want to be able to do the same thing in requests, but the data I'm trying to send is in "your_filename.json".
Please try the following:
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate?key='+ '<MyAPIKey>', json=payload)
Note the key was moved to query params (URL) and json argument was used in place of params.
Okay I figured out the error of my ways. Taking a better look at requests.post function, I see that I'm not using the parameters argument correctly. After this, it worked perfectly,
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate', params=parameters, json=mydata, headers=headers)

Python - Send a list intro Slack message formatting in Python

So I have been playing around with python and Discord's webhook with Slacks message formatting which can be found here: Slack message formatting
However what I am trying to do is to have a multiply URL that can be sent to slack similar like:
and now when I have added all my URL to a list and trying to apply it to the formatting etc:
{
"username": "Google website",
"attachments": [
{
"author_name": "Google",
"color": "#00ff00",
"text": "^Press the link above!",
"title": "www.google.se",
"title_link": URLLIST
}
]
}
It tells me that "Must be str, not a list"
And I have been stuck on this since there is not pretty good documentation about this, Anyone that could know how to do this?
I am guessing you are getting the error, because your URLLIST is not a string.
Here are two solution that will work:
Either you do multiple attachments, where every attachment is one link. Then title_link must be a URL string, not a list.
Example:
{
"attachments": [
{
"fallback": "Required plain-text summary of the attachment.",
"title": "Slack API Documentation",
"title_link": "https://api.slack.com/"
},
{
"fallback": "Required plain-text summary of the attachment.",
"title": "Slack API Documentation",
"title_link": "https://api.slack.com/"
},
{
"fallback": "Required plain-text summary of the attachment.",
"title": "Slack API Documentation",
"title_link": "https://api.slack.com/"
}
]
}
Message Builder Example
Or you just explode your URL list into a text string (which I would do). Then you do not even need attachments.
Example:
{
"text": "<https://www.google.com|8>\n<https://www.google.com|9>\n<https://www.google.com|10>\n"
}
Message Builder Example

How to fetch CloudFlare API dictionary in Paython

I was browsing around for 1 day already, but I was not able to find how to fetch CloudFlare API responses in Python.
Usually the communication between the host and the CloudFlare's servers is established using cURL:
curl -k -s "https://api.cloudflare.com/host-gw.html" -d 'act=user_lookup' -d 'host_key=8ayf9yaoh2h8faosh2o8dhas' -d 'cloudflare_email=admin#tech-world.info' | python -mjson.tool
So this is the cURL request, which returns the following dictionary:
{
"msg": null,
"request": {
"act": "user_lookup",
"cloudflare_email": "admin#tech-world.info"
},
"response": {
"cloudflare_email": "admin#tech-world.info",
"hosted_zones": [
"tech-world.info"
],
"unique_id": "78yastaig238w9ayfhao8h28hdas",
"user_api_key": "ga7srgfr2i7dfagsd2r89hasd",
"user_authed": true,
"user_exists": true,
"user_key": "d8ha92hiuhda7892houkljhadskju"
},
"result": "success"
}
So I am trying to execute the cURL command from python in order to get the dictionary output (this is just placeholder cURL execution exapmle):
import subprocess
my_var = subprocess.call(["curl", "-X", "GET", "-I", "http://www.tech-world.com"])
But the call() method prints the data it receives, but I want to assign the dict to variable for later use.
I have checked the urllib2, but I did not find a way to use it to accomplish my goals.
Why do you use cURL instead of normal Python HTTP library (such as Requests)?
r = requests.post('https://api.cloudflare.com/host-gw.html', data={'host_key': '8ayf9yaoh2h8faosh2o8dhas', 'cloudflare_email': 'admin#tech-world.info', 'act': 'user_lookup'})
Also there is a library named pyflare for working with CloudFlare using Python.
(it's the first text that I post for urgent warning)
I can't comment (too low reputation), but I can't to not alert that's you have opened your credentials from production server.

Categories