Files
pfadi-bussle/helpers/mail.ts
2022-06-23 22:43:00 +02:00

220 lines
5.5 KiB
TypeScript

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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
const data = {
to,
from,
subject,
text: textPlainContent,
attachments,
}
try {
await sgMail.send(data)
} catch (error) {
log.error(error)
if (error.response) {
log.error(error.response.body)
}
// TODO: stuff into DB if failed and retry later
}
}