Отложенная отправка писем при помощи FormIT + Scheduler
Сегодня в нашем телеграм-чатике задали вопрос —
Можно ли как то реализовать отложенную отправку письма, через форму formIT.
Этот вопрос напомнил мне о моих планах, написать инструкцию именно об этом.
По сути подобная задача уже реализована в miniShop2 на базе компонента Scheduler, не так давно опубликованного в Modstore.pro.
Итак, давайте разберемся как же все таки отправить отложенное письмо при помощи FormIt + Scheduler
Как отправлять письма используя FormIt — все знают. Вызываем сниппет FormIT (или, использующие его компоненты ajaxForm, FetchIT). В качестве хука указываем email, который берет на себя функционал мгновенной отправки писем. Если нужно отложить отправку, то напишем свой хук, который будем подключать вместо email;
Создадим пару сниппетов, необходимых на следующих шагах
scheduler_hook
Это хук, который будем подключать в вызов ajaxForm, вместо email
send_email
Это сниппет, который позже в фоновом запланированном режиме будет отправлять письмо
Далее настроим компонент Scheduler. После установки, перейдите в него, откройте вкладку задания и нажмите создать задание
Заполним задание следующим образом:
Замените в вызове formIT или ajaxForm хук email на хук scheduler_hook
После отправки формы, в вашем планировщике должно появиться задание, в котором будет видно заполненные данные клиента, что само по себе уже является плюсом и позволяет отслеживать письма и их содержимое
Обратите внимание на, то, что компонент запускается сервером через серверный планировщик задач CRON
Чтобы выполнение отложенных задач работало — нужно добавить CRON запись на вашем хостинге. Как это сделать описано в документации Scheduler
Можно ли как то реализовать отложенную отправку письма, через форму formIT.
Этот вопрос напомнил мне о моих планах, написать инструкцию именно об этом.
По сути подобная задача уже реализована в miniShop2 на базе компонента Scheduler, не так давно опубликованного в Modstore.pro.
Итак, давайте разберемся как же все таки отправить отложенное письмо при помощи FormIt + Scheduler
Как отправлять письма используя FormIt — все знают. Вызываем сниппет FormIT (или, использующие его компоненты ajaxForm, FetchIT). В качестве хука указываем email, который берет на себя функционал мгновенной отправки писем. Если нужно отложить отправку, то напишем свой хук, который будем подключать вместо email;
Шаг 1
Создадим пару сниппетов, необходимых на следующих шагах
scheduler_hook
Это хук, который будем подключать в вызов ajaxForm, вместо email
<?php
/** @var Scheduler $scheduler */
$path = $modx->getOption(
'scheduler.core_path',
null,
$modx->getOption('core_path') . 'components/scheduler/'
);
$scheduler = $modx->getService('scheduler', 'Scheduler', $path . 'model/scheduler/');
$task = $scheduler->getTask('formit', 'form_email');
// Перечисляем какие поля вы заполняете в сниппете, из тех что требуются для отправки писем
$fields = [
'emailTo',
'emailSubject',
'successMessage',
'fields'
];
$params = [];
foreach($fields as $key) {
if (!empty($scriptProperties[$key])) {
$params[$key] = $scriptProperties[$key];
}
}
if ($task instanceof sTask) {
// Здесь можете указать через какое время выполнить задание.
// + 1 second - мгновенно, + 2 minutes, + 3 hours.
// Также допустимы точные указания времени
$task->schedule('+1 second', $params);
}
return true;
send_email
Это сниппет, который позже в фоновом запланированном режиме будет отправлять письмо
unset($scriptProperties['task']);
unset($scriptProperties['run']);
$scriptProperties['hooks'] = 'email';
$_POST = $scriptProperties['fields'];
unset($scriptProperties['fields']);
$modx->runSnippet('FormIt', $scriptProperties);
if (!empty($scriptProperties['successMessage'])) {
return $scriptProperties['successMessage'];
}
return 'done';
Шаг 2
Далее настроим компонент Scheduler. После установки, перейдите в него, откройте вкладку задания и нажмите создать задание
Заполним задание следующим образом:
- Название — любое произвольное на английском. Я назвал form_email
- Тип задания — на основе сниппета
- Категория — formIT
- Сниппет — созданный на шаге 1 сниппет send_email
Шаг 3
Замените в вызове formIT или ajaxForm хук email на хук scheduler_hook
После отправки формы, в вашем планировщике должно появиться задание, в котором будет видно заполненные данные клиента, что само по себе уже является плюсом и позволяет отслеживать письма и их содержимое
Шаг 4
Обратите внимание на, то, что компонент запускается сервером через серверный планировщик задач CRON
Чтобы выполнение отложенных задач работало — нужно добавить CRON запись на вашем хостинге. Как это сделать описано в документации Scheduler
Поблагодарить автора
Отправить деньги
Комментарии: 8
Классный хак с повторным вызовом FormIT и пробросом туда параметров из задания через $_POST, очень элегантно!
Мне вот на подобие этого нужно было как-то вызывать хук для формита с API-вызовами к внешнему сервису но без отправки формы, так пришлось его код копировать и в сниппет выносить, а стоило сделать вот так как в заметке сделан сниппет send_email, чтобы не дублировать код и не поддерживать потом 2 версии…
К стати дополню список — в AjaxFormitLogin этот метод тоже будет работать
Мне вот на подобие этого нужно было как-то вызывать хук для формита с API-вызовами к внешнему сервису но без отправки формы, так пришлось его код копировать и в сниппет выносить, а стоило сделать вот так как в заметке сделан сниппет send_email, чтобы не дублировать код и не поддерживать потом 2 версии…
К стати дополню список — в AjaxFormitLogin этот метод тоже будет работать
Изобрел — пока статью писал.
Николай, правильно ли я понимаю, что этими действиями мы заменяем хук email и отправка писем (хуки email + FormItAutoResponder) будут откладываться на заданное время?
А если ситуация такая когда отправляются 3 письма: Заявка ушла админу/менеджеру, непонимание ушло клиенту — это всё мгновенно должно уходить после отправки формы. А третье через 15 минут уходит опять же клиенту.
Как на схеме, как прикрутить этот компонент? Заранее благодарен
А если ситуация такая когда отправляются 3 письма: Заявка ушла админу/менеджеру, непонимание ушло клиенту — это всё мгновенно должно уходить после отправки формы. А третье через 15 минут уходит опять же клиенту.
Как на схеме, как прикрутить этот компонент? Заранее благодарен
Да верно. Мы заменяем хук email. Насчет хука FormItAutoResponder…
В сниппете send_email в список выполняемых хуков нужно просто добавить все нужные хуки.
Чтобы письма отправлялись в разное время, нужно просто перебрать email и каждому поставить свою задачу. Перепишем кусок поставновки задачи вот так:
В сниппете send_email в список выполняемых хуков нужно просто добавить все нужные хуки.
Чтобы письма отправлялись в разное время, нужно просто перебрать email и каждому поставить свою задачу. Перепишем кусок поставновки задачи вот так:
// Перечисляем какие поля вы заполняете в сниппете, из тех что требуются для отправки писем
$fields = [
'emailTo',
'emailSubject',
'successMessage',
'fields'
];
$params = [];
foreach($fields as $key) {
if (!empty($scriptProperties[$key])) {
$params[$key] = $scriptProperties[$key];
}
}
if ($task instanceof sTask) {
$emails = $params['emailTo'];
unset($params['emailTo']);
$emails = array_map('trim', explode(',', $emails));
foreach($emails as $email) {
$params['emailTo'] = $email;
// Здесь можете указать через какое время выполнить задание.
switch($email) {
case 'bigboss@mail.ru':
// Этому отправляем сразу
$task->schedule('+1 second', $params);
case 'smallboss@mail.ru':
// Этому отправляем через 5 минут
$task->schedule('+5 minutes', $params);
break;
}
}
}
>> Чтобы письма отправлялись в разное время, нужно просто перебрать email и каждому поставить свою задачу.
Но проблема в том, что мы заранее не знаем почту клиента.
Но проблема в том, что мы заранее не знаем почту клиента.
Заполненные поля формы доступны в параметре $params['fields']. Достаньте email оттуда, нет проблем.
Николай, прошу прощения за может быть нелепый вопрос, но могу ли я сделать третью отправку с задержкой отдельным хуком. А email и FormItAutoResponder оставить в вызове FormIt как есть. Там проблема в том, что клиенту отправляются два разных по содержанию письма, а параметр fiarTpl я поменять не могу(
Можете. Общий Принцип взаимоотношений с менеджером очередей я показал. Доступ к настройкам сниппета, к полям формы есть. Крутите ими как хотите, все данные для этого доступны.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.