Pass data to start of session (IVR) - dialogflow-cx

Looking into starting a project using DialogFlow CX. Seems rather promising but have one issue I cannot seem to find an answer for. The agent will be connected to via IVR (from Flex/Callcenter). I need to gather some information on start so that I can identify the hotel/property that will be referenced in the conversation. I found session parameters but those are isolated to the session from start to finish but not passed to the start of a session. We are starting with about 60 properties and when the agent starts, it needs to "know" what property it is dealing with.
Another quick question - will I need a separate telephony integration number to run multiple concurrent instances?
I am really new to all this so my language may be off. Thanks in advance!!
Robert

Passing parameters to dialogflow Cx depends on your integration, but a general way to do this would be to call a webhook at the Welcome node with parameters set to null that you want to return with updated values from backend:
Return Response in the following manner and it will work via a webhook:
Link to Google Cloud Functions Webhook Example
{
"fulfillment_response":
{
"messages": [
{
"text": {
"text": [
"Test Response"
]
}
}
]
},
"session_info": {
"session": projects/project-name/locations/your-agent-location/agents/a6ed61ef-008b-49bb-8526-d8e68982d2b4/sessions/d3bd9c-9d9-8c8-4a8-f623bdb25,
"parameters": {
"property1": 746932,
"property2":34123
}
}
}
Python Flask Solution:
import os
from flask import Flask, request, redirect
app =Flask(__name__)
#app.route('/test', methods=['POST'])
def test():
req = request.get_json()
session_name=req['sessionInfo']['session']
print(req)
res = {
"fulfillment_response":
{
"messages": [
{
"text": {
"text": [
"Test Response"
]
}
}
]
},
"session_info": {
"session": session_name,
"parameters": {
"property1": 746932,
"property2":34123
}
}
}
return res
if __name__ == "__main__":
app.run(port=5000,debug=True)

Related

Use Postman to test Appsync Subscription

I have been able to successfully execute Appsync GraphQL queries and mutations from Postman. However, i'm struggling to connect to subscriptions which are websocket urls.
How can I achieve the same ?
Since Postman supports WebSockets testing GraphQL subscriptions is achievable as well. Such a testing requires two steps:
connection to a server,
sending a start message.
Establishing a connection:
Create a new WebSocket request.
Put your server URL ws:// or wss://.
Add custom header parameter Sec-WebSocket-Protocol: graphql-ws. Other headers may depend on your server configuration.
Press the "Connect" button.
When the connection is established we may start a subscription.
In the "New message" field put the command.
Press the "Send" button.
The start message should look like this:
{
"id":"1",
"payload": {
"operationName": "MySubscription",
"query": "subscription MySubscription {
someSubscription {
__typename
someField1
someField2 {
__typename
someField21
someField22
}
}
}",
"variables": null
},
"type": "start"
}
operationName is just the name of your subscription, I guess it's optional. And someSubscription must be a subscription type from your schema.
query reminds regular GraphQL syntax with one difference:
__typename keyword precedes every field list.
For example, the query from the payload in regular syntax looks like the following:
subscription MySubscription {
someSubscription {
someField1
someField2 {
someField21
someField22
}
}
}
Example message with parameters (variables):
{
"id":"1",
"payload": {
"operationName": "MySubscription",
"query": "subscription MySubscription($param1: String!) {
someSubscription((param1: $param1)) {
__typename
someField
}
}",
"variables": {
"param1": "MyValue"
}
},
"type": "start"
}
It also reminds regular GraphQL syntax as described above.
variables is an object with your parameters.
#Vladimir's answer is spot on. Adding a few notes for folks still having trouble.
Full document here # https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html
Step 1 - establish connection:
make sure to base64 encode values in "header" and "payload" querystrings
header example:
{
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-api-key":"da2-12345678901234567890123456"
}
payload: You can pass in empty payload
{}
Step 2 - register subscription:
Include the authorization in the message. Escape line feeds properly "\n" throws an error but "\\n" works. it throws the following error - misleading.
Don't forget to stringify value in "data" field.
{
"type": "error",
"payload": {
"errors": [
{
"errorType": "UnsupportedOperation",
"message": "unknown not supported through the realtime channel"
}
]
}
}
{
"id": "2",
"payload": {
"data": "{\"query\":\"subscription onCreateMessage { changeNotification{ __typename changeType from } }\",\"variables\":{}}",
"extensions":{
"authorization":{
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-api-key":"da2-12345678901234567890123456"
}
}
},
"type": "start"
}

Bot Composer and BotBuilder FacebookAdapter resulting in "Object reference not set to an instance of an object"

I am using MS Bot Composer combined with BotBuilder Facebook Adapter in order to post my bot following the "new" rules of Facebook Workplace - important to remember that I've already tried to use this directly on Facebook Messenge, same situation applies.
The integration and connection works fine, the problem now is to understand how to post anything apart from text.
An example below of an attempt to get the correct template
# channelData
-```{
"attachment":{
"type":"template",
"payload":{
"template_type":"button",
"text":"What do you want to do next?",
"buttons":[
{
"type":"web_url",
"url":"https://www.messenger.com",
"title":"Visit Messenger"
}
]
}
}
}```
And then, the bot's answer:
If you go the channel data route, the Facebook adapter expects you to provide a full FacebookMessage object as the channel data. That's one level up from the JSON you've provided, so it would look like this:
{
"message":{
"attachment":{
"type":"template",
"payload":{
"template_type":"button",
"text":"What do you want to do next?",
"buttons":[
{
"type":"web_url",
"url":"https://www.messenger.com",
"title":"Visit Messenger"
}
]
}
}
}
}
However, that won't work because it's missing the other properties a FacebookMessage needs, like sender. Rather than trying to populate the full Facebook message, it may be easier to just go the attachment route instead of the channel data route. You can see how to do that in the Facebook adapter sample:
private static Attachment CreateTemplateAttachment(string filePath)
{
var templateAttachmentJson = File.ReadAllText(filePath);
var templateAttachment = new Attachment()
{
ContentType = "template",
Content = JsonConvert.DeserializeObject(templateAttachmentJson),
};
return templateAttachment;
}
In Composer, you can set the activity's attachments instead of its channel data. Just set the content type to "template" and the content to the payload of the attachment you have now, using the Facebook adapter sample's resources as a guide:
# attachment
- ```
{
"contentType": "template",
"content": {
"template_type": "button",
"text": "What do you want to do next?",
"buttons": [
{
"type": "web_url",
"url": "https://www.messenger.com",
"title": "Visit Messenger"
}
]
}
}
```
You can see how the Facebook adapter treats both channel data and attachments by having a look at the FacebookHelper class.

Terminating Dialogflow Application from Custom Client

I created a custom Golang server to handle Dialogflow's fulfillment. I want my fulfillment server to tell Dialogflow (which would be running the compiled version on a Google home) to terminate my action after a certain period of inactivity. Is this possible in the current architecture?
To mark the end of an Action and close it, you can return false for the expectUserResponse field, like:
{
"payload": {
"google": {
"expectUserResponse": false,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Goodbye!"
}
}
]
}
}
}
}

Amazon Alexa Device Discovery for Smart Home API with Lambda Failing

I have setup an Alexa Smart Home Skill, all settings done, oauth2 processed done and skill is enabled on my Amazon Echo device. Lambda function is setup and linked to the skill. When I "Discover Devices" I can see the payload hit my Lambda function in the log. I am literally returning via the context.succeed() method the following JSON with a test appliance. However Echo tells me that it fails to find any devices.
{
"header": {
"messageId": "42e0bf9c-18e2-424f-bb11-f8a12df1a79e",
"name": "DiscoverAppliancesResponse",
"namespace": "Alexa.ConnectedHome.Discovery",
"payloadVersion": "2"
},
"payload": {
"discoveredAppliances": [
{
"actions": [
"incrementPercentage",
"decrementPercentage",
"setPercentage",
"turnOn",
"turnOff"
],
"applianceId": "0d6884ab-030e-8ff4-ffffaa15c06e0453",
"friendlyDescription": "Study Light connected to Loxone Kit",
"friendlyName": "Study Light",
"isReachable": true,
"manufacturerName": "Loxone",
"modelName": "Spot"
}
]
}
}
Does the above payload look correct?
According to https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discovery-messages the version attribute is required. Your response seems to be missing that attribute.
In my (very short) experience with this, even the smallest mistake in the response would generate a silent error like the one you are experiencing.
I had the same problem. If you are creating discovery for "Entertainment Device", make sure you have wrapped the output in 'event' key for context.succeed
var payload = {
endpoints:
[
{
"endpointId": "My-id",
"manufacturerName": "Manufacturer",
"friendlyName": "Living room TV",
"description": "65in LED TV from Demo AV Company",
"displayCategories": [ ],
"cookie": {
"data": "e.g. ip address",
},
"capabilities":
[
{
"interface": "Alexa.Speaker",
"version": "1.0",
"type": "AlexaInterface"
},
]
}
]
};
var header = request.directive.header;
header.name = "Discover.Response";
context.succeed({ event: {
header: header, payload: payload
} });
Although, in the sample code, this is never mentioned and an incorrect example is given (https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/steps-to-create-a-smart-home-skill). However, the response body provided includes the "event" key.
Recreating lambda function helped me fix the issue. I also set "Enable trigger" check button while creating, though I'm not sure if that matters. After that my device provided by skill was found successfully.
Edit: Answer was wrong. Only useful information was this
This context.fail syntax is actually deprecated. Look up the Lambda context object properties, it should look more like "callback(null, resultObj)" now.
Did you include the return statement in your function?
return {
"header": header,
"payload": payload
}
It was missing in the example and after adding it, I was able to 'discover' my device.

Intel XDK : Parse.com integration "Unauthorized"

I am very new to Intel XDK and i try to make a very simple app like this in that video tutorial: Using Services Datafeed in App Designer.
But instead of the specific service from Rotten Tomatoes i want to integrate a database i have in Parse.com. For that i followed this video tutorial: "Integrating a New Service"
"[https]://software.intel.com/en-us/html5/videos/integrating-a-new-service",
and at the end the response was: "Unauthorized".
Then i found only this answer which comes from Intel's HTML5 Development Forums. I did not get anything either with this. The response was again: "Unauthorized".
And now i am confused and disappointed because:
I can't find other resources to help my self
I don't want to do it someone else instead of me, but
Without a full example, how is supposed to make it to learn?
My code now is similar with this in video: "Integrating a New Service"
In apiconfig.json
{
"MyService": {
"name": "The external service",
"description": "A great API with an external service",
"dashboardUrl": "https://parse.com",
"auth": "key",
"signature": "apiSecret"
}
}
In MyService.js
(function (credentials) {
var exports = {};
exports.ServiceObject = function(params) {
var url = 'https://api.parse.com/1/classes/ServiceObject';
params['apiKey'] = credentials.apiKey;
url = url + '?' + $.param(params);
return $.ajax({url: url, type: 'GET'});
};
return exports;
})
And in MyService.json
{
"endpoints": [
{
"name": "classes",
"dashboardUrl": "https://parse.com/docs/rest",
"methods": [
{
"MethodName": "ServiceObject",
"Synopsis": "Show the entries",
"parameters": [
{
"Name": "objectId",
"Required": "N",
"Default": "",
"Type": "string",
"Description": "The object ID"
},
{
"Name": "text",
"Required": "N",
"Default": "",
"Type": "string",
"Description": "The text"
}
]
}
]
}
]
}
Can someone help me more? In whatever way he thinks best.
Thank you all
Edit:
After the following answer, my problem solved.
"MyService.js" file after the correction is:
(function (credentials) {
var exports = {};
exports.ServiceObject = function(params) {
var url = 'https://api.parse.com/1/classes/ServiceObject';
return $.ajax({
url : url,
headers : {
'X-Parse-Application-Id' : credentials.apiKey,
'X-Parse-REST-API-Key' : credentials.apiSecret
}
});
};
return exports;
})
# user1736947: Your answer was concise and precise, exactly what i needed.
Certainly in the future I will need a lot of help, but for now I can go on my self-education thanks to you.
Thank you very much.
The way the authentication keys are accepted is different for different services. The example in the video.. rottentomatoes.. it accepted keys as a url parameter, so we append the key to the url and send it. However, seems like parse wants the keys in the headers (according to this)
So the equivalent ajax call will be something like :
exports.ServiceObject = function(params) {
var url = 'https://api.parse.com/1/classes/ServiceObject';
return $.ajax({
url : url,
headers : {
'X-Parse-Application-Id' : credentials.apiKey,
'X-Parse-REST-API-Key' : credentials.apiSecret
}
});
This might not fix everything but it will move you a step beyond the authorization issue. Let me know if you are able to retreive the class this way.
To get a particular row entry, append the url with params.objectID.
Also, the XDK services tab has a parse-similar service ... kinvey. It also allows you to create a database online and retreive it.

Resources