Обновление уведомлений
Выдалась свободная минутка (точнее, часик) и я организовал-таки нормальные уведомления о комментариях на почту.
Если кто не в курсе, то раньше было вот так:
Чтобы понять о чём речь, нужно было обязательно пройти на сайт и почитать - что не очень удобно, если там только "спасибо за ответ!".
А теперь уведомления выглядят вот так:
Сразу ясно - надо ли заходить на сайт для ответа, или можно просто удалить письмо. Подобные уведомления не являются чем-то новым, я уже делал такое на modx.pro, но здесь решил улучшить пару моментов.
Во-первых, уведомления не должны отправляться сразу же после создания комментария. У пользователя есть 10 минут для редактирования, в течение которых он может полностью изменить смысл изначального послания. Уведомлять адресата нужно финальным текстом сообщения.
Во-вторых, за эти 10 минут получатель уведомлений может и сам зайти на сайт и всё прочитать. Отправлять юзеру уведомления о том, что он уже видел, ну нужно. Подобным грешит, например, Вконтакте - неоднократно замечал, раздражает.
Значит, нам нужна табличка для уведомлений. В отличие от обычной очереди email я решил сделать ссылки на событие:
$this->schema->create(
'user_notifications',
function (Blueprint $table) {
$table->uuid('id');
// Связи с юзером-получателем уведомления, заметкой и комментом
$table->foreignId('user_id')
->constrained('users')->cascadeOnDelete();
$table->foreignId('topic_id')
->constrained('topics')->cascadeOnDelete();
$table->foreignId('comment_id')
->constrained('comments')->cascadeOnDelete();
// Тип сообщения: обычный коммент или ответ другому юзеру
$table->string('type', 50);
// Уведомление еще актуально
$table->boolean('active')->default(true)->index();
// Уведомление было отправлено
$table->boolean('sent')->default(false)->index();
// Метки времени: created_at и updated_at
$table->timestamps();
// Время отправки
$table->timestamp('sent_at')->nullable();
}
);
Флаг active нам нужен для того, чтобы отключить отправку уведомления, если оно уже устарело - то есть юзер увидел комментарий раньше. Это я определяю по времени последнего просмотра заметки пользователем.
Если зашёл в заметку, то считаем, что прочитал там все комментрии.
Генерация и отправка писем работает по расписанию каждые n минут:
// Дата создания = текущая дата минус 600 секунд
$created_at = Carbon::now()->subSeconds(600)->toDateTimeString();
// Выбираем активные неотправленные уведомления,
// которые были созданы более 10 минут назад
$notifications = UserNotification::query()
->where('created_at', '<=', $created_at)
->where([
'active' => true,
'sent' => false,
]);
foreach ($notifications->cursor() as $notification) {
$notification->sendEmail();
}
Сами email создаются в момент отправки, так что там всегда будет актуальная информация. Главное, чтобы задержка отправки была больше времени редактирования.
public function sendEmail(): ?string
{
// Служба работы с почтой
$mail = new Mail();
// Заголовок зависит от типа уведомления
$subject = getenv($this->type === 'comment-new' ? 'LEXICON_COMMENT_NEW' : 'LEXICON_COMMENT_REPLY');
// Все возможные данные для оформления писем
$data = [
'comment' => $this->comment->toArray(),
'user' => $this->comment->user->toArray(),
'topic' => $this->topic->toArray(),
'author' => $this->topic->user->toArray(),
];
// Почта может вернуть ошибку
if ($err = $mail->send($this->user->email, $subject, $this->type, $data)) {
return $err;
}
// Если отправка прошла без ошибок - отмечаем
$this->sent = true;
$this->sent_at = time();
$this->save();
return null;
}
Заодно это убирает задержку на отправку писем при комментировании.
В будущем в эту табличку уведомений можно добавить и другие события, например вас добавили в избранное, лайкнули, или что-то такое.
Оставляем комментарии к заметке, тестируем новый функционал!
0
👍
👎
❤️
🔥
😮
😢
😀
😡
259
19.02.2023, 10:59:05
2 комментария
Александр Наумов
19.02.2023, 15:20:50
Класс, я даже бы не додумался, что с простыми уведомлениями можно сделать что-то еще и так их прокачать!
С другой стороны такие продвинутые уведомления снизят трафик ))
Василий Наумкин
19.02.2023, 19:49:27
Не такая уж тут активность в комментриях, чтобы что-то снижать - а удобнее будет, в первую очередь мне самому.
bezumkin.ru
Личный сайт Василия Наумкина
Прямой эфир
Василий Наумкин
23.12.2024, 05:33:00
В MODX сначала создали проблему, автоматически генерируя адреса, а потом "решили" заморозкой.
Так ч...
Дмитрий
14.12.2024, 09:10:38
Василий, прошу прощения, тупанул, не разобрался сразу. Фреймворк отличный! "Чистый лист" на vue, рис...
Василий Наумкин
05.12.2024, 20:01:14
В итоге основная ошибка была в неправильном общем root в Nginx, из-за чего запросы не улетали на фай...
Василий Наумкин
01.07.2024, 11:56:41
Да, верно, именно так.
А в контроллере, скорее всего, ловить данные методом post.
Василий Наумкин
26.06.2024, 09:38:15
О, точно, вылезает если не залогинен.
Спасибо, исправил!
Василий Наумкин
09.04.2024, 04:45:01
> Ошибка 500
Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи.
...
Уровни подписки
Спасибо!
500 ₽ в месяц
Эта подписка ничего не даёт, просто возможность сказать спасибо за мои заметки. Подписчики отмечаются зелёненьким цветом в комментариях.
Большое спасибо!
1 000 ₽ в месяц
И эта подписка не даёт ничего, кроме оранжевого цвета в комментариях и возможности сказать спасибо, но уже большое!