В этой заметке напишу о том, как я научил бота делать автоматическую еженедельную рассылку. Задача перед ботом такая: Каждую пятницу он бодро должен собрать некий материал, поднимающий настроение и сделать рассылку всем своим подписчикам.
Поэтому задачу можно разделить на три больших блока:
- Один раз в неделю собрать информацию
- Собрать всех подписчиков
- Разослать этим подписчикам информацию.
С первым пунктом на первый взгляд проблем нет: Делаем запрос к некоему сборщику (который никак не связан с ботом), он должен вернуть массив или объект записей для новой рассылки. Проблема в другом: когда и как запускать этот сборщик.
Можно решать задачу "в лоб" - поставить setInterval или setTimeout и вызывать некую веб-службу, может даже обращаться к api-методу. Но здесь есть очевидный минус: При обновлении скриптов или перезапуска сервера или как в случае с некими популярными хостингами, использующими serverless computing наше приложение после бездействия выключится и таймеры с интервалами исчезнут.
Поэтому первый пункт я советую делать не на уровне NodeJS, а на уровне сервера и помогут нам в этом знания настройки cron'a. Если не знаете, как настраивать, то спросите примеры у гуру или на каком-нибудь другом ресурсе.
Если Ваш бот развёрнут на AWS, то можно написать к примеру такую конфигурацию в файле serverless.yml :
# Каждый день в шесть утра запустить рассылку
sendMail:
handler: handler.sendMail
events:
- http:
path: sendMail
method: post
cors: true
# Запускать эту функцию каждый день в 6 утра (время местное у сервера)
- schedule: cron(0 6 * * ? *)
Здесь говорится о том, что у нас уже есть POST-метод sendMail на нашем сервере и мы хотим его запускать каждый день в шесть утра.
У меня бот развёрнут на heroku и там нет этих возможностей, зато справка heroku говорит, что можно воспользоваться GitHub Actions. В проекте на гитхабе создал каталог .github/workflows , в нём файл manualPOST.yml
name: Cron for friday mailing
on:
schedule:
- cron: "0 6 * * 5"
jobs:
cron:
runs-on: ubuntu-latest
steps:
- name: Call friday sheduler
run: curl -X POST https://telegram-bot.herokuapp.com/api/sendMail
Здесь говорится, что каждую пятницу, в шесть утра, будет вызываться https://telegram-bot.herokuapp.com/api/sendMail , который отвечает за рассылку.
Мой бот находится не по адресу telegram-bot.herokuapp.com , этот адрес я привёл для примера.
Сейчас текст sendMail приводить не буду, позже, возможно в комментах, дам ссылку на гитхаб. В написании этой функции нужно учитывать особенности serverless functions и помнить, что срок их жизни весьма недолгий. Поэтому у меня там запускаются несколько задач в промисах: сбор подписчиков и сбор материала. Затем, когда Promise.all вернёт мне результаты, запускаю другую службу- рассылки адресатам данных. Таким образом сохраняются требования системы о том, что службы сами по себе работают недолго.
Второй и третий шаги рассылки можно позже подсмотреть в гитхабовских проектах.
Top comments (1)
Репозиторий