DEV Community

Stanislav Karol
Stanislav Karol

Posted on • Edited on

Телеграм-бот на NodeJS. Автоматическая рассылка.

В этой заметке напишу о том, как я научил бота делать автоматическую еженедельную рассылку. Задача перед ботом такая: Каждую пятницу он бодро должен собрать некий материал, поднимающий настроение и сделать рассылку всем своим подписчикам.
Поэтому задачу можно разделить на три больших блока:

  1. Один раз в неделю собрать информацию
  2. Собрать всех подписчиков
  3. Разослать этим подписчикам информацию.

С первым пунктом на первый взгляд проблем нет: Делаем запрос к некоему сборщику (который никак не связан с ботом), он должен вернуть массив или объект записей для новой рассылки. Проблема в другом: когда и как запускать этот сборщик.
Можно решать задачу "в лоб" - поставить 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 * * ? *)
Enter fullscreen mode Exit fullscreen mode

Здесь говорится о том, что у нас уже есть 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
Enter fullscreen mode Exit fullscreen mode

Здесь говорится, что каждую пятницу, в шесть утра, будет вызываться https://telegram-bot.herokuapp.com/api/sendMail , который отвечает за рассылку.
Мой бот находится не по адресу telegram-bot.herokuapp.com , этот адрес я привёл для примера.
Сейчас текст sendMail приводить не буду, позже, возможно в комментах, дам ссылку на гитхаб. В написании этой функции нужно учитывать особенности serverless functions и помнить, что срок их жизни весьма недолгий. Поэтому у меня там запускаются несколько задач в промисах: сбор подписчиков и сбор материала. Затем, когда Promise.all вернёт мне результаты, запускаю другую службу- рассылки адресатам данных. Таким образом сохраняются требования системы о том, что службы сами по себе работают недолго.

Второй и третий шаги рассылки можно позже подсмотреть в гитхабовских проектах.

Top comments (1)

Collapse
 
slkarol profile image
Stanislav Karol