Getting Dialogflow webhook path parameters using Actions On Google SDK - node.js

Is there a way to retrieve path parameters setted by Dialogflow fulfillment webhook?
I'm using Node.js actions-on-google SDK in a Google Cloud Function.
My webhook URL is something like this: https://europe-myexample.cloudfunctions.net/actionHandler/v1
I need to get the v1 param to use it in manageWelcomeIntent function.
const NLGService = require('./services/NLGService.js');
const {dialogflow} = require('actions-on-google');
const app = dialogflow();
exports.actionHandler = app;
app.intent('welcome_intent', NLGService.manageWelcomeIntent);

Can't you e.g. use
const url = require('url');, or, even simpler, req.url
for finding out your server url and then extracting the param?

Related

get data from webhook telegram bot with node js

I set the server address for the bot with /setwebhook, now how can I get the data with only node js and https package to access {message :{...} }? (like /getupdates method) but by webhook , probably I mean like the php code but in node js: file_get_contents("php://input") .
Should I use async or https.createServer ? If yes, how and please explain a little
You have to create a server that will handle receiving the data. You can do this by using http.createServer or, more conveniently, using a library such as Express. Simple implementation using Express would look like this:
const app = express();
app.post(`/api/telegram${process.env.TELEGRAM_BOT_TOKEN}`, async (req, res) => {
const message = req.body.message || req.body.edited_message;
...
});
In this example, I use bot token in the webhook url (since I and Telegram are the only entities that know the bot token, I can be sure that the requests to the url come from Telegram). There are better ways to make the webhook secure, such as using secret_token as specified in the docs for setWebhook method.
For development purposes, you can use a service like ngrok to redirect requests from the bot webhook to localhost.
To get an idea of a fully functioning example of implementing webhook with node.js and Express, you can check my open-source project on Github.

Is there a solution for testing the dialogflow fullfilment on local without deploying on production?

I've created an agent on dialogflow, for each change on the inline editor from fulfillment, this implies directly on production, without passing by a test or publishing.
Is there a solution like dev environment to test fulfillment locally before push and deploy on production?
const express = require('express')
const bodyParser = require('body-parser')
const { dialogflow } = require('actions-on-google')
const app = dialogflow()
const expressApp = express().use(bodyParser.json())
app.intent('Default Welcome Intent',(conv)=>{
conv.ask('.....')
})
app.intent("Default Fallback Intent",(conv)=>{
conv.ask('.....')
})
expressApp.post('/', app)
expressApp.listen(5000)
You can run this server and can simulate live using ngrok.
Then you can give ngrok URL in Dialogflow fulfilment and test it out locally.
Yes, there exist a solution. You can use Actions Simulator to test your fulfillment prior to production. In Dialogflow click the Integrations choose Google Assistant. On the integration screen you will see TEST option. Here's the link from the documentation: Simulator
Alternatively, you can create different versions in Environments. Test them using simulator (as described above) then publish it.

How to use IMAGE function from both Dialogflow and Actions-on-Google libraries

I'm using the Fulfillment inline editor. My agent is using functions from both Dialogflow and Actions-on-Google. I have already used succesfull Image functions from Dialogflow, but I also need to use the image of the Action-on-Google library for another. How to do this?
// DialogFlow functions
const { WebhookClient, Card, Image, Suggestion } = require('dialogflow-fulfillment');
// Import the Dialogflow module from the Actions on Google client library.
// https://github.com/actions-on-google/actions-on-google-nodejs
const {dialogflow, Suggestions, BasicCard, MediaObject, SimpleResponse, Table, Button, List} = require('actions-on-google');
The most simple solution would be to add the IMAGE function to the Actions-on-Google functions:
const {dialogflow, [...], Image, List} = require('actions-on-google');
But unfortunately this of course not possible due to ambiguity. How to solve this?

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.

Twilio $_REQUEST['From'] equivalent for node.js

I'm trying to use 'twilio' to grab the caller ID from an incoming phone call. I managed to do this easily in my call.php file using the following:
$callerId=($_REQUEST['From']);
I have now redirected my twilio phone number to access a different URL so that I can use it with node.js (ie call.php is now call.js). However, I cannot seem to request the ['From'] field in a similar manner as with the .php file. Is this possible? What is the easiest way to grab a caller Id and store it in a variable using node.js?
Any thoughts appreciated.
For the sake of completeness, here's a full example of getting Twilio request parameters using Express. Before running, make sure to install dependencies with npm install twilio express. You might also benefit from reading this blog post introducing the Twilio node.js module.
This code is an example of responding to an inbound phone call:
// Module dependencies
var twilio = require('twilio'),
express = require('express');
// Create an Express webapp, and use a middleware
// that parses incoming POST parameters
var app = express();
app.use(express.urlencoded());
// Create a route that responds to a phone call by saying
// the caller's number
app.post('/call', function(request, response) {
var twiml = new twilio.TwimlResponse();
twiml.say('Hello, you called from ' + request.param('From'));
response.type('text/xml');
response.send(twiml.toString());
});
// Start the app on port 3000
app.listen(3000);

Resources