I would like to split functions to different js files, using webhook hosted in firebase.
Because i anticipate i will be writing more functions int the future.
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
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(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
function hello(agent) {
console.log("hello);
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('hello',hello);
agent.handleRequest(intentMap);
});
Your index.js
const functions = require('firebase-functions');
const { WebhookClient } = require('dialogflow-fulfillment');
const welcome = require('./welcome')
const fallback = require('./fallback')
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));
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
agent.handleRequest(intentMap);
});
You can split files like welcome, fallback
=> welcome.js
const welcome = (agent) => {
agent.add(`Welcome to my agent!`);
}
module.exports = welcome
=> fallback.js
const fallback = (agent) => {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
module.exports = fallback
Related
I want to use user sessions in my Dialogflow bot currently whats happening is when I save something in a variable in webhook it saves for all the users I don't want it like that I want different sessions for unique users
const axios = require('axios');
const express = require('express')
const {WebhookClient} = require('dialogflow-fulfillment')
var cookieParser = require('cookie-parser');
var session = require('express-session');
const app = express()
app.use(express.json())
app.get('/', (req, res) => {
res.send("Server Is Working.....")
})
app.post('/webhook', (req, res) => {
// get agent from request
let agent = new WebhookClient({request: req, response: res})
// create intentMap for handle intent
let intentMap = new Map();
// add intent map 2nd parameter pass function
intentMap.set('weather',weatherIntent)
intentMap.set('sessiontest',sessiontest)
// now agent is handle request and pass intent map
agent.handleRequest(intentMap)
})
function sessiontest(agent){
agent.add("session")
}
function weatherIntent(agent){
const apiKey = "23756992e06787aa9225e9b361dfcd66"
const city = agent.parameters.city;
const url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=imperial`
return axios.get(url)
.then(function (response) {
// handle success
console.log(response.data.main.temp);
agent.add("Temp in " + city + " is " + response.data.main.temp)
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always execut
});
}
app.listen(3000, () => {
console.log("Server is Running on port 3000")
})
You can store session data within the session itself, with the parameters being passed in the JSON request and response. You can use conv.data to provide a key-value pair of variables you want saved.
app.intent('Default Welcome Intent', conv => {
conv.data.someProperty = 'someValue'
})
I am working with dialogflow for a chatbot app.
But when I run NodeJS always response with error
Invalid or unknown request type (not a Dialogflow v1 or v2 webhook request)
in the line where I declare the agent.
This is the original code. What is wrong?? :(
'use strict';
const express = require("express");
bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
const { WebhookClient } = require("dialogflow-fulfillment");
var port = process.env.PORT || 3000;
app.post("/order", express.json(), function (req, res) {
// Error on next line
const agent = new WebhookClient({ request: req, response: res });
console.log('Dialogflow Request headers: ' + JSON.stringify(req.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(req.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
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);
})
app.get('/hello', function (req, res) {
res.send ('Hello World');
})
app.listen(port, () => {
console.log("Listening port: " + port);
})
I have created new agent and enables the fulfillment for Default Welcome Intent and also enabled the inline editor but when I invoked my welcome intent in simulator then it gives me default response instead of fulfillment response.
Am I doing something wrong?
this is my code
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
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(`Welcome to my agent!`);
}
function fallback(agent) {
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);
});
I have changed my code and now it's working
this is my new code
'use strict';
const functions = require('firebase-functions');
const {dialogflow} = require ('actions-on-google');
const {Suggestions} = require ('actions-on-google');
const WELCOME_INTENT = 'Default Welcome Intent';
const FALLBACK_INTENT = 'Default Fallback Intent';
const app = dialogflow();
app.intent(FALLBACK_INTENT, (conv) => {
conv.ask("Sorry! Could you please repeat that?");
});
app.intent(WELCOME_INTENT, (conv) => {
conv.ask("Hello!");
conv.ask("What you would like to do?");
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
Relatively new to node.js, I am wondering if anyone could help me please.
My MERN stack is working fine and authentication is working.
I am integrating Google's Dialogflow into a MERN stack and I would like to pass a user's username to the fulfillmentRoutes.js file.
The fulfillmentRoutes.js is as follows (I removed unnecessary code, it is just the bare bones);
fulFillmentRoutes.js
const {WebhookClient, Payload, Card} = require('dialogflow-fulfillment');
const express = require('express');
const router = express.Router();
const jwtDecode = require('jwt-decode');
const chatbot = require('../chatbot/chatbot');
const mongoose = require('mongoose');
const passport = require('passport');
const keys = require('../config/keys');
const Coupon = mongoose.model('coupon');
const Counter = mongoose.model('counters');
const Define = mongoose.model('define');
const sourceFile = require('./api/users.js');
const Themes = require('../models/Themes');
const Time = require('../models/Time');
const Questionexp = require('../models/Questionexp');
var cookieParser = require('cookie-parser');
var session = require('express-session');
module.exports = app => {
app.post('/api/df_text_query', async (req, res) => {
let responses = await chatbot.textQuery(req.body.text, req.body.userID, req.body.parameters);
res.send(responses[0].queryResult);
});
app.post('/api/df_event_query', async (req, res) => {
let responses = await chatbot.eventQuery(req.body.event, req.body.userID, req.body.parameters);
res.send(responses[0].queryResult);
});
app.post('/', async (req, res) => {
const agent = new WebhookClient({ request: req, response: res });
async function learn(agent) {
Demand.findOne({'course': agent.parameters.courses}, function(err, course) {
if (course !== null ) {
course.counter++;
course.save();
} else {
const demand = new Demand({course: agent.parameters.courses});
demand.save();
}
});
let responseText = `You want to learn about ${agent.parameters.courses}.
Here is a link to all of my courses: https://www.udemy.com/user/jana-bergant`;
let coupon = await Coupon.findOne({'course': agent.parameters.courses});
if (coupon !== null ) {
responseText = `You want to learn about ${agent.parameters.courses}.
Here is a link to the course: ${coupon.link}`;
}
agent.add(responseText);
}
async function welcome(agent) {
agent.add(“Hello!);
}
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 Welcome Intent - custom', continuesession);
agent.handleRequest(intentMap);
});
}
The file above file sits in a folder outside the api folder, but inside the routes folder.
I want to share a user's username is personalise conversation using the fulfillment module above.
I have declared a session in my server.js file which sits in the main app root.
server.js
app.use(session({
resave: true,
saveUninitialized: true,
secret: "secret"
}));
In my users.js file in ./routes/api directory, I did the following in users.js
users.js
router.get('/current', passport.authenticate('jwt', { session: false }),
(req, res) => {
req.session.test = req.user.email;
res.send(req.session.test);
res.json({
id: req.user.id,
firstname: req.user.firstname,
lastname: req.user.lastname,
email: req.user.email,
week: req.user.week,
age: req.user.age,
time: req.user.time,
bookmark: req.user.bookmark,
alertDate: req.user.alertDate
});
}
);
However, when I use session extract line (below) in the fulfillmentRoutes.js (file quoted at the beginning) I get undefined.
username = req.session.test;`
Any help would be appreciated please.
Thank you,
P
I'm trying to use the dialog-fulfillment-library with express, without firebase functions. I'm having trouble finding how to res on the agent though.
const { WebhookClient, Card, Suggestion } = require('dialogflow-fulfillment');
module.exports = function () {
let self = {};
self.create = function (req, res, next) {
const agent = new WebhookClient({request: req, response: res});
agent.add(new Suggestion(`Quick Reply`));
agent.add(new Card({
title: `Title: this is a card title`,
imageUrl: 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
text: `This is the body text of a card. You can even use line\n breaks and emoji! 💁`,
buttonText: 'This is a button',
buttonUrl: 'https://assistant.google.com/'
})
);
res.json(agent);
};
return self;
};
I get a TypeError: Converting circular structure to JSON
I've tried decycling the agent but then it doesn't work on the dialogflow side.
using:
res.send(JSON.stringify(agent, decycle()));
returns: Webhook call failed. Error: Failed to parse webhook JSON response: Cannot find field: request_ in message google.cloud.dialogflow.v2.WebhookResponse.
Has anyone used it in this way or is it not possible?
I have submitted a Pull Request for the same.
Following code works for me.
package.json
{
"name": "Test_Agent",
"version": "0.0.1",
"description": "Test Agent webhook",
"main": "server.js",
"author": "Abhinav Tyagi, New Delhi, India",
"dependencies": {
"dialogflow-fulfillment": "^0.4.1",
"body-parser": "^1.18.3",
"express": "^4.16.3",
"actions-on-google": "^2.2.0"
}
}
server.js
'use strict';
const {WebhookClient} = require('dialogflow-fulfillment');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
function welcome (agent) {
agent.add(`Welcome to Express.JS webhook!`);
}
function fallback (agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
function WebhookProcessing(req, res) {
const agent = new WebhookClient({request: req, response: res});
console.info(`agent set`);
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
// intentMap.set('<INTENT_NAME_HERE>', yourFunctionHandler);
agent.handleRequest(intentMap);
res.status(200).send(agent);
}
// Webhook
app.post('/', function (req, res) {
console.info(`\n\n>>>>>>> S E R V E R H I T <<<<<<<`);
WebhookProcessing(req, res);
});
app.listen(8080, function () {
console.info(`Webhook listening on port 8080!`)
});
Make sure to use both action-on-google and dialogflow-fulfillment modules.
The intentMap keys is the intent.displayName.