Корпоративная рассылка может выглядеть стандартной задачей, пока в требованиях не появляются хранение персональных данных, управление согласиями и доказуемая история каждого действия. После этого выбирать приходится уже не сервис отправки писем, а архитектуру полноценной информационной системы.
Меня зовут Алексей Постригайло, я старший партнер ИТ-интегратора "Энсайн". Разберу, почему в одном из проектов мы отказались от готовой платформы и разработали CRM на Django внутри защищенного контура заказчика.
Первоначальная задача звучала просто: создать систему для email-рассылок по базе из 70 000 контактов. Она должна была поддерживать шаблоны, персонализацию, сегменты и статистику.
После уточнения требований стало понятно, что отправка писем занимает лишь небольшую часть процесса. Система должна была хранить персональные данные внутри инфраструктуры заказчика, фиксировать согласия и позволять восстановить историю обработки каждого контакта.
Облачная платформа могла закрыть функции редактора и отправки. Требуемого контроля над хранением данных, журналом операций и логикой согласий она не давала.
Поэтому решение оценивали по 4 критериям:
После оценки этих требований команда выбрала собственную разработку.
Модель данных и история действий
В системе использовалось небольшое количество сущностей, а предполагаемая нагрузка не требовала сложной распределенной модели. Поэтому контактные данные, статус согласия и служебные признаки объединили в одной модели.
Такой подход нельзя считать универсальным. В данном проекте он сокращал число запросов и упрощал обработку данных.
Для каждого контакта система создавала уникальный идентификатор. Он генерировался с помощью выражения:
binascii.hexlify(os.urandom(64)).decode()
Результатом становилась строка из 128 символов. Идентификатор использовался в операциях подтверждения и отзыва согласия.
Каждое значимое действие попадало в журнал с отметкой времени. Система фиксировала импорт контакта, изменение данных, подтверждение согласия и отказ от дальнейших сообщений.
Это позволяло восстановить жизненный цикл записи и проверить, на каком основании контакт находился в активной базе.
Заказчику требовалось самостоятельно готовить письма. Подключение отдельного редактора создавало бы еще одну точку передачи данных и зависимость от стороннего сервиса.
Поэтому редактор шаблонов встроили непосредственно в CRM. Пользователь мог собрать письмо, добавить переменные и выбрать нужный сегмент базы.
При отправке переменные заменялись значениями из карточки контакта. Например, поле FIO подставляло имя получателя.
Такой механизм сократил объем ручной работы. Заказчику больше не требовалось выгружать списки, изменять их во внешних программах и загружать обратно.
Внешнюю систему аналитики подключать не стали. Для учета открытий использовали трекинг-пиксель.
В письмо добавлялось изображение размером 1×1 пиксель. При его загрузке почтовая программа обращалась к серверу, после чего CRM фиксировала технический запрос.
У этого метода есть ограничения. Некоторые почтовые программы блокируют изображения или загружают их заранее. Поэтому показатель открытий дает ориентир, но не может считаться абсолютно точным.
Для проекта такой точности было достаточно. Заказчик получал базовую статистику без передачи данных внешней аналитической платформе.
Самая важная часть системы была связана со статусами контактов.
Пользователь переходил на страницу подтверждения и выбирал действие. CRM обновляла статус и записывала событие в журнал.
Если человек отзывал согласие, контакт сразу исключался из активных рассылок. Сотруднику не требовалось вручную искать запись и менять ее состояние.
Перед отправкой система использовала только актуальную выборку. Это снижало риск рассылки по контактам, которые уже отказались от сообщений.
Разработать CRM было недостаточно. Новый почтовый сервер не может сразу отправлять десятки тысяч писем без риска ухудшить репутацию домена.
Интенсивность отправки увеличивали постепенно. Параллельно настроили SPF, DKIM и DMARC. Эти механизмы помогают принимающей стороне проверить источник письма и снизить вероятность подмены отправителя.
После подготовки инфраструктуры система отправляла письма со скоростью, близкой к 60 000 в час. Этого хватало для работы с базой из 70 000 контактов в заданном временном окне.
Система работала на РЕД ОС в сертифицированном сегменте Selectel. Для защиты применялись Dr.Web и Secret Net Studio для Linux.
На этапе проектирования рассматривались дополнительные меры, включая шифрование всей базы и отдельные серверы для защищенного удаленного доступа. После оценки угроз и сценариев использования от части решений отказались.
Каждая защитная мера влияет на архитектуру, сопровождение и стоимость владения. Поэтому ее нужно привязывать к конкретному риску и требованиям информационной системы.
В этом проекте команда стремилась обеспечить достаточный уровень защиты без механизмов, которые заметно усложнили бы эксплуатацию, но не дали бы соразмерного снижения риска.
Бэкенд CRM разработали за 2 недели. Весь проект занял 3 недели без учета согласования дизайна.
Система:
Критические операции больше не зависели от правил внешнего сервиса. Заказчик самостоятельно управлял данными, логикой рассылок и почтовой инфраструктурой.
Сначала нужно описать полный жизненный цикл данных. Откуда появляется контакт, на каком основании используется, кто может его изменить и что происходит после отзыва согласия.
После этого можно выбирать между готовой платформой и собственной разработкой.
Собственная CRM оправдана, когда требования к хранению, журналированию и бизнес-логике выходят за пределы стандартного сервиса. Если таких требований нет, разработка с нуля только увеличит стоимость и нагрузку на команду.
В этом проекте сложность определяла не отправка писем. Ее определяли данные и необходимость контролировать каждое действие с ними.
Здесь я обычно пишу про проекты, кейсы и ИТ-практику. А если хочется увидеть меня не только в рабочих текстах - приходите в мой тг https://t.me/alekseypostrigaylo. Там - сын, поездки, работа за кадром, личные наблюдения и попытка жить так, чтобы было что вспомнить.