How to get user first_name in telegram chatbot build with dialogflow_es - dialogflow-es

I'm new to Dialogflow and want to understand how to extract a user's first_name in a Telegram chatbot I created. I built a chatbot using intents + inline editor (code below) and learned how to get users' data from responses using agent.parameters, but still can't code anything to extract parts of user's payload data to get first_name without asking for it. I used the following code but it didn't work:
let display_name = agent.originalRequest.payload.data.message.from.first_name
Would be super grateful if someone can explain the right code function to extract this data!
My full inline code is below.
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const admin = require ('firebase-admin');
admin.initializeApp();
admin.auth();
const db = admin.firestore();
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function welcome(agent) {
agent.add(`Hi! Do you want to create an account?`);
}
function createUser(agent) {
agent.add(`Thank you! You have successfully created your account`);
let uid = makeid(28);
let email = agent.parameters.email;
let password = agent.parameters.user_password;
let display_name = agent.parameters.display_name;
admin.auth().createUser({uid: uid, email: email, password: password});
db.collection('users').doc(uid).set(
{uid: uid,
display_name: display_name,
});
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
let intentMap = new Map();
intentMap.set('Welcome Intent', welcome);
intentMap.set('account.creation', createUser);
intentMap.set('Default Fallback Intent', fallback);
agent.handleRequest(intentMap);
});

This is the code that worked for me
let payload = agent.originalRequest;
let firstname = payload.payload.data.from.first_name;

Related

Google Dialogflow doesn't utilize my changes

I'm trying to create a simple AI chatbot command for my discord bot and it's working out, however, my Dialogflow doesn't seem to utilize any changes that I made like new intents or different responses. it always just returns the text from before the changes or just doesn't return anything at all.
I might be really stupid.
This is my code:
const Discord = require("discord.js")
const axios = require('axios');
const uuid = require('uuid');
const dialogflow = require('#google-cloud/dialogflow');
require("dotenv").config();
const projectId = "mydialogprojectid";
console.log(process.env.GOOGLE_APPLICATION_CREDENTIALS)
const config = require(`../config.json`)
exports.run = async(client, message, args) => {
message.channel.startTyping();
// A unique identifier for the given session
const sessionId = uuid.v4();
console.log(sessionId)
// Create a new session
const sessionClient = new dialogflow.SessionsClient();
const sessionPath = sessionClient.projectAgentSessionPath(projectId, sessionId);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
// The query to send to the dialogflow agent
text: args.join(' '),
// The language used by the client (en-US)
languageCode: 'en-US',
},
},
};
// Send request and log result
const responses = await sessionClient.detectIntent(request);
const result = responses[0].queryResult;
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
console.log(result)
message.channel.stopTyping();
return message.channel.send(result.fulfillmentText ? result.fulfillmentText : "Something went wrong, forgive me please! I'm still in beta.")
}
I have the same issue it works on the Dialogflow console etc but when using it in discord it wouldnt find the intent etc like you described.
At first i thought this was just some cache issue. I will update this if i find a solution.

Display data from JSON external API and display to DIALOGFLOW using AXIOS

I need help with Displaying the response I get from my API to Dialogflow UI. Here is my code. I am currently using WebHook to connect Dialogflow to backend in Heroku.
My code
const functions = require('firebase-functions');
var admin = require("firebase-admin");
var serviceAccount = require("../../reactpageagent-dxug-firebase-adminsdk-26f6q-e1563ff30f.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://reactpageagent-dxug.firebaseio.com"
});
const { WebhookClient } = require('dialogflow-fulfillment');
const { Card, Suggestion } = require('dialogflow-fulfillment');
const axios = require('axios');
module.exports = (request, response) => {
const agent = new WebhookClient({ request, response });
function welcome(agent) {
agent.add('Welcome to my agent');
}
function rhymingWordHandler(agent) {
const word = agent.parameters.word;
agent.add(`Here are the rhyming words for ${word}`)
axios.get(`https://api.datamuse.com/words?rel_rhy=${word}`)
.then((result) => {
console.log(result.data);
result.data.map(wordObj => {
console.log(wordObj.word);
agent.add(JSON.stringify(wordObj.word));
return;
// agent.end(`${wordObj.word}`);
});
});
};
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('rhymingWord', rhymingWordHandler);
agent.handleRequest(intentMap);
}
When I console.log my the result. I get the data from the API in my console.log output, but the Data is not displayed in Dialogflow UI I also do not get any error.
Heroku log
I had real trouble with the result.data.map line of code.
In the end, I avoided it and instead processed result.data after the .then((result) => { line by checking the array length that my API returned, and if it was > 0, loop through it to output each line individually, using agent.add. If the array length was 0, I used agent.add to display a message saying 'No records found'. I used a catch to log any errors (again, using agent.add to send an error message to the user).

MalformedResponse when asking for Permission

I am struggling on creating a very basic example asking the user for permission. The setup is
Intents:
"request_permission":
- phrase "where am I?"
- action: "request_permission"
- events: <empty>
"user_info":
- phrase: <empty>
- action: "user_info"
- events: "actions_intent_PERMISSION"
Following the official example using the node.js fulfillment library, I write:
'use strict';
const functions = require('firebase-functions');
const {Permission, DialogflowApp} = require('actions-on-google');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion, SimpleResponse} = require('dialogflow-fulfillment');
const app = dialogflow({debug: true});
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
const app = new DialogflowApp({request, response});
function welcome_intent(agent) {agent.add(`welcome intent`); }
function fallback_intent(agent) {agent.add(`fallback intent.`); }
function request_permission(agent){
let conv = agent.conv();
conv.ask(new Permission({
context: 'I need your location',
permissions: 'DEVICE_COARSE_LOCATION'
}))
agent.add(conv);
}
function user_info(agent){
if (app.isPermissionGranted()) {
const zipCode = app.getDeviceLocation().zipCode;
if (zipCode) {
app.tell(`your zip code ise ${zipCode}`);
} else {
app.tell('I cannot tell your zip code.');
}
} else {
app.tell('Without permission I cannot tell the zip code');
}
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome_intent);
intentMap.set('Default Fallback Intent', fallback_intent);
intentMap.set('request_permission', request_permission);
intentMap.set('user_info', user_info);
agent.handleRequest(intentMap);
});
Still, when starting the simulator and activating my app and then asking "where am I?" I get
MalformedResponse
'final_response' must be set.
And yes, I did check the firebase console logs and the "Fulfillment"-Slider "Enable webhook call for this event" is on.
I wouldn't ask here if there would a V2 compatible example with a very basic permission request. I am aware of the answer in Dialogflow v2 API + Actions v2 API: MalformedResponse 'final_response' must be set

Unable to get device coarse location when testing with google mini device

Hi I'm facing an issue that, i'm unable to get device coarse location when i tested on google mini device with same dialogflow account.I'm able to get user's name but not device location. I'm frustrated regarding this issue.Please help to resolve this.
Here is my code,
const express = require('express');
const bodyParser = require('body-parser');
const {dialogflow,Permission} = require('actions-on-google');
const app = dialogflow({
clientId : 'xyz'
});
app.intent('Default Welcome Intent', conv => {
const options = {
context: 'To locate you',
permissions: ['NAME','DEVICE_COARSE_LOCATION'],
};
conv.ask(new Permission(options));
});
app.intent('User_info',(conv, params, permissionGranted) => {
console.log(conv);
var location=conv.device.location;
console.log(location);
if(permissionGranted){
const name = conv.user.name;
console.log(name);
var resp="you are located at"+conv.device.location.city;
conv.ask(resp);
}else{
conv.close("sorry I'm unable to locate you right now. Okay bye now");
}
});
const expressApp=express().use(bodyParser.json())
expressApp.post('/',app);
expressApp.listen(3000);
I just tested the DEVICE_COARSE_LOCATION permission, and found an empty object in my Firebase logs where I expected to see the location.
Have you tried using DEVICE_PRECISE_LOCATION instead? Here's a sample how that works:
// Handle the Dialogflow intent named 'Default Welcome Intent'.
app.intent('Default Welcome Intent', (conv) => {
conv.ask(new Permission({
context: 'Hi there, to get to know you better',
permissions: ['NAME', 'DEVICE_PRECISE_LOCATION']
}));
});
// Handle the Dialogflow intent named 'actions_intent_PERMISSION'. If user
// agreed to PERMISSION prompt, then boolean value 'permissionGranted' is true.
app.intent('actions_intent_PERMISSION', (conv, params, permissionGranted) => {
if (!permissionGranted) {
conv.ask(`Ok, no worries. What's your favorite color?`);
conv.ask(new Suggestions('Blue', 'Red', 'Green'));
} else {
console.log(conv);
conv.data.userName = conv.user.name.given;
conv.data.userLatitude = conv.device.location.coordinates.latitude;
conv.data.userLongitude = conv.device.location.coordinates.longitude;
conv.ask(`Thanks, ${conv.data.userName} at latitude ${conv.data.userLatitude} and longitude ${conv.data.userLongitude}. What's your favorite color?`);
}
});

How to connect Dialogflow to Cloud Firestore via the Inline Editor in Dialogflow?

I have a Cloud Firestore database that stores the number of inhabitants of all cities in England in 2017.
Then I have a Dialogflow. Whenever I tell the name of a city to Dialogflow, I want it to get the number of inhabitants in that city from Firestore and return it to Dialogflow.
Specifically, I want to implement this via the Inline Editor.
Question: What lines of code do I need to add to the code below in order to make this happen?
So here is the code that I write in the Inline Editor in Dialogflow > Fulfillment > index.js:
'use strict';
const functions = require('firebase-functions');
const firebaseAdmin = require('firebase-admin');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const App = require('actions-on-google').DialogflowApp;
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(`Hello and welcome!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
agent.handleRequest(intentMap);
});
Here is some sample code showing how to connect Firebase's Firestore database to Dialogflow fulfillment hosting on Firebase functions:
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const {WebhookClient} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function writeToDb (agent) {
// Get parameter from Dialogflow with the string to add to the database
const databaseEntry = agent.parameters.databaseEntry;
// Get the database collection 'dialogflow' and document 'agent' and store
// the document {entry: "<value of database entry>"} in the 'agent' document
const dialogflowAgentRef = db.collection('dialogflow').doc('agent');
return db.runTransaction(t => {
t.set(dialogflowAgentRef, {entry: databaseEntry});
return Promise.resolve('Write complete');
}).then(doc => {
agent.add(`Wrote "${databaseEntry}" to the Firestore database.`);
}).catch(err => {
console.log(`Error writing to Firestore: ${err}`);
agent.add(`Failed to write "${databaseEntry}" to the Firestore database.`);
});
}
function readFromDb (agent) {
// Get the database collection 'dialogflow' and document 'agent'
const dialogflowAgentDoc = db.collection('dialogflow').doc('agent');
// Get the value of 'entry' in the document and send it to the user
return dialogflowAgentDoc.get()
.then(doc => {
if (!doc.exists) {
agent.add('No data found in the database!');
} else {
agent.add(doc.data().entry);
}
return Promise.resolve('Read complete');
}).catch(() => {
agent.add('Error reading entry from the Firestore database.');
agent.add('Please add a entry to the database first by saying, "Write <your phrase> to the database"');
});
}
// Map from Dialogflow intent names to functions to be run when the intent is matched
let intentMap = new Map();
intentMap.set('ReadFromFirestore', readFromDb);
intentMap.set('WriteToFirestore', writeToDb);
agent.handleRequest(intentMap);
});
This came from Dialogflow's Firestore sample located here: https://github.com/dialogflow/fulfillment-firestore-nodejs

Resources