Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Send code
import type { NextApiRequest, NextApiResponse } from 'next';
import nodemailer from 'nodemailer';
import type SMTPTransport from 'nodemailer/lib/smtp-transport';
import Mail from 'nodemailer/lib/mailer';
import { FormDataKey, PayloadFormData } from '../../lib/useRMVform';
import { ManVanInputs } from '../../page-components/MvForm';
import { RMVInputs } from '../../page-components/RmvForm';
import {
buildBaseHTML,
buildCallbackHTML,
buildHandymanHTML,
buildIntRmvHTML,
buildManVanHTML,
buildRemovalsHTML,
} from '../../lib/buildHTMLEmail';
import { IntRmvInputs } from '../../page-components/IntRmvForm';
import { HandymanInputs } from '../../page-components/HandymanForm';
import { CallbackInputs } from '../../page-components/RequestCallbackModal';
const isDev = process.env.NODE_ENV !== 'production';
export interface SendAPIRes {
sent: 'fail' | 'ok';
error?: string;
}
export type FormInputsTypes =
| ManVanInputs
| RMVInputs
| IntRmvInputs
| HandymanInputs
| CallbackInputs;
const extractBaseInputs = ({ name, telephone, email, time }: FormInputsTypes) => ({
name,
telephone,
email,
time,
});
const getEmailParams = (payload: any) => {
const k = Object.keys(payload)[0];
return {
subject: payload[k].subject,
replyTo: payload[k].email,
};
};
const buildHTML = (payload: PayloadFormData) => {
const keys = Object.keys(payload);
switch (keys[0]) {
case FormDataKey.MANVAN:
const formData = payload.manvan as ManVanInputs;
const base = extractBaseInputs(formData);
return `
${buildBaseHTML(base)}
${buildManVanHTML(formData)}
`;
case FormDataKey.HANDYMAN:
const formDataHandy = payload.handyman as HandymanInputs;
const baseHandy = extractBaseInputs(formDataHandy);
return `
${buildBaseHTML(baseHandy)}
${buildHandymanHTML(formDataHandy)}
`;
case FormDataKey.INTERNATIONAL:
const formDataInt = payload.international as IntRmvInputs;
const baseInt = extractBaseInputs(formDataInt);
return `
${buildBaseHTML(baseInt)}
${buildIntRmvHTML(formDataInt)}
`;
case FormDataKey.REMOVALS:
const formData2 = payload.removals as RMVInputs;
const base2 = extractBaseInputs(formData2);
return `
${buildBaseHTML(base2)}
${buildRemovalsHTML(formData2)}
`;
case FormDataKey.CALLBACK:
const formDataC = payload.callback as CallbackInputs;
return `
${buildCallbackHTML(formDataC)}
`;
default:
throw new Error(`Form type is invsalid: ${Object.keys(payload)[0]}`);
}
};
const buildEmail = (data: PayloadFormData, subject: string, replyTo: string): Mail.Options => {
return {
from: 'xxx@mail.com',
to: 'xxx@mail.com',
subject: `Rmv London - ${subject}`,
replyTo: replyTo,
html: buildHTML(data),
};
};
const SMTP_HOST = isDev ? 'smtp.mailtrap.io' : process.env.SMTP_HOST;
const SMTP_USER = isDev ? 'xxxxxx' : process.env.SMTP_USER!;
const SMTP_PSW = isDev ? 'xxxxxxx' : process.env.SMTP_PSW!;
const SMTP_PORT = isDev ? 2525 : process.env.SMTP_PORT;
const SMTPtransport = nodemailer.createTransport({
host: SMTP_HOST,
port: SMTP_PORT,
auth: {
user: SMTP_USER,
pass: SMTP_PSW,
},
secureConnection: false,
tls: { ciphers: 'SSLv3' },
requireTLS: true,
logger: true,
debug: false,
} as SMTPTransport.Options);
export default async (req: NextApiRequest, res: NextApiResponse<SendAPIRes>) => {
const hrstart = process.hrtime();
console.log(`Request for email received:`, req.method);
const inputs: PayloadFormData = JSON.parse(req.body);
if (!inputs) {
console.log('Empty body received');
return res.status(400).send({
sent: 'fail',
error: 'Form data is missing',
});
}
if (req.method !== 'POST') {
return res.status(404).send({
sent: 'fail',
error: 'Not found',
});
}
try {
const { subject, replyTo } = getEmailParams(inputs);
const message = buildEmail(inputs, subject, replyTo);
await SMTPtransport.verify();
console.log('Server is ready to take messages', inputs);
await SMTPtransport.sendMail(message);
const hrend = process.hrtime(hrstart);
console.info('Execution time (hr): %ds %dms', hrend[0], hrend[1] / 1000000);
res.status(200).json({ sent: 'ok' });
} catch (error) {
console.log('Can not send email: ', error);
res.status(400).send({
sent: 'fail',
error: 'Email has not been sent',
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment