Is it possible to lookup a database in a Dialogflow intent? - dialogflow-es

I'm trying to make an app using DialogFlow which finds a specific object in a specific place.
This is a generic example.
The user would say something like "Where to I find Dog in Europe" and the app would reply with "Dog can be found in Europe via: breeding, finding it out in the wild or by buying it"
considering Dog as input1 and europe as input2
Ideally the app should be able to cross reference input1 and input2 to find the correct response. Can I implement a database like structure and do this?

You can't access a database from Dialogflow directly, but you can build your own fulfillment backend that can do anything you want. It communicates with Dialogflow via HTTP requests/responses in the Dialogflow Webhook format.

Here is an example fulfillment that reads data from Firebase database - https://github.com/actions-on-google/dialogflow-updates-nodejs

You can't access a database directly in Dialog flow, but you can build your own fulfillment back end. I have been using Airtable as a database and Integromat and Webhooks to query the database and parse the results back to Dialogflow. As a novice coder I found this to be the simnplest way.

KaySubb is right, you can make a fulfillment that reads data from a firebase database(or firestore).
You can do this turning on fulfillment at the bottom page of the intent page.
First go to https://console.firebase.google.com/ (login with google account) and you should be able to see your google cloud platform project.
To use firebase, you need to first install it. Get node.js as you need npm first. I'm not sure what OS you're on but go into command line or terminal and type.
npm install firebase --save
then type:
firebase login
this will authenticate your login and connect your project when you deploy.
Then use go to the directory you want to create your project in:
firebase init functions
Select your project and select javascript, install all dependencies
Now go to functions and open the index.js file. Here you can change you write code needed in js.
Write your functions and type:
firebase deploy
in the command line open in the file directory. When it completes, it will
give you a link. This as the webhook URL in dialogflow (it should start with
https://us-central). If you see only 1 link which says
console.firebase.google.com....... then open that link on a browser, click on
"functions" on the left side of the screen and get the link from there.
This should get you started with firebase, now you can link your project to firebase fulfillment. There is great firestore explanation here
https://www.youtube.com/watch?v=kdk6MhhI8oc
But I'll give you a brief explanation:
On the top of your index.js file you will need:
const functions = require('firebase-functions');
var admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
var firestore = admin.firestore();
The basic code is here:
exports.webhook = functions.https.onRequest((request, response) => {
switch(request.body.result.action){
case 'saveData':
let params = request.body.result.parameters
firestore.collection('colName').doc('docName').add({
name:params.name
age:params.age
}).then(() => {
response.send({
speech:
`this is a response for "${params.name}".`
});
})
.catch((e => {
console.log('Error getting documents', e);
response.send({
speech:
`Sorry, something has gone wrong. Try again and if the problem persists, please report it.`
});
}))
break;
default:
}
})
I'll explain what it does:
You need the switch to decide which intent to do. request.body.result.action returns the action name (write this in dialogflow just above the parameters).
Once that is decided request.body.result.parameters give you the parameters from the intent. params.______ gives you the parameter.
I would definitely recommend reading the official documentation:
https://firebase.google.com/docs/firestore/quickstart
to help understand the data structure to help create the ideal database for you. Essentially a collection is a list and within that a doc is one entry. You can name them yourself of using the entries from param.
respond.send is what the bot will reply to the user, I've also shown how to use the parameters in the response.
.catch will just store any errors in the log, you can read the log in console.firebase.google.com.... open your project and click on function. There will be a place to read logs there. You can check any errors encountered over there.
default: will output whatever default response you wrote on dialogflow at the bottom of the intent.
Hope this helps,comment any questions. I have gone through a huge amount as concisely as I could. This will take some time to get used to and become good at, follow the docs and the youtube videos if you have a lot of trouble!
If you're having even more trouble, there is a slack that helps people that I can direct you to.

Related

Is there a way to intercept the query in nlp.js WebChat API server?

Just getting started with nlp.js, and I'd like to be able to test out some ideas with their Express API server package.
As far as I can tell, there's no way to "intervene" in the QnA bot exchange. For instance, if I'd like to format the output to contain the user's name or a time or whatever.
Say my corpus was a tsv file with:
some question \t welcome, #name
And I wanted to swap out that #name tag? Right now, I just get that string exactly as is.
In the conf.json:
"api-server": {
"port": 3000,
"serveBot": true
}
Maybe there's a pipeline logic to do that?
Can't seem to find a lot of reference material on available events in the pipeline or how to intercede in the WebChat flow out there.

How to remove the embed from specific messages and from messages coming from specific users/bots using Discord.js

I'm trying to code a bot that is able to remove the embed of specific messages or the embed created from the links posted by specific users and bots present in the server.
For example, let's say I don't want to see the twitter embed when someone posts a tweet: my bot would automatically remove the twitter embed.
Other case, I don't want people to see the embed of the messages posted by another user or bot present in the server, my bot would then automatically remove the said embeds.
However, reading the API documentation, I didn't see any possibility to do so. Maybe I missed it or maybe there's a trick to do so. Or maybe it's not supported by the API yet.
So does anyone know how I could achieve that goal please?
PS: Yes, I know I could simply deactivate embeds in the server settings, but that's not the goal I want to achieve here. I want it to be specific to certains links/messages and users/bots.
Thanks
You can use the suppressEmbeds method of message.
client.on("message", message => {
if (message.author.bot) return false;
if (message.author.id !== "YourID") { // Example Condition
message.suppressEmbeds(true) // Removes all embeds from the message.
}
})

Can we use firebase crashlytics for our web application?

I have a web application and I want to track its crashing reports.
Can I use Firebase crashlytics or Fabric for this purpose. In their site its mentioned its only for Android or ios.
Regards,
Makrand
There is feature request: https://github.com/firebase/firebase-js-sdk/issues/710
Looks like it's not supported at all, fabric didn't supported crashlytics on web either so it looks like there are maybe some alternatives like https://www.bugsnag.com but I would like to have it too in one place. Don't see difference between web, android or iOS clients at all, don't know why this is not supported.
But for some possible solution for Vue framework is to catch errors and send it to google analytics where you can connect also your firebase mobile apps. I think to try it this way for now. I didnt tested it yet so don't know if I have to catch window errors too.
Vue.config.errorHandler = function (error) {
//Toast.error(error.message)
console.warn(error.message)
//send error as event to google analytcs...
if (error) message = error.stack;
ga('send', 'event', 'Vue.config.errorHandler', message, navigator.userAgent);
}
window.onerror = function(message, source, lineno, colno, error) {
// maybe we need to also catch errors here and send to GA
}
But I found something like this too for typescript https://github.com/enkot/catch-decorator
While there is still no firebase crashlytics for web, google offers Stackdriver with error reporting functionality - it keeps track of all errors with ability to mark them as resolved (it can also send email notifications about new errors):
You can access it using the below url (make sure to put your firebase {project_id} in the link before clicking it):
https://console.cloud.google.com/errors?project={project_id}
There are two ways on how to use it:
Easy way, limited flexibility.
Every console.error(new Error(...)) reported from your firebase function is automatically tracked in the Stackdriver error logging platform.
So you just need to send an error report from your web app to your firebase function and log it using console.error inside that function.
Note, only an instances of Error object will be sent to the Stackdriver platform. For example console.error("{field1: 'text'}") won't be sent to Stackdriver. More info on that in this doc
More comprehensive way that provides an additional control (you can also report userId, your custom platform name, it's version, user agent, etc):
Here is a quick snippet on how it can be used (in our case we first send the error log from web app to our server and then report the error to Stackdriver):
in firebase nodejs:
const {ErrorReporting} = require('#google-cloud/error-reporting');
let serviceAccount = {...} //service account is your firebase credetials that holds your secret keys etc. See below for more details.
let config = {
projectId: serviceAccount.project_id,
reportMode: "always",
credentials: serviceAccount
}
let errors = new ErrorReporting(config);
Report error to Stackdriver from nodejs:
async function reportError(message){
//message is a string that contains the error name with an optional
//stacktrace as a string representing each stack frame separated using "\n".
//For example:
//message = "Error: Oh-hoh\n at MyClass.myMethod (filename.js:12:23)\n etc.etc."
const errorEvent = this.errors.event()
.setMessage(message)
.setUser(userId)
.setServiceContext("web-app", "1.0.0")
await errors.report(errorEvent)
}
More info about the Stackdriver library is available in this doc. And more info about the stacktrace and it's format can be found in the docs here
A few notes on setting it up:
You need to enable two things:
Enable Stackdrive api for your project using the link below (make sure to set your firebase {project_id} in the url below before clicking it)
https://console.developers.google.com/apis/library/clouderrorreporting.googleapis.com?project={project_id}
Make sure to also grant "Error writer" permission to the firebase service account so Stackdriver can receive the error logs (service account is a sort of representation of a "user" for your firebase project who accesses the services)
To grant the premission, follow the below steps:
first locate the "Firebase service account" using your firebase dashboard link (you can find it below) and remember it's value - it looks something like firebase-adminsdk-{random_symbols}#{project_id}.iam.gserviceaccount.com
Then open gcloud console under "Access"->"IAM". Or use the following link:
https://console.cloud.google.com/access/iam?project={project_id} <- put your firebase project id here
Locate your Firebase service account from the step 1.
Press edit for that account and add "Errors writer" permission:
Where to find the serviceAccount.json:
Regarding the serviceAccount - this is a universal credentials that can be used to authenticate many google services including the Stackdriver. You can obtain yours from your firebase dashboard using the url below (just put your firebase project_id in the link before using it):
https://console.firebase.google.com/u/0/project/{project_id}/settings/serviceaccounts/adminsdk
Open it and click "generate new credentials". This will generate a new service account and download the serviceAccount.json that you need to keep safe (you won't be able to get it again unless you generate a new one).
Apparently Sentry now supports several web frameworks out of the box.
I have recently integrated Sentry crashlytics for Django App.
see here:
https://sentry.io/platforms/

Is accessing the Customer Profile API possible using the Cloud9 code editor in the AWS Lambda web console? If so, how?

First off, I'm new to Alexa skill development, so I have much to learn. I've been banging my head off the desk trying to figure this out. I've found various tutorials and have gone over the information provided by Amazon for accessing the Customer Profile API via an Alexa skill but still can't manage to obtain the customer's phone number.
I'm using the AWS console in-line code editor (Cloud9). Most, if not all, instructions use something like 'axios', 'request', or 'https' modules which I don't think is possible unless you use the ask-cli (please correct me if I'm wrong). Also, I followed a tutorial to initially create the skill which had me use Skillinator.io to create an AWS Lambda template based on the skill's JSON in the Amazon Developer console. The format of the code in the Customer Profile API tutorials does not match what was provided by the Skillinator.io tool. The way the Intent handlers are set up is different, which is where I believe my confusion is coming from. Here's an example:
Skillinator.io code:
const handlers = {
'LaunchRequest': function () {
welcomeOutput = 'Welcome to the Alexa Skills Kit!';
welcomeReprompt = 'You can say, Hello!';
this.emit(':ask', welcomeOutput, welcomeReprompt);
},
};
Tutorial code:
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = 'Welcome to the Alexa Skills Kit!';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Hello World', speechText)
.getResponse();
}
};
Can anyone shed some light and help me understand why there is a difference in the way the handlers are formatted, and how (if possible) to create the request to the Customer Profile API?
I've already completed the steps for the necessary permissions/account linking.
Thanks in advance.
EDIT:
I've learned that the difference in syntax is due to the different versions of the sdk, Skillinator being 'alexa-sdk' or v1 and the various tutorials using 'ask-sdk' or v2.
I'm still curious as to whether using modules like 'axios' or 'request' is possible via the in-line code editor in AWS console or if it's even possible to access the Customer Profile API using sdk v1?
I've decided to answer the question with what I've learned in hopes that others won't waste as much time as I have trying to understand it.
Basically, it is possible to use the above-mentioned modules in sdk v1 using the AWS console's in-line code editor but you must create a .zip file of your code and any necessary modules and upload that .zip to Lambda.
I've edited my original answer to include my findings for the difference in syntax in the intent handlers.
From what I can tell (and please correct me if I'm wrong), it is not possible to access the Customer Profile API using the sdk v1.

Microsoft / Botbuilder for NodeJS: Bind URL Parameters to bot session

SDK
Homepage: https://github.com/Microsoft/BotBuilder
SDK Platform: Node.js
SDK Version: 3.14.0
Issue Description
Hi, I searched for this for a long time now but I haven't found an answer.
I was wondering if there is a way to bind some URL parameters to the User's Bot Session.
For example, if for a specific chat dialog, I set my Endpoint URL to:
http://localhost:3978/api/messages?pronuntiation=british
is there a way to get that url parameter named "pronuntiation" down in the session object like...
bot.dialog("/", function(session){
var desiredPronuntiation = session.someUrlParameters.pronuntiation;
if( desiredPronuntiation == "british"){
///blah
}
});
I think it is possible in C# SDK but I was trying to do this in NodeJS...
I already debugged the proces from the server.post('/api/messages', connector.listen()) down to the ChatConnector.verifyBotFramework() where at the end I found it calls _this.dispatch(req.body, res, next); (ChatbotConnector.js on line 149) passing only the post body but not the request object itself...
So at a first glance I think this is not possible, I just wanted to be sure that I didn't miss anything...
Thanks,
Luis
As far as I know, this isn't supported by the Bot Framework, however I don't see why you need to do it this way. This is something you want to store in the state, for example the userData. You can read more here about managing state in the Bot Framework.
If you want to pass user data to the bot, it depends on the channel. For example Facebook and Webchat allow you to pass data direct to the bot, without user input.

Resources