Рассылки по сегментам на основе MailChimp

в 7:40, , рубрики: api, mailchimp, php, Блог компании Softline, Веб-разработка, рассылки, метки: , , ,

Привет! Сегодня я расскажу о том, как можно интегрировать сервис почтовых рассылок mailchimp на своем сайте.
Сервис дает множество возможностей:
— расширенный трекинг;
— выборки пользователей;
— красивые шаблоны писем;
— интеграция с социальными сетями;
— интеграция с Google Analytics;
— экономия времени на разработку своего проекта.
На основе этого сервиса мы сделали автоматическую рассылку спецпредложений по целевым срезам — определенным вендорам и категориям продуктов. Попробуем вкратце рассказать о некоторых особенностях реализации.

Создание списка пользователей.
Рассылки в mailchimp строятся на основе списка пользователей, поэтому первым делом, в личном кабинете mailchimp.com, создадим такой список: Lists — Create List. Мой список называется «спецпредложения», в нем находятся пользователи, подписавшиеся на новости и акции нашего интернет-магазина. После создания списка необходимо узнать его уникальный номер: Lists — спецпредложения — Settings — List Settings and Unique ID, чтобы работать с этим списком через API.

Рассылки по сегментам на основе MailChimp

Создадим группы пользователей в списке, в моем случае это вендоры и категории: Lists — спецпредложения — Groups — View Groups

Вот, например, секция вендоров:
Рассылки по сегментам на основе MailChimp

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

Кстати, самих групп нельзя создать больше 60, и эта важная информация хранится в виде комментария к одному из методов API.

Импорт пользователей в список рассылки.
Обычно пользователи попадают в список рассылки через форму подписки, но можно их загрузить целой пачкой через механизм импорта. (Lists — спецпредложения — import.) Возможности «откуда» довольно большие, имеется импорт из файлов, гугл контактов, документов и т. д. Импортировать можно сразу в определенные группы.

Рассылки по сегментам на основе MailChimp

Обратите внимание, что в бесплатной версии есть ограничение на 2000 подписчиков, поэтому если вы загрузите туда большее число e-mail адресов, появится сообщение «You've hit your sending limit. Your Forever Free plan can only send while your total subscriber count (all lists combined) is at or under 2000. upgrade to re-enable» и запускать рассылки уже не получится, даже если в рассылке участвуют не все подписчики, а лишь небольшой сегмент.

Также после импорта вы, скорее всего, увидите сообщение «Our review team recently emailed you some questions. Before we can approve your account for sending email campaigns, we need your reply». В нём просят рассказать о вашей компании, указать откуда вы берете списки пользователей – в общем, пройти своеобразную верификацию. Вот объяснение, для чего нужна такая проверка: kb.mailchimp.com/article/why-is-my-account-under-review

API MailChimp
После того как создан список пользователей можно приступить к созданию первой рассылки. Создание и запуск рассылок через панель управления mailchimp нас не интересует, так как нам нужна автоматическая система. Поэтому идем сразу изучать API MailChimp.
На текущий момент API имеет версию 1.3 и находится тут: apidocs.mailchimp.com/api/1.3/

Практически всё, что можно делать через панель управления, реализовано в методах API и есть набор готовых классов-оберток для различных языков. Вот для php: apidocs.mailchimp.com/api/downloads/#php

Для работы с API необходим ключ, который можно создать в личном кабинете:

Рассылки по сегментам на основе MailChimp

Пример работы с API:

<?php 
require_once('MCAPI.class.php');

//ключ API
$apiKey = 'd43a8xxxxxxxxxxxxxxxxxc6867cbd-us4';

//ID списка пользователей
$listId = '8e2xxxxx44';

$mailchimpAPI = new MCAPI($apiKey);

//получаем список групп у списка пользователей
$groups = $mailchimpAPI->listInterestGroupings($listId);

print_r($groups);

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

На скриншоте видна выборка пользователей по 3 разным сегментам: группы, язык, местоположение. Вообще выборки могут быть довольно сложными и для создания таких выборок сделали даже отдельный инструмент — HairBall, подробнее тут: blog.mailchimp.com/introducing-hairball-an-air-app-for-really-complicated-mailchimp-lists/

В нашем проекте мы используем только сегменты по группам (вендоры/категории). Вот пример создания рассылки на основе групп:

$opts= array(
	'list_id'	=> $listId,
	'from_email'	=> 'почта отправителя',
	'from_name'	=> 'название отправителя',
	'tracking'	=> array('opens' => true, 'html_clicks' => true, 'text_clicks' => false),
	'authenticate'	=> true,
	'analytics'	=> array('google'=>'UA-XXXXXX-2'),
	'subject'	=> 'Тема письма',
	'title'		=> 'Заголовок рассылки',
);		
		
$content = array(
	'html' => 'html тело письма',
	'text' => 'plain text тело письма',
);
		
$segmentGroups = array(
	'match' => 'any', 
	'conditions' => array(
		array('field' => 'interests-5555', 'op' => 'all', 'value' => '17#ABBYY, 19#Adobe Systems, 20#McAfee Inc'),
	array('field' => 'interests-4444', 'op' => 'all', 'value' => '88#Антивирусы. Безопасность, 99#Офисные программы, 77#Операционные системы'),
	)
);

//создание рассылки
 
$campaignId = $mailchimpAPI->campaignCreate('regular', $opts, $content, $segmentGroups);
//запуск рассылки
if ($campaignId) {
	$mailchimpAPI->campaignSendNow($campaignId);
}

В массиве $opts задаются настройки рассылки, в массиве $content — содержимое письма, html и plain text.

В параметре $segmentGroups, должен быть специально сформированный массив с сегментами пользователей из списка.

Если сегментом является группа (наш случай), то имя сегмента должно состоять из префикса 'interests-' + ID корневой группы (называется вообще groupings — группировка), а значением — перечисленные через запятую названия групп.

Как видно 5555 и 4444 — это id корневых групп, в нашем случае вендоров и категорий.

Узнать id корневых групп и всю информацию по группам можно через метод listInterestGroupings

$groups = $mailchimpAPI->listInterestGroupings($listId);
print_r($groups);

apidocs.mailchimp.com/api/1.3/listinterestgroupings.func.php

Видно, что API поддерживает выборку по нескольким сегментам. В моём случае это 2 группы, а также поддерживает различные условия, как между сегментами — ключ match = «any» (ИЛИ), match = «all» (И), так и внутри сегментов — ключ op = «all» (полное совпадение со списком в value), op = «one» (одно из совпадений со списком в value).
apidocs.mailchimp.com/api/1.3/campaigncreate.func.php

Вернемся к массиву $content — откуда брать текст письма?
Тут есть несколько ситуаций – например, менеджер в админке mailchimp может выбрать симпатичный шаблон письма, а их там много, отредактировать текст на нужный, сохранить в «мои шаблоны». Далее через метод templates(), (http://apidocs.mailchimp.com/api/1.3/templates.func.php) мы получаем ID нужного шаблона и создаем рассылку на основе него (в массиве $opts метода campaignCreate() нужно указать ключ template_id).

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

Метод campaignCreate() создаст кампанию и вернет ее ID, саму кампанию можно будет наблюдать в списке кампаний в панели управления mailchimp, а после выполнения campaignSendNow() произойдет запуск рассылки, начнут отправляться письма.

Рассылки по сегментам на основе MailChimp

По отправленным рассылкам можно смотреть отчеты. Вот, например, отчет по рассылке некой тестовой группе:
Рассылки по сегментам на основе MailChimp

В итоге мы написали скрипт, который:

1. выбирает новые спецпредложения из нашей бд
2. ищет группы пользователей в mailchimp на основе выборки спецпредложений (спецпредложения привязаны к вендору/категории)
3. генерирует текст письма на основе макета с прикрученными тегами Twig, с блоками топовых, дополнительных спецпредложений, блоком менеджера, баннерами и т.д.
4. запускает рассылку и отмечает время последнего запуска
5. переходит к п.1 на следующий день :)

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

Рассылки по сегментам на основе MailChimp

Но нам была нужна динамическая форма, производящая подписку на определенные группы в зависимости от страниц, на которых она находится.

Воспользуемся API.
Подписка пользователя представлена 2 методами: listSubscribe — создание подписки для нового пользователя и listUpdateMember — обновление подписки пользователя:
apidocs.mailchimp.com/api/1.3/listsubscribe.func.php
apidocs.mailchimp.com/api/1.3/listupdatemember.func.php

Методы практически одинаковые, например указание ключа update_existing = true превращает listSubscribe() в listUpdateMember()

Будем рассматривать только метод listSubscribe, так как он более полный:

$mailchimpAPI->listSubscribe($listId, $email, $mergeVars, $emailType, $doubleOptin, $updateExisting, $replaceGroups, $sendWelcome);

Важные параметры:
• $listId — ID списка пользователей
• $email — почтовый адрес пользователя, подписку которого надо создать или обновить
• $mergeVars — массив с изменяемыми данными, например группы
• $updateExisting — обновлять подписку, если она уже есть
• $replaceGroups — заменить группы, если они есть в $mergeVars или объединить с существующими

Для обновления групп пользователя нам нужен параметр $mergeVars, где ключ id — это id корневых групп (вендоры и категории), а ключ groups — перечисленные через запятую названия групп:

$mergeVars = array('GROUPINGS' => array(
	array(
		'id' => '4444', 
		'groups' =>  '99#Офисные программы, 77#Операционные системы'
	),
));

Также выставляем $replaceGroups = false для объединения уже существующих групп с новыми в $mergeVars.

Для полной замены групп на новые нужно во-первых выставить $replaceGroups = true, а во-вторых в $mergeVars передавать весь массив корневых групп с пустыми значениями самих групп.

$mergeVars = array('GROUPINGS' => array(
	//останутся только эти группы
	array(
		'id' => '4444', 
		'groups' =>  '99#Офисные программы, 77#Операционные системы'
	),
	//удаляем группы
	array(
		'id' => '5555', 
		'groups' => ''
	),
	//удаляем группы
	array(
		'id' => '7777', 
		'groups' => ''
	),
));

То есть параметр $replaceGroups=true работает в пределах одной корневой группы, а не всех.

Используя этот метод мы сделали 2 варианта формы:
1. Для всех пользователей – обычная форма с полем email и скрытыми полями для групп рассылок в зависимости от текущей страницы.
2. Форма в личном кабинете, где отображается список чекбоксов из групп на которые можно подписаться/отписаться.

Особенности метода listSubscribe:
1. Если подписка новая, то вся ее обработка переходит на сервис mailchimp, высылается письмо с подтверждением подписки, после подтверждения дается ссылка на профиль подписчика, где он может редактировать свои данные, профиль опять же находится на сайте mailchimp.
2. Если email пользователя уже есть в списке рассылки, то метод выдаст ошибку и предложит вручную отредактировать личные данные и группы подписчика, ссылка на профиль придет в тексте ошибки $mailchimpAPI->errorMessage. Надо указывать $updateExisting=true — чтобы сделать обновление подписки, но этим ключом можно перезаписать и чужую подписку, поэтому это не подходит для неавторизованного пользователя.

В итоге у нас 2 проблемы:
1. Вся обработка нового подписчика происходит не у нас, мы не можем на ее повлиять, например, выставить группу рассылки.
2. Непонятно как обновлять подписку неавторизованному пользователю, так как мы не можем быть уверены, что указанный email принадлежит ему.

Поэтому мы отключили у listSubscribe отправку писем с подтверждением подписки — параметры $doubleOptin = false, $sendWelcome = false и написали механизм, который:

1 — при отправке формы подписки на нашем сайте высылает письмо с уникальной ссылкой-подтверждением.
2 — обработчик ссылки который жестко создает или обновляет подписку, используя $doubleOptin = false, $sendWelcome = false, $updateExisting = true. Теперь мы уверены что указанный email действительно принадлежит неавторизованному пользователю, так как он перешел по ссылке в своем письме.

Надо понимать, что с параметром $doubleOptin = false мы подписываем/обновляем подписку любого пользователя без его подтверждения, поэтому такой подход стоит использовать только там, где вы точно уверены что данная подписка принадлежит текущему пользователю, например в личном кабинете или при переходе по уникальной ссылке.

В итоге:
На основе рассылок mailchimp вполне реально сделать систему автоматических рассылок по определенным сегментам — группам вендоров и категориям продуктов, сделать формы подписки и отписки на определенные сегменты, кастомизировать шаблоны писем. Всю логику подписки/отписки можно перенести на свой сайт и реализовать ее по своему усмотрению, оставив за самим сервисом отправку писем и сбор статистики.

Автор: Softliner


  1. Евген:

    Привет! Отличная статья! Спасибо!
    Ответь на вопрос –
    Получается, мы не можем ВНУТРИ листа разбить людей на сегменты самостоятельно?
    Пример:
    У меня одинаковая рассылка. Набираю подписчиков с разных каналов, соответственно, с каждого канала свой лист. Получается такая борода.
    И при создании автореспондеров – надо каждый из них копировать для каждого листа. Получается полная борода.
    Этого можно избежать?

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js