Created
April 26, 2019 06:31
-
-
Save priyankavergadia/7e7e4ded174e921ae119c227690a41e8 to your computer and use it in GitHub Desktop.
Cloud Function for Scheduling Appointments with Dialogflow using Google Calendar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*Copyright 2019 Google LLC. | |
SPDX-License-Identifier: Apache-2.0 | |
*/ | |
'use strict'; | |
const functions = require('firebase-functions'); | |
const {google} = require('googleapis'); | |
const {WebhookClient} = require('dialogflow-fulfillment'); | |
// Enter your calendar ID below and service account JSON below | |
const calendarId = "<Add your calendar ID here>" | |
const serviceAccount = {<Add your service account details here>}; // Starts with {"type": "service_account",... | |
// Set up Google Calendar Service account credentials | |
const serviceAccountAuth = new google.auth.JWT({ | |
email: serviceAccount.client_email, | |
key: serviceAccount.private_key, | |
scopes: 'https://www.googleapis.com/auth/calendar' | |
}); | |
const calendar = google.calendar('v3'); | |
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements | |
const timeZone = 'America/Los_Angeles'; | |
const timeZoneOffset = '-07:00'; | |
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => { | |
const agent = new WebhookClient({ request, response }); | |
console.log("Parameters", agent.parameters); | |
const appointment_type = agent.parameters.AppointmentType | |
function makeAppointment (agent) { | |
// Calculate appointment start and end datetimes (end = +1hr from start) | |
//console.log("Parameters", agent.parameters.date); | |
const dateTimeStart = new Date(Date.parse(agent.parameters.date.split('T')[0] + 'T' + agent.parameters.time.split('T')[1].split('-')[0] + timeZoneOffset)); | |
const dateTimeEnd = new Date(new Date(dateTimeStart).setHours(dateTimeStart.getHours() + 1)); | |
const appointmentTimeString = dateTimeStart.toLocaleString( | |
'en-US', | |
{ month: 'long', day: 'numeric', hour: 'numeric', timeZone: timeZone } | |
); | |
// Check the availibility of the time, and make an appointment if there is time on the calendar | |
return createCalendarEvent(dateTimeStart, dateTimeEnd, appointment_type).then(() => { | |
agent.add(`Ok, let me see if we can fit you in. ${appointmentTimeString} is fine!.`); | |
}).catch(() => { | |
agent.add(`I'm sorry, there are no slots available for ${appointmentTimeString}.`); | |
}); | |
} | |
let intentMap = new Map(); | |
intentMap.set('Schedule Appointment', makeAppointment); | |
agent.handleRequest(intentMap); | |
}); | |
function createCalendarEvent (dateTimeStart, dateTimeEnd, appointment_type) { | |
return new Promise((resolve, reject) => { | |
calendar.events.list({ | |
auth: serviceAccountAuth, // List events for time period | |
calendarId: calendarId, | |
timeMin: dateTimeStart.toISOString(), | |
timeMax: dateTimeEnd.toISOString() | |
}, (err, calendarResponse) => { | |
// Check if there is a event already on the Calendar | |
if (err || calendarResponse.data.items.length > 0) { | |
reject(err || new Error('Requested time conflicts with another appointment')); | |
} else { | |
// Create event for the requested time period | |
calendar.events.insert({ auth: serviceAccountAuth, | |
calendarId: calendarId, | |
resource: {summary: appointment_type +' Appointment', description: appointment_type, | |
start: {dateTime: dateTimeStart}, | |
end: {dateTime: dateTimeEnd}} | |
}, (err, event) => { | |
err ? reject(err) : resolve(event); | |
} | |
); | |
} | |
}); | |
}); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "dialogflowFirebaseFulfillment", | |
"description": "Dialogflow fulfillment for the bike shop sample", | |
"version": "0.0.1", | |
"private": true, | |
"license": "Apache Version 2.0", | |
"author": "Google Inc.", | |
"engines": { | |
"node": "6" | |
}, | |
"scripts": { | |
"lint": "semistandard --fix \"**/*.js\"", | |
"start": "firebase deploy --only functions", | |
"deploy": "firebase deploy --only functions" | |
}, | |
"dependencies": { | |
"firebase-functions": "2.0.2", | |
"firebase-admin": "^5.13.1", | |
"actions-on-google": "2.2.0", | |
"googleapis": "^27.0.0", | |
"dialogflow-fulfillment": "0.5.0" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment