Система отсылки e-mail уведомлений

Обсуждаем, как правильно строить приложения
Ответить
Аватара пользователя
Йож
Сообщения: 572
Зарегистрирован: 2015.08.26, 03:05

Система отсылки e-mail уведомлений

Сообщение Йож »

Добрый день!

Погуглил информацию по данной теме, что-то маловато нашлось, пришлось думать самому :D

Т.к. samdark недавно в одной из тем советовал стараться поменьше делать зависимостей от событий, решил их не использовать совсем.
Идея вот в чем:

Есть commandBus.
При определенных выполненных условиях осуществляется команда:

Код: Выделить всё

Yii::$app->commandBus->handle(new SendEmailCommand([
                   'action' => SendEmailCommand::ACTION_ACTIVATION,
                    'params' => [
                       'user_id' => $this->user_id
                    ]
                ]));
или

Код: Выделить всё

Yii::$app->commandBus->handle(new SendEmailCommand([
                   'action' => SendEmailCommand::ACTION_ORDER_SUCCESS,
                    'params' => [
                        'order_id' => $this->order_id
                    ]
                ]));
или

Код: Выделить всё

Yii::$app->commandBus->handle(new SendEmailCommand([
                   'action' => SendEmailCommand::ACTION_FEEDBACK,
                    'params' => [
                        'feedback_id' => $this->feedback_id
                    ]
                ]));
В команду передается только самое необходимое.
В ней уже в зависимости от действия

Код: Выделить всё

const ACTION_ORDER_SUCCESS = 'order_success';
Делаются необходимые приготовления данных, текстов, вьюха для e-mail.

И отсылается в очередь:

Код: Выделить всё

Yii::$app->queue->push(new SenEmailJob([
    'subject' => 'Подтверждение заказа',   
    'to' => $this->to,
    ...
]));
Из плюсов:
1. Можно редактировать всю логику формирования писем в одном месте, не ища по всем контроллерам или моделям, какие же там данные передаются и откуда
2. Независимость от доступности внешних сервисов благодаря очередям

Из минусов:
1. Лишняя нагрузка, т.к. в команде заново запрашивается вся информация о юзере или скажем, о заказе. Впрочем, частично - это плюс, т.к. пришлось бы вытаскивать заказанные товары прямо в actionOrderSuccess()
2. Фиксированный набор экшенов для отправки, придется добавлять новые.
Но можно сделать один дефолтный, в который информация для отправки приходит сразу вся и по прямой отправляется в очередь.

===============
Прошу критики и подсказок, что изменить или добавить в логике. Т.к. осуществил пока только менее чем на половину.
Или, может, сотворил фигню и лучше сделать по-другому?

Спасибо.

Аватара пользователя
ElisDN
Сообщения: 5492
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Система отсылки e-mail уведомлений

Сообщение ElisDN »

У Вас вся куча писем в SendEmailCommand лежит?

И чем это:

Код: Выделить всё

new SendEmailCommand([
    'action' => SendEmailCommand::ACTION_ORDER_SUCCESS,
    'params' => [
        'order_id' => $this->order_id
    ]
])
удобнне чем:

Код: Выделить всё

new OrderCreated($this->order_id)

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

Re: Система отсылки e-mail уведомлений

Сообщение slavcodev »

Йож писал(а):
2017.04.21, 18:31
Т.к. samdark недавно в одной из тем советовал стараться поменьше делать зависимостей от событий
Что-то мне кажется, что причины этого совета прекрасно подходят и к использованию шины и команд.
Ведь рассылка команд ничем не отличается от рассылки событий, это те же сообщения и обработчики подписывающиеся на них.
Жду Yii 3!

Аватара пользователя
Йож
Сообщения: 572
Зарегистрирован: 2015.08.26, 03:05

Re: Система отсылки e-mail уведомлений

Сообщение Йож »

ElisDN писал(а):
2017.04.21, 18:49
У Вас вся куча писем в SendEmailCommand лежит?
Да, думаю, всю обработку туда засунуть, не так и много кода, строк по 5-10 на каждый вид писем.
Layouts для писем в mail/layouts.
ElisDN писал(а):
2017.04.21, 18:49
И чем это:

Код: Выделить всё

new SendEmailCommand([
    'action' => SendEmailCommand::ACTION_ORDER_SUCCESS,
    'params' => [
        'order_id' => $this->order_id
    ]
])
удобнне чем:

Код: Выделить всё

new OrderCreated($this->order_id)
Удобней тем, что не нужно раскидывать все по классам (OrderCreated, FeedbackSended, RegistrationDone, ActivationRequested), "типа" удобно все в одном месте. (тут у меня сомнение есть, может быть, неверно мыслю)

Просто реально хочется сделать аналог событий. событие случилось -> отправилась команда -> подготовилась -> в очередь -> выполнено.
И на каждом этапе при маленькой модификации можно узнать статус операции.
При желании пожно повесить в будущем UI, который все это показывает в реальном времени.

Звучит вроде хорошо, но вот я и спрашиваю, где что можно сделать по-другому, т.к. опыт у меня небольшой..

Аватара пользователя
Йож
Сообщения: 572
Зарегистрирован: 2015.08.26, 03:05

Re: Система отсылки e-mail уведомлений

Сообщение Йож »

Еще идея - сделать NotificationCommand() вместо SendEmailCommand().
И там еще добавить виды нотификаций, например, отправку смс.
Тем самым в нужный контроллер даже не нужно залезать. Там только отсылка команды.
В команде может быть пусто, может быть несколько действий, причем какие-то можно выполнить сразу - простые, посложнее отправить в очередь, чтоб клиент не ждал.

Конечно, команда будет раздута неимоверно, но наверно есть вариант этот код раскидать :)

Ответить