Как мы строили интеграцию с сервисом рассылок: RabbitMQ, вебхуки и CRON

от автора

Введение

Когда мы проектировали интеграцию CRM-системы с внешним сервисом рассылок, задача казалась типовой: пользователь создаёт сообщение или рассылку — и оно уходит через провайдера. Но когда мы начали погружаться в детали, стало понятно: всё решает не API, а архитектура. Как не потерять ни одно сообщение? Как не упасть под нагрузкой массовой рассылки? Как понять, что сообщение действительно доставлено?

В этой статье я расскажу, как мы строили интеграцию с сервисом рассылок, почему выбрали микросервисную архитектуру, зачем понадобились вебхуки и очереди, и как CRON стал нашим спасательным кругом.

Часть 1. Задача и контекст

В CRM-системе пользователь может:

  • создать одиночное SMS-сообщение в CRM (из карточки документа, из формы документа, из раздела «Сообщения»)

  • создать одиночное email-письмо

  • создать массовую SMS- или email-рассылку

Все эти сообщения должны отправляться через внешнего провайдера — сервис, который специализируется на доставке.

Где в CRM это доступно

  • Одиночные сообщения отправляются из формы документа, из раздела «Сообщения» в блоке CRM или из карточки документа

  • Рассылки создаются в разделе «Рассылки» (подраздел «Сообщения и рассылки»)

  • Также сообщение может отправляться автоматически при назначении специального статуса документа

Почему не только REST API

Можно было бы сделать прямую интеграцию: CRM → API провайдера. Но мы столкнулись с ограничениями:

  • провайдер мог не принять запрос из-за нагрузки

  • CRM не должна была тормозить из-за внешних вызовов

  • нужно было гарантировать доставку даже в случае сбоев

Поэтому мы решили строить интеграцию на микросервисной архитектуре с использованием очередей.

Часть 2. Архитектура интеграции

Микросервис-посредник

Мы выделили отдельный микросервис — интеграционный модуль, который:

  • подписывается на вебхуки от CRM

  • отправляет данные в провайдер

  • отслеживает статусы сообщений и рассылок

  • обновляет статусы в CRM

Это позволило нам не трогать ядро CRM при изменениях в интеграции. Любые доработки касались только микросервиса.

Вебхуки — основной канал

CRM отправляет вебхуки при создании сообщения или рассылки. Микросервис подписывается на них и обрабатывает.

Какие модели используются:

  • sms — для одиночных SMS-сообщений

  • senders — для массовых рассылок

Почему вебхуки: это асинхронный способ передачи данных. CRM не ждёт ответа — она просто уведомляет микросервис, и тот начинает обработку.

CRON — как резервный канал

Мы столкнулись с тем, что вебхуки иногда не доходят. Причины разные: сеть, перегрузка, ошибки на стороне провайдера.

Решение: добавили CRON-задачу, которая каждые 3 часа проверяет наличие новых сообщений и рассылок, которые не были обработаны через вебхуки.

Почему 3 часа: это компромисс между оперативностью и нагрузкой на систему. Сообщение не должно потеряться, но и проверять каждую минуту — избыточно.

RabbitMQ — очереди для сообщений

Когда микросервис получает задачу (через вебхук или CRON), он отправляет её в очередь RabbitMQ.

Зачем очередь:

  • сглаживает пиковые нагрузки (сотни сообщений могут прийти в один момент)

  • гарантирует, что задача будет обработана даже в случае сбоя

  • позволяет масштабировать обработку

Детали:

  • отдельная очередь для SMS

  • отдельная очередь для email

  • каждая очередь обрабатывается своим воркером

Часть 3. Два сценария: сообщение и рассылка

Сценарий 1. Одиночное сообщение

Алгоритм:

  1. Микросервис подписывается на вебхуки модели sms

  2. При создании сообщения в интерфейсе CRM микросервис получает вебхук

  3. Запускается процесс отправки сообщения через API провайдера

  4. Если вебхук не дошел, микросервис проверяет наличие новых сообщений через CRON (каждые 3 часа)

  5. После отправки микросервис обновляет статус сообщения в CRM

  6. Проверка статуса происходит каждые 5 минут, пока статус не станет финальным

Сценарий 2. Массовая рассылка

Алгоритм:

  1. Микросервис подписывается на вебхуки модели senders

  2. При создании рассылки в интерфейсе CRM микросервис получает вебхук

  3. Если список контактов новый — он создаётся в провайдере

  4. Если список уже существует — он обновляется

  5. Запускается процесс отправки рассылки через API провайдера

  6. Микросервис получает общие сведения о результатах доставки

  7. Обновляет статус рассылки в CRM каждые 5 минут до получения финального статуса

Часть 4. Что мы узнали в процессе

1. Изучение API провайдера — это отдельный этап

У каждого провайдера своя логика: как создавать сообщение, как проверять статус, как обрабатывать ошибки. Мы потратили время на изучение API провайдера, и это окупилось — мы сразу выбрали правильный подход.

2. Вебхуки не всегда надёжны

Мы планировали, что вебхуки будут основным каналом. Но когда мы обнаружили, что часть сообщений теряется, мы добавили CRON. И это стало лучшим решением в проекте.

3. Очереди спасают от перегрузки

Когда клиенты начали массово отправлять рассылки, система не упала — потому что задачи уходили в очередь и обрабатывались по мере возможностей.

4. Отдельные очереди для SMS и email — правильное решение

SMS и email имеют разную скорость доставки и разные ограничения. Разделение очередей позволило нам настраивать обработку независимо и не смешивать разные типы сообщений.

5. Обновление статусов — это отдельная задача

Статусы не обновляются сами. Мы добавили отдельный механизм, который каждые 5 минут проверял статус сообщений и обновлял их в CRM. Это важно, потому что пользователь должен видеть реальное состояние отправки.

Заключение

Что мы вынесли из этого опыта:

  • микросервисная архитектура позволяет не трогать ядро CRM

  • вебхуки — хороший, но не единственный канал

  • CRON — это не стыдно, если он гарантирует доставку

  • очереди нужны, чтобы система не упала под нагрузкой

  • статусы нужно отслеживать отдельно, с периодической проверкой

Что стало самым важным решением: мы не полагались только на вебхуки. Мы добавили резервный канал. И это позволило нам не потерять ни одного сообщения.

Эта статья основана на личном опыте автора. Все названия компаний и продуктов изменены в соответствии с соглашением о неразглашении. Технические детали и подходы к решению задач соответствуют реальным проектам автора.

ссылка на оригинал статьи https://habr.com/ru/articles/1050276/