- PVSM.RU - https://www.pvsm.ru -
У разработчика, который впервые столкнулся с генерированием электронных писем, практически нет шансов написать приложение, которое будет делать это корректно. Около 40 % писем, генерируемых корпоративными приложениями, имеют те или иные нарушения стандартов, и, как следствие, проблемы с доставкой и отображением. На это есть причины: электронная почта технически гораздо сложнее, чем веб, работа почты регулируется несколькими сотнями стандартов и несчетным количеством общепринятых (и не очень) практик, а почтовые клиенты отличаются разнообразием и непредсказуемостью. Тестирование может заметно улучшить ситуацию, но материалов, посвященных тестированию почты, практически нет.
Почта Mail.Ru регулярно взаимодействует со своими пользователями посредством электронных писем. В нашем проекте все компоненты, отвечающие за генерирование писем, и даже единичные рассылки проходят обязательное тестирование. В этой статье мы поделимся своим опытом (и набитыми шишками).
Приложение может генерировать различные виды писем. Их можно классифицировать по нескольким категориям. По способу выбора получателей: триггерные — выборочные — групповые. По назначению: транзакционные — маркетинговые — служебные. К разным типам писем можно предъявлять разные требования и применять разные сценарии тестирования.
Триггерные письма генерируются в ответ на какие-либо события, например, действия пользователя или изменения статуса каких-либо системных объектов. Они генерируются приложением, а потому наиболее интересны в плане тестирования. Триггерные письма могут быть как транзакционными, так и маркетинговыми.
Выборочные письма отправляются в динамическую выборку пользователей, соответствующих каким-либо критериям.
Групповые письма отправляются известной группе получателей, например, всем пользователям или партнерам. Выборочные и групповые письма чаще всего являются маркетинговыми, отправка таких писем инициируется вручную или по расписанию.
Транзакционные письма генерируются в процессе совершения пользователем какого-либо действия. К таким письмам относятся, например, счета, билеты или уведомления о статусе доставки, письма с кодом восстановления доступа и т.д. Транзакционные письма всегда являются триггерными. Для них важна максимальная совместимость, значит, они должны быть максимально просты, а тестировать их необходимо на большом количестве клиентов.
Маркетинговые письма побуждают пользователя совершить какие-либо действия, например, это может быть предложение индивидуальной скидки исходя из предыдущих покупок. В этих письмах могут использоваться транзакционные данные, они могут быть как триггерными, так и массовыми — периодическими или разовыми. Для данных писем важнее эффективность, обычно она определяется результатами сплит-теста. Некоторыми аспектами совместимости можно пожертвовать ради эффективности.
Групповые маркетинговые письма, например, сообщения о сезонных предложениях, акциях и распродажах, часто рассылаются «вручную» и не являются частью вашего приложения, но к ним также можно (и нужно) применять общие принципы тестирования.
Кроме того, могут быть служебные письма, генерируемые для сотрудников, для автоматических или автоматизированных систем CRM, журналирования, аудита или DWH. Такие письма являются триггерными, а это значит, что они также являются частью приложения и должны проходить тестирование.
Все эти роли не обязательно выполняет отдельно выделенный сотрудник: роль маркетолога может выполнять кто-то из продуктовых менеджеров, а роль deliverability-специалиста — например, сотрудник поддержки или сетевой инженер. А в стартапах с высокой долей вероятности всем этим придется заниматься одному человеку, и им может оказаться специалист по качеству.
Структура почты похожа на огромный айсберг, и в ней есть два уровня. Существует более сотни различных стандартов, регулирующих почту, но практически все они относятся к одному из этих двух уровней:
Подводная часть айсберга — это сетевая служба, базовым протоколом которой является прикладной протокол SMTP, определяемый RFC 5321. Он отвечает за доставку писем. Для доставки письма формируется так называемый SMTP-конверт, в который включаются адреса отправителя и получателя уровня SMTP. Также за доставку письма отвечают другие сетевые службы, такие как DNS. Основным компонентом сетевой инфраструктуры является Агент Передачи Сообщений (Mail Transfer Agent, или чаще используется аббревиатура MTA). MTA отвечает за работу с очередью доставки сообщений и сам процесс доставки на серверы получателей. Примеры MTA — Postfix, Sendmail, exim, служба Microsoft SMTP.
Эту подводную часть айсберга, к которой относятся MTA, параметры DNS и прочие сетевые параметры, мы будем называть почтовой инфраструктурой, или инфраструктурой доставки сообщений.
Надводная часть айсберга — это само письмо. Базовая структура письма определяется стандартом RFC 5322. Письмо состоит из служебных заголовков и одной или нескольких частей с данными. В данных может быть текст письма в формате plain text и/или HTML, инлайновые изображения или вложения практически любого типа.
У почтовой инфраструктуры, как правило, есть один или несколько интерфейсов, с помощью которых отправляется письмо (попадает в очередь доставки MTA). Например, сервис SMTP Submission, функция mail()
в PHP, передача данных во внешнее приложение mail или sendmail, API внутренних или внешних сервисов (к примеру, GetResponse, SendPulse или Amazon SES). Мы будем считать эти интерфейсы частью инфраструктуры. Достаточно часто бывает ситуация, когда приложение A подготавливает данные для письма и список получателей, а затем передает их в приложение B через его API (для маркетинговых массовых рассылок это может производиться вручную через пользовательский интерфейс — UI), а уже приложение B генерирует почтовое сообщение в формате RFC 5322 и каким-либо образом ставит его в очередь доставки MTA. С точки зрения приложения A (и при его тестировании), приложение B будет частью почтовой инфраструктуры. API или UI приложения B будет для приложения A интерфейсом почтовой инфраструктуры. Хотя с точки зрения приложения B ситуация будет иной, и почтовой инфраструктурой для него будут более низкоуровневые сетевые приложения или протоколы.
При тестировании каждого приложения важно выделить все используемые им почтовые инфраструктуры (их может быть несколько), и для каждой инфраструктуры выделить используемые интерфейсы (их тоже может быть несколько для каждой инфраструктуры). Для каждого интерфейса как можно точнее определяется состав и формат передаваемых в него данных, например: текст письма в TEXT/HTML, текст письма в TEXT/PLAIN, тема письма, имя получателя, адрес получателя, имя отправителя, адрес отправителя письма (RFC5321.From), адрес отправителя SMTP-конвера (RFC5322.mailfrom). Далее разрабатывается набор требований для каждого параметра (представления, кодировки, граничные значения и т.д.), определяются методы контроля каждого из параметров (каким способом можно сравнить фактический результат с ожидаемым).
За генерирование письма и данных в нем, как правило, отвечает тот самый продукт, который мы тестируем. Обычно это серверное (но иногда клиентское) приложение. Оно определяет структуру письма, часть служебных заголовков, форматы инкапсуляции данных, представления строк и кодировки текста. Простым примером такого приложения может послужить скрипт, который формирует письмо и вызывает функцию mail()
.
Основные элементы приложения, которые необходимо контролировать:
Хотим мы этого или нет, но айсберг надо тестировать весь. Можно выделить несколько основных компонентов, требующих тестирования:
Упор в тестировании следует делать на: доставляемость письма; корректность DNS-записей, включая PTR/FCrDNS, MX- и A-записи; параметры SMTP-протокола (HELO, использование TLS); авторизацию письма (SPF/DKIM/DMARC); адреса SMTP-конверта (если они не управляются приложением); корректность обработки входных параметров интерфейса инфраструктуры; отслеживание, учет и обработку не доставленных писем.
Надо тестировать инфраструктуру при начальном внедрении и каждый раз, когда вносятся изменения в саму инфраструктуру (меняется конфигурация MTA, DNS или сети) или интерфейс отправки письма; используется новый домен, сеть или API; существенно меняются характеристики отправляемых писем, такие как их язык, размер или количество. По опыту, инфраструктура имеет склонность меняться без объявления войны, поэтому базовые тесты следует проводить периодически, даже если нет информации о каких-либо изменениях.
К составлению плана и чек-листов тестирования инфраструктуры можно и нужно привлекать сетевого инженера и deliverability-специалиста.
Следует контролировать адреса SMTP-конверта (если они управляются приложением, т.е. передаются в интерфейс — envelope-from, envelope-to), значения служебных заголовков письма (Date, Message-ID, List-Unsubscribe, Auto-Submitted и т.п.), авторизацию письма (DKIM/DMARC), MIME-кодировки (base64, quoted-printable), общую правильность формата письма, например отсутствие не-ASCII символов в заголовках, состав подставляемых данных, корректность срабатывания триггеров, механизмы отписки, механизмы трекинга письма и сбора статистики (postmaster-заголовки, например, Feedback-ID или X-Mailru-Msgtype, а также трекинговые пиксели).
Тестировать приложение нужно при его разработке, при изменении всех его связанных компонентов, отвечающих за генерирование и хранение данных, при существенных изменениях шаблонов писем, при изменении используемой инфраструктуры или интерфейса к ней, а также в рамках общих регрессов.
Проверяется структура письма (Content-Type, Content-Disposition, вложенность Multipart-частей письма, кодировки текста, строковые параметры), значение целевых и отображаемых заголовков (From, To, Reply-to, Subject), отображение письма в списке писем и при чтении в различных интерфейсах, микроформаты (например, что событие календаря распознается как событие календаря, или авиабилет как авиабилет), брендирование.
Шаблоны писем следует тестировать каждый раз при внесении хотя бы малейших изменений, а также отдельно, например, в ситуации, когда письма попадают в приложение до того, как готова серверная часть.
К составлению чек-листа по тестированию шаблона письма рекомендуется привлечь email-маркетолога и deliverability-специалиста.
IP-адрес, выбранный для почтового сервера, должен быть максимально похож на IP-адрес почтового сервера. Рекомендуется проверить его с помощью утилиты whois. В частности, адрес отправителя не должен принадлежать сети, которая может восприниматься как динамическая; у выбранной сети должны быть действующие контакты, на которые можно отправлять жалобы; сеть обязательно должна быть используемой (иметь статус ASSIGNED в RIPE). IP-адрес должен иметь корректно настроенную PTR-запись. Ее можно настроить самостоятельно через панель управления
У каждого домена, используемого в адресах конверта или заголовках письма, должна быть валидная MX-запись, указывающая на A-запись хоста, который, как минимум, может обрабатывать сообщения о невозможности доставки. Для MX недопустимо напрямую ссылаться на IP-адрес.
Контролируйте прохождение SPF, DKIM, DMARC. SPF позволяет владельцу домена указать в TXT-записи список серверов, имеющих право отправлять email-сообщения с обратными адресами в этом домене. Настраивается она для адреса, используемого в envelope-from (SMTP-конверте), в разделе управления DNS-зонами домена. DKIM обеспечивает проверку авторства сообщения или принадлежности его отправителя определенному домену с помощью технологий цифровой подписи, которая добавляется в само письмо (в его заголовок DKIM-Signature). Обычно DKIM-подпись настраивается на уровне MTA (инфраструктуры). DMARC задает политику проверки приходящей почты в определенном домене и действия над письмами, не проходящими аутентификацию SPF или DKIM. При попытке нарушения этой политики приходит структурированный отчет со сведениями о такой попытке. DMARC, также как и SPF, публикуется в виде TXT-записи в доменной зоне.
Проверьте доставляемость писем до основных почтовых служб — для России Mail.Ru, Yandex, GMail, Microsoft (Hotmail / Outlook.com / Office365), Rambler, nic.ru. В пришедших письмах нужно проконтролировать правильность HELO; наличие и прохождение проверок PTR/FCrDNS, SPF, DKIM и DMARC; валидность заголовков и данных в них, в частности, синхронность часов в датах и правильность временных зон.
На формирование некоторых параметров, например, авторизацию, доставляемость и попадание в спам интегрально влияют все компоненты, однако для их контроля обычно есть отдельные оперативные инструменты — DMARC и FBL-отчеты, API сервисов postmaster, инструменты трекинга писем, статистика доставки. Тестирование должно учитывать уровень внедрения инструментария оперативного мониторинга в компании — например, при отсутствии оперативного контроля DMARC-отчетов следует регулярно тестировать авторизацию писем, при отсутствии оперативного контроля доставляемости — регулярно проверять, как и куда попадают письма, даже если никакой разработки, связанной с отправкой писем, не ведется.
Для проверки инфраструктуры можно использовать специализированные сервисы, например, mail-tester.com, mxtoolbox.com.
Проверить прохождение SPF, DKIM, DMARC обычно можно по заголовку Authentication-Results на сервере получателя.
Проверьте валидность SPF-записи на предмет синтаксиса, лимита на DNS-запросы (например, с помощью mxtoolbox.com). При формировании SPF должны быть учтены все источники рассылок (не забудьте CRM-системы, все используемые инфраструктуры доставки, в том числе те, через которые проводятся разовые маркетинговые кампании). Рекомендуется задавать разрешенные серверы для домена через список сетей (‘ip4’ / ‘ip6’). SPF проверяется для адреса отправителя из SMTP-конверта. Проверьте, что домен SMTP-конверта (envelope-from) соответствует домену из заголовка From. Типичные ошибки, связанные с SPF, перечислены в этой статье [21].
Проверьте DNS-запись DKIM, валидность и состав DKIM-подписи (DKIM-Signature). Проверьте, что используется DKIM-ключ размером не менее 1024 бит. Рекомендуемый режим хэширования DKIM-подписи: relaxed/relaxed. Убедитесь, что подписаны все важные заголовки (From, To, Subject, Date, Message-ID, MIME-Version, Content-Type), не подписаны трекинговые заголовки (Received, Delivered-To, Return-Path), и DKIM проходит валидацию на основных почтовых службах. Настройте на одной из почтовых служб переадресацию на другую, DKIM не должен «биться» на переадресованных письмах. Убедитесь, что домен DKIM-подписи соответствует домену отправителя из заголовка From.
Проверьте прохождение DMARC на основных почтовых службах. Проверьте получение DMARC-отчетов, идентифицируйте и устраните проблемы с прохождением SPF и DKIM для всех IP-адресов вашей инфраструктуры.
Проверьте, что письма доставляются на внешние серверы с использованием шифрования (TLS). Проверить наличие TLS иногда можно по заголовку Received на сервере получателя: например, указание протокола ESMTPS или наличие параметров вида (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); указывает на наличие TLS.
Адреса конверта
Проверку генерирующего приложения начнем с адресов в SMTP-конверте.
Адреса конверта — это адреса уровня почтовой инфраструктуры. Они не видны пользователю, но важны для доставки, потому что в какой ящик попадёт письмо, определяется именно адресом конверта.
Адрес получателя в конверте (envelope-to, он же RCPT TO:) — это адрес, на который будет реально доставлено письмо.
Адрес отправителя в SMTP-конверте (обычно называется envelope-from, smtp.mailfrom или Return-Path) — на этот адрес будут доставляться сообщения о невозможности доставить письмо и автоответы. Пользователю этот адрес невидим. Также этот адрес используется для авторизации SPF. Проверяем, что:
Адреса заголовков письма
Эти адреса либо непосредственно видны пользователю, либо используются при ответе на письмо.
Адрес отправителя (заголовок From:) — это адрес и имя отправителя, отображаемые в списке писем и при чтении письма. Проверяем, что:
Адрес Reply-To — на этот адрес будут отправляться «ручные» ответы при ответе пользователя на письмо. Он не является обязательным: при его отсутствии для ответа используется адрес из From. Проверяем, что Reply-To:
Адрес To:
Реальная кодировка текста должна совпадать с указанной в заголовке. Желательно использовать одну кодировку во всех заголовках и частях письма. Рекомендуется использовать UTF-8 как широко поддерживаемую. Кодировка указывается в заголовках Content-Type и в теге <MЕTA> HTML-части.
Заголовки From:, Message-ID: и Date: должны формироваться непосредственно в скрипте отправки письма (а по стандартам — вместе с текстом письма) и обязательно в правильном формате. В случае их отсутствия или некорректности формирования, эти заголовки может добавить один из транзитных серверов, что приводит к нарушению целостности DKIM-сигнатуры.
8-битные символы в заголовках, включая тему письма (Subject) и имена вложенных файлов (Content-Type и Content-Disposition), должны отсутствовать; все символы, отличные от ASCII, в том числе кириллица, должны быть закодированы в quoted-printable или base64.
Для HTML-части письма желательно формировать альтернативную — текстовую (plain) часть. Также необходимо проверять соответствие и читаемость plain text-части письма (при её наличии) и общую структуру письма.
По стандарту RFC 5322, длина строки в письме не должна превышать 998 8-битных символов. Следует учитывать что в UTF-8 символ может занимать несколько октетов. Терминатором строк в электронной почте выступает пара CRLF (<сr> ascii 13, lf> ascii 10), занимающая 2 октета. Нужно проверять корректность терминатора строк, так как письма часто посылают с помощью Unix-скрипта, а в Unix терминатором строк служит один символ lf — для электронной почты это ошибка. Также следует проверять, не разбивают ли терминаторы строк символы в кодировке UTF-8: нельзя допускать наличие терминатора строк между двумя октетами одного символа, например, кириллического. Во избежание таких ситуаций необходимо разбивать текст до формирования письма, либо кодировать текст в base64.
Необходимо проверить правильность разметки аттачей и инлайнов — то есть корректность формирования заголовков «Content-Disposition: inline», если это картинка, отображаемая внутри письма, либо «Content-Disposition: attachment», если файл предназначен для скачивания.
Структура письма, по возможности, должна быть максимально простой: в частности, не должно встречаться больше одной multipart-части каждого типа (mixed, alternative, related), причем multipart/mixed используется только если письмо содержит вложенные файлы, multipart/related — при наличии инлайновых изображений, multipart/alternative — при наличии plain text- и HTML-частей. В общем виде структура письма, при отсутствии в нем аттачей и инлайн-картинок, должна выглядеть следующим образом:
multipart/alternative
— text/plain
— text/html
Порядок частей важен, text/plain должен идти ДО text/html или multipart/related. Это нужно для того, чтобы по умолчанию показывалась HTML-часть, и только если её отображение по каким-то причинам недоступно — отображалась plain-часть.
При наличии в письме инлайн-картинок его структура должна выглядеть следующим образом:
multipart/alternative
— text/plain
— multipart/related
—— text/html
—— image/… (инлайн-картинка)
—— image/… (инлайн-картинка)
Инлайн-картинки должны иметь Content-Disposition: inline и находиться строго внутри multipart/related-части.
В самом сложном случае, когда имеются и инлайновые изображения, и вложенные файлы, письмо имеет следующую структуру:
multipart/mixed
— multipart/alternative
—— text/plain
—— multipart/related
——— text/html
——— image/png
——— image/png
…
— application/octet-string (content-disposition: attachment)
— application/octet-string (content-disposition: attachment)
…
(multipart/related- и multipart/alternative-части должны быть закрыты до аттачей, аттачи относятся к внешней multipart/mixed-части)
Любые URI (в атрибутах src, href, стилях и т.п.) должны содержать протокол и имя хоста (https://example.com/somepath [22]). Типичными ошибками является использование относительных ссылок (/somepath) и отсутствие протокола (//example.com/somepath), что недопустимо для писем, т.к. в них протоколом по умолчанию может быть file://.
Почему верстать письма так сложно?
Почтовые клиенты так или иначе показывают пользовательский контент в рамках своего интерфейса. Потенциально это может приводить к различным проблемам безопасности — межсайтовому скриптингу (XSS, Crossite scripting), подмене интерфейса (interface spoofing), DOM clobbering, деанонимизации пользователя / утечке информации (например, IP-адреса пользователя или куки через внешние запросы) и т.д., поэтому любой почтовый сервис и почтовое приложение имеет ту или иную степень защиты от каждого класса атак. К сожалению, нет единого подхода к организации этой защиты. Она может быть организована через:
- изолированные ограниченные фреймы,
- фильтрацию тегов и/или атрибутов,
- ограничения на абсолютное позиционирование,
- запрет или ограничение на использование блочных стилей (что критично для адаптивной верстки),
- запрет на внешние элементы по умолчанию (т.е. загрузка внешних изображений требует разрешения пользователя) или использование прокси для доступа к ним,
- конвертацию HTML-писем в другой промежуточный формат (например Microsoft Exchange / Outlook используют RTF, из-за чего добиться адекватного отображения элементов в Outlook обычными методами может быть чрезвычайно сложно),
- запрет или ограничение на использование форм или их отдельных элементов.
Также в письмах используются специфические элементы, такие как инлайн-изображения и URI cid://, поддержка которых может быть ограничена. Например, Mozilla Thunderbird не поддерживает cid:// для фоновых изображений.
Даже корректно сформированное письмо может по-разному отображаться в разных интерфейсах из-за особенностей их реализации и фильтрации содержимого письма.
При наличии ошибок в формате письма поведение становится полностью непредсказуемым. Например, в почтовых клиентах может быть разное поведение при неправильных URI, по-разному обрабатывается некорректное форматирование заголовков, по-разному работает автоопределение кодировки, если она не указана или указана неверно. Поэтому письмо надо обязательно посмотреть в разных интерфейсах: корректное отображение письма в одном интерфейсе не говорит о том, что оно составлено правильно (на самом деле, даже корректное отображение письма во всех интерфейсах не гарантирует отсутствие проблем с отображением в будущем).
Необходимо обратить внимание на следующие моменты:
Маркетинговые исследования выходят за рамки этой статьи, но следует упомянуть несколько основных моментов, существенно влияющих на качество писем.
Рассылка имеет цель, поэтому она должна брать качеством, а не количеством (как это делают спамеры). Рассылка в обязательном порядке должна быть сегментирована. При проведении рекламной кампании нужно точно знать, кто попадает в сегментную выборку, зачем ему предлагаемый продукт и что хочется донести.
Для каждой рассылки необходимо посчитать CTR списка писем — это отношение количества прочитанных писем к общему количеству разосланных. В postmaster.mail.ru можно смотреть показатели по уникальным пользователям. Если замер идет через счетчик в письме (пиксель), то оценивается абсолютное количество открытий. CTR < 10% — это очень низкий показатель, такую рассылку нежелательно проводить. Следует стремиться к CTR > 30%. Для маркетинговых писем также большое значение имеют CTR переходов по ссылкам в письме и процент совершенных действий («продаж») по этим ссылкам. Обязательно нужно следить за жалобами (отмечанием письма как спам). Обычно для разовых рассылок хорошим показателем является десятая доля процента, для регулярных — сотая доля процента. Критические значения, после которых рассылка практически трактуется как спам, указаны здесь: https://help.mail.ru/developers/mailing_rules/technical [25].
Необходимо проводить сплит-тестирование различных вариантов рассылки для получения оптимальных показателей. Всего лишь изменение имени отправителя и темы письма может увеличить CTR в несколько раз и многократно снизить количество жалоб. Количество писем должно быть статистически значимо для оценки результатов (для больших проектов обычно это несколько тысяч). Рассылается финальный вариант письма (в несколько этапов для дополнительного замера показателей и «прогрева» — начиная примерно с 10 000 получателей, с увеличением примерно на порядок в сутки).
Главная мысль: электронные письма являются частью вашего приложения, возможно, одной из наиболее сложных и проблемных. В то же время зачастую это «слепое пятно» с точки зрения тестирования. Надеюсь, что мне удалось привлечь ваше внимание к этой проблеме.
Выражаю огромную благодарность за помощь в подготовке статьи Владимиру Дубровину z3apa3a [26] и Алене Лихачевой s4ever [27]. В статье также использовались материалы Эдуарда Тянтова EdT [28] и Александра Пуртова 4Alexander [29].
Автор: blondnika
Источник [30]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/testirovanie/288718
Ссылки в тексте:
[1] Какие бывают электронные письма: https://habr.com/company/mailru/blog/419591/#1
[2] Кто участвует в процессе тестирования и контроля: https://habr.com/company/mailru/blog/419591/#2
[3] Почтовое сообщение и почтовый транспорт: https://habr.com/company/mailru/blog/419591/#3
[4] Интерфейс почтовой инфраструктуры и границы тестируемого приложения: https://habr.com/company/mailru/blog/419591/#4
[5] Определение тестируемых параметров: https://habr.com/company/mailru/blog/419591/#5
[6] Типичная структура генерирующего приложения: https://habr.com/company/mailru/blog/419591/#6
[7] Что и когда тестировать: https://habr.com/company/mailru/blog/419591/#7
[8] Инфраструктура доставки: https://habr.com/company/mailru/blog/419591/#8
[9] Генерирующее приложение: https://habr.com/company/mailru/blog/419591/#9
[10] Структурный и вёрсточный шаблоны письма: https://habr.com/company/mailru/blog/419591/#10
[11] Базовые требования при проверке инфраструктуры: https://habr.com/company/mailru/blog/419591/#11
[12] Требования к авторизации: https://habr.com/company/mailru/blog/419591/#12
[13] Проверка генерирующего приложения: https://habr.com/company/mailru/blog/419591/#13
[14] Требования к почтовым адресам: https://habr.com/company/mailru/blog/419591/#14
[15] Требования к заголовкам писем: https://habr.com/company/mailru/blog/419591/#15
[16] Требования к структуре письма: https://habr.com/company/mailru/blog/419591/#16
[17] Требования к URI: https://habr.com/company/mailru/blog/419591/#17
[18] Требования к вёрстке письма: https://habr.com/company/mailru/blog/419591/#18
[19] Проведение сплит-тестов: https://habr.com/company/mailru/blog/419591/#19
[20] хостингом: https://www.reg.ru/?rlink=reflink-717
[21] в этой статье: https://habr.com/company/mailru/blog/338700/
[22] https://example.com/somepath: https://example.com/somepath
[23] example.com: http://example.com
[24] иначе они могут быть использованы для спама: https://habr.com/company/mailru/blog/354310/
[25] https://help.mail.ru/developers/mailing_rules/technical: https://help.mail.ru/developers/mailing_rules/technical
[26] z3apa3a: https://habr.com/users/z3apa3a/
[27] s4ever: https://habr.com/users/s4ever/
[28] EdT: https://habr.com/users/edt/
[29] 4Alexander: https://habr.com/users/4alexander/
[30] Источник: https://habr.com/post/419591/?utm_source=habrahabr&utm_medium=rss&utm_campaign=419591
Нажмите здесь для печати.