buttons from webhook dialogflow cx - python

I have a diaglogflow cx assistant and I have my own web front. I am getting the responses from a webhook and there is no problem with texts but I would like to add buttons, cards, images... that, although they cannot be seen in dialogflow cx, I can use the info in my front.
The problem is that dialogflow cx does not resend it in the response to the front that call it. I'm sending this response from the webhook server:
{
"fulfillment_response": {
"messages": [
{
"text": {
"text": [
"webhooktext"
]}}],
"richContent": [[
{
"type": "buttons",
"options": [
{
"text": "button 1"
},
{
"text": "button 2"
}]}]]}}
And I am receiving this in the front app:
"responseId": "fc385ea7-6f8c-4828-9e25-5196916c4028",
"queryResult": {
"text": "hey",
"languageCode": "es",
"responseMessages": [
{
"text": {
"text": [
"dialogflow text"
]
}
},
{
"payload": {
"kbID": "greeting"
}
},
{
"text": {
"text": [
"webhooktext"
]
}
}
],
"webhookPayloads": [
{}
],
"currentPage": {...},
"intent": {...},
"intentDetectionConfidence": 1.0,
"diagnosticInfo": {...},
"webhookStatuses": [...],
"match": {...}
},
"responseType": "FINAL"
}
I was expecting to receive the button data in the responseMessages array or even in webhookPayloads. I have tried to manage the webhook response structure but sometimes it gives an error message in the front dictionary and other times it shows as above.
Should I change richContext key? Where do I place it?

Text along with images and other components can be parsed in Dialogflow CX. You can refer to this documentation for response texts and parse them on your side as per your requirement. For adding visual elements , you can refer to this link.
The most common way to achieve this in Python is to use pf.json_format.MessageToJson method according to this StackOverflow case.

Related

Access to intent slots from lambda function

I created a simple bot with a simple lex intent. This lex intent has one single slot slotTwo.
Then I linked it with a python lambda function. I want to access to the value of that slot from inside the lambda function.
python lambda function receives the parameters context and event. The link below shows the structure for the parameter event.
https://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html
I copy it here too:
{
"currentIntent": {
"name": "intent-name",
"slots": {
"slot name": "value",
"slot name": "value"
},
"slotDetails": {
"slot name": {
"resolutions" : [
{ "value": "resolved value" },
{ "value": "resolved value" }
],
"originalValue": "original text"
},
"slot name": {
"resolutions" : [
{ "value": "resolved value" },
{ "value": "resolved value" }
],
"originalValue": "original text"
}
},
"confirmationStatus": "None, Confirmed, or Denied (intent confirmation, if configured)"
},
"bot": {
"name": "bot name",
"alias": "bot alias",
"version": "bot version"
},
"userId": "User ID specified in the POST request to Amazon Lex.",
"inputTranscript": "Text used to process the request",
"invocationSource": "FulfillmentCodeHook or DialogCodeHook",
"outputDialogMode": "Text or Voice, based on ContentType request header in runtime API request",
"messageVersion": "1.0",
"sessionAttributes": {
"key": "value",
"key": "value"
},
"requestAttributes": {
"key": "value",
"key": "value"
}
}
However, when I print out the content of this parameter I see only the slot and I can access to its value directly, first level.
START RequestId: 60a541d8-b3c8-48b0-a7a3-6b3f65d96482 Version: $LATEST
{
"slotTwo": "some text here"
}
The test from the lambda console works fine. It is able to retrieve the value and continue the logic.
However when I test the bot from Lex it does not work.
Any idea why?
Thanks so much
Ester
My bad.
I missed that the values indicated in the lamdda test must correspond to the whole JSON structure. So now I added this as event test:
{
"currentIntent": {
"name": "intent-name",
"slots": {
"slotTwo": "Hi from the sendmessagetest"
}
}
}
and I access the slot within the lambda this way:
messagetext = event['currentIntent'] ['slots'] ['slotTwo']
Feel free to delete my post if you find it confusing.
Thanks everyone

create card response from custom webhook written in python for dialogflow

i wrote a webhook in python3 and deployed in my own machines the text provided in fulfillmentText is displayed properly but rich response with cards is not displayed. how can i display my response using basic cards?
{
"fulfillmentText": "My train is in Hyderabad",
"fulfillmentMessages": [
{
"card": {
"title": "card title",
"subtitle": "card text",
"imageUri": "https://assistant.google.com/static/images/molecule/Molecule-Formation-stop.png",
"buttons": [
{
"text": "button text",
"postback": "https://assistant.google.com/"
}
]
}
}
]
}
this is my code trying to display the content in the form of cards this is exactly what dialogflow aslo expects as a response format
https://dialogflow.com/docs/fulfillment
{
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": ""
}
},
{
"basicCard": {
"title": "Train",
"image": {
"url": "https://8e39b052.ngrok.io/train.jpg",
"accessibilityText": "Train Image"
},
"buttons": [
{
"title": "WhereIsMyTrain",
"openUrlAction": {
"url": "https://whereismytrain.in/"
}
}
],
"imageDisplayOptions": "WHITE"
}
}
]
}
}
}
}
this worked for me i was not sending it as a payload before

Slack send attachment returning 500 error

I am trying to send an attachment to a Slack web hook.
I have followed the API documentation and can send a simple message. When I try send an attachment I get a 500 error, I presume there is an issue with my payload but I cannot work it out for the life of me.
How do I get the attachment to post successfully?
import slackweb
slack = slackweb.Slack(url='WEB HOOK URL HERE')
slack.notify(text="Maguro is a sushi")
attachments = []
attachment = {
"attachments": [
{
"fallback": "Required plain-text summary of the attachment.",
"color": "#36a64f",
"pretext": "Optional text that appears above the attachment block",
"author_name": "Bobby Tables",
"author_link": "http://flickr.com/bobby/",
"author_icon": "http://flickr.com/icons/bobby.jpg",
"title": "Slack API Documentation",
"title_link": "https://api.slack.com/",
"text": "Optional text that appears within the attachment",
"fields": [
{
"title": "Priority",
"value": "High",
"short": False
}
],
"image_url": "http://my-website.com/path/to/image.jpg",
"thumb_url": "http://example.com/path/to/thumb.png",
"footer": "Slack API",
"footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png",
"ts": 123456789
}
]
}
attachments.append(attachment)
slack.notify(attachments=attachments)
You're missing two required fields in your Slack message with attachments: text and channel. You also need to lowercase the value of the short field to false.
See the corrected message here in Slack's message tester:
{
"text": "You need this field",
"channel": "C########",
"attachments": [
{
"fallback": "Required plain-text summary of the attachment.",
"color": "#36a64f",
"pretext": "Optional text that appears above the attachment block",
"author_name": "Bobby Tables",
"author_link": "http://flickr.com/bobby/",
"author_icon": "http://flickr.com/icons/bobby.jpg",
"title": "Slack API Documentation",
"title_link": "https://api.slack.com/",
"text": "Optional text that appears within the attachment",
"fields": [
{
"title": "Priority",
"value": "High",
"short": false
}
],
"image_url": "http://my-website.com/path/to/image.jpg",
"thumb_url": "http://example.com/path/to/thumb.png",
"footer": "Slack API",
"footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png",
"ts": 123456789
}
]
}
Create a JSON structure including those two fields and your attachments variable, and you should be good to go.

Trouble Getting Alexa to Playback Streaming Audio

Python 3.6 and Flask-Ask
I can't seem to get Alexa to stream audio for my current hobby project (http://github.com/michaeljdietz/jukebox).
I can stream the audio manually through a web browser no problem with the https stream URL in my response object. Both Alexa and the AVS Service Simulator respond with speech and text correctly to the request. The directive appears to be formatted right to me, to the best of my knowledge anyway.
Here is the response to Alexa which should trigger the playback:
{
"version": "1.0",
"response": {
"outputSpeech": {
"text": "Playing the album The Bends by Radiohead on your jukebox",
"type": "PlainText"
},
"speechletResponse": {
"outputSpeech": {
"text": "Playing the album The Bends by Radiohead on your jukebox"
},
"directives": [
{
"playBehavior": "REPLACE_ALL",
"type": "AudioPlayer.Play",
"audioItem": {
"stream": {
"token": "334f1e7e-938d-4dea-a732-45884c6f6db9",
"url": "https://michaeljdietz.me/songs/1426",
"offsetInMilliseconds": 0
}
}
}
],
"shouldEndSession": true
}
},
"sessionAttributes": {}
}
UPDATE: It does seem to work about 1 out of 10 times for the same stream URL. Below is the response on from Alexa when it fails.
{
"version":"1.0",
"context": {
"AudioPlayer":{
"offsetInMilliseconds":0,
"token":"*****",
"playerActivity":"FINISHED"
},
"System": {
"application": {
"applicationId": "*****"
},
"user" {
"userId":"*****"
},
"device": {
"deviceId": "*****",
"supportedInterfaces": {
"AudioPlayer": {}
}
},
"apiEndpoint":"https://api.amazonalexa.com",
"apiAccessToken":"*****"
}
},
"request": {
"type":"AudioPlayer.PlaybackFailed",
"requestId":"*****",
"timestamp":"2018-01-09T00:02:48Z",
"locale":"en-US",
"currentPlaybackState": {
"offsetInMilliseconds":0,
"token":"*****",
"playerActivity":"FINISHED"
},
"error": {
"message":"Setting up renderers for an unknown media type: UNDEFINED",
"type":"MEDIA_ERROR_UNKNOWN"
},
"token":"*****"
}
}
Based on Amazons blog and documentation, it seems you're missing "type": "AudioPlayer.Play"in your directives.

Slack chat.postMessage attachment gives no_text

When I try to add an attachment to my message I either only get the text or if I leave out the text I get "error": "no_text", is there any way to send an attachmet with chat.postMessage?
This is the python code I use for sending the message:
r = requests.post('https://slack.com/api/chat.postMessage', params=json.loads("""
{
"token": "xoxp-mytokenhere",
"channel": "C4mychannelhere",
"attachments": [
{
"text": "Question?",
"fallback": "Question?",
"callback_id": "callback_id",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "question",
"text": "Yes",
"style": "good",
"type": "button",
"value": "yes"
},
{
"name": "question",
"text": "Nope",
"style": "good",
"type": "button",
"value": "no"
}
]
}
]
}
"""))
Based on the comment I went with the following solution:
r = requests.post('https://slack.com/api/chat.postMessage', params=json.loads({
"token": "xoxp-mytokenhere",
"channel": "C4mychannelhere",
"attachments": json.dumps([
{
"text": "Question?",
"fallback": "Question?",
"callback_id": "callback_id",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "question",
"text": "Yes",
"style": "good",
"type": "button",
"value": "yes"
},
{
"name": "question",
"text": "Nope",
"style": "good",
"type": "button",
"value": "no"
}
]
}
])
}))
It looks like you're trying to send a JSON string as your entire set of parameters to chat.postMessage.
chat.postMessage and other web API methods only support URL-encoded query or POST body parameters, so your fields like token and channel and attachments are sent as application/x-www-form-urlencoded key/value pairs instead.
To complicate things a little further, the attachments parameter actually does take a string of URL-encoded JSON data. Your JSON array needs to be URL-encoded and stuffed into that parameter.
Depending on your goals, you could either skip using json.loads and just pass that JSON string as your attachments parameter and requests will take care of URL-encoding it for you -- or you can use something like json.dump on a native Python array you build with the same attributes.

Categories

Resources