mirror of
https://github.com/tomru/pfadi-bussle.git
synced 2026-03-03 06:27:11 +01:00
use nodemailer instead of sendgrid
This commit is contained in:
162
helpers/mail.ts
162
helpers/mail.ts
@@ -1,32 +1,46 @@
|
||||
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'
|
||||
import nodemailer from 'nodemailer';
|
||||
|
||||
const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY
|
||||
const ADMIN_EMAIL = process.env.ADMIN_EMAIL
|
||||
const FROM_EMAIL = process.env.FROM_EMAIL
|
||||
const smtpUser = process.env.SMTP_USER
|
||||
const smtpPass = process.env.SMTP_PASS
|
||||
const adminEmail = process.env.ADMIN_EMAIL
|
||||
const fromEmail = process.env.FROM_EMAIL
|
||||
|
||||
if (!SENDGRID_API_KEY) {
|
||||
throw new Error('NO SENDGRID_API_KEY set!')
|
||||
if (!smtpUser) {
|
||||
throw new Error('NO SMTP_USER set!')
|
||||
}
|
||||
|
||||
if (!ADMIN_EMAIL) {
|
||||
if (!smtpPass) {
|
||||
throw new Error('NO SMTP_PASS set!')
|
||||
}
|
||||
|
||||
if (!adminEmail) {
|
||||
throw new Error('No ADMIN_EMAIL set!')
|
||||
}
|
||||
|
||||
if (!FROM_EMAIL) {
|
||||
if (!fromEmail) {
|
||||
throw new Error('No FROM_EMAIL set!')
|
||||
}
|
||||
|
||||
sgMail.setApiKey(SENDGRID_API_KEY)
|
||||
let transporter = nodemailer.createTransport({
|
||||
host: "wirtanen.uberspace.de",
|
||||
port: 587,
|
||||
secure: false,
|
||||
auth: {
|
||||
user: smtpUser,
|
||||
pass: smtpPass,
|
||||
},
|
||||
logger: true,
|
||||
});
|
||||
|
||||
const footer = `
|
||||
|
||||
Viele Grüße
|
||||
|
||||
--
|
||||
Thomas Ruoff
|
||||
Pfadi Bussle Wart
|
||||
|
||||
@@ -105,115 +119,85 @@ 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)
|
||||
}
|
||||
await sendMail({
|
||||
to: [{ address: adminEmail, name: 'Pfadi-Bussle Wart' }],
|
||||
from: { address: fromEmail, name: 'Pfadi-Bussle Wart' },
|
||||
subject: `Buchung für ${booking.days} eingegangen!`,
|
||||
text: getReceivedBookingAdminText(booking),
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
await sendMail({
|
||||
to: [{ address: booking.email, name: booking.name }],
|
||||
from: { address: fromEmail, name: 'Pfadi-Bussle Wart' },
|
||||
subject: `Deine Pfadi-Bussle Buchung ist eingegangen!`,
|
||||
text: getReceivedBookingBookerText(booking),
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
await sendMail({
|
||||
to: [{ address: booking.email, name: booking.name }],
|
||||
from: { address: fromEmail, name: 'Pfadi-Bussle Wart' },
|
||||
subject: `Deine Pfadi-Bussle Buchung wurde bestätigt!`,
|
||||
text: getBookingConfirmedText(booking),
|
||||
attachments: [
|
||||
{
|
||||
content: Buffer.from(generateCalendarEntry(booking)).toString(
|
||||
'base64'
|
||||
),
|
||||
type: 'text/calendar',
|
||||
filename: 'pfadibussle-buchung.ics',
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
await sendMail({
|
||||
to: [{ address: booking.email, name: booking.name }],
|
||||
from: { address: fromEmail, name: 'Pfadi-Bussle Wart' },
|
||||
subject: `Deine Pfadi-Bussle Buchung wurde abgelehnt!`,
|
||||
text: getBookingRejectedText(booking),
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
await sendMail({
|
||||
to: [{ address: booking.email, name: booking.name }],
|
||||
from: { address: fromEmail, name: 'Pfadi-Bussle Wart' },
|
||||
subject: `Deine Pfadi-Bussle Buchung wurde storniert!`,
|
||||
text: getBookingCanceledText(booking),
|
||||
})
|
||||
}
|
||||
|
||||
async function sendMail({
|
||||
to,
|
||||
from,
|
||||
subject,
|
||||
textPlainContent,
|
||||
text,
|
||||
attachments,
|
||||
}: {
|
||||
to: { email: string; name?: string }[]
|
||||
from: { email: string; name?: string }
|
||||
to: { address: string; name: string }[]
|
||||
from: { address: string; name: string }
|
||||
subject: string
|
||||
textPlainContent: string
|
||||
text: string
|
||||
attachments?: {
|
||||
content: string
|
||||
type?: string
|
||||
filename: string
|
||||
}[]
|
||||
}): Promise<void> {
|
||||
const data = {
|
||||
|
||||
// send mail with defined transport object
|
||||
await transporter.sendMail({
|
||||
to,
|
||||
from,
|
||||
subject,
|
||||
text: textPlainContent,
|
||||
text,
|
||||
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
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user