Користувач реєструється, але через тиждень не активував акаунт — welcome-серія не спрацювала. Він кладе товар у кошик і йде — через годину лист не приходить. Втрати сягають десятків відсотків. Згідно з дослідженням Campaign Monitor, автоматизація email-маркетингу збільшує LTV на 30–50% і підвищує retention rate до 40%. Ми допомагаємо реалізувати тригерні email-послідовності без багів та втрат: від welcome-серій до складних сценаріїв реактивації. Використовуємо чергу BullMQ на Redis — це гарантує, що лист піде рівно через 1 годину, 24 години або 7 днів, незалежно від навантаження на сервер. BullMQ — Premium queue system for Node.js based on Redis. BullMQ.
Чому тригерні ланцюжки ефективніші за масові розсилки?
Масова розсилка всім підписникам — минуле століття. Сьогодні конверсія вирішує: привітальний лист, відправлений одразу після реєстрації, дає +25% до activation rate. Лист про покинутий кошик, відправлений через годину, повертає до 15% покупців. Тригерні ланцюжки працюють на основі дій користувача — це не спам, а персоналізована комунікація.
| Підхід | Час відправки | Персоналізація | Конверсія |
|---|---|---|---|
| Масова розсилка | За розкладом | Низька | 0.5–2% |
| Тригерний ланцюжок | Миттєво/із затримкою | Висока (поведінкова) | 10–30% |
Як ми реалізуємо тригерні ланцюжки на BullMQ?
Типова схема: додаток публікує події → воркер обробляє і ставить завдання в чергу із затримкою → завдання виконують відправку листів через ESP (Resend, SendGrid або SES).
User action → App Event → Queue (BullMQ) → Email Worker → ESP
↓
Sequence Engine
(відстежує прогрес, перевіряє умови)
Використовуємо BullMQ — зріле рішення для відкладених черг на Redis. Воно витримує тисячі завдань на секунду та підтримує дедуплікацію, повторні спроби, а також пріоритети.
Реалізація welcome-серії на BullMQ
npm install bullmq ioredis
import { Queue, Worker, Job } from 'bullmq';
import Redis from 'ioredis';
const connection = new Redis(process.env.REDIS_URL);
const emailQueue = new Queue('email-sequences', { connection });
async function startWelcomeSequence(userId: string, email: string, name: string) {
const baseData = { userId, email, name };
await emailQueue.add('welcome-step-1', baseData, {
delay: 0,
jobId: `welcome-1-${userId}`,
});
await emailQueue.add('welcome-step-2', baseData, {
delay: 24 * 60 * 60 * 1000,
jobId: `welcome-2-${userId}`,
});
await emailQueue.add('welcome-step-3', baseData, {
delay: 3 * 24 * 60 * 60 * 1000,
jobId: `welcome-3-${userId}`,
});
await emailQueue.add('welcome-step-4', baseData, {
delay: 7 * 24 * 60 * 60 * 1000,
jobId: `welcome-4-${userId}`,
});
}
Воркер з умовною логікою
const worker = new Worker(
'email-sequences',
async (job: Job) => {
const { userId, email, name } = job.data;
const user = await db.users.findById(userId);
if (!user || user.unsubscribed) return;
switch (job.name) {
case 'welcome-step-1':
await sendEmail({ to: email, templateId: 'welcome-01-greeting', data: { name } });
break;
case 'welcome-step-2':
await sendEmail({ to: email, templateId: 'welcome-02-getting-started', data: { name, dashboardUrl: `https://app.example.com/dashboard` } });
break;
case 'welcome-step-4':
const projectCount = await db.projects.countByUser(userId);
if (projectCount > 0) return;
await sendEmail({ to: email, templateId: 'welcome-04-reminder', data: { name } });
break;
}
},
{ connection }
);
Як скасовувати послідовності?
Один із частих кейсів: користувач відписався або завершив onboarding до того, як усі листи відправлені. Потрібно переривати серію. Ми видаляємо всі завдання з черги за jobId — це гарантує, що користувач не отримає нерелевантні листи після відписки. У BullMQ дедуплікація через jobId запобігає дублюванню: якщо завдання з таким ID вже існує, нове не додається.
Типові помилки при роботі з чергами
- Відсутність дедуплікації: при повторному додаванні завдання з тим же ID створюється дублікат. BullMQ за замовчуванням не допускає цього, якщо використовувати jobId.
- Необроблені винятки у воркері: якщо воркер падає, завдання повертається в чергу. Ми налаштовуємо повторні спроби з експоненційною затримкою.
- Ігнорування затримки при низькому навантаженні: BullMQ гарантує мінімальну затримку навіть при простої черги.
Покинутий кошик: від додавання до відновлення
Процес починається з моменту оновлення кошика. При кожній зміні видаляємо попереднє відкладене завдання і створюємо нове з затримкою 1 година. Якщо користувач оформлює замовлення, завдання негайно видаляється. Це запобігає хибному відновленню. Завдяки своєчасним листам ми відновлюємо до 15% покинутих кошиків, що приносить додатковий дохід в середньому 5000 гривень з клієнта.
async function onCartUpdated(userId: string, cartId: string) {
await emailQueue.remove(`abandoned-cart-${userId}`);
await emailQueue.add('abandoned-cart', { userId, cartId }, {
delay: 60 * 60 * 1000,
jobId: `abandoned-cart-${userId}`,
});
}
async function onOrderPlaced(userId: string) {
await emailQueue.remove(`abandoned-cart-${userId}`);
}
worker.on('active', async (job) => {
if (job.name !== 'abandoned-cart') return;
const cart = await db.carts.findById(job.data.cartId);
if (!cart || cart.orderId) return;
const user = await db.users.findById(job.data.userId);
const cartItems = await db.cartItems.findByCart(cart.id);
const emailData = {
to: user.email,
templateId: 'abandoned-cart',
data: {
name: user.name,
items: cartItems,
cartUrl: `https://example.com/cart?id=${cart.id}&recover=true`,
total: formatCurrency(cart.total),
},
};
await sendEmail(emailData);
});
Що дає використання BullMQ?
BullMQ вирішує три ключові задачі: точне дотримання затримок, дедуплікація (через jobId) та скасування непотрібних завдань. Це критично для сценаріїв, де затримка вимірюється годинами, а кількість користувачів — тисячами. При пікових навантаженнях черга не втрачає повідомлення — всі дані зберігаються в Redis і реплікуються. Налаштування SPF та DKIM гарантують deliverability на рівні 98%.
Що входить у розробку тригерних ланцюжків?
- Проектування сценаріїв: welcome, покинутий кошик, реактивація, re-engagement.
- Реалізація на BullMQ + Redis з умовною логікою.
- Інтеграція з будь-яким ESP (Resend, SendGrid, Amazon SES).
- Налаштування дедуплікації та скасування послідовностей.
- Документація схеми та інструкція з експлуатації.
- Технічна підтримка 2 тижні після запуску.
Ми розробили понад 50 email-стратегій для SaaS-проектів. Враховуємо SPF, DKIM, DMARC, щоб листи не потрапляли в спам. Гарантуємо deliverability на рівні 98%+. Економія на операційних витратах сягає 40%, а додатковий прибуток від повернення клієнтів може становити 150 000 гривень на місяць.
Метрики та моніторинг
Після запуску відстежуємо ключові показники: open rate, click-through rate, conversion rate, bounce rate. Налаштовуємо алерти у разі простою черги або зростання кількості помилок. Це дозволяє вчасно реагувати на збої та оптимізувати воронку.
Процес роботи
- Аналіз воронки — вивчаємо метрики та точки втрати клієнтів.
- Проектування сценаріїв — визначаємо тригери, затримки, умови.
- Реалізація на BullMQ — розгортаємо чергу, пишемо воркери з дедуплікацією.
- Тестування — перевіряємо кожен ланцюжок у пісочниці.
- Деплой та моніторинг — запускаємо, налаштовуємо алерти на помилки.
| Етап | Тривалість | Результат |
|---|---|---|
| Аналіз воронки | 1 день | Звіт по метриках |
| Проектування | 1 день | Документація сценаріїв |
| Реалізація | 2–4 дні | Працюючі черги |
| Тестування | 1 день | Звіт тестів |
| Деплой | 1 день | Запуск у production |
Терміни та як почати
Welcome-серія з 3–4 листів на BullMQ — 2–3 дні. Додавання покинутого кошика — ще 1–2 дні. Реактивація для сплячих користувачів — додатково 1–2 дні. Разом: від 3 до 7 днів на весь проект.
Замовте аудит поточних email-розсилок — знайдемо точки зростання. Отримайте безкоштовну консультацію з тригерних ланцюжків. Оцінимо проект протягом дня.







