[EmailQueue] - Очередь писем
С сайта бывает требуется отсылать много писем. Но многие хостеры ограничивают число писем что можно сразу отправить. Например на одном хостинге можно отправить только 60 писем в минуту. Чтобы обойти это ограничение нужно организовывать очередь писем и отправлять письма частями по, например, 50 штук. Чтобы не писать такую очередь каждый раз когда отправка многих писем нужна в компоненте, написал отдельный компонент что организует такую очередь.

В админке сделано относительно удобное управление очередью.
Для отправки писем из очереди поставите в cron файл core/components/emailqueue/cron/send.php с нужной периодичностью.
Настройки:
emailqueue_limit — сколько писем отправлять за раз.
emailqueue_store_days — сколько дней письма хранить в очереди.
Для помещения писемь в очередь используйте примерно такой код:
Думаю небольшие компоненты для разработчиков лучше делать бесплатными. Так что компонетнт по крайней мере пока бесплатный :). Но от доната не откажусь. Кто захочет поблагодарить Номер кошелька Яндекс 410011280920822
Гитхаб https://github.com/touol/EmailQueue
UPD 10.12.2018
В версии 1.1.0-beta
Сделан более удобный topBar.
Добавлен статус «Отправляется» для для избежания отправки дубликатов писем.
Добавлены хуки EmailQueue и EmailQueueAutoResponder для замены хуков email и FormItAutoResponder в FormIt/AjaxForm.
EmailQueue — Cниппет для drop-in replacement замены хука email для FormIt/AjaxForm
Просто в вызове поменять хук на EmailQueue
EmailQueueAutoResponder — Cниппет для drop-in replacement замены хука FormItAutoResponder для FormIt/AjaxForm
Просто в вызове поменять хук на EmailQueueAutoResponder
И не все параметры FormIt поддерживает (например emailHtml, emailToName, emailCC, итд), т.к. компонент их не учитывает.
Если хотите помочь развитию компонента делайте мне пулл-реквест на гитхабе. Или просто публикуйте изменения кода в комментариях :).

В админке сделано относительно удобное управление очередью.
Для отправки писем из очереди поставите в cron файл core/components/emailqueue/cron/send.php с нужной периодичностью.
Настройки:
emailqueue_limit — сколько писем отправлять за раз.
emailqueue_store_days — сколько дней письма хранить в очереди.
Для помещения писемь в очередь используйте примерно такой код:
if (!$EmailQueue = $modx->getService('emailqueue', 'EmailQueue', $modx->getOption('emailqueue_core_path', null,
$modx->getOption('core_path') . 'components/emailqueue/') . 'model/emailqueue/', array())) {
return;
}
$queue_email = $modx->newObject('EmailQueueItem');
$data1 = array(
'sender_package'=>'UserTest', //дополнение отправитель письма
'to'=>$invite->user_email, //емаил
'subject'=>$modx->lexicon('usertest_invite_subject',array('test_name' => $test->name)), // тема письма
'body'=>$modx->getChunk('tpl.UserTest.InviteEmail',array('test_name' => $test->name,'link'=>$invite->url)), // тело письма
'date'=>date("Y-m-d H:i:s"), // дата в очереди. Нужно чтоб письма удалялись по истечении срока хранения.
);
if($modx->getOption('usertest_invite_email_from', null, false))
$data1['from'] = $modx->getOption('usertest_invite_email_from'); //необязательно
if($modx->getOption('usertest_invite_email_from_name', null, false))
$data1['from_name'] = $modx->getOption('usertest_invite_email_from_name'); //необязательно
$queue_email->fromArray($data1);
if($queue_email->save())
$modx->log(modX::LOG_LEVEL_INFO,"Приглашение на $email добавлено в очередь писем!");Дополнительно можно задать:$queue_email->reply_to // обратный адрес
$queue_email->attachments //полные имена приклепляемых файлов через запятуюКомпонент доступен в Modstore https://modstore.pro/packages/alerts-mailing/emailqueue.Думаю небольшие компоненты для разработчиков лучше делать бесплатными. Так что компонетнт по крайней мере пока бесплатный :). Но от доната не откажусь. Кто захочет поблагодарить Номер кошелька Яндекс 410011280920822
Гитхаб https://github.com/touol/EmailQueue
UPD 10.12.2018
В версии 1.1.0-beta
Сделан более удобный topBar.
Добавлен статус «Отправляется» для для избежания отправки дубликатов писем.
Добавлены хуки EmailQueue и EmailQueueAutoResponder для замены хуков email и FormItAutoResponder в FormIt/AjaxForm.
EmailQueue — Cниппет для drop-in replacement замены хука email для FormIt/AjaxForm
Просто в вызове поменять хук на EmailQueue
EmailQueueAutoResponder — Cниппет для drop-in replacement замены хука FormItAutoResponder для FormIt/AjaxForm
Просто в вызове поменять хук на EmailQueueAutoResponder
[[!Formit?
&hooks=`EmailQueue,EmailQueueAutoResponder`
&emailTpl=`feedbackEmail`
&emailTo=`test@mail.ru`
&emailSubject=`Сообщение с сайта`
&replyTo=`[[+email]]`
&emailFrom=`[[++emailsender]]`
&fiarTpl=`feedbackEmail`
&fiarSubject=`Сообщение с сайта`
&fiarReplyTo=`[[+email]]`
&fiarFrom=`[[++emailsender]]`
]]Поддержку вложений не делал, т.к. не было необходимости.И не все параметры FormIt поддерживает (например emailHtml, emailToName, emailCC, итд), т.к. компонент их не учитывает.
Если хотите помочь развитию компонента делайте мне пулл-реквест на гитхабе. Или просто публикуйте изменения кода в комментариях :).
Комментарии: 69
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Тоже со временем воспользуюсь, возьму на заметку.
Использовал для этих целей очереди Sendex, добавлял туда письма и дёргал очередь через крон. Ваше дополнение удобнее и видна статистика отправленных писем.
Я обычно даты в свои таблицы записываю в unix-формате и никаких проблем с этим. Пример беру с дат в таблице ресурсов, там все они в unix-е.
Тогда и текстом можно будет нормально написать, и сколько угодно кнопок туда напихать по мере развития компонента.
Хотя бы для некоторых кнопок.
Развития компонента пока не планируется :). В смысле, а есть куда его развивать? Рассылки все равно лучше делать через специализированные сервисы. Хостеры, если блокируют письма, то ничего не сообщают и не понятно ушло письмо или нет. Этот компонент на случай если сервис еще не имеет смысла подключать.
Например первое что я поискал, это возможность подключения шаблонов.
Это можно например реализовать так: отдельное поле template в таблице, в который можно будет указывать id существующего шаблона или чанка. В форме можно это селектом сделать самоподгружающим эти эти элементы, но на первое время и простое поле тоже сойдёт, главное чтобы работало. В самом шаблоне чтобы были доступны переменными (желательно через Fenom если установлен) все поля письма. Ну и если шаблон указан, то отправляется письмо красиво оформленное, если нет, то простой текст.
Для многих это довольно важно, т.к. кастомизация, сохранения брендового стиля и т.д.
Создание и редактирование писем в компоненте это просто на всякий случай. Чтоб протестировать компонент или просто отправку писем. Посмотреть что вообше в очереди лежит.
Спасибо за объяснение, забыл про getChunk (что компонент больше для разработчиков) и сосредоточился на удобстве формы из админки…
Кнопки Ошибки и Все непонятно что делают, просят больше описания действий. Ну и значков просят, а то высота кнопок прыгает.
Две кнопки удалить — тоже можно было бы их в выпадалку запрятать и текст написать.
Я просто не сразу заметил, что у кнопок есть подсказка при наведении, да и не всегда она у меня срабатывает, видно потому что навешана на иконку значка, а не на всю кнопку.
Лучше в выпадающий список запрятать некоторые кнопки.
который использует компонент modHelpers?
На первый взгляд кажется, что проще переписать весь сниппет и сделать по вашему шаблону, но непонятно, что вписывать в графе
sender_package Нужно только чтоб видеть откуда письмо в очереди. Если вдруг несколько компонентов сразу отправляют. Можно написать что угодно или даже оставить пустым.
ps пока помню — есть небольшая ошибка в верхнем меню компонента.
тэг title (всплывающая подсказка) при наведении на кнопки не выводится в FF, а в chrome выводится только при наведении на иконку внутри кнопки, а не на саму кнопку. Может пригодится.
что то вроде такого
странно что на $modx->getService не ругается
то есть ничего не передаёт.
Не знаете с чем может быть связано?
П.С. Лично мне кажется странным вот этот код
Зачем создавать массив?
Да и вообще весь описанный код странный. Но это вопрос к автору кода.
И ошибок никаких не выдает. Журнал тоже пуст.
Хм. Он 3 часа обещает скачиваться. Может все таки дадите доступ к вашему MODX?
А так же стоит 0 в поле attachments, которое вроде и не указано нигде в вызове.
с доступом ну никак, могу сделать копию
В emailqueue.mysql.schema.xml вместо этого
сделал это
Я эти поля как в modExtra сделано так и делал.
Если вызвать ещё и в начале сниппета, тогда работает. Только глаз режет :-)
Спасибо!
сейчас вопрос другой
Просто в вызове поменять хук на email_queue (или свое название сниппета)
Поддержку вложений не делал, т.к. не было необходимости.
И не все параметры FormIt поддерживает (например emailHtml, emailToName, emailCC, итд), т.к. компонент их не учитывает.
Вот сейчас отправлять нужно от домена заказчика, а чтобы соблюсти все DKIM, SPF и прочее без правки DNS вариант только через доступ по SMTP.
А коннект к SMTP визуально секунды 3 и это тормозит на фронте.
Плюс опять же возможны какие-то лимиты по кол-ву в час, одновременных соединений и тп.
И у пользователя возникает ошибка и форма не отправляется.
Допустим лимит стоит 50 писем за раз, а запуск скрипта каждую минуту.
В большинстве случаев все работает и 50 писем успевают отправится за 1 минуту.
Но в какой-то час SMTP или сеть начнет тормозить и отправка станет занимать 3-5 сек.
За минуту успеют отправится только 20 писем, затем запуститься второй скрипт и начнет отправлять оставшиеся 30 письма, т.к. они еще не помечены как отправленные. В итоге пользователю будут приходить дубли.
Просто убрал все лишнее что сейчас не нужно было мне и адаптировал под компонент.
И он на первое время сойдет, но для полноценной замены желательно чтобы поддерживал все параметры FormIt, такие как скрытые копии, html или текст сообщение, вложения и прочее.
docs.modx.com/extras/revo/formit/formit.hooks/formit.hooks.email
Можно не все их в таблицу добавлять, оставить только важные, которые отображать в компоненте, а остальные в поле properties в json-виде, так расширять можно будет без правки схемы. Главное чтобы скрипт отправки поддерживал.
И у FormIt есть еще хук FormItAutoResponder docs.modx.com/extras/revo/formit/formit.hooks/formit.hooks.formitautoresponder
Это бывает полезно для обратной связи когда email уходит менеджеру, а пользователю дополнительно отправляется другой email со своим шаблоном «Спасибо за ваш отзыв. Менеджер уже занимается вашим вопросом»
С поддержкой всех параметров сложно. Не думаю что я буду это делать :(. У меня в этом потребности нет. И все прописать достаточно сложно. Сегодня я сделаю топбар и статус отправляется и выложу на гитхаб. Если вы захотите, можете сделать форк доработать компонент прислать мне пулл-реквест.
насчет FormItAutoResponder подумаю как прикрутить.
Ну если кто и будет это делать, то просто создать еще один сниппет, который понимает парметры FormItAutoResponder и добавляет еще одно письмо в очередь.
Я для своего хука так и делал. Через FormIt можно указать несколько получателей в параметре &emailTo, я на каждого создавал отдельное письмо в очереди.
Теперь всё логично и понятно — компонент имеет вид завершенного продукта.
Можно смело использовать на всех проектах без опаски за непонятный функционал (такая путаница с кнопками была раньше).
Примерно так. Не тестировал.