Как стать автором
Обновить

Комментарии 21

Неплохо.

А как на сервисе происходит одобрение списка рассылки? Т.е. как вы защищаетесь от спамеров, которые с вашей системы рассылают спам?
Каждая рассылка проходит модерацию. Т.е. это ручная проверка + поиск адресов из списка в черных списках сервиса. Ну и с пользователем не помешает поговорить, откуда он эту базу взял и какие письма планируется рассылать.

В общем ответ на ваш вопрос — вручную. В следующих статьях распишу процесс подробнее.
Если почтовый клиент по этой причине разочаровывается в вашем пикселе, он просто вырежет его из письма и вы не узнаете о том, открыл ваш адресат письмо или нет.

Т.е. почтовый клиент не пойдет по ссылке после того, как сходил по ссылке и ему не понравился ответ?
В этом случае на пиксель вы получите только «безголовый» запрос от робота с почтового клиента, а реальный получатель картинку не увидит, т.к. она будет вырезана. Соответственно запрос от его браузера вы тоже не увидите. По крайней мере с этим я столкнулся в gmail.

Также в некоторых email-клиентах такие пиксели не вырезаются, но тем не менее запросы браузера к реальным src картинок блокируются прокси-сервисом почтового сервиса.
У вас в статье написано про почтовый клиент, а вы отвечаете про почтовый сервис.
А что такое «робот с почтового клиента»? Наверное, тоже с почтового сервиса?
Да, здесь имеется в виду почтовый сервис, спасибо за то, что поправили, внес правки в статью.
На яндекс.почте все изображения кешируются и по сути этот пиксель открывает один раз — кэширующий сервис яндекса, и в просторах интерента прочел, что подоные пиксели могут быть негативно восприняты почтовым сервером яндекса — что это значит я сам не понял, но навсякий случай сделал пиксель как тут (без хэша) и соответственно любой может пройтись скриптом и пометить все мои письма, как прочитанные. А вот для отслеживания ссылки и отписок, я добавил хэш валидности переданных параметров
$hash = md5($user_id . config::sys('mail.solt1') . $email . config::sys('mail.solt2') . $mail_id);
$link = SITEURL . '/r/' . base64url_encode($mail_id . '/' . $email . '/' . $user_id . '/' . $hash);

И я специально передаю все параметры, чтобы потом в скрипте можно быстро проверть их на валидность, без выполнения запросов к БД.
А вот рассылка писем — это вообще отдельная песня. Я сдела так, что в базу заносятся список SMTP серверов, и по ним происходит равномерная расылка писем.
Примерно так screenshotlink.ru/e2defa882bb7715eb0da43b7b4f7d621.png
И соответственно использовать бесплатные почтовые службы.

Вопрос, а поему бы не пойти "ленивым" путем по учету открытия пикселя — то есть считать это по логам nginx?

Что-то я не уверен, что парсинг логов nginx проще, чем обработка запроса к API :) Тем более, этот метод API можно потом переиспользовать.
Кроме того парсинг логов это плохо, потому что нужен realtime. Пользователь хочет знать когда прочитали письмо, а не когда парсер получил ивент из логов.

ну у парсера будет задержка 5-10 минут, а если грамотно класть логи, например в тот же elasticsearch, то все будет зависеть от скорости реиндекса. У меня около 30 секунд. На объемы от 100ГБ до пары-тройки Тб. И тут API будет дергать ES, именно когда клиент запрашивает. То есть почти рилтайм. А при открытии API нагрузка на бекэнд машины будет меньше.

Ну, это дело вкуса. Поэтому я и сказал, что это не будет проще — вы сами сказали что вам нужно и elasticsearch прикрутить чтобы он логи парсил, а потом еще и его API дергать со стороны сервиса.
Мы тоже так делали, пока не получилась особо удачная рассылка :)
Представьте, куча пользователей ломится по ссылке — а перейти не может, потому что бекенд и база заняты записью перехода пользователя.
Поэтому сейчас подобный лог пишется nginx`ом, а дальше по крону разгребается хоть раз в 5 минут.

> Пользователь хочет знать когда прочитали письмо, а не когда парсер получил ивент из логов.
Уточните у пользователя, что ему важнее — узнать ровно в тот же момент, что письмо прочитано и пользователь перешел на статью, или чтобы все желающие пользователи прочитали статью. :)
В первом случае он моментально узнает о всех, кто пробился на сайт, во втором о всех, но с задержкой в несколько минут. Я думаю, все выберут второй вариант.
Тогда логичнее унести трекинг в асинхронный таск :) Класть в какой-нибудь rabbitmq сообщение, а потом уже в рамках асинхронной задачи писать ивент в базу. Спасибо за хороший пример, подумаю по поводу оптимизации.

Ну вот коллега el777 верно говорит. Я рассматриваю тут ситуацию как системщик, а не разработчик. стоимость связки nginx-elastic-api будет ощутимо дешевле, чем любые варианты с celery/rabbit/DB. Собственно жто вопрос разделяемых ресурсов. Когда писем не очень много — это не важно, когда начинаешь масштабироваться — то вопрсо встает совсем под другим углом.

Тупая последовательная запись в лог файл всегда быстрее и надежнее.
В любом случае — совсем realtime не выйдет никогда. Либо вам нужно будет очень крутое и дорогое решение. Обновляйте лог раз в минуту — и будет счастье.
Это же email даже не мессенджер — его когда прочитают, тогда и прочитают. Вы можете отправить сейчас и прочтут через пару часов. И кому тут важна задержка в 5 минут?
ссылку на пиксель я делаю уникальную и с подписью
чтобы злые люди не могли досить по ней или генерировать их
Спасибо за статью. Есть ли в планах написать модуль сбора базы адресов? Реализация обязательной функции double opt-in? Проверка подтверждения рассылки перед отправкой? Функция проверки черноты домена рассылки по СПАМ базам? (Не обязательно, но желательно)
Что вы подразумеваете под «модулем сбора базы адресов»?
Каждый пользователь моего сервиса может сгенерировать форму подписки для определенного списка подписчиков и встроить на сайт. Процедура подписки через эту форму включает double-opt-in авторизацию. Соответственно, человек подписавшийся через эту форму сразу попадает в определенный список подписчиков.

Что означает «Проверка подтверждения рассылки перед отправкой»?

Репутацию доменов я проверяю через mx-toolbox, пока вручную, попозже напишу робота.
Да я этот процесс сбора и имел в виду =)

Проверка подтверждение — это отсутствие возможности отправки по базе не прошедшей процесс double opt-in. Если домен попадет в СПАМ фильтр, залогированный факт того, что получатель сам согласился на рассылку — один из немногих «рычагов» выведение домена из-под фильтра. Обычно его требуют при разборках с владельцами почтового сервиса.
Хотелось бы узнать, как боретесь с тем фактом, что значительная часть получателей отключает картинки и соответственно прочтение письма не фиксируется. И наоборот, когда письмо показывается в предпросмотре и наш пиксель сигнализирует прочтение, хотя на самом деле письмо отправляется в корзину.
С этим никак нельзя бороться. Но я добавляю событие об открытии письма каждый раз дополнительно при переходе по ссылке в письме, если оно не было зафиксировано ранее.
Плюс клиент может разместить в теле письма ссылку на его веб-версию, и тогда получатель сможет открыть его на сайте, там все картинки будут на месте.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории