Files
pfadi-bussle/helpers/mail.ts
Thomas Ruoff 9f3b6bb2e1 remover booker, that's overdosed
It also brings the problem of consolidating bookers over multiple
bookings. The amount of data is not justifying having it in an own
entity
2021-06-21 23:21:23 +02:00

217 lines
5.1 KiB
TypeScript

import { Booking } from '../db/booking'
import { getBaseURL } from '../helpers/url'
import { daysFormatFrontend } from './date'
import { generateCalendarEntry } from './ical'
import { retryWithDelay } from './retryWithDelay'
const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY
const ADMIN_EMAIL = process.env.ADMIN_EMAIL
const FROM_EMAIL = process.env.FROM_EMAIL
const SENDGRID_URL = 'https://api.sendgrid.com/v3/mail/send'
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!')
}
const footer = `
Viele Grüße
Thomas Ruoff
Pfadi Bussle Wart
Tel. 0151/212 253 62
`
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()}/booking/${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()}/booking/${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 getReceivedBookingAdminText(booking: { uuid: string }): string {
return `Hallo lieber Admin,
es ging folgende Buchung ein: ${getBaseURL()}/admin/booking/${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) {
console.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) {
console.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) {
console.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) {
console.error(
`Failed in sendBookingRejectedMail 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 = {
personalizations: [
{
to,
},
],
from,
subject,
content: [{ type: 'text/plain', value: textPlainContent }],
attachments,
}
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${SENDGRID_API_KEY}`,
},
body: JSON.stringify(data),
}
return retryWithDelay({
run: async () => {
const resp = await fetch(SENDGRID_URL, fetchOptions)
const bodyText = await resp.text()
if (!resp.ok) {
throw new Error(
`Failed to send mail with status ${resp.status}: ${bodyText}`
)
}
},
})
}