Как мы построили CRM для рассылок с нуля, чтобы вернуть контроль над персональными данными

от автора

Привет, Хабр! Меня зовут Алексей Постригайло, я старший партнер ИТ-интегратора “Энсайн”. Больше 20 лет я занимаюсь системной интеграцией и управлением проектами.  Сегодня хочу поделиться историей одного проекта, который начался с, казалось бы, рутинной задачи — рассылки. Но, как это часто бывает, дьявол оказался в деталях, а именно — в персональных данных.

Рис. 1. Защищенный контур CRM: централизованное управление контактами, журналирование действий и модуль управления согласиями.

Рис. 1. Защищенный контур CRM: централизованное управление контактами, журналирование действий и модуль управления согласиями.

1) Постановка задачи: цена зависимости от внешних платформ

К нам пришел клиент с задачей: нужна CRM-система для email-рассылок, которая будет жить внутри нашего защищенного контура. Причем система должна была полноценно работать с персональными данными (ПДн): хранить их, управлять согласиями, персонализировать контент и скрупулезно фиксировать каждое действие пользователя (рис. 1). Существующие на тот момент популярные онлайн-сервисы для этой задачи уже не годились. Наши сценарии работы вышли далеко за рамки их стандартного функционала, где рассылка — это только верхушка айсберга.

2) Выбор решения: свое или готовое?

Первый вопрос, который встал перед командой: адаптировать готовый облачный сервис или пилить свое решение с нуля? На первый взгляд, оба варианта рабочие. Отправить письма — не проблема, это умеет любой приличный сервис. Однако в подобных проектах требования регуляторов (152-ФЗ, Приказ №21 ФСТЭК и др.) диктуют архитектуру. Поэтому, чтобы не наломать дров, мы сразу задали себе несколько ключевых вопросов: 

  • Где будут храниться данные? Принципиально — они не должны покидать контур заказчика. Никаких «облачных» историй у третьих лиц.

  • Кто будет контролировать этот контур? Внешние сервисы не дают нужной гибкости. Ты зависишь от их техподдержки, обновлений и политик безопасности.

  • Как будет вестись журнал действий и согласий? Нам требовалось полное, доказуемое журналирование (логирование) каждого действия: от загрузки данных до отзыва согласия.

  • Насколько глубоко можно настроить логику? Нужна была кастомная логика управления согласиями, а не просто галочка «согласен».

Готовый сервис — это удобно, спору нет. Подключил, настроил и поехал. Но как только речь заходит о полном контроле над данными, это удобство превращается в тыкву. Оно упирается в жесткие рамки платформы. Простой пример: популярные сервисы рассылок предлагают 4-й уровень защищенности персональных данных (УЗ-4), а требования законодательства в нашем кейсе диктовали минимум второй (УЗ-2). Доверить такой объем ПДн стороннему API, даже самому защищенному, — примерно то же самое, что и оставить ключ от квартиры под ковриком. Всегда есть риск. Поэтому взвесив плюсы и минусы,мы двинулись в сторону разработки собственной CRM на Django.

3) Задачи и наши решения

Расскажу по задачам, которые мы решали, и инструментам, которые для этого использовали. 

Задача: обеспечить хранение данных и доказуемость действий

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

Во-вторых, для отслеживания всех манипуляций с персональными данными мы задействовали встроенные в Django механизмы журналирования. Любое действие, будь то импорт контакта или подтверждение согласия, с отметкой времени падало в журнал (см. рис. 2). Это дало нам возможность отследить полный жизненный цикл обработки персональных данных.

Для каждого пользователя мы генерировали уникальный идентификатор (UID). Для этого использовали криптографически стойкий алгоритм binascii.hexlify(os.urandom(64)).decode(). На выходе получалась 128-символьная строка. Можете представить, каковы шансы подобрать или случайно угадать такой ключ для базы в 70 тысяч пользователей? Правильно, практически нулевые.

Рис. 2. Жизненный цикл обработки персональных данных: от импорта контакта до фиксации актуального статуса с полным журналированием каждого шага.

Рис. 2. Жизненный цикл обработки персональных данных: от импорта контакта до фиксации актуального статуса с полным журналированием каждого шага.

Задача: создавать персонализированные и визуально-привлекательные письма

Отдельная задача — дать в руки заказчику инструмент для создания красивых и личных писем. Для этого мы встроили в CRM редактор шаблонов, чтобы верстать макеты можно было прямо в системе, без прыжков по сторонним сервисам. Для персонализации использовали плейсхолдеры (например, FIO). При отправке они автоматически заменялись на реальные данные пользователя. Также добавили гибкую систему фильтров, чтобы можно было легко формировать рассылки на конкретные сегменты аудитории. Эти простые, в общем-то, инструменты убрали из процесса рутину, снизили риск ошибки из-за человеческого фактора и ощутимо ускорили подготовку кампаний.

Задача: собирать статистику, не используя внешние сервисы

Поскольку сервис мы писали с нуля, у нас не было навороченных инструментов аналитики, как в готовых платформах. Да мы и не могли их использовать из соображений безопасности. Задачу сбора статистики по открытиям писем решили старым дедовским способом — с помощью трекинг-пикселя. В каждое письмо мы добавляли невидимое изображение размером 1×1 пиксель. Когда человек открывал письмо, его почтовый клиент обращался к нашему серверу за этой картинкой. Мы фиксировали этот запрос и таким образом анонимно, без сбора лишних данных, получали нужную статистику (см. рис. 3).

Рис. 3. Схема работы трекинг-пикселя: письмо отправляется из CRM, при открытии происходит безопасный запрос к серверу для загрузки невидимого изображения, что позволяет собрать анонимную статистику без передачи данных внешним сервисам.

Рис. 3. Схема работы трекинг-пикселя: письмо отправляется из CRM, при открытии происходит безопасный запрос к серверу для загрузки невидимого изображения, что позволяет собрать анонимную статистику без передачи данных внешним сервисам.

Задача: обеспечить высокую доставляемость писем

Следующая важная задача — обеспечить высокую доставляемость писем. Чтобы наши сообщения летели во «Входящие», а не в спам, мы «прогревали» почтовые серверы. Это обязательная процедура для новых доменов. Перед основным запуском система автоматически рассылала нейтральные письма небольшими порциями по всей базе подписчиков. Благодаря этому «прогреву» почтовый сервер заказчика «познакомился» с другими серверами и «заработал» репутацию надежного отправителя. После такого «прогрева» все 70 000 писем уходили со скоростью, близкой к целевой — 60 000 писем в час.

Кстати, грамотный расчет времени на «прогрев» и правильная настройка почтовой инфраструктуры (SPF, DKIM, DMARC) — это не какие-то «серые схемы», а основа основ и прямая экономия ресурсов в будущем. Кому интересны технические детали этого процесса, можете почитать, например, вот тут. А я в одной из следующих статей расскажу, как такой подход помогает экономить на масштабе.

Задача: автоматизировать управление согласиями

Мы свели к минимуму ручную работу с согласиями. Для этого разработали алгоритм, который обрабатывал ответы со страницы подтверждения согласия. Его результаты мы вывели через отдельный модуль в административную панель CRM, чтобы доступ к базе данных с актуальными статусами был максимально оперативным. Система управляла согласиями автоматически: пользователь нажал «Согласен» — в базе данных обновился статус, в журнале появилась запись. Нажал «Отказаться» — получил соответствующий статус, и его данные тут же исключились из активных рассылок. Никаких ручных правок, все строго по букве 152-ФЗ.

4) Инфраструктура и разумная достаточность

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

Для создания защищенной инфраструктуры мы использовали стек российских технологий: РЕД ОС, хостинг в сертифицированном сегменте Selectel, антивирус Dr.Web и Secret Net Studio для Linux для контроля доступа. 

При этом мы сознательно не стали внедрять некоторые избыточные, на наш взгляд, меры защиты.  Например, шифрование всей базы данных или разворачивание отдельных VPN-серверов для доступа. Такие решения серьезно усложнили бы архитектуру и кратно увеличили бы стоимость владения системой.  

Мы оценили риски, нагрузку и сценарии использования и сознательно выбрали достаточный уровень защиты вместо избыточного. Нашей целью была реальная, адекватная процессу безопасность, а не «бумажная» безопасность для галочки.

5) Результаты

ИТОГО, что мы получили на выходе:

  • Сроки: Бэкенд написали за 2 недели. Весь проект под ключ, не считая согласования дизайна, занял 3 недели.

  • Масштаб: система уверенно обслуживала базу в 70 000 пользователей.

  • Автоматизация: сбор согласий и управление ими были автоматизированы на 100%. Перед ключевым мероприятием заказчик одной кнопкой получил полностью готовую к рассылке, актуальную базу.

  • Независимость: клиент получил 100% независимость от внешних сервисов рассылок и их политик.

Какие выводы я для себя сделал?

Этот кейc — отличное напоминание: система может казаться простой по набору функций, но как только дело доходит до ПДн, безопасности и аудита, ее реальная сложность резко возрастает. Нельзя обеспечить соответствие закону, просто написав хороший код. Это всегда работа на трех уровнях, как три кита, на которых все держится: логика самого приложения, грамотно выстроенная инфраструктура и отлаженные процессы у самого заказчика. Уберите одного кита — и вся конструкция рухнет.

P.S. Эта CRM, пройдя боевое крещение, в итоге стала одним из наших коробочных продуктов. Так что если перед вами стоят похожие задачи по работе с персональными данными — вы знаете, к кому обратиться. Будем рады помочь.

Спасибо, что дочитали! Подписывайтесь, чтобы быть в курсе!

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