Rich response fulfillment Dialogflow Messenger - dialogflow-es

I'm using Dialogflow Messenger integration. Custom Payloads are working from the Dialogflow platform, but I don't know how to use them from Webhook.
Here is my JavaScript code that doesn't works:
const functions = require('firebase-functions');
const { dialogflow } = require('actions-on-google');
const { Card, Suggestion } = require('dialogflow-fulfillment');
const { WebhookClient } = require('dialogflow-fulfillment');
const app = dialogflow();
const response = {
"fulfillment_messages": [{
"payload": {
"richContent": [
[{
"type": "chips",
"options": [{
"text": "Empezar!"
}]
}]
]
}
}]
}
const numero = (conv) => {
conv.ask(response);
};
app.intent("numero", numero);
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
The intent is detected correctly but the code for the rich response is not working, the chatbot response is: 'Cannot display response in Dialogflow simulator. Please test on the Google Assistant simulator instead.'.
I want to know how to use all possible custom payloads (Info response, Description response, Button response...).

Your JSON response in the webhook should be-
const response = {
"fulfillment_messages": [{
"payload": {
"richContent": [
[{
"type": "chips",
"options": [{
"text": "Empezar!"
}]
}]
]
}
}]
}
Your response on dialogflow messenger would look like
Here is another stackoverflow post that might help-
How to show Rich Response Buttons (''Chips) Using Dialogflow Fulfillment?

Related

Node.js Paypal Payout api error in Live enviornment

I am using a PayPal payout API to transfer money, its working perfect in sandbox environment but when I changed it to live environment it is throwing some error:
text: '{"name":"VALIDATION_ERROR","message":"Invalid request - see details","debug_id":"a641429b40e07","information_link":"https://developer.paypal.com/docs/api/payments.payouts-batch/#errors","details":[{"field":"items[0].receiver","location":"body","issue":"may not be null"}],"links":[]}'
This is the code I am using to request a payout
let requestBody = {
"sender_batch_header": {
"recipient_type": "EMAIL",
"email_message": "SDK payouts test txn",
"note": "Enjoy your Payout!!",
"sender_batch_id": 'asd12432',
"email_subject": "This is a test transaction from SDK"
},
"items": [{
"note": "Your 5$ Payout!",
"amount": {
"currency": "USD",
"value": 20
},
"receiver": 'payment#reciever.com',
"sender_item_id": "Test_txn_1"
}]
}
// Construct a request object and set desired parameters
// Here, PayoutsPostRequest() creates a POST request to /v1/payments/payouts
let request = new paypal.payouts.PayoutsPostRequest();
request.requestBody(requestBody);
// Call API with your client and get a response for your call
let createPayouts = async function () {
let response = await client.execute(request);
console.log(`Response: ${JSON.stringify(response.statusCode)}`);
// If caladfl returns body in response, you can get the deserialized version from the result attribute of the response.
console.log(`Payouts Create Response: ${JSON.stringify(response.result)}`);
//res.redirect('/adam?payment=success');
res.redirect('/adam?payment=success');
}
createPayouts();

Dialogflow CX webhook for fulfilment to reply user using nodejs

I tried using dialogflow-fulfillment library but I guess it is for Dialogflow ES so now I am using
#google-cloud/dialogflow-cx library but I don't know how to use this library for webhook connection to reply to users using fulfilments, there is very little material available for Dialogflow CX.
// use credentials or keyFilename i'm using keyFile
credentials: {
private_key: "-----BEGIN PRIVATE KEY-----==\n-----END PRIVATE KEY-----\n",
client_email:"pro1a3711.iam.gserviceaccount.com",
},
keyFilename: './pr.json'
}
const {SessionsClient} = require('#google-cloud/dialogflow-cx');
const projectId = 'pro1-293711';
const location = 'global';
const agentId = 'da2271f5-0221-4dce-98d3-efa----9dd';
const languageCode = 'en';
const query = ['hello'];
// Imports the Google Cloud Some API library
//console.log(WebhooksClient)
const client = new SessionsClient(config);
//console.log("client",client)
async function detectIntentText() {
const sessionId = Math.random().toString(36).substring(7);
const sessionPath = client.projectLocationAgentSessionPath(
projectId,
location,
agentId,
sessionId
);
console.info(sessionPath);
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
},
languageCode,
},
};
const [response] = await client.detectIntent(request);
console.log(`User Query: ${query}`);
for (const message of response.queryResult.responseMessages) {
if (message.text) {
console.log(`Agent Response: ${message.text.text}`);
}
}
if (response.queryResult.match.intent) {
console.log(
`Matched Intent: ${response.queryResult.match.intent.displayName}`
);
}
console.log(
`Current Page: ${response.queryResult.currentPage.displayName}`
);
}
detectIntentText()```
Note that the dialogflow-fulfillment library only supports Dialogflow ES and the #google-cloud/dialogflow-cx library is only used for node.js applications to access Dialogflow CX API.
As there are no fulfillment libraries available yet for Dialogflow CX, you can refer to the Dialogflow CX webhook request and webhook response for building webhook services for your Dialogflow CX agent.
You can also refer to the sample webhook service code for Dialogflow CX using Node.js and express below:
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post("/webhook", (request, response) => {
let tag = request.body.fulfillmentInfo.tag;
let jsonResponse = {};
if (tag == "welcome tag") {
//fulfillment response to be sent to the agent if the request tag is equal to "welcome tag"
jsonResponse = {
fulfillment_response: {
messages: [
{
text: {
//fulfillment text response to be sent to the agent
text: ["Hi! This is a webhook response"]
}
}
]
}
};
} else {
jsonResponse = {
//fulfillment text response to be sent to the agent if there are no defined responses for the specified tag
fulfillment_response: {
messages: [
{
text: {
////fulfillment text response to be sent to the agent
text: [
`There are no fulfillment responses defined for "${tag}"" tag`
]
}
}
]
}
};
}
response.json(jsonResponse);
});
const listener = app.listen(process.env.PORT, () => {
console.log("Your app is listening on port " + listener.address().port);
});

actions-on-google Account Linking Signin status is "ERROR" always

I got this sample code from the docs of actions on google account linking with google account. The signin.status is always "ERROR". I have tried on actions console simulator, google assistant app on my phone and on a google home mini with personal results on. But the result is the same in all cases.
const express = require('express');
const bodyParser = require('body-parser');
const {actionssdk, SignIn} = require('actions-on-google');
const app = actionssdk({
// REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
clientId: <client_id>,
});
// Intent that starts the account linking flow.
app.intent('actions.intent.MAIN', (conv) => {
conv.ask(new SignIn('To get your account details'));
});
// Create an Actions SDK intent with the `actions_intent_SIGN_IN` event.
app.intent('actions.intent.SIGN_IN', (conv, params, signin) => {
console.log(signin)
if (signin.status === 'OK') {
const payload = conv.user.profile.payload;
conv.ask(`I got your account details, ${payload.name}. What do you want to do next?`);
} else {
conv.ask(`I won't be able to save your data, but what do you want to do next?`);
}
});
app.intent('actions.intent.TEXT', (conv) => {
conv.close("bye");
})
//Run server
const expressApp = express().use(bodyParser.json());
expressApp.post('/', function(req,res){
app(req,res);
});
expressApp.listen(8080,() => {console.log("listening")});
This is the signin object I'm being returned
{ '#type': 'type.googleapis.com/google.actions.v2.SignInValue',
status: 'ERROR' }
EDIT
My actions.json is as follows
{
"actions": [
{
"description": "Default Welcome Intent",
"name": "MAIN",
"fulfillment": {
"conversationName": "fulfilment function"
},
"intent": {
"name": "actions.intent.MAIN",
"trigger": {
"queryPatterns": [
"talk to Care Cat"
]
}
}
},
{
"description": "Everything Else Intent",
"name": "allElse",
"fulfillment": {
"conversationName": "fulfilment function"
},
"intent": {
"name": "actions.intent.TEXT"
}
}
],
"conversations": {
"fulfilment function": {
"name": "fulfilment function",
"url": <url>
}
},
"locale": "en"
}
Could it be because it is still a test app which is not published yet?
Can someone help me with this?
In your Google Cloud Platform Account, check your IAM settings and enable the Dialogflow API Admin
Documentation for more details: https://cloud.google.com/dialogflow/docs/access-control

Why does this fulfillment code for Dialogflow does not work?

I am playing around a bit with the Dialogflow. As I was trying to figure out the options in the responses, I also wanted to test if Dialogflow has dynamic response. For example, fetch a data from Database (Firebase Database or MongoDB) and show it as a response instead of hard coding every response.
I have learnt that Fulfillment can do that job. When I enabled the Inline editor in Fulfillment in Dialogflow, it already has some code to be deployed. I figured, just for testing, I would write some very basic function in Fulfillment and see if it works.
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
function test(agent){
agent.add('test confirmed!');
}
// // Uncomment and edit to make your own intent handler
// // uncomment `intentMap.set('your intent name here', yourFunctionHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function yourFunctionHandler(agent) {
// agent.add(`This message is from Dialogflow's Cloud Functions for Firebase editor!`);
// agent.add(new Card({
// title: `Title: this is a card title`,
// imageUrl: 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
// text: `This is the body text of a card. You can even use line\n breaks and emoji! 💁`,
// buttonText: 'This is a button',
// buttonUrl: 'https://assistant.google.com/'
// })
// );
// agent.add(new Suggestion(`Quick Reply`));
// agent.add(new Suggestion(`Suggestion`));
// agent.setContext({ name: 'weather', lifespan: 2, parameters: { city: 'Rome' }});
// }
// // Uncomment and edit to make your own Google Assistant intent handler
// // uncomment `intentMap.set('your intent name here', googleAssistantHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function googleAssistantHandler(agent) {
// let conv = agent.conv(); // Get Actions on Google library conv instance
// conv.ask('Hello from the Actions on Google client library!') // Use Actions on Google library
// agent.add(conv); // Add Actions on Google library responses to your agent's response
// }
// // See https://github.com/dialogflow/dialogflow-fulfillment-nodejs/tree/master/samples/actions-on-google
// // for a complete Dialogflow fulfillment library Actions on Google client library v2 integration sample
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('test-intent',test);
// intentMap.set('your intent name here', yourFunctionHandler);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
The function test is the only thing I have added to the already pre existing code along with the intentMap.set('test-intent', test);.
I have the intent as follows:
{
"id": "3fea3cec-d3f0-4d4e-a838-b4134894ea05",
"name": "test-intent",
"auto": true,
"contexts": [],
"responses": [
{
"resetContexts": false,
"affectedContexts": [],
"parameters": [
{
"id": "de3d79b3-b062-445a-8c55-d499a2d7b12d",
"required": false,
"dataType": "",
"name": "sample",
"value": "1",
"promptMessages": [],
"noMatchPromptMessages": [],
"noInputPromptMessages": [],
"outputDialogContexts": [],
"isList": false
}
],
"messages": [
{
"type": "simple_response",
"platform": "google",
"textToSpeech": "t",
"ssml": "",
"displayText": ""
}
],
"defaultResponsePlatforms": {},
"speech": []
}
],
"priority": 500000,
"webhookUsed": false,
"webhookForSlotFilling": false,
"fallbackIntent": false,
"events": [],
"userSays": [
{
"id": "d8aee895-8326-4454-b0f4-c2237984d968",
"data": [
{
"text": "testing...",
"userDefined": false
}
],
"isTemplate": false,
"count": 0,
"updated": 0,
"isAuto": false
}
],
"followUpIntents": [],
"liveAgentHandoff": false,
"endInteraction": false,
"templates": []
}
It is bare bones with nothingness. I just wanted to test the response in Actions on Google.
I only get the response I have manually entered in the 'testing-intent' in Actions on Google..
What am I doing wrong?
I already figured out the problem I have when I looked at the testing-intent's json before posting this question. I had to Enable webhook call for this intent.
Go to bottom portion of the selected intent page you want to enable Fulfillment.
Click Fulfillment to expand it.
Click Enable webhook call for this intent

How to connect watson assisstant v2 with Amazon skill kit in Aws Lambda?

Hello I want to connect my watson assisstant with an alexa device,
for this I need Amazon development skill kit and AWS lambda. But i can't connect watson because i got problem with my promises and i can't see the logs of my code in the amazon developer console. And my assistant work on nodeJs application.
There is the headers of my watson :
const assistant = new AssistantV2({
version: '2019-02-28',
iam_apikey: 'apiSecretKey',
url: 'https://gateway-lon.watsonplatform.net/assistant/api'
});
const assistant_id = "assistantIDSecret" ;
There is some codes that i tried :
const MyNameIsIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'SearchIntent';
},
async handle(handlerInput) {
assistant.createSession({
assistant_id: assistant_id
})
.then(res => {
session_id = res.session_id;
})
.catch(err => {
console.log(err);
});
assistant.message({
assistant_id: assistant_id,
session_id: session_id,
input: {
'message_type': 'text',
'text': "hello"
}
})
.then(res => {
console.log(JSON.stringify(res, null, 2));
speechText = res.output.generic.response.text;
})
.catch(err => {
speechText = err;
});
}, function(err){
speechText = "Problem with Api call";
});
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
},
};
I tried to replace then, catch by an await:
try{
let res = await assistant.createSession({
assistant_id: assistant_id
});
session_id = res.session_id;
let message = await assistant.message({
assistant_id: assistant_id,
session_id: session_id,
input: {
'message_type': 'text',
'text': "hello"
}
});
speechText = message.output.generic.response.text;
}catch(err){
speechText = err;
}
The results of speechText should give me "Good day to you" it's a response that comes from Watson.but now Alexa says "Sorry, I can't understand the command. Please say again."
Do you have an others ways to try this? thanks you!
Sounds like you have managed to call out to Watson Assistant, and if the response configured in your dialog node was "Good day to you" -which is what you have received, then that connection is working. If I remember right however the response that Alexa is expecting is a JSON object, not a string. So you need to format the response to meet Alexa's needs.
A quick look at this site: https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html
indicates that the following is a good example the required response json packet.
{
"version": "string",
"sessionAttributes": {
"key": "value"
},
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "Plain text string to speak",
"playBehavior": "REPLACE_ENQUEUED"
},
"reprompt": {
"outputSpeech": {
"type": "PlainText",
"text": "Plain text string to speak",
"playBehavior": "REPLACE_ENQUEUED"
}
},
"shouldEndSession": true
}
}
Note. I cannot confirm as I have never had an Alexa Skill taken to production ( only built them as demo's under the development environment, and shared with a limited few). But I have been informed that Amazon are not happy for their skills to off load work to Watson. Which is a shame.

Resources