creating Table card in google assistant - dialogflow-es

Below is the complete code which i am running to show the table in google assistant.
'use strict';
const {Table} = require('actions-on-google');
process.env.DEBUG = 'dialogflow:debug';
exports.dialogflowFirebaseFulfillment =
functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function showTable(){
const conv = agent.conv();
agent.add("this is sample table");
agent.add(new Table({
dividers: true,
columns: ['header 1', 'header 2', 'header 3'],
rows: [
['row 1 item 1', 'row 1 item 2', 'row 1 item 3'],
['row 2 item 1', 'row 2 item 2', 'row 2 item 3'],
],
}));
}
let intentMap = new Map();
intentMap.set('TableView',showTable); //TableView is my intent name
agent.handleRequest(intentMap);
});
While running the above code its showing me an below error
TypeError: Table is not a constructor
at showTable (/user_code/index.js:74:15)
at WebhookClient.handleRequest (/user_code/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:303:44)
at exports.dialogflowFirebaseFulfillment.functions.https.onRequest (/user_code/index.js:102:9)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:57:9)
at /var/tmp/worker/worker.js:735:7
at /var/tmp/worker/worker.js:718:11
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)

The most likely cause of this is that you didn't import the Table object with a line such as
const {Table} = require('actions-on-google');

I faced this issue and one probable reason might be the incorrect version of actions-on-google in the package.json file.Usually we used to copy the package.json from existing samples to our new project.So old ones has the version of 2.0.0-alpha.4. Since Table cards are added after that version,the dialogflow throws error.You may use the version- 2.6.0.This worked for me.
Below is my index.js file.
'use strict';
const {dialogflow,Table} = require('actions-on-google');
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion,List,Image} = require('dialogflow-fulfillment');
const app= dialogflow({debug:true});
app.intent('Table View Sample',(conv) =>{
conv.ask('This is a simple table example.');
conv.ask(new Table({
dividers: true,
columns: ['header 1', 'header 2', 'header 3'],
rows: [
['row 1 item 1', 'row 1 item 2', 'row 1 item 3'],
['row 2 item 1', 'row 2 item 2', 'row 2 item 3'],
],
}));
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
Below is my package.json file.
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "~6.0"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "2.6.0",
"firebase-admin": "^4.2.1",
"firebase-functions": "^0.5.7",
"dialogflow": "^0.1.0",
"dialogflow-fulfillment": "0.3.0-beta.3"
}
}
Hope this helps someone!
Thanks.

Related

Webhook stopped working. Has there been a deprication or requirements change?

I'm revisiting a Dialogflow Essentials app set up a few years ago that suddenly stopped working at the webhook calls. The URLs that respond to the webhooks are still functioning perfectly. Has there been a change in webhook requirements or a Google deprication that might account for this?
The "help" and "goodbye" functions internal to the app are still working, but when a webhook call is executed we get a reply that the app "isn't responding right now. Please try again soon." and the app leaves the conversation.
The relevant code is NodeJS version 8 (which should still be functional, though depricated) and is applied using the Inline Editor within Dialogflow. Here are the functions:
function get_keywords(agent) {
const keywords = agent.parameters.keywords;
const site_id = agent.parameters.site_id;
return axios.get(`https://www.FutureOfNews.com/AdEverywhere/SI/PR/AN/GA_API/StorySummary_API.cfm?SiteID=${site_id}&Keywords=${keywords}`)
.then((result) => {
console.log(result.data);
if (response.statusCode != 200) {
agent.add(`Error. Could not connect to news server.`);
} else {
if (result.data.storyFound.length < 1) {
agent.add(result.data.speech);
} else {
if (result.data.storyPhotoURL.length > 1) {
agent.add(result.data.speech);
agent.add(new Card({
title: result.data.storyHeadline,
imageUrl: result.data.storyPhotoURL,
buttonText: 'Full Story',
buttonUrl: result.data.storyURL,
imageDisplayOptions: "WHITE"
}));
} else {
agent.add(result.data.speech);
agent.add(new Card({
title: result.data.storyHeadline,
buttonText: 'Full Story',
buttonUrl: result.data.storyURL,
imageDisplayOptions: "WHITE"
}));
}
}
}
});
}
function get_rss_feed_id(agent) {
const rss_feed_id = agent.parameters.rss_feed_id;
const site_id = agent.parameters.site_id;
return axios.get(`https://www.FutureOfNews.com/AdEverywhere/SI/PR/AN/GA_API/NewsHeadlines_API.cfm?SiteID=${site_id}&RSSFeedID=${rss_feed_id}`)
.then((result) => {
agent.add(result.data.speech);
});
}
Here are versions of the URLs called by the webhooks (with real/live parameter values):
Headlines Group
Specific news item
I'm not seeing any activity in logs relating to these calls, and I see no billing/credit-card issues.
Any thoughts on why this is suddenly failing would be greatly appreciated!
I cannot create a NodeJS 8 environment since it is already deprecated. Instead, I tested your code in NodeJS 10 and it works fine for me.
For testing, I used an intent that is triggered with "Test" and I hard coded values for keywords,site_id,rss_feed_id. And it returned the expected result from the code.
Code used for testing:
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card} = require('dialogflow-fulfillment');
const axios = require('axios');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function yourFunctionHandler(agent) {
const keywords = 'investigation';
const site_id = 15;
return axios.get(`https://www.FutureOfNews.com/AdEverywhere/SI/PR/AN/GA_API/StorySummary_API.cfm?SiteID=${site_id}&Keywords=${keywords}`)
.then((result) => {
console.log(result.data);
if (response.statusCode != 200) {
agent.add(`Error. Could not connect to news server.`);
} else {
if (result.data.storyFound.length < 1) {
agent.add(result.data.speech);
} else {
if (result.data.storyPhotoURL.length > 1) {
agent.add(result.data.speech);
agent.add(new Card({
title: result.data.storyHeadline,
imageUrl: result.data.storyPhotoURL,
buttonText: 'Full Story',
buttonUrl: result.data.storyURL,
imageDisplayOptions: "WHITE"
}));
} else {
agent.add(result.data.speech);
agent.add(new Card({
title: result.data.storyHeadline,
buttonText: 'Full Story',
buttonUrl: result.data.storyURL,
imageDisplayOptions: "WHITE"
}));
}
}
}
});
}
function get_rss_feed_id(agent) {
const rss_feed_id = 1;
const site_id = 15;
return axios.get(`https://www.FutureOfNews.com/AdEverywhere/SI/PR/AN/GA_API/NewsHeadlines_API.cfm?SiteID=${site_id}&RSSFeedID=${rss_feed_id}`)
.then((result) => {
agent.add(result.data.speech);
});
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('test intent', yourFunctionHandler);
//intentMap.set('test intent', get_rss_feed_id);
agent.handleRequest(intentMap);
});
Package.json:
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "10"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"firebase-functions": "^2.0.2",
"firebase-admin": "^5.13.1",
"googleapis": "^27.0.0",
"actions-on-google": "2.2.0",
"dialogflow-fulfillment": "0.6.1",
"axios": "0.21.1"
}
}
Test using get_keywords():
Test using get_rss_feed_id():
What I could suggest is to upgrade to NodeJS 10 to ensure that the function is on a supported version of Node.js. See migration guide.

Agent unable to print all results received from Axion library request in Dialogflow

I'm trying to print all results received from the following request (this code not working):
function searchForProducts(agent) {
// category_name = 'Cooking' for example
const category_name = agent.parameters.category_name;
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/qvlk728a5p23g/search?Categories=*${category_name}*&Status=1`).then(function (res) {
let Categories = res.data[0];
if (Categories) {
for(var i=0;i<res.data.length;i++){
agent.add(`https://alaswadtrading.com/index.php?route=product/product&product_id=${Categories.ProductID}\n\n${Categories.Name}`);
}
} else {
agent.add(`No items found in the selected category (${category_name})`);
}
resolve();
});
});
}
The problem I'm facing is the agent can only print on result through the following code (this record working but return only one URL):
function searchForProducts(agent) {
const category_name = agent.parameters.category_name;
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/qvlk728a5p23g/search?Categories=*${category_name}*&Status=1`).then(function (res) {
let Categories = res.data[0];
if (Categories) {
agent.add(`https://alaswadtrading.com/index.php?route=product/product&product_id=${Categories.ProductID}\n\n${Categories.Name}`);
} else {
agent.add(`No items found in the selected category (${category_name})`);
}
resolve();
});
});
}
What I'm doing wrong?
============ After Applying Proposed Solution ================
Hello, since yesterday I'm testing but with no luck to get the exact problem. Here what I did:
I created new Intent which will trigger your code once "Test" received.
I have test the code using different ways, and here the result:
Category_Name = “Cooking”:
- Dialogflow Agent Test: Worked (https://imgur.com/sov6Th5).
- Web Agent Test: Not Worked (https://imgur.com/15qxgdR).
- Dialogflow Web Messenger: Worked (https://imgur.com/5ajzd2j).
- Twilio: Not Worked (https://imgur.com/fsrYtDG) and error message was (https://imgur.com/jP6TRbZ).
But, when I changed the Category_Name = “Small%20Appliances”:
- Dialogflow Agent Test: Worked (https://imgur.com/undefined).
- Web Agent Test: Worked (https://imgur.com/undefined).
- Dialogflow Web Messenger: Worked (https://imgur.com/rCn8ksT).
- Twilio: Worked (https://imgur.com/kfXGqTf).
Here a link for web test (I will keep Category_name=’Cooking’) so you can see the result:
https://bot.dialogflow.com/004077c2-d426-472c-89f0-4997e2955d59
What do you think?
Using your code above I was able to loop through agent.add() and got the results. I used test as user input that matches intent "test intent".
Here is a snippet of the 29 similar outputs of your code provided:
Here is the full code:
index.js
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const axios = require('axios');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function yourFunctionHandler(agent) {
const category_name = 'Cooking';
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/qvlk728a5p23g/search?Categories=*${category_name}*&Status=1`).then(function (res) {
console.log(res.data);
let Categories = res.data[0];
if (Categories) {
for(var i=0;i<res.data.length;i++){
agent.add(`https://alaswadtrading.com/index.php?route=product/product&product_id=${Categories.ProductID}\n\n${Categories.Name}`);
}
} else {
agent.add(`No items found in the selected category (${category_name})`);
}
resolve();
});
});
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('test intent', yourFunctionHandler);
agent.handleRequest(intentMap);
});
package.json
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "10"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"firebase-functions": "^2.0.2",
"firebase-admin": "^5.13.1",
"googleapis": "^27.0.0",
"actions-on-google": "2.2.0",
"dialogflow-fulfillment": "0.6.1",
"axios": "0.21.1"
}
}
Just a suggestion, since your objective is to show all products under a certain "category" you might want to loop through the whole res.data. In this example I just used category_name = 'Cooking' and printed all products that is under the specified category.
function yourFunctionHandler(agent) {
const category_name = 'Cooking';
return new Promise((resolve, reject) => {
axios.get(`https://sheetdb.io/api/v1/qvlk728a5p23g/search?Categories=*${category_name}*&Status=1`).then(function (res) {
let Categories = res.data;
if (Categories) {
for (const product of Categories ){
agent.add(`https://alaswadtrading.com/index.php?route=product/product&product_id=${product.ProductID}\n\n${product.Name}`);
}
} else {
agent.add(`No items found in the selected category (${category_name})`);
}
resolve();
});
});
}
This will result to:

fulfillment code error Webhook call failed. Error: UNAVAILABLE

I am developing a voice assistant through dialogflow, google calendar and voximplant.
I have a problem in the fulfillment code because, I don't know why, but I constantly get this error in the DIAGNOSTIC INFO, as well as a series of errors on the console log. Would anyone know how to give me a hand?
I will post the code below:
// 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 {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
// Enter your calendar ID below and service account JSON below
const calendarId = 'c_d86ppgn4qqpmfpq1cjd2higja8#group.calendar.google.com';
const serviceAccount = {
"type": "service_account",
"project_id": "italians-do-it-better",
"private_key_id": "xxxxxxxxxxxx",
"private_key": "-----BEGIN PRIVATE KEY-----\nxxxxxxxxxx\n-----END PRIVATE KEY-----\n",
"client_email": "xxxxxxxxxx#italians-do-it-better.iam.gserviceaccount.com",
"client_id": "xxxxxxxxxxx",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/appointmentscheduler%40italians-do-it-better.iam.gserviceaccount.com"
};
const serviceAccountAuth = new google.auth.JWT({
email: serviceAccount.client_email,
key: serviceAccount.private_key,
scopes: 'https://www.googleapis.com/auth/calendar'
});
const calendar = google.calendar('v3');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
const timeZone = 'Europe/Kaliningrad';
const timeZoneOffset = '+02:00';
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({request, response});
console.log("Parameters", agent.parameters);
const appointment_type = "Default";
//agent.parameters.AppointmentType;
function makeAppointment (agent) {
// Calculate appointment start and end datetimes (end = +1hr from start)
console.log("Parameters", agent.parameters.date);
//Variabili più calcolo orario
const guests = agent.parameters.guests;
const dateTimeStart = new Date(Date.parse(agent.parameters.date.split('T')[0] + 'T' + agent.parameters.time.split('T')[1].split('+')[0] + timeZoneOffset));
const dateTimeEnd = new Date(new Date(dateTimeStart).setHours(dateTimeStart.getHours() + 1));
console.log("date start ", dateTimeStart, " date end ", dateTimeEnd);
const date = new Date(agent.parameters.date);
const bookingDate = new Date(date);
const phonenumber = agent.parameters.phonenumber;
let name = agent.parameters.name;
const email = agent.parameters.email;
var phone = phonenumber.toString().length;
const now = new Date();
const appointmentTimeString = dateTimeStart.toLocaleString( 'en-US', {timeZone:'Europe/Kaliningrad'});
if (guests < 1){
agent.add(`You need to reserve a table for at least one person. Please try remaking the reservation!`);
}
else if (guests > 100){
agent.add(`You can't make a reservation for more than 100 guests. Please try remaking the reservation!`);
}else if (dateTimeStart < now){
agent.add(`You can't make a reservation in the past. Please try remaking the reservation.`);
}
else if (bookingDate.getFullYear() > now.getFullYear()) {
agent.add(`You can't make a reservation for ${bookingDate.getFullYear()} yet. Please choose a date in ${now.getFullYear()}.`);
}
else if (phone != 10) {
agent.add(`Your phone number has to be atleast 10 digits. Please try remaking the reservation!`);
} else {
console.log("appointmentTimeString: ", appointmentTimeString);
// Check the availibility of the time, and make an appointment if there is time on the calendar
return createCalendarEvent(dateTimeStart, dateTimeEnd, guests, name, phonenumber, email, appointment_type).then(() => {
agent.add(`Ok, let me see if we can fit you in. ${appointmentTimeString} is fine!.`);
}).catch(() => {
agent.add(`I'm sorry, there are no slots available for ${appointmentTimeString}.`);
});
}
let intentMap = new Map();
intentMap.set('collectIncorrectValues', makeAppointment);
intentMap.set('ScheduleAppointment.yes', makeAppointment);
agent.handleRequest(intentMap);
}});
function createCalendarEvent (dateTimeStart, dateTimeEnd, guests, name, phonenumber, email, appointment_type) {
const appointmentTimeString = dateTimeStart.toLocaleString( 'en-US', {timeZone:'Europe/Kaliningrad'});
return new Promise((resolve, reject) => {
calendar.events.list({
auth: serviceAccountAuth, // List events for time period
calendarId: calendarId,
timeMin: dateTimeStart.toISOString(),
timeMax: dateTimeEnd.toISOString()
}, (err, calendarResponse) => {
// Check if there is a event already on the Calendar
if (err || calendarResponse.data.items.length > 0) {
reject(err || new Error('Requested time conflicts with another appointment'));
} else {
// Create event for the requested time period
calendar.events.insert({ auth: serviceAccountAuth,
calendarId: calendarId,
resource: {summary: 'Appointment: '+ appointment_type +' Appointment ', description: appointmentTimeString +',\n Name: ' + name + ',\n Guests: '+ guests + ',\n Phonenumber: ' + phonenumber + ',\n Email: ' +email,
start: {dateTime: dateTimeStart},
end: {dateTime: dateTimeEnd}}
}, (err, event) => {
err ? reject(err) : resolve(event);
}
);
}
});
});
}
package.json:
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "10"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "^2.2.0",
"firebase-admin": "^5.13.1",
"firebase-functions": "^2.0.2",
"dialogflow": "^0.6.0",
"dialogflow-fulfillment": "^0.5.0"
}
}
Console log error:
Dialogflow error:
Console log error:
{
"textPayload": "Error: No handler for requested intent\n at WebhookClient.handleRequest (/workspace/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:317:29)\n at exports.dialogflowFirebaseFulfillment.functions.https.onRequest (/workspace/index.js:89:10)\n at cloudFunction (/workspace/node_modules/firebase-functions/lib/providers/https.js:57:9)\n at process.nextTick (/layers/google.nodejs.functions-framework/functions-framework/node_modules/#google-cloud/functions-framework/build/src/invoker.js:100:17)\n at process._tickCallback (internal/process/next_tick.js:61:11)",
"insertId": "000000-9adc6f24-bfa5-469b-ae82-5f4124522534",
"resource": {
"type": "cloud_function",
"labels": {
"function_name": "dialogflowFirebaseFulfillment",
"region": "us-central1",
"project_id": "italians-do-it-better"
}
},
"timestamp": "2021-07-13T08:31:30.209Z",
"severity": "ERROR",
"labels": {
"execution_id": "v9ps952et2kk"
},
"logName": "projects/italians-do-it-better/logs/cloudfunctions.googleapis.com%2Fcloud-functions",
"trace": "projects/italians-do-it-better/traces/f4d789b9c84aaf5bb311c9332f125ca8",
"receiveTimestamp": "2021-07-13T08:31:30.716907289Z"
}

Dialogflow #vitalets/google-translate-api Translation not working

I am using firebase and my translation doesn't working :(
I am not getting any response from it but other functions are working fine
here is my index.js
// 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');
const translate = require('#vitalets/google-translate-api');
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 addTwoNo(agent) {
const sno = agent.parameters['sno'];
const fno = agent.parameters['fno'];
var sum = sno + fno ;
agent.add(`Sum is `+sum)
}
function tratext(agent) {
const text = agent.parameters['text'];
const lto = agent.parameters['lang-to'];
const lfrom = agent.parameters['lang-from'];
const ltoLen = lto.length > 0;
const lfromLen = lfrom.length > 0;
if(ltoLen){
translate(agent.text, {to: lto}).then(res => {
agent.add(res.text);
}).catch(err => {
console.error(err);
});
} else {
translate(agent.text, {to: 'en'}).then(res => {
agent.add(res.text);
}).catch(err => {
console.error(err);
});
}
translate(agent, {to: 'en'}).then(res => {
console.log(res.text);
//=> I speak English
console.log(res.from.language.iso);
//=> nl
}).catch(err => {
console.error(err);
});
}
// // 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/fulfillment-actions-library-nodejs
// // 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('addTwoNo', addTwoNo);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('tratext',tratext)
// intentMap.set('your intent name here', yourFunctionHandler);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
and here is my package.json
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "10"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "^2.2.0",
"firebase-admin": "^5.13.1",
"firebase-functions": "^2.0.2",
"dialogflow": "^0.6.0",
"dialogflow-fulfillment": "^0.5.0",
"#vitalets/google-translate-api": "^4.0.0"
}
}
I am using pay to go firebase
i tested using addTwoNo function and it is working but translate doesn't
I hope I get some help
It seems that, under your tratext function(agent), you are translating the "agent" instead of the "agent.text". You could try as following:
translate(agent.text, {to: 'en'}).then(res => {
console.log(res.text);
//=> I speak English
console.log(res.from.language.iso);
//=> nl
}).catch(err => {
console.error(err);
});
Also, in order to discard any issue with the translate api authentication, you could debug the translate api by translating a dummy text. I suggest you to try using this code snippet and verify the logs generated:
translate("Hola mundo", {to: 'en'}).then(res => {
console.log(res);
}).catch(err => {
console.error(err);
});
Finally, I found a github repository where a user shared a code snippet for translating text using the dialogflow fulfillment under NodeJS, that you may use for reference.

Cannot read property 'parameters' of undefined while passing Context - Actions on Google

Currently I am trying to develop an action.
I am trying to achieve to reuse an intent. Concretely said, it means that the Assistant shall give me the first three items of a list and if I ask for more, then it should give me the next three items of the list.
I implemented the logic, which is locally working but sadly I always got the first three items from the list. Therefore i tried using a context, where I want to pass the index as a parameter and here i am running into the problem. The cloud function logs always gives me:
Cannot read property 'parameters' of undefined.
I am using dialog v2 api and the actions on Google sdk. Following link provides an example how to implement the context and I don't see a big difference there. https://developers.google.com/actions/reference/nodejsv2/overview
The code written for it looks like this:
app.intent('Default Welcome Intent', conv => {
conv.ask('Welcome.')
const lifespan = 100;
const parameters = {
index: 0,
};
conv.contexts.set('movieCtx', lifespan, parameters);
});
app.intent('New Cinema Movies Intent', async conv => {
let movieCtx = conv.contexts.get('movieCtx');
let index = movieCtx.parameters[index]
let movieRepository = new MovieRepository();
movieRepository.index = index;
await movieRepository.fetchNextTitle(3).then(function(titles) {
movieCtx.parameters[index] = movieRepository.index;
conv.ask('The 3 movies are:' + titles.join(', '))
return true;
}).catch(function(err) {
console.log(err);
return false;
});
})
My dependencies:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"actions-on-google": "^2.5.0",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.0.3",
"pg": "^7.7.1"
},
"devDependencies": {
"eslint": "^4.12.0",
"eslint-plugin-promise": "^3.6.0"
},
"private": true
}
Update:
I also tried to change the following lines but also that couldn't help me:
const parameters = {
movieIndex: 0,
};
let index = movieCtx.parameters['movieIndex']
The line
let index = movieCtx.parameters[index]
Should probably be
let index = movieCtx.parameters['index']
(You don't have index defined previous to that, so it is trying to get the reference of undefined, which isn't valid.)
I was able to find the answer!
const {dialogflow} = require('actions-on-google');
const functions = require('firebase-functions');
const MovieRepository = require('./PostgreSQL/MovieRepository');
let movieRepository = new MovieRepository();
const app = dialogflow({debug: true});
const AppContexts = {
NUMBER: 'number',
}
app.intent('Default Welcome Intent', (conv) => {
const lifespan = 10;
const parameters = {
movieIndex: 0,
};
conv.contexts.set(AppContexts.NUMBER, lifespan, parameters);
conv.ask('Welcome!')
});
app.intent('New Cinema Movies Intent', async (conv) => {
const movieCtx = conv.contexts.get(AppContexts.NUMBER);
await movieRepository.fetchNextTitle(3).then(function(titles) {
movieCtx.parameters.movieIndex = movieRepository.index;
conv.ask('The 3 movie titles are: ' + titles.join(', '));
return true;
}).catch(function(err) {
console.log(err);
return false;
});
})
app.intent('Default Fallback Intent', conv => {
conv.ask('Sorry. Can you repeat?')
})
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
As you can see you have to create the AppContext above the intents. Somhow weird but important is that you apply
NUMBER: 'number'
to the context, otherwise you get an undefined context again. And to access your parameters you just need to append your the value of your parameter like this:
movieCtx.parameters.movieIndex

Resources