У вас бывало такое, что вы приходите в кино и смотрите трейлеры перед началом фильма, при этом некоторые из них цепляют вас достаточно сильно и вы даете себе обещание посмотреть этот фильм если не в кинотеатре, то хотя бы позже, когда он станет доступен для скачивания? Смею предположить, что да. Но часто заканчивается это тем, что вы успешно забываете про это и, в лучшем случае, случайно находите этот фильм пролистывая список уже вышедших фильмов.
Я достаточно часто сталкивался с такой проблемой и решил ее созданием Eve — Telegram-бота, который помогает мне не забывать про релизы моих любимых фильмов. Что это, как оно работает и как разрабатывалось вы можете почитать под катом!
- Предисловие
- Зачем?
- Выбор технологий
- Telegraf.js
- Структура проекта
- Инициализация и запуск
- Обрабатываем пользовательский ввод
- Локализация
- Заключение
Предисловие
Node JS da Telegram Bot (Telegraf JS) | Genemator
Данная статья не является подробным гайдом по созданию Telegram-ботов. И хотя по ходу статьи я буду достаточно часто ссылаться на свой проект, целью данного материала является рассказ про разработку в общем, а именно выбор технологий, ключевые моменты и подводные камни, с которыми я столкнулся.
Зачем?
Итак, как я написал выше, я достаточно часто забываю посмотреть те фильмы, трейлер которых мне понравился. Я долго думал над решением этой проблемы. Первое, что пришло мне в голову — создание нативного приложения для смартфонов, но т.к. я никогда не занимался этим раньше, это заняло бы достаточно много времени и не факт, что конечный результат удовлетворял бы мои потребности, а также потребности потенциальных пользователей.
Следующей идеей было создание PWA. Вполне себе интересный вариант для того, чтобы познакомиться с технологией, но ее я решил оставить на будущее. В то же самое время я достаточно давно пользуюсь Telegram и за все это время у меня скопилось достаточное количество ботов, которые периодически делают мою жизнь немного проще. В конечном счете взвесив все плюсы и минусы, я решил, что данная платформа отлично подойдет для данной идеи.
Выбор технологий
Если прошерстить Github на предмет наличия Telegram-ботов, то можно увидеть, что большая часть из них написана на Python. Python действительно замечательный язык и отлично подходит для данной идеи, но мне хотелось реализовать данный проект именно на NodeJS + TypeScript. Применив соответствующие фильтры я наткнулся на 2 достаточно популярных инструмента: node-telegram-bot-api и Telegraf.js.
До этого опыта разработки ботов у меня не было, поэтому при выборе из этих двух было не совсем понятно на какие параметры следует смотреть. В итоге посмотрев документацию и полистав issues к каждой из библиотек, я остановился на Telegraf.js. Решающим фактором стало наличие механизма middlewares, который устроен таким же образом, как и в популярном фреймворке Express.js. Также Telegraf.js имеет более частую историю обновлений и хорошо структурированную документацию, из чего можно предположить, что разработчики прикладывают достаточно усилий для улучшения инструмента. Более того, он содержит тайпинги для TypeScript, что определенно является плюсом для выбранного стека.
Как создать телеграм бота на JS, Бот на Telegraf и деплой на Heroku
Telegraf.js
Telegraf.js — основная библиотека, на которой был написан проект. Она использует несколько интересных подходов, которые позволяют создавать сложных ботов с сохранением простоты кода. Ниже представлены наиболее интересные механизмы:
- Middlewares — да, это те же самые middlewares, которые доступны в Express.js. Когда пользователь что-то отправляет боту, сообщение вначале проходит через все зарегистрированные middlewares, а уже после попадает в контроллер. Middlewares могут модифицировать контекст, а также приостанавливать выполнение запроса, например, если обычный пользователь попытается попасть в область для администраторов. Telegraf.js предоставляет несколько крайне полезных middlewares «из коробки», но также можно использовать и разработанные лично. Именно middlewares считаются киллер-фичей Telegraf.js
- Sessions — сессии, которые могут хранить в себе информацию, не привязанную к контроллеру. Можно привести аналогию с глобальными переменными, которые доступны из любого места в боте. Очень удобная вещь, которая используется, например, для локализации. Есть возможность хранить сессии в разных режимах — БД, redis, локальные файлы и т.д.
- Webooks — бот может работать в двух режимах — long polling или Webhooks. И хотя работают они одинаково быстро, все же в production среде лучше использовать второй вариант. Таким образом, боту не нужно будет стучаться на сервер Telegram, вместо этого он сам будет получать все обновления.
bot.hears(‘hello’, async ctx => < await ctx.reply(‘Hello!’); >);
Работает это просто: если написать боту hello, то он просто ответит Hello! Зная этот аспект работы, попробуем представить, как может работать бот для поиска фильмов:
- Пользователь пишет, что хочет перейти к поиску фильмов;
- Пользователь вбивает название фильма;
- Бот возвращает список фильмов и предлагает пользователю сохранить выбранный фильм в свою библиотеку;
- .
Да, можно любой присланный текст принимать за название фильма, но мы же хотим сделать бота с блэкджеком и путанами хорошим интерфейсом.
Структура проекта
Есть подозрение, что статья получится достаточно объемной, а потому, чтобы не растягивать ее еще больше, я опущу некоторые моменты. Например, чтобы бот начал работать, необходимо начать с получения Telegram Bot API token. Прочитать о том, как это сделать, можно в официальной документации Telegram или же в документации к Telegraf.js.
Файловая структура проекта выглядит следующим образом:
Структура проекта
Работает это следующим образом:
- src/controllers — это и есть те самые сцены, про которые было написано выше. В данном проекте каждая сцена представляет из себя отдельный контроллер, который занимается обработкой соответствующих запросов.
- src/locales — переводы для разных языков. Telegraf.js позволяет относительно просто добавить локализацию к боту с использованием middlewares.
- src/models — модели для MongoDB.
- src/types — тайпинги для TypeScript. К сожалению, не все используемые в проекте библиотеки имеют тайпинги по умолчанию.
- src/util — различные функции-помощники, которые используются в разных частях проекта. Здесь можно посмотреть как работает проверка доступности фильма для скачивания, управление сессиями, создание клавиатур, обработчики ошибок и еще много всего интересного.
- src/bot.ts — главный файл, где производится вся подготовка и запуск бота.
- src/telegram.ts — в данном случае мы создаем объект класса Telegram из библиотеки Telegraf.js. С помощью этого объекта мы можем отправлять пользователям сообщения первыми, используя их ID, а не ждать, пока они что-то напишут. Например, в данном проекте мы отправляем пользователю сообщение о том, что фильм, за которым он следил, уже можно скачать. Конечно же, данный объект предоставляет гораздо больше возможностей.
- Все остальное — конфигурации для разных частей проекта, которые не будут рассмотрены в этой статье
Инициализация и запуск
Когда мы разобрались со структурой проекта, давайте посмотрим, как собственно происходит запуск бота. Опять же, в целях сокращения статьи я не буду вставлять сюда код целиком, а расскажу лишь про главные, на мой взгляд, моменты. Полный код вы можете посмотреть в репозитории, ссылка на который доступна в конце статьи.
Начинается все с подключения к БД, где хранится информация о пользователях и отслеживаемых ими фильмах. После успешного подключения мы регистрируем все используемые в проекте сцены, задаем параметры для локализации и добавляем несколько middlewares — обработку сессий, локализацию, настройку сцен, а также несколько собственных. Одна из них, например, получает всю информацию о пользователе в соответствии с его ID и добавляет ее к контексту, который используется в контроллерах. Наконец, после всех основных приготовлений, мы запускаем бота либо в development (long polling), либо в production (Webhooks) режиме.
Важно: если вы используете разные методы получения обновлений (long polling и Webhooks), то при запуске бота в режиме long polling сперва удалите слушающий Webhook с помощью GET запроса на api.telegram.org/botYOUR_TOKEN/deleteWebhook. В противном случае бот может работать неправильно.
Обрабатываем пользовательский ввод
Ура! Бот работает, подключен к базе данных и готов принимать сообщения от пользователей. Но как правильно это сделать?
В первую очередь, пользователям будет удобно пользоваться встроенной Telegram-клавиатурой. По сути, при нажатии на кнопки этой клавиатуры отправляются сообщения с содержимым этих кнопок. Дальше мы просто добавляем обработчики этого текста и выполняем определенные действия.
В файле bot.ts как раз стоят такие обработчики. Так как бот поддерживает два языка, то и кнопки могут содержать разный текст — на русском и английском языках. В telegraf-i18n есть функция match, которая умеет обрабатывать нажатие одной и той же кнопки с разными языками.
Большинство обработчиков в bot.ts выполняют единственную функцию — они запускают пользователя в соответствующую сцену. Так, у нас есть несколько разделов — поиск фильмов, моя коллекция, настройки и контакты. Для каждого из разделов есть своя сцена и своя кнопка, при нажатии на которую пользователь перемещается в соответствующую сцену.
Важно: обязательно добавьте обработчик, который будет выпускать пользователя из сцены, иначе они рискуют остаться там навсегда! Также полезным будет сделать одну общую команду (в боте используется /saveme), которая будет добавлена в каждую сцену и в главный файл. Эта команда будет служить выходом из любой сцены, а также сбрасывать пользовательские настройки.
И вот, пользователь хочет перейти к поиску фильмов. Нажатием на соответствующую кнопку мы перемещаем его в сцену поиска. Для удобства, у каждой сцены есть своя папка с файлами, каждый из которых выполняет определенную функцию.
Внутри сцены можно использовать свои middlewares, которые лежат в файле middlewares.ts. Например, используя middleware в сцене поиска, мы можем достаточно просто пробросить всю информацию о фильме в соответствующие методы, а не выполнять одну и ту же функцию каждый раз внутри них.
В Telegram также есть inline-клавиатура. Возможно вы встречали сообщения с голосованиями, под которыми есть несколько полупрозрачных кнопок и при нажатии на одну из них количество голосов меняется. Эти кнопки и есть inline-клавиатура
Вот как это выглядит у Eve
В каждой кнопке содержится информация, при нажатии на кнопку она будет передана в соответствующий обработчик. Размер передаваемой информации не должен превышать 64 байта! Чтобы научить бота слушать нажатия на кнопки, нам нужно зарегистрировать их с помощью bot.action(/trigger/, callback). В первый параметр попадают все данные, которые были привязаны к кнопке.
Я решил использовать нечто вроде Actions из Redux, где к каждой кнопке привязан объект вида . При регистрации listeners мы можем использовать простой RegExp, например: bot.action(/actionName/, callBack). Все обработчики для inline-клавиатуры находятся в файлах actions.ts.
Помимо этого, в некоторых сценах лежат файлы helpers.ts, которые содержат в себе небольшие функции вынесенные туда с целью разгрузить остальные файлы. По большей части там лежат генераторы клавиатур для разных действий со стороны пользователя.
Локализация
Так как это важная тема, я думаю ее стоит упомянуть отдельно. Как я говорил ранее, Telegraf.js содержит довольно большое количество middlewares, одной из которых является telegraf-i18n. В репозитории присутствует подробная инструкция и особых проблем у меня с этим не возникло, но все же я добавлю пару слов о том, как это работает в данном проекте.
Есть папка locales, где лежат файлы для локализации, которые представляют из себя JSON объект вида < «ключ»: «перевод» >. Далее, везде, где нам нужно использовать разные языки, мы используем метод из этой библиотеки, куда передаем нужный нам перевод по ключу, а на выходе получаем соответствующий перевод. Для хранения информации о выбранном пользователем языке может использоваться сессия. Также еще раз стоит упомянуть про кнопки. В этой же библиотеке есть функция match, поэтому если текст на кнопке меняется в зависимости от языка, то эта функция поможет вам повесить правильный listener.
Важно: если вы собираетесь использовать локализацию и писать бота на TypeScript, не забудьте добавить папку с переводами в tsconfig.json, иначе код не скомпилируется. Например:
«include»: [«src/locales/*.json»]
Спасибо что дочитали до конца! В этой статье я постарался максимально подробно описать процесс создания Telegram-бота в целом, без сильной привязки к своему проекту. Я надеюсь, что после прочтения этой статьи, а также изучения исходного кода Eve, вы сможете с легкостью создать бота, который сможет помочь вам.
Как и обещал, исходный код вы можете посмотреть на GitHub, а попробовать Eve в деле вот здесь. Я буду безмерно благодарен за любую критику и предложения по улучшению.
Отдельно хочу отметить раздел в документации Telegraf.js с интересными open source проектами, на которые можно посмотреть и вдохновиться архитектурой и решениями. Я, в свою очередь, хочу отметить один из них — The Guard Bot. Поистине большой и хорошо сделанный бот, откуда я позаимствовал часть решений для своей разработки.
А на данный момент я рассказал все, что хотел, буду рад ответить на ваши вопросы, предложения и комментарии!
Источник: habr.com
Что такое telegraf telegram
В этой статье мы рассмотрим очень такую вещь для автоматизации продаж/общения/…., как telegram bots.
Telegraf – данная тузла написана по всем стандартам JavaScript: асинхронность, поддержка middlewares, поддержка сценариев и прочее.
Чем же примечателен телеграф?
- Поддержка сценариев, сессий.
- Поддержка промежуточных обработчиков (middlewares).
- Красивая, простая реализация, огромное API, которое можно запросто расширять.
Существует огромное кол-во дополнений для этой библиотеки, которые подключаются примерно так:
i18n добавляет поддержку мультиязычности в наших бота, но это все потом, для начала нам нужно изучить основы написания приложений.
Основы
Создаем пустой проект на NodeJs, далее нам нужно создать индексный файл, назовем его index.js.
Добавляем Telegraf в наш проект
Для создания нового инстанса бота, нам нужно создать экземпляр, делается это следующим образом:
Все, бот, вернее его зачатки созданы. Вы прекрасны!
Обработчики
Далее рассмотрим метод для ответа на команду /start
Теперь рассмотрим остальные события, предназначенные для хендла данных юзера:
- bot.hears(regex|string, middlewares) – хендлим текст в чате юзера
- bot.action(regex|string, middlewares) – отвечаем на callbackQuery
- bot.command(regex|string, middlewares) – хендлим /command от юзера
Есть и другие обработчики, но нам пока достаточно этих двух. Теперь предлагаю рассмотреть, как будут работать ответы на примерах, для этого запустим бота командой
bot.startPolling()
Подредактируем стартовый метод, добавив немного кнопок.
Кстати, тоже интересный факт, ежели мы пишем, что я хороший/кликаем на такую кнопку, то благодаря вызову метода next() выполняется сначала первый hears/action, а потом и второй, ежели бы мы его не использовали, то сработал бы лишь первый обработчик.
Предлагаю вам попрактиковаться в таких методах самостоятельно, а мы продолжим.
Сессии
Данная фича позволяет нам сохранять абсолютно любые данные в ОЗУ с привязкой к конкретному юзеру, это очень удобно.
bot.use(session())
Далее рассмотрим использование сессий на старых примерах, немного их подредактировав.
Вот как можно бороться с токсичными людьми и с пассивной агрессией, порождаемой ими
Заметили странный bot.use? Таким образом мы добавляем новый обработчик, который выполняется в первую очередь, он проверяет, токсичен ли наш юзер или нет. В первом случае, сценарий останавливается и дальнейшие обработчики не выполняются, во втором, ничего не меняется и сценарии выполняются как надо.
Сценарии
Это подразделение, как по мне, чуть сложнее, но все же оно очень важно для правильного стиля написания ботов.
Создаем папку scenes и файл сцены в ней, дабы в проекте была красивая структура.
В файл StartScene.js мы поместим сам сценарий, далее предлагаю немного подредактировать index.js, дабы добавить поддержку сцен.
Теперь перейдем к сценарию, что важно знать, сцены позволяют нам разграничивать различные функции бота.
Обработчики тут те же самые, кроме leave и enter. enter – вход в сцену, leave – выход из сцены.
Источник: full-arts.ru