Created
October 5, 2019 02:09
-
-
Save jirawatee/afed8837d536114a59c8fedf0b08b2ac to your computer and use it in GitHub Desktop.
Appointment Scheduler in Fulfillment
This file contains 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
"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