mjml EMail
This commit is contained in:
112
src/services/email-service.js
Normal file
112
src/services/email-service.js
Normal file
@@ -0,0 +1,112 @@
|
||||
// src/services/email-service.js
|
||||
const { SESv2Client, SendEmailCommand } = require('@aws-sdk/client-sesv2');
|
||||
const nodemailer = require('nodemailer');
|
||||
const mjml2html = require('mjml');
|
||||
|
||||
const sesClient = new SESv2Client({
|
||||
region: process.env.AWS_REGION || 'us-east-2'
|
||||
});
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
SES: {
|
||||
sesClient,
|
||||
SendEmailCommand
|
||||
}
|
||||
});
|
||||
|
||||
function generateInvoiceEmailHtml(invoice, customText, melioLink) {
|
||||
const formattedText = customText || '';
|
||||
|
||||
const buttonMjml = melioLink
|
||||
? `<mj-button background-color="#2563eb" color="white" border-radius="6px" href="${melioLink}" font-weight="600" font-size="16px" padding-top="25px">
|
||||
Pay Now (Free ACH)
|
||||
</mj-button>`
|
||||
: '';
|
||||
|
||||
const template = `
|
||||
<mjml>
|
||||
<mj-head>
|
||||
<mj-attributes>
|
||||
<mj-all font-family="ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif" />
|
||||
</mj-attributes>
|
||||
<mj-style inline="inline">
|
||||
.email-body p {
|
||||
margin: 0 0 14px 0 !important;
|
||||
}
|
||||
.email-body p:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
</mj-style>
|
||||
</mj-head>
|
||||
<mj-body background-color="#f4f4f5">
|
||||
|
||||
<mj-section padding="0">
|
||||
<mj-column>
|
||||
<mj-spacer height="20px" />
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
|
||||
<mj-section background-color="#ffffff" padding="30px" border-radius="8px 8px 0 0">
|
||||
<mj-column>
|
||||
<mj-text font-size="22px" font-weight="700" color="#1e3a8a" padding="0">
|
||||
Bay Area Affiliates, Inc.
|
||||
</mj-text>
|
||||
<mj-text font-size="15px" color="#64748b" padding="5px 0 0 0">
|
||||
Invoice #${invoice.invoice_number || invoice.id}
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
|
||||
<mj-section background-color="#ffffff" padding="0 30px 30px 30px">
|
||||
<mj-column>
|
||||
<mj-text css-class="email-body" font-size="15px" color="#334155" line-height="1.5" padding="0">
|
||||
${formattedText}
|
||||
</mj-text>
|
||||
|
||||
${buttonMjml}
|
||||
|
||||
<mj-divider border-color="#e2e8f0" border-width="1px" padding-top="30px" padding-bottom="20px" />
|
||||
|
||||
<mj-text font-size="14px" color="#64748b" line-height="1.5" padding="0">
|
||||
<strong>Prefer to pay by check?</strong><br/>
|
||||
Please make checks payable to Bay Area Affiliates, Inc. and mail to:<br/>
|
||||
1001 Blucher Street<br/>
|
||||
Corpus Christi, Texas 78401
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
</mj-body>
|
||||
</mjml>
|
||||
`;
|
||||
|
||||
// validationLevel: 'strict' fängt falsche Attribute ab, bevor sie an den Kunden gehen
|
||||
const result = mjml2html(template, { validationLevel: 'strict' });
|
||||
|
||||
if (result.errors && result.errors.length > 0) {
|
||||
console.error('MJML Parse Errors:', result.errors);
|
||||
}
|
||||
|
||||
return result.html;
|
||||
}
|
||||
|
||||
async function sendInvoiceEmail(invoice, recipientEmail, customText, melioLink, pdfBuffer) {
|
||||
const htmlContent = generateInvoiceEmailHtml(invoice, customText, melioLink);
|
||||
|
||||
const mailOptions = {
|
||||
from: '"Bay Area Affiliates Inc. Accounting" <accounting@bayarea-cc.com>',
|
||||
to: recipientEmail,
|
||||
subject: `Invoice #${invoice.invoice_number || invoice.id} from Bay Area Affiliates, Inc.`,
|
||||
html: htmlContent,
|
||||
attachments: [
|
||||
{
|
||||
filename: `Invoice_${invoice.invoice_number || invoice.id}_BayAreaAffiliates.pdf`,
|
||||
content: pdfBuffer,
|
||||
contentType: 'application/pdf'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return await transporter.sendMail(mailOptions);
|
||||
}
|
||||
|
||||
module.exports = { sendInvoiceEmail };
|
||||
@@ -33,8 +33,9 @@ async function generatePdfFromHtml(html, options = {}) {
|
||||
}
|
||||
|
||||
const page = await browser.newPage();
|
||||
await page.setContent(html, { waitUntil: 'networkidle0', timeout: 60000 });
|
||||
|
||||
//await page.setContent(html, { waitUntil: 'networkidle0', timeout: 60000 });
|
||||
await page.setContent(html, { waitUntil: 'load', timeout: 5000 });
|
||||
|
||||
const pdf = await page.pdf({
|
||||
format,
|
||||
printBackground,
|
||||
|
||||
Reference in New Issue
Block a user