feat(listmonk): schedule weekly transactional emails

This commit is contained in:
ryan 2025-05-01 01:01:22 +03:00
parent c1bd2aa9b8
commit ffae0780e9
2 changed files with 73 additions and 19 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
.env
node_modules/
.qodo

View file

@ -10,6 +10,12 @@ export async function submitToListmonk(req, res) {
const listmonkBaseUrl = process.env.LISTMONK_BASE_URL;
const listId = parseInt(process.env.LIST_ID, 10);
const welcomeTemplateId = parseInt(process.env.PRESET_CAMPAIGN_ID, 10);
const week1TemplateId = parseInt(process.env.TEMPLATE_ID_WEEK_1, 10);
const week2TemplateId = parseInt(process.env.TEMPLATE_ID_WEEK_2, 10);
const week3TemplateId = parseInt(process.env.TEMPLATE_ID_WEEK_3, 10);
const week4TemplateId = parseInt(process.env.TEMPLATE_ID_WEEK_4, 10);
// Encode username and password as base64
const auth = Buffer.from(`${listmonkUsername}:${listmonkPassword}`).toString('base64');
@ -40,6 +46,50 @@ export async function submitToListmonk(req, res) {
}
}
async function scheduleTransactionalEmails(email, name, message, auth, baseUrl) {
const MAX_TIMEOUT_MS = 2147483647;
const SCHEDULES = [
{ delayMs: 7 * 24 * 60 * 60 * 1000, templateId: week1TemplateId }, // 1 week
{ delayMs: 14 * 24 * 60 * 60 * 1000, templateId: week2TemplateId }, // 2 weeks
{ delayMs: 21 * 24 * 60 * 60 * 1000, templateId: week3TemplateId }, // 3 weeks
{
delayMs: Math.min(28 * 24 * 60 * 60 * 1000, MAX_TIMEOUT_MS), // 4 weeks (capped)
templateId: week4TemplateId
}
];
for (const { delayMs, templateId } of SCHEDULES) {
setTimeout(async () => {
const payload = {
template_id: templateId,
subscriber_emails: [email],
from_email: "Janek <janek@melonion.me>",
data: { name, message }
};
try {
const res = await fetch(`${baseUrl}/tx`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${auth}`
},
body: JSON.stringify(payload)
});
if (!res.ok) {
console.error(`Error sending email with template ${templateId}:`, await res.text());
} else {
console.log(`Email sent with template ${templateId}`);
}
} catch (err) {
console.error(`Error dispatching scheduled email for template ${templateId}:`, err);
}
}, delayMs);
}
}
try {
// Add subscriber
const response = await fetchWithRetry(listmonkSubscriberUrl, {
@ -59,10 +109,10 @@ export async function submitToListmonk(req, res) {
const result = await response.json();
console.log('Subscriber added successfully:', result);
// Send transactional email
// Send welcome message immediately
const transactionalUrl = `${listmonkBaseUrl}/tx`;
const txPayload = {
template_id: parseInt(process.env.PRESET_CAMPAIGN_ID, 10),
template_id: welcomeTemplateId,
subscriber_emails: [email],
from_email: "Janek <janek@melonion.me>",
data: { name, message }
@ -83,9 +133,12 @@ export async function submitToListmonk(req, res) {
}
const dispatchResult = await txResponse.json();
console.log('tx dispatched successfully:', dispatchResult);
console.log('Welcome email dispatched successfully:', dispatchResult);
res.status(200).json({ message: 'Subscription and welcome email sent successfully!', result });
// Schedule the remaining follow-up emails
await scheduleTransactionalEmails(email, name, message, auth, listmonkBaseUrl);
res.status(200).json({ message: 'Subscription and emails scheduled successfully!', result });
} catch (error) {
console.error('Error submitting to Listmonk:', error);