Статья, в которой рассмотрим, как на базе компонента Sendex организовать еженедельную email рассылку писем подписчикам сайта.

Создание автоматической email рассылки для CMS MODX Revolution

Создание email рассылки для MODX Revolution на основе дополнения Sendex будет состоять из следующих основных шагов:

  • установка компонента Sendex;
  • создания email шаблона письма;
  • создания подписки;
  • разработки ресурса, на котором зарегистрированный и анонимный пользователь смогут не только подписаться на email рассылку, но также отписаться от неё;
  • создания php скрипта create.letters.php для автоматического формирования основного содержимого email рассылки и очереди писем для отправки;
  • настройки планировщика cron, который будет запускать в определённые моменты времени файлы create.letters.php и send.php.

Установка компонента Sendex

Установка компонента Sendex осуществляется через поставщика modstore.com. Если он у вас не установлен, то сначала создайте его. После этого загрузите и установите для CMS MODX Revolution дополнение Sendex.

Создание email шаблона письма

Разрабатывать рассылку начнём с создания шаблона. Он необходим для создания HTML структуры (email шаблона) письма. В качестве имени зададим ему, например, значение SendexTemplate.

Содержимое шаблона (пример):

<table style="background-color: #f1f1f1; width:100%; font-family:-apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;" align="center" width="100%" border="0" cellpadding="0" cellspacing="0">
  <tbody>
    <tr>
      <td align="center" style="vertical-align:top;padding:30px 0;text-align:center">
        <table style="text-align:left;width:680px;margin:0 auto;font-size:14px;border-spacing:0px">
          <tbody> 
            <tr>
              <td bgcolor="#fff" style="padding: 15px;">
                <font color="#777" style="font-size:18px">[[+newsletter.name]] ([[+phx:input=`now`:strtotime:date=`%d.%m.%Yг.`]])</font>
              </td>
            </tr>
            <tr><td height="25"></td></tr>
            <tr>
              <td bgcolor="#fff" style="padding: 15px;">
                [[+newsletter.description]]
              </td>
            </tr>
            <tr><td height="25"></td></tr>
            <tr>
              <td bgcolor="#fff" style="padding: 20px 15px; color: #777; font-size: 14px;">
                <p>© 2017 Мой сайт.</p>
                <p style="font-size: 12px;">Это сообщение было отправлено на [[+subscriber.email]] потому, что вы подписались на еженедельную рассылку. Данное письмо не требует ответа.</p>
                <p style="font-size: 12px;">Если вы не хотите больше получать письма от нас, то щелкните <a href="[[~10?scheme=`full`&sx_action=`unsubscribe`&code=`[[+subscriber.code]]`]]" target="_blank">здесь</a>.</p>
              </td>
            </tr>
          </tboy>
        </table>
      </td>
    </tr>
  </tbody>
</table>

Назначение ссылки и плейсхолдеров в содержимом шаблона SendexTemplate:

  • [[+newsletter.name]] - название подписки;
  • [[+newsletter.description]] - описание (основное содержимое) подписки;
  • [[+subscriber.email]] - email адрес подписчика;
  • ~10 - формирует ссылку на 10 ресурс сайта (этот ресурс, а точнее сниппет Sendex, расположенный в нём, будет осуществлять отписку от рассылки, если конечно пользователь перейдёт по ней);
  • [[+subscriber.code]] - код подписчика.

Создание рассылки

Для создания рассылки откроем в админке MODX страницу Sendex (Приложения -> Sendex). Переключимся на вкладку "Подписки" и нажмём на кнопку "Создать".

MODX Sender - Создание подписки
MODX Sender - Создание подписки

В диалоговом окне "Создать подписку" заполним поля формы следующими значениями:

  • Название - Информационная рассылка;
  • Шаблон - SendexTemplate;
  • Тема письма - Мой сайт - Еженедельная информационная рассылка;
  • Ответный email - no-reply@mysite.ru;
  • Исходящий email - no-reply@mysite.ru;
  • Отправитель - Мой сайт.

Поле "Описание" заполнять не будем. Его наполнение будем осуществлять с помощью php скрипта create.letters.php. Данный скрипт будем запускать с помощью планировщика cron раз в неделю.

MODX Sender - Отображение созданной подписки (имеющей id = 1) в таблице рассылок
MODX Sender - Отображение созданной подписки (имеющей id = 1) в таблице рассылок

Создание ресурса «Email подписка»

Создадим в админке MODX Revolution ресурс (pagetitle - Email подписка).

В содержимое ресурса поместим вызов 2 сниппетов:

[[!SendexEventTracking]]
[[!Sendex? 
  &id=`1`
]]

Сниппет Sendex

Сниппет Sendex осуществляет подписку пользователя на рассылку (в данном случае ту, которая имеет идентификатор 1), а также отписку от неё.

Подписку на рассылку, а также отписку от неё авторизированный пользователь осуществляет с помощью щелчка по кнопке.

MODX Sender - Форма подписки на email рассылку для авторизированного пользователя (пример)
MODX Sender - Форма подписки на email рассылку для авторизированного пользователя

Анонимный же пользователь осуществляет подписку через ссылку в письме. Для получения письма он должен ввести свой email адрес в форму подписки и нажать на кнопку «Подписаться».

MODX Sender - Форма подписки на email рассылку для анонимного (не авторизированного) пользователя (пример)
MODX Sender - Форма подписки на email рассылку для анонимного (не авторизированного) пользователя

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

Настройка вывода форм, связанных с подпиской, сниппет Sendex осуществляет с помощью параметров:

  • tplSubscribeGuest - чанк (по умолчанию tpl.Sendex.subscribe.guest), содержащий форму, с помощью которой анонимный пользователь может подписаться на рассылку.
  • tplActivate - чанк (по умолчанию tpl.Sendex.activate), содержащий email шаблон, на основании которого будет формироваться письмо анонимному пользователю. Основное содержимое письма – это ссылка, по которой ему необходимо перейти для того, чтобы подтвердить подписку.
  • tplSubscribeAuth – чанк (по умолчанию tpl.Sendex.subscribe.auth), содержащий форму подписки, которая будет показываться авторизированному пользователю;
  • tplUnsubscribe – чанк (по умолчанию tpl.Sendex.unsubscribe), содержащий форму, посредством которой авторизированный пользователь может отписаться от рассылки.

При необходимости вы можете настроить содержимое каждого чанка. Но лучше это делать не в исходных чанках, а в их копиях, которые затем указать сниппету с помощью соответствующих параметров:

Например:

[[!Sendex? 
  &id=`1`
  &tplSubscribeAuth=`tplSendexSubscribeAuth`  
  &tplSubscribeGuest=`tplSendexSubscribeGuest`
  &tplUnsubscribe=`tplSendexUnsubscribe`  
  &tplActivate=`tplSendexActivate`
]]

Сниппет SendexEventTracking

Сниппет SendexEventTracking предназначен для отображения на странице информационных сообщений, связанных с email подпиской.

Вывод того или иного сообщения зависит от наличия в составе URL одного из следующих параметров: sx_subscribed, sx_confirmed, sx_unsubscribed.

Код сниппета SendexEventTracking:

<?php
$output = '';
$subscribed = $modx->getOption('subscribed', $scriptProperties, 'tplSendexEventSubscribed');
$confirmed = $modx->getOption('confirmed', $scriptProperties, 'tplSendexEventConfirmed');
$unsubscribed = $modx->getOption('unsubscribed', $scriptProperties, 'tplSendexEventUnsubscribed');
if ($_GET['sx_subscribed']) {
  $output = $modx->getChunk($subscribed);
}
if ($_GET['sx_confirmed']) {
  $output = $modx->getChunk($confirmed);  
}
if ($_GET['sx_unsubscribed']) {
  $output = $modx->getChunk($unsubscribed);  
}
return $output;

Все информационные сообщения хранятся в чанках (по умолчанию): tplSendexEventSubscribed, tplSendexEventConfirmed, tplSendexEventUnsubscribed.

Код чанка tplSendexEventSubscribed (пример):

<div class="alert alert-danger">На указанный почтовый ящик отправлено письмо, содержащее ссылку. Перейдите по ссылке для подтверждения email адреса, на который будут высылаться раз в неделю новые статьи.</div>

Код чанка tplSendexEventConfirmed (пример):

<div class="alert alert-danger">Вы успешно подписаны на еженедельную email рассылку сайта.</div>

Код чанка tplSendexEventUnsubscribed (пример):

<div class="alert alert-danger">Вы успешно отписаны от рассылки новых статей сайта.</div>
MODX Sender - Отображения информационного сообщения о том что указанный email адрес необходимо подтвердить, чтобы на него получать рассылку
MODX Sender - Отображения информационного сообщения о том что указанный email адрес необходимо подтвердить, чтобы на него получать рассылку

Автоматическое формирование тела email рассылки

Формировать тело рассылки будем выполнять автоматически с помощью php файла. Для этого создадим файл create.letters.php, например, в директории cron (/core/components/sendex/cron/) со следующим содержимым:

<?php
require_once dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/config.core.php';
require_once MODX_CORE_PATH.'model/modx/modx.class.php';
$modx = new modX();
$modx->initialize('web');
$modx->getService('error','error.modError', '', '');

// id раздела, в котором расположены статьи
$parent = array(5,6,7);
// создадим запрос на выборку новых статей, расположенных в указанных разделах (дата публикации не позже 7 дней)
$query = $modx->newQuery('modResource', array(
  'publishedon:>=' => strtotime('-7 days'),
  'parent:IN' => $parent
));
// ограничим выборку 5 элементами
$query->limit(5);
// получим статьи
$resources = $modx->getCollection('modResource', $query);

$output = '';
// переберём статьи и сформируем ответ
foreach ($resources as $resource) {
  $id = $resource->get('id');
  $pagetitle = $resource->get('pagetitle');
  $description = $resource->get('description');
  $url = $modx->makeUrl($id,'','','https');
  // получим tv поле image (id=2)
  $image = $modx->getObject('modTemplateVarResource',array( 'tmplvarid' => 2, 'contentid' => $id ));  
  if (is_object($image)) {
    $image = 'http://mysite.ru/assets/images/'.$image->get('value');
  } else {
    $image = '';
  }
  $output .= $modx->getChunk('tpl.newsletter.article',array(
    'pagetitle' => $pagetitle,
    'description' => $description,
    'url' => $url,
    'image' => $image
  ));
}
$count = count($resources);

// не будем формировать очередь, если количество новых статей равно нулю
if ($count==0) {
  exit();
}

// формируем очередь (создаём письма для отправки подписанным пользователям)
$modx->addPackage('sendex', MODX_CORE_PATH . 'components/sendex/model/');
/** @var sxNewsletter $newsLetter */
if ($newsLetter = $modx->getObject('sxNewsletter', 1)) {
  $newsLetter = $modx->getObject('sxNewsletter', 1);
  $newsLetter->set('description',$output);
  $newsLetter->save();
  $response = $newsLetter->addQueues();
}

exit();

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

<tr>
  <td bgcolor="#fff" style="padding: 15px;">
    <table border="0" cellpadding="0" cellspacing="0" align="left" width="100%">
      <tbody>        
        <tr>          
          <td width="12" valign="middle" style="padding:10px 0;">
            <span style="display:block;border-left:5px solid #2ecc71">
              <font style="font-size:20px"> </font>
            </span>
          </td>                  
          <td valign="middle" style="padding: 10px 0;">
            <font color="#2ecc71" style="font-size:20px">[[+pagetitle]]</font>
          </td>
        </tr>
      </tbody>
    </table>
  </td>
</tr>
<tr>
  <td valign="top" bgcolor="#fff">
    <table border="0" cellpadding="0" cellspacing="0" align="left" style="width:100%;">
      <tbody>        
        <tr>
          <td valign="top">
            <img itemprop="image" src="[[+image]]" alt="[[+pagetitle]]" style="max-width: 100%;">
          </td>
        </tr>
        <tr>
          <td valign="top" style="padding: 15px;">
            <font color="#777" style="font-size:14px">[[+description]]</font>
          </td>
        </tr>
        <tr>          
          <td align="right" style="padding: 5px 15px 10px 0px;"> 
            <a href="[[+url]]" target="_blank">
              <font color="#2ecc71" style="font-size:14px">
              Читать далее...</font></a>
          </td>
        </tr>
      </tbody>
    </table>
  </td>
</tr>    
<tr><td height="25"></td></tr>
MODX Sender - Пустая очередь писем (до запуска файла create.letters.php)
MODX Sender - Пустая очередь писем (до запуска файла create.letters.php)
MODX Sender - Письма для отправки (после запуска файла create.letters.php)
MODX Sender - Письма добавленные в очередь для отправки (после запуска файла create.letters.php)

Настройка cron для запуска email рассылки по расписанию

Заключительное действие - это добавление в программу-планировщик cron двух заданий для запуска их в определённое время с определённой периодичностью.

Например:

  1. файл create.letters.php (формирование писем и додавление их в очередь) - например, каждый четверг в 6 часов утра (0 6 * * 4);
  2. файл send.php (отправка писем) - например, каждый четверг, начиная с 7 часов утра (*/12 7-9 * * 4).

Если подписчиков много, то письма можно отправлять небольшими порциями (например, по 50 штук) каждые 5 минут (*/12) в течение 3 часов (7-9). Файл send.php необходимо запускать после выполнения файла create.letters.php.

Содержимое файла send.php:

<?php

require_once dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/config.core.php';
require_once MODX_CORE_PATH . 'config/' . MODX_CONFIG_KEY . '.inc.php';
require_once MODX_CONNECTORS_PATH . 'index.php';

$modx->addPackage('sendex', MODX_CORE_PATH . 'components/sendex/model/');

$q = $modx->newQuery('sxQueue');
$q->limit($modx->getOption('sendex_queue_limit', null, 50, true)); // 50 - количество писем, отправляемых за один раз

$queue = $modx->getCollection('sxQueue', $q);
/** @var sxQueue $email */
foreach ($queue as $email) {
	$email->send();
}
Пример создания новой задачи для cron с помощью панели управления виртуальным хостингом
Пример создания новой задачи для cron с помощью панели управления виртуальным хостингом

Пример содержимого email письма (рассылки)

После отправки рассылки, каждый подписанный пользователь получит на свой адрес письмо, содержащий материал собранный create.letters.php.

Пример содержимого еженедельной email рассылки
Пример содержимого еженедельной email рассылки