Reputation: 4733
I have used dialogflow-fulfillment-nodejs library and have to store results of dialogflow chatbot in the firestore database. So that when users enter their details in the chatbot while ordering, they get stored in the firestore database. Here is the code I have tried but it's not working:
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
var firestore = admin.firestore();
const { WebhookClient } = require('dialogflow-fulfillment');
const { Carousel } = require('actions-on-google');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.firestorehotelreservation = functions.https.onRequest((request, response) => {
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
const params = request.body.queryResult.parameters
switch (request.body.result.action) {
case 'input.welcome':
//let params = request.body.result.parameters;
firestore.collection('orders').add(params)
.then((agent) => {
agent.add(`Welcome to my agent!`);
})
.catch((e => {
console.log("error: ", e);
response.send({
speech: "something went wrong when writing on database"
});
}))
break;
case 'input.unknown':
firestore.collection('orders').add(params)
.then((agent) => {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
})
.catch((e => {
console.log("error: ", e);
response.send({
speech: "something went wrong when writing on database"
});
}))
break;
case 'RoomBooking':
firestore.collection('orders').add(params)
.then((agent) => {
agent.add(`${params.name} your hotel booking request for ${params.RoomType}room is forwarded for
${params.persons}persons. We will contact you on ${params.email} soon`);
})
.catch((e => {
console.log("error: ", e);
response.send({
speech: "something went wrong when writing on database"
});
}))
break;
case 'complaint':
firestore.collection('orders').add(params)
.then((agent) => {
agent.add(`Your ${params.typeFeedback} is duly noted against: \n Subject: ${params.subject}.
\n Description: ${params.description}`);
})
.catch((e => {
console.log("error: ", e);
response.send({
speech: "something went wrong when writing on database"
});
}))
break;
default:
response.send({
speech: "no action matched in webhook"
})
}
});
The chatbot worked perfectly fine when I coded without the dialogflow-fulfillment-nodejs library and I got the response at dialogflow chatbot.
Upvotes: 1
Views: 265
Reputation: 4733
In case if anyone is looking for the same question; Here is how I corrected the code. It is working now.
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const { WebhookClient } = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const _agent = new WebhookClient({ request, response });
// const params = request.body.queryResult.parameters;
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
console.log('working');
agent.add(`Good day! Do you want to book a room or have some feedback for us?`);
}
function fallback(agent) {
agent.add(`I'm sorry, I didn't understand. Can you say that again?`);
}
function roombooking(agent) {
const firstname = agent.parameters.firstname;
const lastname = agent.parameters.lastname;
const persons = agent.parameters.persons;
const email = agent.parameters.email;
const RoomType = agent.parameters.RoomType;
console.log(firstname, persons, email, RoomType);
console.log("agent parameters: ", agent.parameters);
const dialogflowAgentRef = db.collection('data').doc();
return db.runTransaction(t => {
t.set(dialogflowAgentRef, { entry: firstname, lastname, persons, email, RoomType});
return Promise.resolve('Write complete');
}).then(doc => {
agent.add(`${firstname} ${lastname} your hotel booking request for ${RoomType} room is forwarded for
${persons} persons. We will contact you on ${email} soon`);
}).catch(err => {
console.log(`Error writing to Firestore: ${err}`);
agent.add(`Failed to write on database`);
});
}
function complaint(agent) {
const typeFeedback = agent.parameters.typeFeedback;
const subject = agent.parameters.subject;
const description = agent.parameters.description;
const dialogflowAgentRef = db.collection('data').doc(); //.doc=docRef,('agent=anythin'=path)
return db.runTransaction(t => {
t.set(dialogflowAgentRef, { entry: typeFeedback, subject, description });
return Promise.resolve('Write complete');
}).then(doc => {
agent.add(`Your ${typeFeedback} is duly noted against: \n Subject: ${subject}.
\n Description: ${description}`);
}).catch(err => {
console.log(`Error writing to Firestore: ${err}`);
agent.add(`Failed to write on database`);
});
}
// Run the proper handler based on the matched Dialogflow intent
const intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('RoomBooking', roombooking);
intentMap.set('Complaint', complaint);
_agent.handleRequest(intentMap);
});
Upvotes: 1
Reputation: 50741
The biggest issue is that the agent
parameter doesn't appear to be a WebhookClient object, which it needs to be if you're going to call add()
and have it add to the reply. It looks like your agent
is the result from the firestore call.
Typically, one also sets up a function for each Intent, maps the Intent Name (rather than the Action name) to this function, and uses a dispatcher that is part of the dialogflow-fulfillment library to determine which handler function should be called.
It isn't clear why you think you need to use the library. If you're handling the input yourself, and you're sending JSON output fine, you don't need to use the library.
Upvotes: 0