import { Booking } from '../db/booking' import { getBaseURL } from '../helpers/url' import { log } from '../helpers/log' import { daysFormatFrontend } from './date' import { generateCalendarEntry } from './ical' import sgMail from '@sendgrid/mail' const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY const ADMIN_EMAIL = process.env.ADMIN_EMAIL const FROM_EMAIL = process.env.FROM_EMAIL if (!SENDGRID_API_KEY) { throw new Error('NO SENDGRID_API_KEY set!') } if (!ADMIN_EMAIL) { throw new Error('No ADMIN_EMAIL set!') } if (!FROM_EMAIL) { throw new Error('No FROM_EMAIL set!') } sgMail.setApiKey(SENDGRID_API_KEY) const footer = ` Viele Grüße Thomas Ruoff Pfadi Bussle Wart Tel. 0151/212 253 62 ${getBaseURL()} ` function getReceivedBookingBookerText(booking: Booking): string { return `Hallo liebe/r ${booking.name}, Vielen Dank für Deine Buchungsanfrage zum ${daysFormatFrontend(booking.days)}! Nach Prüfung bestätigen wir die Buchung bald per E-Mail! Du kannst sie jederzeit unter ${getBaseURL()}/bookings/${booking.uuid} einsehen und auch stornieren. ${footer} ` } function getBookingConfirmedText(booking: Booking): string { return `Hallo liebe/r ${booking.name}, deine Buchunganfrage zum ${daysFormatFrontend( booking.days )} bestätigen wir gerne! Bitte melde dich spätestens 7 Tage vor dem Buchungstermin per E-Mail oder Telefon um eine Schlüsselübergabe zu vereinbaren. Du kannst deine Buchung weiterhin unter ${getBaseURL()}/bookings/${booking.uuid} einsehen und stornieren. ${footer} ` } function getBookingRejectedText(booking: Booking): string { return `Hallo liebe/r ${booking.name}, es tut uns leid, aber deine Buchungsanfrage zum ${daysFormatFrontend( booking.days )} konnten wir leider nicht bestätigen. Willst du das Bussle an einem anderen Termin buchen? Dann stelle bitte nochmal eine Buchungsanfrage auf ${getBaseURL()}. ${footer} ` } function getBookingCanceledText(booking: Booking): string { return `Hallo liebe/r ${booking.name}, deine Buchungsanfrage zum ${daysFormatFrontend(booking.days)} wurde storniert. Willst du das Bussle an einem anderen Termin buchen? Dann stelle bitte nochmal eine Buchungsanfrage auf ${getBaseURL()}. ${footer} ` } function getReceivedBookingAdminText(booking: { uuid: string }): string { return `Hallo lieber Admin, es ging folgende Buchung ein: ${getBaseURL()}/admin/bookings/${booking.uuid} MfG` } export async function sendReceivedBookingAdminMail( booking: Booking ): Promise { try { await sendMail({ to: [{ email: ADMIN_EMAIL }], from: { email: FROM_EMAIL, name: 'Pfadi-Bussle Wart' }, subject: `Buchung für ${booking.days} eingegangen!`, textPlainContent: getReceivedBookingAdminText(booking), }) } catch (error) { log.error(`Failed in sendReceivedBookingMail for ${booking.uuid}`, error) } } export async function sendReceivedBookingBookerMail( booking: Booking ): Promise { try { await sendMail({ to: [{ email: booking.email, name: booking.name }], from: { email: FROM_EMAIL, name: 'Pfadi-Bussle Wart' }, subject: `Deine Pfadi-Bussle Buchung ist eingegangen!`, textPlainContent: getReceivedBookingBookerText(booking), }) } catch (error) { log.error(`Failed in sendReceivedBookingMail for ${booking.uuid}`, error) } } export async function sendBookingConfirmed(booking: Booking): Promise { try { await sendMail({ to: [{ email: booking.email, name: booking.name }], from: { email: FROM_EMAIL, name: 'Pfadi-Bussle Wart' }, subject: `Deine Pfadi-Bussle Buchung wurde bestätigt!`, textPlainContent: getBookingConfirmedText(booking), attachments: [ { content: Buffer.from(generateCalendarEntry(booking)).toString( 'base64' ), type: 'text/calendar', filename: 'pfadibussle-buchung.ics', }, ], }) } catch (error) { log.error(`Failed in sendBookingConfirmedMail for ${booking.uuid}`, error) } } export async function sendBookingRejected(booking: Booking): Promise { try { await sendMail({ to: [{ email: booking.email, name: booking.name }], from: { email: FROM_EMAIL, name: 'Pfadi-Bussle Wart' }, subject: `Deine Pfadi-Bussle Buchung wurde abgelehnt!`, textPlainContent: getBookingRejectedText(booking), }) } catch (error) { log.error(`Failed in sendBookingRejectedMail for ${booking.uuid}`, error) } } export async function sendBookingCanceled(booking: Booking): Promise { try { await sendMail({ to: [{ email: booking.email, name: booking.name }], from: { email: FROM_EMAIL, name: 'Pfadi-Bussle Wart' }, subject: `Deine Pfadi-Bussle Buchung wurde storniert!`, textPlainContent: getBookingCanceledText(booking), }) } catch (error) { log.error(`Failed in sendBookingCanceledMail for ${booking.uuid}`, error) } } async function sendMail({ to, from, subject, textPlainContent, attachments, }: { to: { email: string; name?: string }[] from: { email: string; name?: string } subject: string textPlainContent: string attachments?: { content: string type?: string filename: string }[] }): Promise { const data = { to, from, subject, text: textPlainContent, attachments, } try { await sgMail.send(data) } catch (error) { log.error('Failed to send email', error) if (error.response) { log.error('Failed to send email', error.response.body) } // TODO: stuff into DB if failed and retry later } }