Все знают, как сделать рассылку. Многие умеют создавать триггерные цепочки. Кто-то умеет настроить рассылку из RSS-ленты блога. Нам пришлось закопаться глубже, потому что мы хотели, чтобы наша рассылка была не простой, а красивой и детальной. Ведь она делается из интересного блога, на который мы тоже потратили немало сил.
За каждую детальку в простом на вид письме пришлось побороться с этой симпатичной обезьянкой. Все получилось. Рассказываем — как.
MailСhimp — англоязычный и иногда нелогичный в интерфейсе сервис. Но он столько всего умеет и настолько популярен, что для него написали дотошные инструкции о доставке контента до читателей всеми возможными способами.
Мы для рассылок блога компании PromoPult также выбрали MailСhimp. Одна из фич MailСhimp — автокампании. Можно запланировать регулярные рассылки, отдельные письма, настроить приветственные письма и много всего.
Эта история — про настройку авторассылки постов из блога. Дайджест свежих материалов в почту подписчика один раз в неделю.
Как мы решили задачу
Создание RSS-ленты
Что внутри ленты
Делаем финт ушами
Вывод контента из ленты в шаблоне письма
Отдельной строкой:
ИТОГО: Если у вас все стандартно и несложно, юзайте стандартные средства MailChimp и не парьтесь
Ссылки в тему RSS-лент в MailChimp:
Стандартный вариант для авторассылки и почему он нам не подошел
У самого MailСhimp есть прекрасная документация по любым функциям, и конкретно об этом тоже есть: Share Your Blog Posts with Mailchimp. Переводы на русский язык тоже найдутся, разной степени адекватности.
Кратко, что нужно, чтобы сделать авторассылку:
- Создать отдельную RSS-ленту для MailChimp (или даже не создавать, а использовать стандартную ленту).
- Создать кампанию, указать источник, настроить условия отправки.
- Создать и выбрать шаблон.
- Готово. Вы — восхитительны!
Что не устроило нас — какие-то собственные вещи добавить просто невозможно.
Есть базовые данные из RSS-ленты, которые прекрасно понимает MailСhimp:
- Базовая информация о ленте (название, ссылка, описание, дата формирования или обновления ленты) —
*|RSSFEED|*
. - Ссылка на отдельный пост — тег
*|RSSFEED:URL|*
, смотрит на<link>
внутри<item>
(здесь и далее). - Заголовок отдельного поста — тег
*|RSSITEM:TITLE|*
, смотрит на<title>
. - Дата публикации отдельного поста — тег
*|RSSITEM:DATE|*
, смотрите на<pubDate>
. - Текстовый анонс отдельного поста — тег
*|RSSITEM:CONTENT|*
, смотрите на<description>
, если этого тега внутри<item>
нет — MailChimp смотрит на<content:encoded>
. Внутри можно использовать HTML-теги.
- Полное содержание отдельного поста — тег
*|RSSITEM:CONTENT_FULL|*
, смотрит на<content:encoded>
. - Изображение поста, часто — превью (миниатюра — в терминах WordPress) — тег
*|RSSITEM:IMAGE|*
, смотрит на<media:content>
и не забудьте про дополнительные теги и атрибуты для медиа-вложений: возрастные маркировки, информация о самом файле и проч.
А у нас есть дополнительные штуки у отдельного поста:
- Счётчик комментариев;
- Счётчик просмотров;
- Счётчик лайков;
- Дату публикации поста хочется показывать в человеческом формате: во-первых, на русском языке, со склонениями и если пост опубликован в текущем году — не показывать год публикации (сейчас в блоге так всё и работает, в письмах хочется такого же внимания к деталям);
- Отдельная кастомная обложка поста, до которой нужно как-то достучаться;
- Категория с ссылкой на все посты из категории.
И в обычную RSS-ленту такое не засунуть — нет соответствующих тегов. Кастомные же теги MailСhimp не понимает и не стоит его винить в этом. Нужно искать решение, которое устроит всех и не сломается.
Данные, которые нужно показать в отдельной карточке поста в шаблоне дайджеста, привязаны к внешнему виду. Дизайнер нарисовал, верстальщик много страдал и сверстал письмо.
Карточка поста блога PromoPult в еженедельном дайджесте
Как мы решили задачу
Создание RSS-ленты
Первым делом важно создать отдельную RSS-ленту для MailChimp. В блоге PromoPult уже есть несколько подобных лент: для Яндекс.Дзена и для Турбо-страниц.
Создать новую ленту можно через add_feed(). Вот такой код в файле функций темы:
functions.php:
/* start Добавляем ленту для рассылки постов через MailChimp */
add_action( 'init', 'customRSSforMC' );
function customRSSforMC() {
add_feed( 'mchimp', 'customRSSforMCFunc' );
}
function customRSSforMCFunc() {
get_template_part( 'rss', 'mchimp' );
}
/* end Добавляем ленту для рассылки постов через MailChimp */
В строке №7 get_template_part( 'rss', 'mchimp' );
— указывает на то, что шаблон для ленты лежит в корне папки темы и называется rss-zen.php
.
После создания файла и добавления функции нужно зайти в админку WordPress, настройки ЧПУ: «Консоль > Настройки > Постоянные ссылки» и нажать кнопку «Сохранить изменения», чтобы WordPress обновил настройки урлов и по заданному /feed/URL
в первом параметре строки №4 открывалась новая RSS-лента.
Сделать это нужно один раз при создании ленты.
Смотрите наш пример: https://blog.promopult.ru/feed/mchimp
Что внутри ленты
Внутри самой ленты — обычный цикл постов WordPress: query_posts(). Это позволяет выбирать и фильтровать посты очень гибко: как если бы вы настраивали отдельные категории, страницы с выборками, архивами и всем, что нужно для подборок материалов в WordPress.
Но перед тем как прийти к идеальному решению задачи — было несколько попыток запихнуть важные для письма данные внутрь стандартных конструкций RSS-лент и использовать их в MailChimp.
Например, был такой вариант для счётчика комментов:
<item>
[...]
<title><?php the_title_rss(); ?></title>
<link><?php the_permalink_rss(); ?>?utm_source=newsletter</link>
// если комментариев больше или равно 1, то показать количество
<?php if (get_comments_number() >= 1) { ?>
<commentsCounter><?php comments_number('0', '1', '%'); ?></commentsCounter>
<?php } ?>
[...]
</item>
Такой вариант, конечно, срабатывает в плане данных: всё, что нужно, получается и корректно выводится. Но MailChimp не понимает тега <commentsCounter>
, как и любых других нестандартных тегов.
Так же, например, с датами. У MailChimp есть свой тег: *|RSSITEM:DATE:d/m/y|*
, и ему можно передавать опции форматирования даты. Но, к сожалению, в письме это выглядит совсем не человечно. Про перевод даты вообще можно не говорить.
Ещё проблема — картинки. Вы страдали и сверстали своё прекрасное письмо. Вам нужно вывести картинку. В шаблоне письма вы делаете так:
<img
src="*|RSSITEM:IMAGE|*"
alt="*|RSSITEM:TITLE|*"
/>
Но парсер MailChimp может приходить и ломать вёрстку, добавляя свои свойства, классы и другой код в тег картинки <img ... />
.
Совет. Если вы используете стандартную ленту и теги, то не забудьте включить галочку «Изменение размера изображений RSS-канала в соответствии с шаблоном» в настройках кампании:
Промежуточные выводы: что-то идёт не так, стандартных вариантов не хватает, письмо страшное и не человечное. Нестандартных данные не вывести.
Делаем финт ушами: все размечаем сами
Если стандартного ничего нельзя сделать в RSS ленте, чтобы парсер сервиса MailChimp это правильно понял, то можно передать готовый размеченный и свёрстанный кусок кода для карточки поста просто в теге
<description>
отдельного элемента <item>
в ленте.Есть только отдельный минус: все стили для письма должны быть заинлайнены, то есть всё, что описано через .class
превращается в стили в атрибуте style=”...”
.
<!-- до инлайна так: -->
<style>
.post-meta {
Margin: 8px 0;
}
.post-category {
border-radius: 3px;
border: #adb2b2 1px solid;
color: #adb2b2 !important;
border-bottom: #adb2b2 1px solid !important;
padding: 2px 6px;
font-size: 13px;
line-height: 13px;
Margin: 0 8px 0 0;
}
</style>
<div class="post-meta">
<a
href="https://blog.promopult.ru/category/seo"
target="_blank"
class="post-category">SEO: поиск и внутренняя оптимизация</a>
</div>
<!-- после инлайна так: -->
<div style="Margin: 8px 0;">
<a
href="https://blog.promopult.ru/category/seo?utm_source=newsletter"
target="_blank"
style="Margin: 0 8px 0 0; border: #adb2b2 1px solid; border-bottom: #adb2b2 1px solid !important; border-radius: 3px; color: #adb2b2 !important; font-size: 13px; line-height: 13px; padding: 2px 6px; text-decoration: none;">SEO: поиск и внутренняя оптимизация</a>
</div>
Для вёрстки писем блога использовался «Печкин» — gulp-сборщик шаблонов писем, который собирает письмо из блоков и сам инлайнит стили. Также можно пользоваться онлайн-инлайнерами стилей, например, Premailer.io.
В шаблоне RSS-ленты доступен цикл постов. Поэтому можно вытащить и сформировать всё как хочется и нужно.
Первый подход к решению был частичным: оставить стандартными теги заголовка, урла, краткого описания, а вот мета-информацию поста: просмотры, лайки, комменты, категорию и дату публикации формировать отдельным куском HTML-кода и вставлять в нужное место разметки.
От этого варианта также пришлось отказаться из-за сломавшейся вёрстки и отсутствия контроля над разметкой и стилями картинки. И позже перенести всю разметку блока карточки поста в тег <description>
.
<?php while (have_posts()): the_post(); ?>
<item>
<description><![CDATA[
<div class="post-card">
<?php if ( get_post_meta($post->ID, 'imga', true) ) { ?>
<div class="post-card__img">
<a href="<?php the_permalink(); ?>?utm_source=newsletter" target="_blank">
<img
src="<?php echo $postImg[0]; ?>"
alt="<?php the_title(); ?>">
</a>
</div>
<?php } ?>
<div class="post-card__info">
<h2>
<a href="<?php the_permalink(); ?>?utm_source=newsletter"><?php the_title(); ?></a>
</h2>
<p>
<a href="<?php the_permalink(); ?>?utm_source=newsletter">
<?php if ( !empty( get_post_meta($post->ID, 'intro', true) ) ) {
echo get_post_meta($post->ID, 'intro', true);
} else {
$content = get_the_content(); $trimmed_content = wp_trim_words( $content, 12, '...' ); echo $trimmed_content;
} ?>
</a>
</p>
<div>
<p>
<?php if (get_the_date('Y') == date('Y')) { the_time('j F'); } else { the_time('j F Y'); } ?>,
<?php
$categories = get_the_category();
if( $categories[0] ) {
echo '<a href="' . get_category_link($categories[0]->term_id ) . '?utm_source=newsletter">'. $categories[0]->name . '</a>';
}
?>
<?php if(function_exists('the_views')) { ?>
<span>
<span>
<img
src="icon-views.png"
alt="Просмотры поста">
</span>
<span class="item__text"><?php the_views(); ?></span>
</span>
<?php } ?>
<?php if (function_exists('get_simple_likes_counter')) { if (get_simple_likes_counter( get_the_ID() ) >= 1) { ?>
<span>
<span class="item__icon">
<img
src="icon-like.png"
alt="Лайки поста">
</span>
<span><?php echo get_simple_likes_counter( get_the_ID() ); ?></span>
</span>
<?php } } ?>
<?php if (get_comments_number() >= 1) { ?>
<span>
<span>
<img
src="icon-comments.png"
alt="Комментарии поста">
</span>
<span><?php comments_number('0', '1', '%'); ?></span>
</span>
<?php } ?>
</p>
</div>
</div>
</div>
]]></description>
</item>
<?php endwhile; wp_reset_query(); ?>
В примере кода нет инлайн-стилей, чтобы всё выглядело аккуратно. Боевой же вариант ленты отдаётся с полной разметкой и стилями.
Все адреса для графики в примере также упрощены. В боевом варианте все нужные картинки, иконки, фотографии и всё, что важно для письма, — залиты в админку MailChimp через Content Studio, а уже в шаблонах использованы адреса полного вида для src-
атрибутов тегов <img />
.
В строках №№20—24 мы выбираем вариант текста-анонса (интро) статьи. Если заполнен кастомный в свойствах поста в произвольных полях записи — get_post_meta(), то показываем его, если его нет, то показываем то, что лежит в get_the_content().
Также выбираем картинку-обложку поста. У нас есть две картинки, связанные со статьей: небольшое превью (отображается в карточке поста на главной странице) и обложка из шапки поста. Берем большую обложку.
Пример шапки с фоном в посте блога PromoPult
Поскольку всё это происходит в стандартном цикле WordPress, то доступны все способы сортировок. Например, показать самое просматриваемое и залайканные за последние 12 дней, отсортировав от большего к меньшему количеству лайков.
Вывод контента из ленты в шаблоне письма
Поскольку все данные для отдельной карточки поста находятся внутри тега <description>
, вложенного в отдельный элемент <item>
, то достаточно только его и показать в шаблоне письма:
<h1>Свежие материалы недели в блоге PromoPult</h1>
<p>*|RSSFEED:DESCRIPTION|*</p>
<!--
*|RSSFEED:DESCRIPTION|* покажет: «21 августа — 28 августа»,
из тега <description> общей ленты
-->
*|RSSITEMS:|*
*|RSSITEM:CONTENT|*
*|END:RSSITEMS|*
Данные корректно отображаются, HTML-код вставляется в цикле и автокампания работает.
Отдельной строкой про RSSFEED и FEEDBLOCK
Чем отличается *|RSSFEED|*
и *|FEEDBLOCK|*?
В различиях разобраться просто:
*|FEEDBLOCK|*
можно использовать внутри любых шаблонов писем и кампаний. Например, хотите в периодическом выпуске рассылке рассказать про последние посты — используйте его. Указать можно ссылку на любой RSS-источник.*|RSSFEED|*
работает только в автокампаниях и в качестве источника видит то, что указано в настройках кампании.
ИТОГО: Если у вас все стандартно и несложно, юзайте стандартные средства MailChimp и не парьтесь
Но если у вас дизайн блога и рассылки нарисованы специально и трижды с боем согласованы, если есть желание добавить имеющиеся данные в авто-письма или хотя бы дату просклонять по-русски, то придется немножко заморочиться и отдавать в MailChimp уже готовые упакованные данные.
Как — мы рассказали.
Ссылки на тему RSS-лент в MailChimp:
- Feedblock RSS Merge Tags — документация про использование тегов
*|FEEDBLOCK|*
в шаблонах писем - RSS Merge Tags — документация про тег
*|RSSFEED|*
в шаблонах писем - Email Design Reference > RSS Merge Tags — начало работы с MailChimp и использование блоков RSS-лент в шаблонах писем
ghostinushanka
А потом выясняем что обезьянки до сих пор не умеют в кастомный «Return-Path» из-за которого не проходят проверки dmarc (SPF alignment) и либо уходим к другому сервису, либо выключаем dmarc на своём домене.
PromoPult Автор
Кажется, что до наступания на эту штуку нужно как-то дорасти и точно смотреть либо на собственное решение, либо выбирать сервисы по другим параметрам.
MailChimp — клёвый и всё, что есть в его коробке позволяется быстро создать и управлять рассылками для каких-то маленьких и средних дел: блоги, сайты, магазины, сообщества. Даже в бесплатном тарифе.
А расскажите, пожалуйста, свою историю, зачем кастомный
Return-Path
и в какой момент понадобилось и для каких задач?ghostinushanka
Чтобы наступить на эту штуку, достаточно поддерживать все стандарты борьбы со спамом
Про DMARC и как он относится к SPF и DKIM можно почитать вот тут и вот тут. На хабре об этом писало как минимум мейлру в своём блоге пару лет назад.
Если вкратце, как только вы хотите чтобы от имени вашего домена, например promopult.ru кто-то другой посылал почту, например mailchimp и вы не хотите чтобы она не падала в спам у нормальных провайдеров, вам нужно разрешить на уровне ваших DNS записей это делать. Последнее требование, чтобы домен из «from» соответствовал домену из «return-path». В противном случае это автоматический фейл проверки. А обезьянки настраивать это не позволяют (и год назад походу даже не понимали зачем это надо, вот твит тред)