Работа с API почтового сервиса Mandrill

Mandrill это мощный почтовый сервис от MailChimp. Он является одним из самых удобных в использовании и настройке из семейства однотипных сервисов для отправки почтовых уведомлений. Этот сервис удобно использовать не только для рассылки неких писем коммерческого характера, но и обычных уведомлений с личного сайта. Так как электронные письма, отправляемые с личных сайтов, могут попадать в спам, то это будет еще одним плюсом в пользу решения о выборе услуг данного сервиса.

Для взаимодействия сервиса Mandrill с приложением, существует API с довольно широким спектром возможностей, с основными из них нам и предстоит, познакомиться. К тому же имеется возможность использования базового (бесплатного аккаунта) позволяющего производить рассылку до 12000 писем в месяц.

Использование API

Поскольку осуществление взаимодействия с API Mandrill предполагается реализовывать на PHP, то саму библиотеку берем отсюда. Можно воспользоваться установкой через Composer или стандартной установкой (скачиваем, распаковываем и подключаем необходимые модули). Если вы выбрали второй вариант установки, то вам необходимо найти в скачанном архиве каталог “src”, в нем то и содержатся файлы и каталоги необходимой библиотеки.

Для того чтобы иметь возможность использования API, необходимо получить API ключ (имеется ввиду, что вы уже зарегистрированы). Заходим в аккаунт и слева в меню кликаем по пункту “Settings” и в разделе “API Keys” сможем увидеть свой ключ:

Mandrill - Получение API ключа

Далее потребуется создать субаккаунт. Для этого опять же в левостороннем меню кликаем по пункту “Outbound” и после открытия соответствующего раздела настроек, нажимаем кнопку “Create a Subaccount”:

Создание субаккаунта

Для отправки письма можно воспользоваться заранее созданным шаблоном, который должен быть доступен в вашем аккаунте, или же ограничиться отправкой обычного текстового сообщения. Также имеется возможность оформления письма в формате HTML. Для отправки письма, существуют следующие методы класса Mandrill_Messages:

  • array send(message [, async = false [, ip_pool = null [, send_at = null]]]) – в качестве параметра message требуется передать заполненную в виде массива структуру данных, приводимую в табл. 1. Параметр async – устанавливает фоновую пакетную отправку сообщений. В качестве параметра ip_pool требуется указывать имя выделенного пула ip адресов, как видно из описания прототипа функции этот параметр не является обязательным. И в качестве последнего параметра send_at можно указать время в формате UTC timestamp YYYY-MM-DD HH:MM:SS для запланированной отправки письма. Но для этого потребуется платный аккаунт с положительным балансом;
  • array sendTemplate(template_name, template_content, message [, async = false [, ip_pool = null [, send_at = null]]]) – данный метод отличается от предыдущего наличием двух дополнительных параметров. В первом параметре template_name указывается имя существующего шаблона. А второй параметр template_content является массивом элементов динамического контента, структура данных которых описана в табл. 2. Подробнее можно ознакомиться здесь.

Таблица 1. Описание полей структуры данных для отправки письма

Параметр Тип Описание
html string Текст с содержанием HTML разметки.
text string Текст письма.
subject string Тема письма.
from_email string Email отправителя.
from_name string Имя отправителя.
to array Массив элементов “to”, содержащих данные об отправителе.
global_merge_vars array Массив элементов “global_merge_vars”, содержащих глобальные данные о метках шаблона.
merge_vars array Массив элементов “merge_vars”, содержащих данные о метках шаблона.
subaccount string Уникальный идентификатор субаккаунта.
attachments array Массив вложений добавляемых к письму.
images array Массив изображений добавляемых к письму.
Структура параметра массива to
email string Email адресата.
name string Имя адресата.
type string Тип заголовка. По умолчания используется “to”. Возможные варианты (to, cc, bcc).
Структура параметра массива global_merge_vars
name string Имя переменной, чувствительность к регистру. Имя переменной не может начинаться с символа “_”.
content string Значение переменной.
Структура параметра массива merge_vars
rcpt string Email адрес получателя, к которому буду применены локальные подстановочные метки шаблона.
vars array Массив элементов “vars”, содержащих локальные данные о метках шаблона. Структура параметра массива “vars” идентична структуре параметра массива “global_merge_vars”.
Структура параметра массива attachments
type string MIME type вложений.
name string Имя файла.
content string Содержимое файла должно быть в кодировке base64.
Структура параметра массива images.
type string MIME type файла – должен быть изображением.
name string Имя файла.
content string Содержимое файла должно быть в кодировке base64.

Таблица 2. Структура элемента массива использующегося в параметре template_content

Параметр Тип Описание
name string Имя метки.
content string Содержимое метки.

Метод send() позволяет произвести текстовую отправку письма, а второй метод предоставляет возможность производить отправку писем с использованием, заранее созданных шаблонов. Оба метода возвращают массив со структурой данных представленной в табл. 3.

Таблица 3. Структура ответа, для каждого адресата

Параметр Тип Описание
email string Email адресата.
status string Статус отправки: отправлено, в очереди, запланировано, отклонено или отправка не возможна.
reject_reason string Причина отказа доставки письма. Может быть, одной из следующих вариантов: rejected, hard-bounce, soft-bounce, spam, unsub, custom, invalid-sender, invalid, test-mode-limit, rule
_id string Уникальный идентификатор отправленного сообщения.

Чтобы потом не отвлекаться, создадим на будущее сразу и шаблон. Для этого в уже знакомом нам левостороннем меню кликаем по пункту “Outbound” и после перехода в соответствующий раздел, нажимаем кнопку “Create a Template”:

Mandrill - создание шаблона

Здесь нам будет предложено ввести имя шаблона. После ввода такового, нажимаем кнопку “Start Coding”:

Mandrill - указание имени шаблона

И уже на завершающем этапе нам необходимо заполнить предлагаемые поля. Затем в правом поле нужно написать код для будущего нашего подстановочного шаблона. Обратите внимание на то, что редактор шаблона должен находиться в режиме “HTML”. После заполнения всех необходимых нам полей, нажимаем кнопку “Publish”:

Mandrill - заполнение полей шаблона

Теперь, когда уже все настроено, можно производить отправку письма. Исходный код отправки письма:

// Подключение библиотеки Mandrill
require_once ('Mandrill.php');

$mail = new Mandrill('API key');

/* Блок динамического контента */
$tpl_con = array(
	array(
		'name' => 'my-label',
		'content' => '<h2>Моя рассылка</h2>'
	)
);

$data = array(
	'html' => 'It is html text',
	'text' => 'It is simple text',
	'subject' => 'Hi friend',
	'from_email' => 'friend@example.com',
	'from_name' => 'Michael',
	'to' => array(		
		array(
			'email' => 'example@gmail.com',
			'name' => 'Lucas',
			'type' => 'to'
		)
	),
	'global_merge_vars' => array(
		array(
			'name' => 'NAME',
			'content' => 'Lucas'
		)
	),
	'merge_vars' => array(
		array(
			'rcpt' => 'example@gmail.com',
			'vars' => array(
				array(
					'name' => 'NAME',
					'content' => 'Lucas'
				)
			)
		)
	),
	'attachments' => array(
		array(
			'type' => 'application/pdf',
			'name' => 'test.pdf',
			'content' => base64_encode(file_get_contents('test.pdf'))
		)
	),
	'images' => array(
		array(
			'type' => 'image/png',
			'name' => 'Smiley.png',
			'content' => base64_encode(file_get_contents('Smiley.png'))
		)
	),
	'subaccount' => 'cust-123'
);

try {
	/* Отправка обычного письма */
	$result = $mail->messages->send($data);
	print_r($result);
	/* Отправка письма с использованием шаблона */
	$result = $mail->messages->sendTemplate('example', $tpl_con, $data);
	print_r($result);
} catch(Mandrill_Error $error) {
	echo 'Error: ' . get_class($error) . ' - ' . $error->getMessage();
}

Результаты работы двух методов представлены ниже. На нижнем изображении виден результат применения шаблона.

Mandrill — результат отправки

Мы отправили одно и то же письмо с использованием обоих доступных нам методов. Для того чтобы можно было увидеть отличия. В качестве примера к письму были прикреплены изображение и документ в формате PDF

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

*|name|* - формат написания метки, имя является регистронезависимым

которая в будущем будет заменена на ее содержание. А для динамического контента в HTML теге указывается следующий атрибут:

mc:edit="section-name", идентификатор является регистрозависимым

где, section-name – уникальный идентификатор, означающий, что данные указанного идентификатора будут вставлены в содержащий его HTML тег. Так же стоит учесть, что элементы шаблона указанные в поле “global_merge_vars” (см. табл. 1), будут заменены на соответствующие элементы, указанные в поле “vars” структуры “merge_vars” для указанных email адресов в поле “rcpt” структуры “merge_vars”.

Рассмотрим следующий пример:

'to' => array(	
	array(
		'email' => 'example_1@gmail.com',
		'name' => 'Lucas 2',
		'type' => 'to'
	),
	array(
		'email' => 'example_2@gmail.com',
		'name' => 'Lucas 1',
		'type' => 'to'
	)
),
'global_merge_vars' => array(
	array(
		'name' => 'NAME',
		'content' => 'Lucas'
	)
),
'merge_vars' => array(
	array(
		'rcpt' => 'example_1@gmail.com',
		'vars' => array(
			array(
				'name' => 'NAME',
				'content' => 'Alex'
			)
		)
	)
)

Здесь переопределение метки произойдет только для получателя с адресом “example_1@gmail.com”. Соответственно метка в шаблоне с именем “NAME”, будет заменена на имя “Alex”, для остальных получателей содержание метки останется “Lucas”.

При использовании обоих методов для отправки писем необходимо учитывать следующие факторы:

  • При использовании метода send():
    • Если в структуре данных (см. табл. 1) указано поле “html” и оно содержит некие данные, то поле “text” будет им перекрыто.
  • При использовании метода sendTemplate():
    • Если в редакторе шаблонов (см. выше) шаблон имеет формат “HTML”, то ни одно из двух полей: “html” и “text” не сможет перекрыть текст шаблона;
    • Если в редакторе шаблонов, шаблон имеет формат “Text”, то для его автоматической подстановки в шаблон письма при отправке, запрещено указывать в структуре данных поля: “html” и “text”. Вернее указывать можно, но они не должны содержать никаких данных, иначе в тело письма пойдут данные указанные в одном из двух полей в порядке приоритета (html, text);
    • Если в шаблоне не заполнить поле “subject”, то приоритет перейдет к одноименному полю (при наличии такового) в структуре данных (см. табл. 1).

Перечень возможных ошибок содержится в табл. 4.

Таблица 4. Перечень возможных ошибок, при неудавшейся отправке письма

Invalid_Key Неверный API ключ.
Unknown_Message Идентификатор сообщения не существует.
ValidationError Параметры, переданные при вызове, являются некорректными.
GeneralError Произошла ошибка во время запроса.