Пользователь регистрируется, но через неделю не активировал аккаунт — 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-рассылок — найдём точки роста. Получите бесплатную консультацию по триггерным цепочкам. Оценим проект в течение дня.







