Реализация триггерных email-цепочек (Welcome, Abandoned Cart, Reactivation)

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация триггерных email-цепочек (Welcome, Abandoned Cart, Reactivation)
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка триггерных email-последовательностей (welcome, брошенная корзина)

Триггерные последовательности — это цепочки писем, которые запускаются автоматически в ответ на действие пользователя. Welcome-серия, брошенная корзина, re-engagement, onboarding-подсказки. Каждое письмо отправляется в нужный момент, а не по расписанию.

Архитектура

Типичная схема: приложение публикует события → воркер обрабатывает и ставит задачи в очередь с задержкой → задачи выполняют отправку писем.

User action → App Event → Queue (BullMQ) → Email Worker → ESP (Resend/SendGrid)
                   ↓
             Sequence Engine
         (отслеживает прогресс,
          проверяет условия)

Реализация на 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 });

// Запуск welcome-последовательности
async function startWelcomeSequence(userId: string, email: string, name: string) {
  const baseData = { userId, email, name };

  // Письмо 1: сразу после регистрации
  await emailQueue.add('welcome-step-1', baseData, {
    delay: 0,
    jobId: `welcome-1-${userId}`,  // дедупликация
  });

  // Письмо 2: через 1 день — как пользоваться продуктом
  await emailQueue.add('welcome-step-2', baseData, {
    delay: 24 * 60 * 60 * 1000,
    jobId: `welcome-2-${userId}`,
  });

  // Письмо 3: через 3 дня — примеры use case
  await emailQueue.add('welcome-step-3', baseData, {
    delay: 3 * 24 * 60 * 60 * 1000,
    jobId: `welcome-3-${userId}`,
  });

  // Письмо 4: через 7 дней — если не активировал — напоминание
  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 }
);

Брошенная корзина

// При добавлении в корзину — сохранить и поставить задачу
async function onCartUpdated(userId: string, cartId: string) {
  // Отменить предыдущую задачу (если была)
  await emailQueue.remove(`abandoned-cart-${userId}`);

  // Новая задача через 1 час
  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);

  await sendEmail({
    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),
    },
  });
});

Отмена последовательности

Важно уметь прерывать серию — при отписке, при завершении onboarding:

async function cancelWelcomeSequence(userId: string) {
  await Promise.all(
    [1, 2, 3, 4].map(step =>
      emailQueue.remove(`welcome-${step}-${userId}`)
    )
  );
}

Сроки

Welcome-серия из 3–4 писем с BullMQ + условные проверки — 2–3 дня. Брошенная корзина + отмена при оформлении заказа — ещё 1–2 дня.