Вступивший в действие в мае этого года GDPR серьезно повлиял на рынок интернет-маркетинга. Его участникам хочется формировать максимально точную аудиторию для показа объявлений, но теперь для этого необходимо получить явное согласие пользователя, иначе даже небольшой нишевый ресурс может нарваться на многомиллионные штрафы. Некоторые ресурсы закрылись, но многие преобразуются в соответствии с новыми требованиями. И наш проект сервиса управления рекламными кампаниями для клиента из США – отличный тому пример.
![image](https://habrastorage.org/r/w780q1/webt/i2/ko/yo/i2koyopci8twyqzurhdgqkcxym8.jpeg)
Наш клиент, американская компания из Лос-Анджелеса, фокусируется на маркетинге в музыкальной индустрии. Его сервис обеспечивает поддержку сложных рекламных кампаний для коллективов самых разных размеров – от банды за углом до звезд мировой сцены.
По сути сервис нашего клиента – это стартап, развивающий специализированную маркетинговую платформу, которая успела собрать инвестиции со стороны звукозаписывающих компаний, поскольку учитывает особенности поведения аудитории в отдельно взятой индустрии. Платформа позволяет таргетировать рекламу, анализируя поведение пользователей, однажды проявивших интерес к тому или иному коллективу. Основные пользователи ресурса – музыканты и работники индустрии (менеджеры, сотрудники звукозаписывающих компаний, организаторы концертов и многие другие).
К моменту начала нашего проекта сервис уже функционировал и успел завоевать определенную позицию на рынке. Однако это был, скорее, прототип, проверяющий основную гипотезу бизнеса, тем более что часть функционала была реализована через партнерские сервисы. Мы подключились к разработке, чтобы создать полноценную архитектуру, а GDPR стал тем самым толчком, который запустил все преобразования. Перед нами была поставлена задача не просто обновить существующий сервис, а перестроить его с учетом нового законодательства, освежить и привести к большему единообразию пользовательский интерфейс.
Весь проект был разделен на несколько этапов.
![image](https://habrastorage.org/r/w780q1/webt/pi/0r/n8/pi0rn8jspha0icrlm2fowfagm8k.jpeg)
На первом этапе мы переписали с нуля ту часть, которая ранее уже работала на PHP, – укорачиватель ссылок и сервис авторизации.
Укорачиватель ссылок – это часть функционала, которая доступна бесплатно всем зарегистрированным пользователям и используется для привлечения клиентов к платным услугам компании. Сервис позволяет привести длинную ссылку к короткой форме, чтобы опубликовать ее в социальных сетях. При этом ссылку можно кастомизировать, настроив, например, геотаргетинг: в зависимости от страны, из которой пришел пользователь, ему можно показывать разные лендинги.
Обновляя бэкенд, мы использовали OpenJDK 1.8, Kotlin и Spring boot/data/web – стандартный фреймворк для проекта, не ожидающего высоких нагрузок. Кстати, именно в этом проекте мы попробовали Kotlin “в бою” впервые, и за счет своего синтаксиса он позволил нам существенно ускорить разработку. Определенно, мы будем использовать его и в других проектах.
БД сервиса авторизации и укорачивателя, реализованных на первом этапе, построена на основе PostgreSQL – для решения этих задач хорошо подошла реляционная модель хранения данных.
На втором этапе мы взялись за управление рекламными кампаниями. Этот функционал у платформы клиента также существовал ранее, но через сервис партнера, за который приходилось платить. Теперь же платформа заказчика доросла до тех масштабов, когда нужно было позаботиться о своей инфраструктуре. Собственный сервис, в отличие от стороннего, гораздо проще развивать в нужном направлении, оперативно внося требуемые изменения.
В этой части проекта мы реализовали только внешний API для менеджера кампаний. А вот на третьем этапе развили данный модуль – доработали API и сделали для менеджера кампаний полноценный UI.
Параллельно мы разработали небольшую собственную DMP (data management platform), управляющую сбором данных о посетителях. Данные DMP хранятся в MongoDB, поскольку мы решили оставить задел на будущее горизонтальное масштабирование этой базы. Сейчас DMP обслуживает до 2 тыс. запросов в секунду (в пиках), при этом мы ориентировались на хранение примерно терабайта данных. Такой объем можно было бы сохранить и в PostgreSQL, однако в перспективе для масштабирования пришлось бы применить большие усилия.
Та же MongoDB используется в базе менеджера кампаний (Campaign DB) – тут нам хорошо подошла модель документо-ориентированной базы данных. Кампании идут как единые сущности и могут расширяться.
Все кеши работают на Redis.
Фронтенд: Angular 5, TypeScript, HTML5, Sass, Node.js, npm, Angular CLI.
В ходе последнего этапа проекта мы выполнили интеграцию систем клиента и сервиса ключевого партнера, открывающего компании доступ к огромной базе музыкантов, что обеспечит рост числа пользователей.
Были в проекте и определенные сложности. Заказчик хотел сохранить накопленные за время работы сервиса пользовательские данные и регистрации, немного изменив при этом модель. Параллельно с переделкой архитектуры мы переносили регистрации и меняли ее принципы – с username на email в качестве логина, что принесло нам немало бессонных ночей из-за ограничений на число пользователей с одинаковым адресом электронной почты. Изменилась и модель прав в системе. Ранее сервис работал по двухуровневой модели, мы же реализовывали модель прав без ограничений (включая возможность выдавать ограниченные права).
Параллельно расширялся функционал. Например, на одном из этапов появился multistore, с помощью которого для конечных посетителей, переходящих по коротким ссылкам на определенную композицию, можно настраивать страницы со списком сервисов, где эти композиции доступны для легальной покупки или прослушивания.
Основной рынок нашего клиента – США, но из Европы приходило порядка 10% трафика, который компании не хотелось терять. С момента вступления нового регламента в силу (25 мая 2018 года) его таргетинг был просто отключен. После консультаций с юристами мы построили сервис таким образом, чтобы он не противоречил GDPR, и с 16 августа снова запустили таргетинг.
Честно говоря, мы всей группой недели две изучали тонкости регламента. Сложность на данном этапе была в том, что при общей размытости формулировок пока нет правоприменительной практики – реальных случаев, которые могли бы показать, как делать правильно, а как неправильно. Однако теперь (после собственных изысканий и консультаций с юристами) мы уверены в реализованной архитектуре решения.
Логика работы сервиса подразумевала причисление пользователя, переходящего по короткой ссылке, к определенной аудитории, чтобы потом ему можно было показывать рекламу. С точки зрения GDPR этого нельзя делать без явного согласия самого пользователя. И мы реализовали запрос согласия – при переходе по ссылке внизу страницы появляется плашка с вопросом и двумя кнопками. Запрос открывается для пользователей, чей IP относится к Европе, а их ответ сохраняется в виде куки, так что посетителям не приходится каждый раз жать на кнопки.
Если пользовательского согласия (т.е. куки) нет, мы просто не показываем ему пиксель, т.е. в общей статистике сервиса будет засчитан факт посещения, но не будут собраны и учтены пользовательские данные.
GDPR накладывает архитектурные ограничения – персональные данные нужно не только корректно собирать, но и безопасно хранить. В нашем случае эти ограничения касаются реализованного DMP (несмотря на то, что там хранятся обезличенные данные с анонимными идентификаторами, которые лишь гипотетически позволяют их деанонимизировать) и базы сервиса авторизации. В нашей архитектуре эти базы явно выделены в отдельные блоки. В соответствии с регламентом доступ третьих лиц к этим “чувствительным” модулям, естественно, ограничен.
К базе авторизации имеет доступ только соответствующий сервис. Все остальные сервисы ничего не знают о персональных данных пользователя платформы – им достаточно валидации со стороны сервиса авторизации.
В базу DMP заходит также лишь одноименный сервис. При этом из базы отдаются только агрегаты данных об аудитории, но не сами данные. Эти агрегаты ложатся в основу аналитики, которую получают в личном кабинете пользователи сервиса из музыкальной индустрии.
У нас также предусмотрена обязательная процедура выгрузки и удаления пользовательских данных. Тут стоял вопрос в том, как проверить, что пользователь действительно правомерно запрашивает свои данные. И мы в качестве фактора для проверки используем сохраняемую у пользователя “куку”.
Проект был закончен совсем недавно, поэтому о каких-то численных результатах говорить пока рано.
Автор статьи: Николай Еремин
P.S. Мы публикуем наши статьи на нескольких площадках Рунета. Подписывайтесь на наши страницы в VK, FB или Telegram-канал, чтобы узнавать обо всех наших публикациях и других новостях компании Maxilect.
![image](https://habrastorage.org/webt/i2/ko/yo/i2koyopci8twyqzurhdgqkcxym8.jpeg)
О сервисе
Наш клиент, американская компания из Лос-Анджелеса, фокусируется на маркетинге в музыкальной индустрии. Его сервис обеспечивает поддержку сложных рекламных кампаний для коллективов самых разных размеров – от банды за углом до звезд мировой сцены.
По сути сервис нашего клиента – это стартап, развивающий специализированную маркетинговую платформу, которая успела собрать инвестиции со стороны звукозаписывающих компаний, поскольку учитывает особенности поведения аудитории в отдельно взятой индустрии. Платформа позволяет таргетировать рекламу, анализируя поведение пользователей, однажды проявивших интерес к тому или иному коллективу. Основные пользователи ресурса – музыканты и работники индустрии (менеджеры, сотрудники звукозаписывающих компаний, организаторы концертов и многие другие).
К моменту начала нашего проекта сервис уже функционировал и успел завоевать определенную позицию на рынке. Однако это был, скорее, прототип, проверяющий основную гипотезу бизнеса, тем более что часть функционала была реализована через партнерские сервисы. Мы подключились к разработке, чтобы создать полноценную архитектуру, а GDPR стал тем самым толчком, который запустил все преобразования. Перед нами была поставлена задача не просто обновить существующий сервис, а перестроить его с учетом нового законодательства, освежить и привести к большему единообразию пользовательский интерфейс.
Реализация
Весь проект был разделен на несколько этапов.
![image](https://habrastorage.org/webt/pi/0r/n8/pi0rn8jspha0icrlm2fowfagm8k.jpeg)
На первом этапе мы переписали с нуля ту часть, которая ранее уже работала на PHP, – укорачиватель ссылок и сервис авторизации.
Укорачиватель ссылок – это часть функционала, которая доступна бесплатно всем зарегистрированным пользователям и используется для привлечения клиентов к платным услугам компании. Сервис позволяет привести длинную ссылку к короткой форме, чтобы опубликовать ее в социальных сетях. При этом ссылку можно кастомизировать, настроив, например, геотаргетинг: в зависимости от страны, из которой пришел пользователь, ему можно показывать разные лендинги.
Обновляя бэкенд, мы использовали OpenJDK 1.8, Kotlin и Spring boot/data/web – стандартный фреймворк для проекта, не ожидающего высоких нагрузок. Кстати, именно в этом проекте мы попробовали Kotlin “в бою” впервые, и за счет своего синтаксиса он позволил нам существенно ускорить разработку. Определенно, мы будем использовать его и в других проектах.
БД сервиса авторизации и укорачивателя, реализованных на первом этапе, построена на основе PostgreSQL – для решения этих задач хорошо подошла реляционная модель хранения данных.
На втором этапе мы взялись за управление рекламными кампаниями. Этот функционал у платформы клиента также существовал ранее, но через сервис партнера, за который приходилось платить. Теперь же платформа заказчика доросла до тех масштабов, когда нужно было позаботиться о своей инфраструктуре. Собственный сервис, в отличие от стороннего, гораздо проще развивать в нужном направлении, оперативно внося требуемые изменения.
В этой части проекта мы реализовали только внешний API для менеджера кампаний. А вот на третьем этапе развили данный модуль – доработали API и сделали для менеджера кампаний полноценный UI.
Параллельно мы разработали небольшую собственную DMP (data management platform), управляющую сбором данных о посетителях. Данные DMP хранятся в MongoDB, поскольку мы решили оставить задел на будущее горизонтальное масштабирование этой базы. Сейчас DMP обслуживает до 2 тыс. запросов в секунду (в пиках), при этом мы ориентировались на хранение примерно терабайта данных. Такой объем можно было бы сохранить и в PostgreSQL, однако в перспективе для масштабирования пришлось бы применить большие усилия.
Та же MongoDB используется в базе менеджера кампаний (Campaign DB) – тут нам хорошо подошла модель документо-ориентированной базы данных. Кампании идут как единые сущности и могут расширяться.
Все кеши работают на Redis.
Фронтенд: Angular 5, TypeScript, HTML5, Sass, Node.js, npm, Angular CLI.
В ходе последнего этапа проекта мы выполнили интеграцию систем клиента и сервиса ключевого партнера, открывающего компании доступ к огромной базе музыкантов, что обеспечит рост числа пользователей.
Были в проекте и определенные сложности. Заказчик хотел сохранить накопленные за время работы сервиса пользовательские данные и регистрации, немного изменив при этом модель. Параллельно с переделкой архитектуры мы переносили регистрации и меняли ее принципы – с username на email в качестве логина, что принесло нам немало бессонных ночей из-за ограничений на число пользователей с одинаковым адресом электронной почты. Изменилась и модель прав в системе. Ранее сервис работал по двухуровневой модели, мы же реализовывали модель прав без ограничений (включая возможность выдавать ограниченные права).
Параллельно расширялся функционал. Например, на одном из этапов появился multistore, с помощью которого для конечных посетителей, переходящих по коротким ссылкам на определенную композицию, можно настраивать страницы со списком сервисов, где эти композиции доступны для легальной покупки или прослушивания.
О GDPR стоит сказать отдельно
Основной рынок нашего клиента – США, но из Европы приходило порядка 10% трафика, который компании не хотелось терять. С момента вступления нового регламента в силу (25 мая 2018 года) его таргетинг был просто отключен. После консультаций с юристами мы построили сервис таким образом, чтобы он не противоречил GDPR, и с 16 августа снова запустили таргетинг.
Честно говоря, мы всей группой недели две изучали тонкости регламента. Сложность на данном этапе была в том, что при общей размытости формулировок пока нет правоприменительной практики – реальных случаев, которые могли бы показать, как делать правильно, а как неправильно. Однако теперь (после собственных изысканий и консультаций с юристами) мы уверены в реализованной архитектуре решения.
Логика работы сервиса подразумевала причисление пользователя, переходящего по короткой ссылке, к определенной аудитории, чтобы потом ему можно было показывать рекламу. С точки зрения GDPR этого нельзя делать без явного согласия самого пользователя. И мы реализовали запрос согласия – при переходе по ссылке внизу страницы появляется плашка с вопросом и двумя кнопками. Запрос открывается для пользователей, чей IP относится к Европе, а их ответ сохраняется в виде куки, так что посетителям не приходится каждый раз жать на кнопки.
Если пользовательского согласия (т.е. куки) нет, мы просто не показываем ему пиксель, т.е. в общей статистике сервиса будет засчитан факт посещения, но не будут собраны и учтены пользовательские данные.
GDPR накладывает архитектурные ограничения – персональные данные нужно не только корректно собирать, но и безопасно хранить. В нашем случае эти ограничения касаются реализованного DMP (несмотря на то, что там хранятся обезличенные данные с анонимными идентификаторами, которые лишь гипотетически позволяют их деанонимизировать) и базы сервиса авторизации. В нашей архитектуре эти базы явно выделены в отдельные блоки. В соответствии с регламентом доступ третьих лиц к этим “чувствительным” модулям, естественно, ограничен.
К базе авторизации имеет доступ только соответствующий сервис. Все остальные сервисы ничего не знают о персональных данных пользователя платформы – им достаточно валидации со стороны сервиса авторизации.
В базу DMP заходит также лишь одноименный сервис. При этом из базы отдаются только агрегаты данных об аудитории, но не сами данные. Эти агрегаты ложатся в основу аналитики, которую получают в личном кабинете пользователи сервиса из музыкальной индустрии.
У нас также предусмотрена обязательная процедура выгрузки и удаления пользовательских данных. Тут стоял вопрос в том, как проверить, что пользователь действительно правомерно запрашивает свои данные. И мы в качестве фактора для проверки используем сохраняемую у пользователя “куку”.
Проект был закончен совсем недавно, поэтому о каких-то численных результатах говорить пока рано.
Автор статьи: Николай Еремин
P.S. Мы публикуем наши статьи на нескольких площадках Рунета. Подписывайтесь на наши страницы в VK, FB или Telegram-канал, чтобы узнавать обо всех наших публикациях и других новостях компании Maxilect.