Webhook allowing GET method - dialogflow-es

According to the documentation,
"When an intent in which a webhook was enabled is triggered,
Dialogflow sends data to the service in the form of POST request with
a POST body in the format of response to a query."
So I assume that a GET request is not possible...isn´t it?
In Postman I am able to make a GET request using my code but after deploying to Heroku and setting the URL in the fulfillment section, I am not able to get any proper response beyond a "Webhook call failed. Error: 404 Not Found".
Thanks a lot.
Here´s the code.
This was my first attempt using Node :-)
const express = require('express');
const bodyParser = require('body-parser');
const http = require('https');
var port = process.env.PORT || 8080;
const server = express();
server.use(bodyParser.json());
server.post('/get-movie-details', function (req, res) {
//This line is crashing the app in Heroku from Dialogflow. Paramaters are not correctly passed
let movieToSearch = req.body.result.parameters.query;
let finalurl = encodeURI('https://api.themoviedb.org/3/search/movie?api_key=c21ed50674dabf90143d1136bf9279ae&language=en-US&query=' + req.body.result.parameters.query + '&page=1&include_adult=false');
console.log('This is the finalUrl: ' + finalurl);
http.get(finalurl, (responseFromAPI) => {
responseFromAPI.on('data', function (chunk) {
let movie = JSON.parse(chunk)['results'][0];
let dataToSend = movie.original_title + ' is a ' + movie.vote_average + ' vote average released in ' + movie.release_date + '. Maybe you want some more information?';
return res.json({
speech: dataToSend,
displayText: dataToSend,
source: 'The movieDataBase'
});
});
}, (error) => {
return res.json({
speech: 'Something went wrong!',
displayText: 'Something went wrong!',
source: 'get-movie-details'
});
});
});
server.listen(port);
console.log('Server started! At https://localhost:' + port);

Correct, a GET request isn't possible. The size of the JSON being sent can easily exceed the URL length allowed by GET.

Related

Node js(Express framework): not able to print number API from external server to client browser

I am trying to retrieve weather API from external server and when I am console logging particular data of weather API, it's also showing on my command prompt.
But when I am using get method to show that data on browser I am only able send string data like "description": moderate rain and not number data like "temp": 27
it the crash the app.
Node js code:
//jshint esversion:6
const express = require("express");
const app = express();
const https = require("https");
app.get("/", function(req, res) {
const url = "https://api.openweathermap.org/data/2.5/weather?q=mumbai&appid=d88391210768983e6be06cdd76bdcde3&units=metric";
https.get(url, function(response) {
console.log(response.statusCode);
response.on("data", function(data) {
const weatherData = JSON.parse(data);
const temp= weatherData.main.temp;
const description= weatherData.weather[0].description;
console.log(temp);
console.log(description);
res.send(temp);
});
});
});
app.listen(3000, function() {
console.log("Server is running on port: 3000");
});
You should ideally return a json.
It can be:
res.send({temp: temp, description: description});
The res.send has to return a string/object/array/buffer.
You could do something like:
res.status(200).send(temp)
But sending json response is preferable, and you can scale it as well.
Another hack kind of solution is:
res.send("" + temp)

NodeJS + Express Cors + SocketIO = XMLHttpRequest error

I have created a simple app with nodejs to test socketIO, I have run the server on a sub-domain on my website and the client (In ReactJS) is on another sub-domain.
My server always send me the famous error:
Access to XMLHttpRequest at
'https:///socket.io/?EIO=3&transport=polling&t=MyFav6q'
from origin 'https://' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I have try than 10 solutions but they don't work, I don't know what's the problem here.
app.js
const cors = require("cors");
const app = require("express")();
app.use(cors());
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
socket.emit('message', 'Vous êtes bien connecté !');
socket.on('message', function (message) {
console.log(socket.pseudo + ' me dit: ' + message);
socket.broadcast.emit('message', socket.pseudo + " dit: "+message);
});
socket.on("pseudo", pseudo => {
socket.pseudo = pseudo;
socket.broadcast.emit('message', socket.pseudo + " s'est connecté !");
});
socket.on("reset-draw", data => {
socket.broadcast.emit('reset-draw', socket.pseudo + " a reset le dessin !");
});
socket.on("draw-rect", data => {
console.log(data);
socket.broadcast.emit('draw-rect', data);
});
});
server.listen(8100);
Client on socketIO part:
import socketIOClient from "socket.io-client";
[...]
componentDidMount() {
this._context = this.refs.canvas.getContext('2d');
const socket = socketIOClient("https://<ServerURL>");
socket.emit('pseudo', "testing_guy");
socket.on("reset-draw", data => {
this._context.clearRect(0, 0, 500, 500);
console.log(data);
});
socket.on("draw-rect", data => {
this.drawRect(data);
});
}
Set origins property to io on the server.
io.origins('*')
By default in any case, anything is allowed:
Sets the allowed origins value. Defaults to any origins being allowed.
If no arguments are supplied this method returns the current value.
You can also passo a validation function
I need to use the IP and port send by my host server and after that I have tried a lot of things but it has only work one day after.

Error when requesting API from Angular and Nodejs

I am attempting to use a Nodejs server as a proxy server to get around CORS of specific API's, such as darksky.net or googleapis. As shown in my Angular 8 code below, I try to send a get request to my NodeJS server, passing three parameters. Once the NodeJs server has received these parameters, I request the API, but I get a 404 error in return.
Angular code:
this.http.get('search/coords/',
{
params: {
address: this.street,
city: this.city,
state: this.state
}
}).subscribe(data => {
this.lattitude = data['results']['geometry']['location']['lat'];
this.longitude = data['results']['geometry']['location']['lon'];
console.log(this.lattitude);
console.log(this.longitude);
this.coords = {
lat: this.lattitude,
lon: this.longitude
};
});
return this.coords;
}
And here is my current Nodejs/Express code:
const express = require('express')
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
var request = require('request');
const app = express();
var url = "";
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended': 'false'}));
app.use(cors());
app.get('search/coords/', function (req, res) {
var street = req.query.address;
var city = req.query.city;
var state = req.query.state;
url = "https://maps.googleapis.com/maps/api/geocode/json?address=" + street + "," + city + "," + state + "&key=blah/"
request(url, function(error, response, body) {
if (!error && response.statusCode == 200) {
var info = JSON.parse(body);
res.send(info);
}
})
});
Specifically, I receieve a GET 404 not found error and an ERROR HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/search/coords/?address......." I'm new to angular and nodejs, so any help would be much appreciated.
There are two problems:
First is that you did not start the Node server
Second is that if you call this.http.get('search/coords', ...) then the default domain for that request is the current one, which is http://localhost:4200 and that is not you Node server port.
To make it work, you need to address both of the above.
So firstly, add this code to the Node.js server file (at the very bottom) to make it listen on some port:
app.listen(3000, () => {
console.log('Listening on port', 3000);
});
Then, modify your Angular code to make it look like this:
this.http.get('http://localhost:3000/search/coords/', ....);
It should work that way.

Dialogflow handles one webhook correctly but refuses another

I'm currently using Glitch's(Glitch.com) node.js to connect Dialogflow to code and I'm running into a problem. As you can see below; I have two intents I'm trying to pass values to, characterHandler and openHandler.
Now the weird thing is that it does execute the web hook correctly if I trigger the intent on Dialogflow corresponding to "characterHandler", but it returns "UnhandledPromiseRejectionWarning: Error: no matching intent handler for: null" in the console and fails while triggering "openHandler" and I have no clue why.
Does anyone know what I'm doing wrong?
'use strict';
process.env.DEBUG = 'actions-on-google:*';
const express = require('express');
const bodyParser = require('body-parser');
const request = require("request");
const { DialogflowApp } = require('actions-on-google');
const Map = require('es6-map');
const app = express();
app.use(bodyParser.json());
let characters = ['The Pied Piper', 'Red Riding Hood', 'The Big Bad Wolf'];
// [START Action]
app.post('/', function (request, response) {
const assistant = new DialogflowApp({request, response});
console.log('Request headers: ' + JSON.stringify(request.headers));
console.log('Request body: ' + JSON.stringify(request.body));
const CHARACTERS = 'story.characters';
const OPENINGTIMES = 'openingTimes';
function characterHandler (assistant) {
let responseText = "How about";
responseText = characters[Math.floor(Math.random() * characters.length)];
assistant.tell(responseText);
}
function openHandler (assistant) {
assistant.tell('This attraction is currently full');
}
const actionMap = new Map();
actionMap.set(CHARACTERS, characterHandler);
actionMap.set(OPENINGTIMES, openHandler);
assistant.handleRequest(actionMap);
});
// [END Action]
// Renders the homepage
app.get('/', function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('');
res.end();
});
if (module === require.main) {
// [START server]
// Start the server
let server = app.listen(process.env.PORT || 3000, function () {
let port = server.address().port;
console.log('App listening on port %s', port);
});
// [END server]
}
module.exports = app;
Your open handler function is mapped to 'openingTimes'. Make sure that exactly matches the intent name and make sure that the intent was actually saved correctly.

Facebook messenger bot error "TypeError: Cannot read property '0' of undefined."

I'm trying to create a Facebook chatbot using NodeJS, Express, and a Heroku server.
I created my webhook on Heroku and had it verified and saved by Facebook. I then ran this code to connect my webhook to Facebook.
curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=<token>"
this returned {success:true}.
So then I started adding code that would reply to incoming messages but I can't seem to get it to receive the sent information. Whenever I send a message I get no reply.
Everything is connected and running but this error I am getting "TypeError: Cannot read property '0' of undefined" is because I'm not getting the message information sent to my webhook from facebook. This is the line of code that is empty:
messaging_events = req.body.entry[0].messaging;
Here is my full code:
var express = require('express');
var bodyParser = require('body-parser');
var request = require("request")
var app = express();
var port = process.env.PORT || 3000;
// body parser middleware
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', function (req, res) {
if (req.query['hub.verify_token'] === '8FKU9XWeSjnZN4ae') {
res.send(req.query['hub.challenge']);
console.log("app.get ran")
res.sendStatus(200)
}
console.log("Error: wrong validation token")
})
app.post('/', function (req, res) {
messaging_events = req.body.entry[0].messaging;
console.log("app.post ran")
for (i = 0; i < messaging_events.length; i++) {
event = req.body.entry[0].messaging[i];
sender = event.sender.id;
if (event.message && event.message.text) {
text = event.message.text;
sendTextMessage(sender, "Text received, echo: "+ text.substring(0, 200));
}
}
res.sendStatus(200);
});
app.listen(port, function () {
console.log('Listening on port ' + port);
});
var token = "<myToken>";
function sendTextMessage(sender, text) {
messageData = {
text:text
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending message: ', error);
} else if (response.body.error) {
console.log('Error: ', response.body.error);
}
});
}
Here are my Heroku Logs:
So I'm confused as to why I'm not getting the message data when my webhook is connected to Facebook and they are communicating. I also made sure I had all the subscription fields necessary checked.
Anyone see the problem? Any help is appreciated. Thanks!
Edit: I'm following this guide by the way - https://developers.facebook.com/docs/messenger-platform/quickstart
I had the same problem. Can you add app.use(bodyParser.json()) before bodyParser.urlencoded() ) ?

Resources