what is the difference between webhook client and action-on-google - dialogflow-es

I have a question about the Dialogflow node js code.
There are two different way to build an intent in code :
with the webhook client
with action on google
the code has a form like :
app.intent(....) with conv.ask or a basic function with agent.add(...) .

Related

Handle Dialogflow requests from multiple users through ngrok

I'm working on a website for school, using Dialogflow, ReactJs and NodeJs. I am pretty new to doing this and I am not certain whether my implementation will work for my use case.
My website involves a game, which the server-side needs game state information from. I am sending requests from React to NodeJs as follows:
axios({
method: 'post',
url: '/game_state',
data: {'current_player': current_player}
// ... (more data is sent in reality)
}
);
My post requests are then handled by NodeJs as follows:
app.post('/game_state',express.json(),(event)=>{
current_player = event.body.current_player;
// ... (more data)
});
This data can then be accessed by a Dialogflow request. For example, if the user asks: "Who's turn is it?", an intent with webhook fulfillment can then be triggered. The code for that:
function turn(agent){
current_player == 1 ? agent.add("Your turn") : agent.add("My turn");
}
As I said before, I am not very experienced with developing websites. I want to be able to use my implementation with multiple users at the same time, so one user's game states shouldn't influence those of another user.
So far, I've been using (the free version of) ngrok to test my website. My implementation works perfectly fine if only one user is accessing the link. However, when I open the website twice on the same computer (using the ngrok-generated link) and interact with e.g. the turn intent, I notice that the turn response will be the same for both even if for one session, it's the player's turn and for the other, it's the chatbot's turn.
Most likely, the post request is being overwritten given that the same link is used. I would like to find a solution that makes it possible to use the same link but have the server keep the game state information separate for each user. I feel like this might be possible with a user ID, but I'm stumped on how to implement that.
I know something like this may be an option: app.get("/game_state/:id", ...), but I am not sure how to also get this information to be available for the Dialogflow part of the implementation. Dialogflow calls the server itself, so it doesn't pass this user ID with it. Somehow, I'd need to distinguish it there as well.
Any suggestions would be greatly appreciated!
When you make Dialogflow detected intent API call at that time you are creating a session path
const sessionPath = await sessionClient.projectAgentSessionPath(PROJECTID, sessionId);
If you pass session Id = 123456789A so for this Id Dialogflow managed all context and parameter on Id 123456789A
session Id = USER
when you get the webhook call to the server you also get this session Id or we also called UserId like
let userId = agent.session.split('/')[4]
you can find more information here
dialogflow session

Making a POST request in webhook in an Actions on Google app.intent [duplicate]

This question already has an answer here:
Making an HTTP POST request from fulfillment in Dialogflow
(1 answer)
Closed 4 years ago.
We are creating an action that will take user's input and create an entity in our database (datastore).
Ideally, we would like to be able to access the user's raw input audio, but it doesn't seem that is possible.
As a work around we are going to send the speech-to-text of user's utterance to our backend services. We are using firebase cloud functions for our fulfillment and an external rest api for our crud operations.
We are trying to make a post request in a webhook to create an entity based on user's input, but when I check my logs it doesn't seem like the post request is reaching our service. I'm not able to debug what or if we are getting a response back
app.intent('favorite color', (conv, {color}) => {
const options = {
// options
};
function callback(error, response, body) {
// log response or error
}
request(options, callback);
const luckyNumber = color.length;
// Respond with the user's lucky number and end the conversation.
conv.close('This word has ' + luckyNumber + ' letters.');
});
// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
This question is not the same as the one that it was marked as a duplicate because the solution was the account type not supporting POST requests to an external API and not the HTTP Client we were using
The Inline Editor in the Dialogflow console uses Firebase Cloud Functions, as you already know.
Unfortunately, Firebase Cloud Functions DOESN'T support external API calls in it's free plan. You may need to switch to blaze plan or deploy your fulfillment elsewhere.

Response from Webhook using NodeJS Client

I built a custom webhook as a fulfillment endpoint for a Dialogflow intent. It works fine when I respond with raw JSON, ie: {'fullfillmentText':'hi'},
but does not seem to work using the "actions-on-google" library.
The code from their website implies this should work:
app.intent('myintent', (conv) => {
conv.close('See you later!');
});
But it does not. Google Home just says my app isn't responding. It might be that as it stands my function (using Fn Project) has to return JSON and if I return JSON as a response that it isn't expecting it fails. Maybe someone can shed some light?
Edit 1:
I'm using a custom webhook using the Fn Project open source functions as a service. Demonstrating how to use the project is my purpose here so I don't want to use inline editor or Google Cloud Functions or firebase or any other default option.
Here's the rest of the code
const fdk = require('#fnproject/fdk');
const request = require('request');
const dialogflow = require('actions-on-google');
const app = dialogflow({
debug: true,
});
fdk.handle(function (input) {
app.intent('myintent', (conv) => {
conv.ask('I could not understand. Can you say that again?');
});
return {'fulfillmentText': 'response from webhook'}
});
Although you are creating the app object, which does the Intent handler processing and such, and registering a handler with it via app.intent(), you're not doing anything to "export" it so app's methods are called when the webhook is triggered. When called, it gets the body of the request and will format the JSON for the response.
If, for example, you were using Firebase functions, you would connect app to be handled through the functions with something like
exports.fulfillment = functions.https.onRequest(app);
But you're not. You're using a different framework.
The library comes with a number of frameworks that are supported out of the box, but the Fn Project isn't one of them. In theory, you can create your own Framework object which will do this for you (the "Frameworks" section of this article discusses it briefly, but doesn't go into details about how to do so).
As you surmise, it may be easiest for you to just read the JSON request and generate the JSON response yourself without using the actions-on-google library. Or you can look into a library such as multivocal to see if it would be easier to leverage its multi-framework support.

When is a conversation started on Facebook? - NodeJS SDK

When a facebook messenger user start a conversation I want to get the data like name, photo, etc ... and send to my API.
But I'm doubtful when I should do this.
It would be in the:
bot.on('conversationUpdate', (session) => {
// On here??
})
Facebook doesn't support the conversationUpdate event. It won't send events when you start a conversation, however you could solve your issue in two different ways.
Create a custom middleware that checks if you already have the userData from Facebook and retrieve it when you don't have it yet.
Create a custom middleware that translates Facebook's callbacks to intents
I already created those for NodeJS, which you can use in your bot. BotBuilder-FacebookExtensions
If you need more guidance, you can read the blogs I wrote about this:
How to retrieve User Data from Facebook /
How to process Facebook Messenger callbacks

Getting Agent Info from API.ai fulfilment request

Is there a way that I can get the API.ai agent information from the fulfillment request?
I am trying to capture any unique parameter from Node.js code that can be passed from Agent. This will be utilized for proceeding with the logic for multiple agents using a single code base.
For Amazon Alexa I could get the Skill Application Id from the session. Is there something similar in API.ai?
If you want to get agent id you can make something like this (using express framework):
app.post(`/:agent_id/webhook`, (req, res) => {
const apiai_agent_id = req.params.agent_id;
// webhook code...
});
And on fulfillment page in this case for each agent you have to specify it's own webhook URL like
https://mywebhooks.com/55982e7c-db17-47ee-92bb-176476228942/webhook
(you can get agent id for webhook URL from browser's address bar)
You can use the API.AI's sessionId or intentId which will be unique across agents. The sessionId and intentId* is sent with every fulfillment webhook request. The of the JSON sent are similar to this:
{
"id": "1a4b6209-51ec-47a1-a797-2e2f71926ac8",
"sessionId": "1503343146047"
...
}
but will contain other elements as well.
*intentId may include additional numeric identifier after the intent ID if you are using slot filling
Source: https://api.ai/docs/fulfillment#request

Resources