Skip to content

Instantly share code, notes, and snippets.

@karladler
Created May 19, 2019 20:32
Show Gist options
  • Save karladler/ad43248a4cef4528acec401ef8664ca7 to your computer and use it in GitHub Desktop.
Save karladler/ad43248a4cef4528acec401ef8664ca7 to your computer and use it in GitHub Desktop.
Dialogflow express.js backend for two intents. One fetches next event from barcamp app, the other reacts to opnions.
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Text, Suggestion} = require('dialogflow-fulfillment');
const cache = require('memory-cache');
const https = require('https');
const express = require('express');
const PORT = process.env.PORT || 5000;
const HOUR = 60 * 60 * 1000;
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
function toTime(dateStr) {
return new Date(dateStr).getTime();
}
function getNextEvents(events) {
const now = new Date().getTime();
let counter = 0;
return events.filter((event) => {
const eventStart = toTime(event.time.start);
if (counter < 8 && eventStart > now && eventStart < now + 24 * HOUR) {
counter += 1;
return true;
}
return false;
});
}
function getEvents() {
let events = cache.get('events');
if (events !== null) {
return JSON.parse(events);
}
return new Promise((resolve, reject) => {
https.get('https://lineupr.com/api/organizers/mobilecamp/events/2019/data', function (resp) {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
const parsedData = JSON.parse(data);
events = parsedData.items;
cache.put('events', JSON.stringify(events), 5000);
resolve(events);
});
}).on("error", (err) => {
reject(err);
});
});
}
const processWebhook = function( request, response ) {
const agent = new WebhookClient({ request, response }); // TODO mock on local
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function fallback(agent) {
agent.add(`Orsch wer bleede!`);
agent.add(`Das habsch nu ni verstandn. Was meesnte?`);
}
function nextEvents(agent) {
return getEvents().then((events) => {
const soonEvents = getNextEvents(events);
if (!soonEvents || soonEvents.length === 0) {
agent.add("Leider keine Events in nächster Zeit gefunden.");
return;
}
const responseMsg = soonEvents.map((ev) => {
return `${ev.name} Start: ${new Date(ev.time.start).toLocaleTimeString('de-DE')}`;
}).join(' # ');
agent.add(new Text({
text: responseMsg
}));
}).catch((err) => {
agent.add("Fehler beim abrufen der Events :( " + err.message);
});
}
function opinionResponse(agent) {
const opinion = agent.parameters['opinion'];
let textMsg = '';
switch(opinion) {
case 'schlecht':
textMsg = 'Na dann geh doch zu Netto!';
break;
case 'super':
textMsg = 'Das sehe ich auch so!';
break;
case 'gut':
textMsg = 'Das Mobile Camp ist immer so gut wie seine Teilnehmer!';
break;
default:
textMsg = `"${opinion}" verstehe ich nicht. Kannst du das nochmal anders formulieren?`;
}
agent.add(new Text({
text: textMsg
}));
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Nächste Events', nextEvents);
intentMap.set('Gruesse-NAME-Frage-Meinung-antwort', opinionResponse);
intentMap.set('Default Fallback Intent', fallback);
agent.handleRequest(intentMap);
};
const app = express();
app.use( express.json() );
app.get('/', (req, res) => res.send('OK'))
app.post('/', (req, res) => processWebhook(req, res));
app.listen(PORT, () => console.log(`Listening on ${ PORT }`));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment