Skip to content

Instantly share code, notes, and snippets.

@jirawatee
Created October 5, 2019 02:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jirawatee/afed8837d536114a59c8fedf0b08b2ac to your computer and use it in GitHub Desktop.
Save jirawatee/afed8837d536114a59c8fedf0b08b2ac to your computer and use it in GitHub Desktop.
Appointment Scheduler in Fulfillment
"use strict";
const { WebhookClient, Payload } = require("dialogflow-fulfillment");
const functions = require("firebase-functions");
const { google } = require('googleapis');
const calendarId = "88888888888888@group.calendar.google.com";
const serviceAccount = {
"type": "service_account",
"project_id": "line-bot",
"private_key_id": "xxxxx",
"private_key": "xxxxx",
"client_email": "dialogflow-appointment@line-bot.iam.gserviceaccount.com",
"client_id": "88888888888",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/dialogflow-appointment%40line-bot.iam.gserviceaccount.com"
};
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:debug";
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function confirmAppointment(agent) {
const dateTimeStart = new Date(
Date.parse(agent.parameters.date.split('T')[0] + 'T' + agent.parameters.time.split('T')[1])
);
const appointmentTimeString = dateTimeStart.toLocaleString(
'en-US',
{ weekday: 'short', day: 'numeric', month: 'short', hour: 'numeric', minute: 'numeric', timeZone: 'Asia/Bangkok' }
);
return agent.add(`ยืนยันนัด ` + appointmentTimeString + ` ไหมคะ?`);
}
function makeAppointment(agent) {
const appointment_type = agent.parameters.AppointmentType;
const dateTimeStart = new Date(
Date.parse(agent.parameters.date.split('T')[0] + 'T' + agent.parameters.time.split('T')[1])
);
// Calculate appointment start and end datetimes (end = +1hr from start)
const dateTimeEnd = new Date(new Date(dateTimeStart).setHours(dateTimeStart.getHours() + 1));
const appointmentTimeString = dateTimeStart.toLocaleString(
'en-US',
{ weekday: 'short', day: 'numeric', month: 'short', hour: 'numeric', minute: 'numeric', timeZone: 'Asia/Bangkok' }
);
// 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(`ลงตาราง ${appointmentTimeString} ให้เรียบร้อยแล้วจ้า`);
}).catch(() => {
agent.add(`ขออภัยค่ะ ช่วงเวลานี้ ${appointmentTimeString} ไม่ว่างนะคะ`);
});
}
let intentMap = new Map();
intentMap.set('Appointment', confirmAppointment);
intentMap.set('Appointment - yes', 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) => {
if (err !== null) {
reject(err);
} else {
resolve(event);
}
});
}
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment