import { Booking } from '@prisma/client'; import { google } from 'googleapis' import { getBaseURL } from '../helpers/url' import { getDays, getNextDay, dateFormatBackend } from '../helpers/date' import { log } from '../helpers/log' const calendarId = process.env.GOOGLE_CALENDAR_ID let credentials: object try { credentials = JSON.parse(process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON) } catch (error) { log.error( 'Unable to parse process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON - invalid JSON?' ) throw error } const auth = new google.auth.GoogleAuth({ credentials, scopes: ['https://www.googleapis.com/auth/calendar'], }) const calendar = google.calendar({ version: 'v3', auth, }) export async function getBookedDays() { const { data } = await calendar.events.list({ calendarId, timeMin: new Date().toISOString(), timeZone: 'utc', }) return ( data.items // ignore non all-day events .filter((event) => !!event.start.date) .flatMap((event) => getDays({ startDate: event.start.date, endDate: event.end.date, endDateExclusive: true, }) ) ) } function getSummary(booking: Booking): string { let summary = '' if (booking.org) { summary += `${booking.org} - ` } summary += booking.name return summary } function getDescription(booking: Booking) { const bookingUrl = `${getBaseURL()}/admin/booking/${booking.uuid}` return `Managelink ${bookingUrl}` } export async function createCalendarEvent(booking: Booking) { const exclusiveEndDate = dateFormatBackend( getNextDay(new Date(booking.endDate)) ) const data = { calendarId, requestBody: { summary: getSummary(booking), description: getDescription(booking), start: { date: booking.startDate }, end: { date: exclusiveEndDate }, }, } const response = await calendar.events.insert(data, {}) booking.calendarEventId = response.data.id return booking } export async function deleteCalendarEvent(booking: { calendarEventId: string }) { await calendar.events.delete({ calendarId, eventId: booking.calendarEventId, // TODO: really useful? sendNotifications: true, }) booking.calendarEventId = null } export async function patchCalendarEvent(booking: Booking ) { await calendar.events.patch({ calendarId, eventId: booking.calendarEventId, }); return booking; }