Как уже я уже писал, не так давно мы начали работать с командой одного популярного freemium сервиса, являющегося системой управления проектами. Сервис генерирует довольно большое количество писем, исчисляемое в тысячах в день, это в основном различные уведомления пользователям о произошедших изменениях и ежедневные напоминания о приближении/истечении срока выполнения каких-либо работ. Пользователи также могут отвечать на пришедшие письма и таким образом обновлять данные. Поскольку количество пользователей увеличивается, мы заметили, что увеличиваются и наши счета SendGrid, которые, будучи freemium сервисом, нам хотелось бы минимизировать. Также нам хотелось понять насколько эффективно мы используем почту и не отправляем ли мы часть почты просто в никуда, платя за доставку SendGrid. Всё чаще стали возникать вопросы о том, что кто-то не получил какое-то уведомление или его ответ на письмо из сервиса не был им получен и опубликован. Таким образом, второй проблемой была невозможность эффективно заниматься поддержкой пользовательских проблем, связанных с доставкой почты, поскольку постоянно приходилось просматривать и собственную базу, и интерфейс SendGrid. При том, что это занимало уйму времени, это часто не давало никакого результата. После отправки письма по smtp у нас не оставалось никакой связи между записями в нашей базе данных и результатом на стороне SendGrid. Аналогичной была ситуация с входящей почтой. Для тех, кто еще не сталкивался, опишу как это работает в SendGrid: письма получаются SendGrid-ом, они парсятся и затем полученные данные отправляются POST-ом по указанному адресу, т.е. вам. Так вот, когда возникает ситуация, что чье-то письмо не было опубликовано в нашем сервисе, непонятно кто виноват — SendGrid не смог его пропарсить или наш скрипт не отработал. Вы поймёте нас, если вы попадали в ситуацию, когда правдивый ответ — «ну не знаю я, блин, почему письмо не пришло» пользователю не напишешь, и проходится только обещать в скором времени разобраться с его вопросом. Чтобы наши обещания не стали ложью, я взялся за дело. Итак — у нас возникла необходимость в полном контроле над процессом доставки и получения писем. Текущим положением дел было — отправка (по smtp) и получение почты через SendGrid, полное отсутствие связи наших и SendGrid данных, тысячи писем в день и их экспоненциальный рост, выливающийся во всё большие суммы и отсутствие эффективного механизма решения проблем пользователей. Задача — максимально связать наши данные с данными SendGrid, чтобы сократить расходы и повысить качество и скорость поддержки клиентов. Первым делом мы обратились за ответами на наши вопросы к их документации. Оказалось, что у SendGrid есть 2 хука, которые как раз и дают нужный нам контроль над состоянием писем. Первый хук, это Events — SendGrid отправляет на указанный урл уведомления о событиях, генерируемых в их системе. Для идентификации конкретного письма они предлагают использовать механизм уникальных аргументов и категорий, которые могут быть переданы в виде специального заголовка при отправке письма через SMTP. И в дальнейшем уведомления о событиях включают в себя эти аргументы и категории, что позволяет точно определить к какому именно письму относится данное событие. Что это дает? Во-первых, «если повар нам не врет», мы всегда точно знаем, доставлено ли письмо пользователю. Во-вторых, можно полностью или частично автоматизировать процесс повторной отправки писем, которые получили статус «Deferred» или попали в Bounces список. Кроме того, теперь мы быстро узнаем о занесении нового email-а в Bounces список и можем оперативно принимать меры. Есть и дополнительные бонусы, связанные с использованием категорий писем. Как было сказано выше, отправляемому письму могут быть назначены категории и согласно документации их может быть до 10. Данные категории используются затем при составлении отчетов в интерфейсе SendGrid, их можно сравнивать друг с другом на симпатичного вида графиках. Правда, к сожалению, у них почему-то только одноуровневая система категорий, а нам было бы удобнее использовать двухуровневый подход. Двухуровневый потому, что первый уровень у нас определяет приложение, отправившее письмо, а второй уровень — действие, которое вызывало его отправление. Например, приложение Todo отправляет письма при создании, редактировании и смене даты окончания записи. Использование второй категории дает нам более полное представление о том, кто и сколько генерирует писем внутри одного приложения. Однако подобные действия есть и в других приложениях, таким образом, сама по себе категория Add не столь интересна для статистики, сколько ее привязка к конкретному приложению. Впрочем, возможно, что кому-то и такой срез статистики будет полезен. Несколько слов о реализации: проект написан с использованием CodeIgniter и письма отправляются стандартной библиотекой Email. Однако она не позволяет создавать собственные заголовки при отправке писем по SMTP, следовательно, ее нужно расширить собственным классом. Взяв в качестве примера библиотеку github.com/leonbarrett/CodeIgniter-Sendgrid-API/blob/master/system/libraries/Email.php мы сделали собственную библиотеку, отбросив все ненужное и упростив оставшееся до одного метода :). На самом деле вышло 2 метода, поскольку метод _set_header() объявлен в классе CI_Email как private, что не позволяет его использовать в классах-наследниках.Вот полный код библиотеки:
if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CodeIgniter * * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author Deep Shift Labs Dev Team * @copyright Copyright (c) 2013, Deep Shift Labs * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 * @filesource */ // ------------------------------------------------------------------------ /** * CodeIgniter Email Class * * Permits email to be sent using Mail, Sendmail, or SMTP. * * @package CodeIgniter * @subpackage Libraries * @category Libraries * @author Deep Shift Labs Dev Team * @link http://deepshiftlabs.com */ class MY_Email extends CI_Email { /** * Add a Header Item * * @access private * @param string * @param string * @return void */ private function _set_header($header, $value) { $this->_headers[$header] = $value; } /** * Add a Sendgrid header * * @access public * @param array * @return void */ public function addSendGridHeader($data) { $xsmtpapi = json_encode($data); // Add spaces so that the field can be foldd $xsmtpapi = preg_replace('/(["]}])([,:])(["[{])/', '$1$2 $3', $xsmtpapi); $this->_set_header('X-SMTPAPI', $xsmtpapi); } }
Таким образом, добавление к письму уникальных аргументов и категорий происходит одним вызовом метода addSendGridHeader(), например так:
$this->email->addSendGridHeader(array('unique_args'=>array('email_id'=>1), 'category'=>array('help', 'question')));
Однако вернемся к хукам, второй хук, Inbound Parse, позволяет получать ответ от пользователей. После соответствующей настройки MX записи домена или поддомена Sendgrid начинает присылать на указанный адрес обработанное письмо с ответом. К нашему удивлению, оказалось, что для входящих писем нет никаких событий, т.е. получить информацию о том, в какой стадии обработки оно находится сейчас невозможно. Остается лишь надеяться, что этот процесс у них отлажен и не дает сбоев, т.е. все, что они получили передается нам, проверить-то все равно невозможно. Исходя из этого нам остается лишь зафиксировать те стадии обработки писем, которые происходят на нашей стороне. У нас получились следующие статусы входящих писем: ‘received’, ‘hash_checked’, ‘duplicate’, ‘processed’. Наверняка вас заинтересовал второй статус ‘hash_checked’, во всяком случае я надеюсь, что это произошло, потому что сейчас я буду рассказывать о нем. Кроме того, что мы не получаем никаких событий о входящих письмах от SendGrid, мы также вообще ничего не получаем, что помогло бы идентифицировать начальное письмо. Ни уникальных аргументов, ни категорий, вообще ничего. Т.е. понять на какое письмо мы получили ответ просто так невозможно. А ведь здорово было бы, если бы SendGrid взял задачу привязки отправленных и полученных писем на себя — мы передаем уникальные заголовки с отправленным письмом и они же возвращаются нам вместе с ответом. Это часть того самого непаханного поля, о котором я писал в предыдущем посте. Но поскольку этого нет, приходится выкручиваться самостоятельно. Мы пошли путем использования специального хэша в адресе для заголовка «Reply-To», он выглядит как:
"db051171af45b683c50eb3d66017ecf2+с@incoming.servicedomain.com"
Этот хэш генерируется таким образом, что мы точно знаем какой записи в системе он соответствует. Это может быть запись Todo, дискуссия или еще что-нибудь. При получении письма мы определяем запись, к которой письмо относится, и если ее удалось определить, письму присваивается статус ‘hash_checked’. Далее мы проверяем, не является ли письмо дубликатом, чтобы не создавать несколько одинаковых комментариев. Затем собственно создается новый комментарий и письму присваивается статус ‘processed’. Одной из задач, которые мы хотели решить, была возможность повторной отправки писем, которые не были доставлены пользователям. Для этого все необходимые данные сохраняются в базу. Поскольку проект написан на CodeIgniter, то таковыми данными являются тело письма и сформированные перед отправкой заголовки, которые включают в себя сабжект, получателей, наши уникальные параметры и прочее. Само сохранение писем было реализовано буквально в несколько строк кода при переопределении метода send() стандартной библиотеки Email. Итак, письма сохраняются, однако нет особого смысла хранить исходные данные писем, которые были благополучно доставлены, верно? Во всяком случае, для нас его нет и потому мы внесли небольшие изменения в скрипт, который получает события от SendGrida — если пришло уведомление о событии ‘delivered’, то мы удаляем все соответствующие данному письму записи из таблицы. Здесь использовано множительное число не случайно, для ускорения процесса сохранения писем в базу мы не проверяем является ли это первой попыткой его отправить или нет, т.е. в случае нескольких попыток отправить одно и то же письмо в базе будет сохранено несколько его экземпляров. Логическим завершением было добавление действия для повторной отправки писем из базы, с этим сложностей не возникло, хотя и потребовались небольшие изменения упомянутой выше библиотеки для работы с письмами. Если будет интересно, пишите в комментариях и я расскажу какие именно. Вот в общих чертах и всё о том, как мы контролируем свою отправляемую и получаемую почту. Запустив эту новую подсистему и поднакопив данных, мы начнем её оптимизировать и автоматизировать те случаи, где решение понимаемо нами и программируется. Если вы уже решали подобную задачу и поделитесь своим опытом в комментариях — буды вам очень признателен. P.S. При релизе описанной выше системы автоматизации мы столкнулись с неприятной ситуацией. Наши Production и Pre-production версии системы используют разные аккаунты в SendGrid для того, чтобы тестовые письма не влияли на статистику реальной системы. 15 сентября мы попробовали запустить изменения на Production сервере и оказалось, что почему-то мы не можем получить данные из присылаемых уведомлений о событиях. Недолгое расследование выявило причину — 6 сентября SendGrid запустил третью версию Event webhook-a, в которой был кардинально изменен формат передаваемых данных. В версиях 1 и 2 это были обычные POST переменные, теперь же присылается JSON структура с массивом записей. Довольно странно, что компания SendGrid не предупредила своих платных клиентов о таких существенных изменениях. По закону подлости, приложение Event Notification в аккаунте для Pre-production было активировано до 6-го сентября и соответственно мы тестировали на версии 2 хука. Перед релизом 15-го числа мы активировали уведомления в аккаунте, используемом живой системой, и нас молча подключили уже к версии 3 хука. Таким образом, мы были вынуждены перенести релиз, чтобы изменить и протестировать парсер уведомлений.
Обзор Sendgrid
Sendgrid – облачное программное решение для email-рассылок с собственными серверами. Софт позволяет получить все преимущества электронных маркетинговых кампаний для бизнеса без необходимости установки и настройки дополнительного оборудования. Приложение предоставляет возможность отправлять письма напрямую из интерфейса или интегрировать его функционал с помощью API.
Сервис предназначен в первую очередь для маркетологов и отделов продаж бизнеса различных сфер – от торговых сетей до стартапов, но пригодится любой компании, которой необходимо вести коммуникацию с пользователем через электронную почту, даже если суть этого взаимодействия – простое оповещение клиента о заказах и подтверждение email.
Sendgrid предлагает два типа email-рассылок: маркетинговые и транзакционные (технические письма с информацией о подключении, пароле, заказах). Система позволяет сегментировать базу аудитории для создания нескольких типов рассылок с учётом особенности каждой группы. Создавать письма можно на основе блочного редактора с опцией Drag & Drop или с помощью html, а готовые сообщения тестировать в 6 вариациях на небольших целевых группах. Приложение предлагает возможность настройки автоматических кампаний по заданным параметрам. Добавлять контакты можно вручную, импортом из .CSV или с помощью API. Встроенная аналитика в режиме реального времени демонстрирует результаты рассылок.
Ключевые особенности
- Маркетинговые и транзакционные рассылки
- Автоматические рассылки
- API
- Аналитика в реальном времени
0.00Отзывов 0 0% нравится Официальный сайтhttps://sendgrid.comОбратная связь[email protected]Реферальная программаОтсутствуетСтатусРаботает 11 лет (с 2009)
Sendgrid представляет собой облачный сервис на собственных серверах интернет-площадки для отправки транзакционных или триггерных писем клиентам. Принадлежит другой компании-владельцу сервиса для настройки автоматического обмена SMS и звонков Twilio. Проект Sendgrid начал свою работу в 2017 году, основное предназначение сервиса заключается в решении задач маркетинга через e-mail-сообщения: отправка рекламных и информационных уведомлений, электронных писем в ответ на определенные действия пользователя и проч. Реферальной системы у сервиса нет.
Как работает Сендгрид
Сервис Sendgrid предлагает автоматизировать маркетинговую рассылку электронной почты за счет следующих возможностей:
- с помощью данной площадки пользователь может настроить отправку рекламных и триггерных писем своим клиентам в определенные дни, часы и т.п. Послать письмо можно как из Sendgrid, так и используя протокол SMTP или API;
- созданные электронные письма можно тестировать на спам, делать проверку рассылок перед отправкой клиентам через интеграцию приложения Inbox Rendering;
- дизайн письма можно выбрать из предлагаемых готовых шаблонов, а можно использовать специальный блочный редактор на основе HTML или Drag&Drop;
- список клиентской базы можно сегментировать для отправки каждой группе различных типов электронных писем;
- контакты добавляются либо вручную, либо через импорт из файлов формата CSV или через API;
- аналитика открытых и прочитанных электронных писем в режиме реального времени.
Преимущества сервиса и его отличия от конкурентов
Главное преимущество Sendgrid в масштабности сервиса − с площадкой работают такие компании как Uber, airbnb, ebay и прочие, что повышает лояльность пользователей к сервису. Также среди особенностей можно выделить:
- Sendgrid предлагает как бесплатную версию с ограниченным количеством e-mail, предоставляемых на месяц, так и 3 варианта платных пакетов с расширенным функционалом. За количество писем сверх пакета также придется доплатить;
- Для масштабирования работы сервис предлагает купить дополнительные IP-адреса;
- Поскольку Sendgrid использует собственные сервера, нет необходимости привлекать специалистов и ресурсы для создания собственного сервиса отправки электронных рассылок;
- Платформа соответствует требованиям международного стандарта SOC2 (TypeII);
- Служба поддержки сервиса находится на связи с пользователями 24/7. Также можно обратиться к специалистам Sendgrid для оптимизации созданной программы рассылок, устранения возникающих неполадок и решения любых проблем при отправке писем.
Пользователи в своих отзывах отмечают гибкость настроек электронной рассылки в сервисе Sendgrid, наличие готовых шаблонов, эффективность и отзывчивость службы технической поддержки, возможность работать с бесплатной версией, включая хранение клиентской базы до 200 адресов на облаке, выделенные IP-адреса, а также удобную систему отслеживания открытых и прочитанных писем.
В качестве недостатков в комментариях можно встретить упоминание о высокой стоимости тарифов по сравнению с подобными сервисами, неэффективность системы отчетности. Интерфейс Sendgrid выполнен на английском языке, что также усложняет работу с площадкой для большинства пользователей.
What is sendgrid? … take a tour!
Используемые источники:
- https://habr.com/ru/post/194098/
- https://coba.tools/sendgrid
- https://gembla.net/sendgrid