Разрабатываем Telegram-бота для отслеживания фильмов на NodeJS и TypeScript

  • Главная »
  • NodeJS »
  • Node.JS: Делаем своего Telegram бота

Дата: 06.07.2017 в 17:53, Категория:NodeJS

  • 124459
  • 125 —>

51458248708f4062.png

Если вы открыли чат с ботом, кликаем на кнопку «Start«.

0bd0e571ddf47970.png

После чего, бот нам выдает все доступные команды.

Отправляем команду /newbot или кликаем по активной ссылке этой команды. Далее, бот нас попросить ввести имя для нашего бота.

Можете не париться с именем и вписать любое тестовое имя. Плюс в том, что вы в любой момент сможете удалить тестового бота или поменять имя.

Я решил во время статьи создать бота для этого блога и назвал его «Archakov Blog«.

На последнем этапе, бот попросит вас придумать никнейм (логин). К никнейму в конце обязательно надо добавить суффикс «bot» можно и «Bot«. К сожалению, никнейм поменять больше не получится. Если это ваш первый бот, не парьтесь и придумайте любой никнейм.

В итоге, получаем сообщение о том, что бот был создан и в конце будет указан его токен. Этот токен нам пригодится в процессе разработки.

Не советую делиться токеном с другими людьми. Так как он дает полный доступ к вашему боту. Начиная от редактирования имени и до удаления бота.

Теперь приступим к написанию кода и первым делом установим Node.JS. У меня OS X и хочу предупредить, что от операционной системы не будет зависеть разработка нашего бота.

Как установить Node.JS рассказывать я не хочу и не буду. Для этого обращаемся к гугл с запросом как установить Node.JS.

После того, как установили Node.JS, начинаем разрабатывать наше приложение, а точней бота. Node.JS ищет в каждой папке наличие папки node_modules с модулями, откуда он и будет подключать библиотеку для работы с Telegram API.

Советую поучиться работать с npm командой в консоли. Заранее установите этот менеджер пакетов, он нам скоро пригодится. Кстати, очень крутая и полезная штука, в будущем пригодится. Особенно, когда наступит апокалипсис, будете сидеть и пакеты устанавливать…

Создаем папку с тестовым проектом, к примеру telegram-bot. Далее, в этой папке создаем файл index.js и все! Вы красавчик! Бот создан, можете работать с ним.

Ага, канешна. Код сам не напишется!

Прежде чем его и писать, установим модуль node-telegram-bot-api. Для этого открываем консоль, пропишем путь к директории нашего проекта cd telegram-bot (укажите полный путь к этой папке).

В моем случае, это cd /Applications/MAMP/htdocs/telegram-bot.

Если вы на Windows, советую создавать папку в корне диска, чтобы можно было обращаться к проекту по короче, к примеру cd C:telegram-bot.

Отлично, теперь не забываем про npm. В консоли вбиваем команду: npm install node-telegram-bot-api или yarn add node-telegram-bot-api (в зависимости от того, что вы используете yarn или npm).

И через несколько секунд модуль установился. Ура! В репозитории уже есть пример кода и с помощью этого кода, сделаем своего мега-тру-бота.

Теперь перейдем к файлу index.js и напишем немного кода.

// Подключаем библиотеку для работы с Telegram API в переменную var TelegramBot = require('node-telegram-bot-api');  // Устанавливаем токен, который выдавал нам бот var token = 'ТУТ_ВСТАВЛЯЕМ_ТОКЕН'; // Включить опрос сервера. Бот должен обращаться к серверу Telegram, чтобы получать актуальную информацию // Подробнее: https://core.telegram.org/bots/api#getupdates var bot = new TelegramBot(token, { polling: true });  // Написать мне ... (/echo Hello World! - пришлет сообщение с этим приветствием, то есть "Hello World!") bot.onText(//echo (.+)/, function (msg, match) {     var fromId = msg.from.id; // Получаем ID отправителя     var resp = match[1]; // Получаем текст после /echo     bot.sendMessage(fromId, resp); });  // Простая команда без параметров bot.on('message', function (msg) {     var chatId = msg.chat.id; // Берем ID чата (не отправителя)     // Фотография может быть: путь к файлу, поток (stream) или параметр file_id     var photo = 'cats.png'; // в папке с ботом должен быть файл "cats.png"     bot.sendPhoto(chatId, photo, { caption: 'Милые котята' }); });

В начале кода мы подключили модуль (библиотеку) для работы с Telegram API. Далее, в переменной token вставляем наш токен, который выдавал нам BotFather при создании нашего бота.

Работа с командами очень простая и понятная. Советую немного потренироваться еще с регулярными выражениями, правильно составлять команду по маске. Данный модуль содержит кучу полезных методов. Прочтите документацию в репозитории этого модуля.

Давайте в качестве моего примера, попробуем сделать напоминалку важных дел. Конечно, пример не ахти, но кому-нибудь будет полезно.

Подключаем модуль для работы с Telegram API и прописываем токен:

var TelegramBot = require('node-telegram-bot-api');  var token = 'ТУТ_ВСТАВЛЯЕМ_ТОКЕН'; var bot = new TelegramBot(token, {polling: true});

Далее, создаем переменную в которой будут храниться все заметки от пользователя.

var notes = [];

Добавляем команду /напомни, с помощью которой и будем добавлять напоминание.

bot.onText(/напомни (.+) в (.+)/, function (msg, match) {     var userId = msg.from.id;     var text = match[1];     var time = match[2];      notes.push({ 'uid': userId, 'time': time, 'text': text });      bot.sendMessage(userId, 'Отлично! Я обязательно напомню, если не сдохну :)'); });

</pre></pre></pre>

  • userId — хранит ID пользователя который прислал сообщение.
  • text — хранит первый параметр — текст. Его бот и должен прислать мне.
  • time — хранит второй параметр — время. Устанавливаем время когда прийдет уведомление.

Сохраняем все эти параметры в наш массив notes и бот отправляет сообщение, что запись успешно сохранилась.

Теперь надо поставить таймер, он будет каждую секунду проверять записи, которые совпадают с конкретным временем. Если одно из напоминаний соответствует настоящему времени (часу и минуте), то отправляем пользователю напоминание.

</ul>

setInterval(function(){     for (var i = 0; i < notes.length; i++) {     const curDate = new Date().getHours() + ':' + new Date().getMinutes();     if (notes[i]['time'] === curDate) {       bot.sendMessage(notes[i]['uid'], 'Напоминаю, что вы должны: '+ notes[i]['text'] + ' сейчас.');       notes.splice(i, 1);     }   } }, 1000);

Чтобы вы поняли как работает код выше, я нарисовал схему:

Итого:

var TelegramBot = require('node-telegram-bot-api');  var token = 'ТУТ_ВСТАВЛЯЕМ_ТОКЕН'; var bot = new TelegramBot(token, {polling: true});  var notes = [];  bot.onText(/напомни (.+) в (.+)/, function (msg, match) {     var userId = msg.from.id;     var text = match[1];     var time = match[2];      notes.push({ 'uid': userId, 'time': time, 'text': text });      bot.sendMessage(userId, 'Отлично! Я обязательно напомню, если не сдохну :)'); });  setInterval(function(){     for (var i = 0; i < notes.length; i++) {     const curDate = new Date().getHours() + ':' + new Date().getMinutes();     if (notes[i]['time'] === curDate) {       bot.sendMessage(notes[i]['uid'], 'Напоминаю, что вы должны: '+ notes[i]['text'] + ' сейчас.');       notes.splice(i, 1);     }   } }, 1000);

Сохраняем наш скрипт, я назвал reminder.js. Запускаем его через консоль, командой node reminder.js

В итоге, я получил свое ожидаемое напоминание.

Спасибо за внимание. Не ленитесь учить JavaScript, за ним будущее веб и в частности всей галактики! Так же, выкладываю полный файл reminder.js.

</pre></pre>

ПОДПИШИСЬ НА ОБНОВЛЕНИЯ

Только новые публикации и никакого мусора.

  • Tutorial

С полным кодом можно ознакомиться по ссылке. Сегодня мы будем разрабатывать телеграм бота на node js, который умеет выводить статистику зараженных коронавирусом по всем странам. Прежде всего в контакт-лист телеграмма нужно добавить @botFather и написать ему команду /newBot. Далее задаем имя нашего бота и, если оно не занято, придумываем идентификатор бота, по которому его можно будет найти. Вот и все, наш телеграмм бот готов и botfather поделился с нами API Token, благодаря которому мы сможем управлять ботом Далее создадим новый проект, введем npm init и добавим файл bot.js в котором будет разрабатываться наш бот. Затем я установлю telegraf — это один из популярных фреймворков для создания телеграмм бота. Смотрим документацию телеграфа, копируем в наш проект первоначальную настройку бота и быстро пройдемся по всем методам, которые указаны в примере:

const { Telegraf } = require('telegraf') const bot = new Telegraf(process.env.BOT_TOKEN) //сюда помещается токен, который дал botFather bot.start((ctx) => ctx.reply('Welcome')) //ответ бота на команду /start bot.help((ctx) => ctx.reply('Send me a sticker')) //ответ бота на команду /help bot.on('sticker', (ctx) => ctx.reply('')) //bot.on это обработчик введенного юзером сообщения, в данном случае он отслеживает стикер, можно использовать обработчик текста или голосового сообщения bot.hears('hi', (ctx) => ctx.reply('Hey there')) // bot.hears это обработчик конкретного текста, данном случае это - "hi" bot.launch() // запуск бота

Поместим api token в наш пример и запуcтим бота.

node bot

Проверим работу нашего бота: Теперь разберемся что лежит в ctx Для этого после объявления константы bot мы можем использовать log:

ctx.message.from.first_name

Перезапустим наш проект, введем команду /start и в консоли мы получим объект, в котором мы сможем посмотреть необходимые данные о юзере:

{  "update_id": 375631294,  "message": {    "message_id": 11,    "from": {      "id": 222222,      "is_bot": false,      "first_name": "Женя",      "username": "Evgenii",      "language_code": "ru"    },    "chat": {      "id": 386342082,      "first_name": "Женя",      "username": "Evgenii",      "type": "private"    },    "date": 1593015188,    "text": "/start",    "entities": [      {        "offset": 0,        "length": 6,        "type": "bot_command"      }    ]  } }

Нас будет интересовать объект message, из которого мы сможем достать имя юзера

ctx.message.from.first_name

И текст, который он отправил боту:

ctx.message.text

Мы знаем что лежит в ctx и теперь мы можем приступить к подключению стороннего api, с помощью которого мы сможем получать статистику по коронавирусу. Для этого я буду использовать библиотеку, которая называется covid19-api. Установим ее в наш проект и заимпортим в файл bot.js:

const covidApi = require('covid19-api')

Далее мы удалим наш обработчик стикеров и сделаем новый обработчик, который отслеживает текст и отправляет запрос, чтобы получить данные о коронавирусе, используя метод getReportsByCountries, который можно найти в документации covid19-api:

bot.on('text', async ctx => {    const covidData = await covidApi.getReportsByCountries(ctx.message.text) //сюда помещаем сообщение юзера    ctx.reply(covidData) //и выведем полученные данные })

Давайте проверим какие данные мы получим. Для примера напишем нашему боту в телеграме: ‘russia’: Отлично, мы получили целый ряд данных. Но если мы введем название страны с опечаткой наш бот прекратит работать и выдаст ошибку в консоль: Чтобы это избежать нам нужно сделать обработчик ошибок и оповещать юзера, что такой страны не существует. Так же произведем небольшой рефакторинг кода и сделаем нашего бота более дружелюбным, изменим вывод сообщения, которое отправляется по команде /start, настроем корректное отображения данных о статистике и создадим в отдельном файле константу, которая будет содержать список всех стран на английском языке и будем выводить ее при использовании команды /help. В итоге получаем код:

const { Telegraf } = require('telegraf'); const covidApi = require('covid19-api'); const COUNTRIES_LIST = require('./const') const bot = new Telegraf('1170363720:AAFJ4ALJebB8Luh5kt1DStmYYqV3TparhKc') bot.start( ctx => ctx.reply(`    Привет ${ctx.from.first_name}!    Узнай статистику по Коронавирусу.    Введи страну на английском языке и получи статистику.    Получить весь список стран можно по команде /help." `)) bot.help( ctx => ctx.reply(COUNTRIES_LIST)) // список всех стран на английском языке можно взять в документации covid19-api bot.on('text', async (ctx) => {    try {        const userText = ctx.message.text        const covidData = await covidApi.getReportsByCountries(userText)        const countryData = covidData[0][0]        const formatData = `            Страна: ${countryData.country},            Случаи: ${countryData.cases},            Смерти: ${countryData.deaths},            Выздоровело: ${countryData.recovered}`        ctx.reply(formatData)    } catch(e) {        ctx.reply('Такой страны не существует, для получения списка стран используй команду /help')    } }) bot.launch()

Который срабатывает как нам нужно: Поздравляю! Мы завершили настройку нашего телеграм бота, который выводит статистику заболевших коронавирусом.

Предисловие

Данная статья не является подробным гайдом по созданию 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, что определенно является плюсом для выбранного стека.

Telegraf.js

Telegraf.js — основная библиотека, на которой был написан проект. Она использует несколько интересных подходов, которые позволяют создавать сложных ботов с сохранением простоты кода. Ниже представлены наиболее интересные механизмы:

  • Middlewares — да, это те же самые middlewares, которые доступны в Express.js. Когда пользователь что-то отправляет боту, сообщение вначале проходит через все зарегистрированные middlewares, а уже после попадает в контроллер. Middlewares могут модифицировать контекст, а также приостанавливать выполнение запроса, например, если обычный пользователь попытается попасть в область для администраторов. Telegraf.js предоставляет несколько крайне полезных middlewares «из коробки», но также можно использовать и разработанные лично. Именно middlewares считаются киллер-фичей Telegraf.js
  • Sessions — сессии, которые могут хранить в себе информацию, не привязанную к контроллеру. Можно привести аналогию с глобальными переменными, которые доступны из любого места в боте. Очень удобная вещь, которая используется, например, для локализации. Есть возможность хранить сессии в разных режимах — БД, redis, локальные файлы и т.д.
  • Webooks — бот может работать в двух режимах — long polling или Webhooks. И хотя работают они одинаково быстро, все же в production среде лучше использовать второй вариант. Таким образом, боту не нужно будет стучаться на сервер Telegram, вместо этого он сам будет получать все обновления.Важно: обязательным условием для Webhook’ов является поддержка сервером SSL/TLS. Также убедитесь, что порт, на котором запущен Webhook, открыт и доступен извне.
  • Markup — с помощью этого класса можно научить бота отвечать в markup/markdown разметке. Это важно если вы, например, делаете HTML-игру. Тем не менее в своем проекте я использовал его только для bold/italic текста.
  • Stage — крайне интересный модуль, который помог мне сохранить нервы и некоторое количество часов разработки. Здесь я расскажу подробнее. Бот умеет слушать сообщения от пользователя и, в зависимости от типа или содержимого сообщения, перенаправлять его в тот или иной контроллер, который выполнит свою функцию и отправит ответ пользователю. Выглядит это следующим образом:
    bot.hears('hello', async ctx => {   await ctx.reply('Hello!'); }); 

    Работает это просто: если написать боту hello, то он просто ответит Hello! Зная этот аспект работы, попробуем представить, как может работать бот для поиска фильмов:

    1. Пользователь пишет, что хочет перейти к поиску фильмов;
    2. Пользователь вбивает название фильма;
    3. Бот возвращает список фильмов и предлагает пользователю сохранить выбранный фильм в свою библиотеку;

    Внимание, вопрос! Как бот сможет различать, когда пользователь пишет ему, что хочет начать искать фильм, а когда он пишет само название фильма для поиска?Да, можно любой присланный текст принимать за название фильма, но мы же хотим сделать бота с блэкджеком и путанами хорошим интерфейсом. И тут в игру вступают сцены (Stages)! Легче всего будет рассказать на примере выше. Когда пользователь говорит, что хочет перейти к поиску фильмов, мы запускаем сцену. Внутри этой сцены стоят свои отдельные обработчики текста — bot.hears(…). Таким образом, все последующие сообщения будут относиться непосредственно к поиску фильмов до тех пор, пока пользователь не напишет сообщение для выхода и не покинет сцену. После этого обработчики внутри этой сцены деактивируются до тех пор, пока пользователь не вернется туда снова. Далее я расскажу, как я использовал сцены, чтобы сделать обработку событий максимально простой.

Структура проекта

Есть подозрение, что статья получится достаточно объемной, а потому, чтобы не растягивать ее еще больше, я опущу некоторые моменты. Например, чтобы бот начал работать, необходимо начать с получения 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, где к каждой кнопке привязан объект вида {a: actionName, p: payload}. При регистрации 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. Поистине большой и хорошо сделанный бот, откуда я позаимствовал часть решений для своей разработки. А на данный момент я рассказал все, что хотел, буду рад ответить на ваши вопросы, предложения и комментарии!Я начал погружение в мир IT лишь три недели назад. Серьезно, три недели назад я даже не понимал синтаксиса HTML, а знакомство с языками программирования заканчивалось школьной программой по Pascal 10-летней давности. Однако я решился поехать в IT-лагерь, для детей которого было бы неплохо сделать бота. Я решил, что это вряд ли так сложно. С этого начался длинный путь, в рамках которого я:

  • развернул облачный сервер с Ubuntu,
  • зарегистрировался на GitHub,
  • выучил базовый синтаксис JavaScript,
  • прочитал тонну статей на английском и русском языках,
  • сделал, наконец, бота,
  • написал эту статью, наконец.

Выглядел итоговый результат примерно так: Скажу сразу, это статья для начинающих — чтобы просто понять, как делать элементарные вещи с самой нулевой точки. А еще — для продвинутых программистов — просто чтобы их немного посмешить. 1. Как писать код на JS? Я понимал, что стоит для начала хотя бы разобраться в синтаксисе языка. Выбор пал на JavaScript, просто потому что следующим шагом для меня было создание приложения на ReactNative. Я начал с курса на Codecademy и остался в большом восторге. Первые 7 дней бесплатно. Реальные проекты. Рекомендую. Прохождение его заняло порядка 25 часов. На самом деле далекоооо не все из него пригодилось. Вот так примерно выглядит структура курса и подробно первый блок.2. Как зарегистрировать бота? В начале мне очень помогла вот эта статья из блога некоего Арчакова. Он разжевывает самое начало. Но главное, что там есть — это инструкция по регистрации бота. Лучше я не напишу, и поскольку это самая легкая часть, просто напишу суть. Нужно создать бота и получить его API. Это делается через другого бота — @BotFather. Найдите его в telegram, напишите ему, пройдите простой путь и получите (сохраните!) API-ключ (это набор цифр и букв). Он пригодился мне позже.3. Как выглядит код бота? После долгого изучения статей, я понял, что стоит использовать какую-то библиотеку (сторонний код в формате модуля), чтобы не мучаться с изучением API телеграма и созданием с нуля больших кусков кода. Я нашел фреймворк telegraf, который нужно было как-то подключить к чему-то при помощи npm или yarn. Примерно так я понимал тогда, из чего состоит развертывание бота. Смеяться здесь. Я не обижусь. Больше всего при последующем создании бота мне помогли примеры, указанные внизу страницы:3. Как создать собственный облачный сервер за 100 рублей После долгих поисков я понял, что команда ‘npm’ из картинки выше относится к командной строке. Командная строка есть везде, но чтобы получилось ее исполнить, нужно поставить NodePackageManager. Проблема была в том, что программировал я на PixelBook с ChromeOS. Я пропущу здесь большой блок про то, как я познавал Linux — для большинства это пустое и ненужное. Если у вас есть Windows или MacBook, у вас уже есть консоль. Если в двух словах, я поставил Linux через Crostini. Однако в процессе я понял, что для постоянной работы бота (а не только когда у меня включен компьютер) мне нужен облачный сервер. Я выбрал vscale.io Я закинул 100 рублей, купил самый дешевый сервер Ubuntu (см.картинку). 4. Как подготовить сервер для запуска бота После этого я понял, что нужно сделать на сервере какую-то папку, в которую я положу файл с текстом кода. Для этого в консоли (запускать прямо на сайте через кнопку «Открыть консоль») я вбил

mkdir bot

bot — это стало название моей папки. После этого я установил npm и Node.js, что позволит запускать мне потом код из файликов с разрешением *.js

sudo apt update sudo apt install nodejs sudo apt install npm

Очень рекомендую на этом этапе настроить подключение к серверу через свою консоль. Вот инструкция Это позволит работать с сервером напрямую через консоль своего компьютера.5. Как написать код первого бота. А вот теперь просто открытие для меня. Любая программа — это просто строки текста. Их можно вбить куда угодно, сохранить с нужным расширением и все. Ты прекрасен. Я использовал Atom, но реально, можно просто в блокноте стандартном писать. Главное — сохранить потом файл в нужном расширении. Это как написать текст в Word и сохранить. Я сделал новый файл, в который вставил код из примера на странице telegraf и сохранил в файл index.js (вообще не обязательно называть файл так, но так принято). Важно — вместо BOT_TOKEN вставьте свой API-ключ из второго пункта.

const Telegraf = require('telegraf')  const bot = new Telegraf(process.env.BOT_TOKEN) bot.start((ctx) => ctx.reply('Welcome!')) bot.help((ctx) => ctx.reply('Send me a sticker')) bot.on('sticker', (ctx) => ctx.reply('')) bot.hears('hi', (ctx) => ctx.reply('Hey there')) bot.launch()

6. Как закинуть код на сервер через github Теперь мне нужно было закинуть как-то этот код на сервер и запустить его. Для меня это стало челленджем. В итоге, после долгих мытарств я понял, что проще будет создать файл на github, который позовляет обновлять код при помощи команды в консоли. Я зарегал аккаунт на github и сделал новый проект, куда и загрузил файл. После этого мне нужно было понять, как же настроить загрузку файлов с моего аккаунта (открытого!) на сервер в папку bot (если вдруг вы вышли из нее — просто напишите cd bot).7. Как загрузить файлы на сервер через github ч.2 Мне нужно было поставить на сервер программу, которая будет загружать файлы с git. Я поставил git на сервер, вбив в консоль

apt-get install git

После этого мне нужно было настроить загрузку файлов. Для этого я вбил в командную строку

git clone git://github.com/b0tank/bot.git bot 

В итоге все из проекта загрузилось на сервер. Ошибкой на данном этапе было, что я, по сути, сделал вторую папку внутри уже существующей папки bot. Адрес до файла выглядел как */bot/bot/index.js Я решил пренебречь этой проблемой. И чтобы подгрузить библиотеку telegraf, которую мы запрашиваем в первой строке кода, вбейте в консоль команду.

npm install telegraf

8. Как запустить бота Для этого, находясь в папке с файлом (чтобы переходить из папки в папку через консоль — выполняйте команду формата cd bot Чтобы убедиться, что вы там, где нужно можно вбить команду, которая отобразит в консоли все файлы и папки, которые там лежат ls -a Для запуска я ввел в консоль

node index.js 

Если нет никакой ошибки — все хорошо, бот работает. Ищите его в телеграме. Если ошибка есть — применяйте свои знания из 1 пункта.9. Как запустить бота в фоновом режиме Достаточно быстро вы поймете, что бот работает только тогда, когда вы сами сидите в консоли. Чтобы решить эту проблему я использовал команду

screen

После этого появится экран с каким-то текстом. Это значит, что все хорошо. Вы на виртуальном сервере на облачном сервере. Чтобы понять лучше, как это все работает — вот статья. Просто заходите в свою папку и вбивайте команду по запуску бота

node index.js

10. Как работает бот и как расширить его функционал Что же умеет наш бот из примера? Он умеет

bot.start((ctx) => ctx.reply('Welcome!'))

говорить «Welcome!» в момент старта (попробуйте поменять текст)

bot.help((ctx) => ctx.reply('Send me a sticker'))

в ответ на стандартную команду /help отправлять сообщение «Send me a sticker»

bot.on('sticker', (ctx) => ctx.reply(''))

в ответ на стикер отправлять одобрение

bot.hears('hi', (ctx) => ctx.reply('Hey there'))

отвечать «Hey there», если ему пишут ‘hi’ bot.launch() Если вы посмотрите код на github, то быстро поймете, что сильно далеко от этого функционала я не ушел. Что активно используется, так это функция ctx.replyWithPhoto Она позволяет отправлять заданное фото или gif в ответ на определенный текст. Значимая часть кода была написана детьми 11-13 лет, которым я дал доступ к боту. Они ввели свои user-case. Думаю, легко определить, какая часть сделана была ими. Например, на сообщение «джейк» приходит гифка с известным персонажем из мультика Adventure Time. Чтобы развивать бота дальше, подключать клавиатуру нужно смотреть примеры, например, отсюда11. Как обновлять код и перезапускать бота Не забывайте, что надо обновлять код не только на github, но и на сервере. Делать это просто — стопим бота (нажать ctrl+c), — вводим в консоль, находясь в целевой папке, git pull — вновь запускаем бота командой node index.jsEND Многие вещи, описанные в этом файле, будут супер очевидны для продвинутых программистов. Однако когда я сам пытался одним махом перепрыгнуть пропасть до мира ботов, мне очень не хватало подобного гайда. Гайда, в котором не пропускается очевидные и простые для любого IT-специалиста вещи. В дальнейшем я планирую пост про то, как сделать свое первое приложение на ReactNative в таком же стиле, подписывайтесь!Используемые источники:

  • https://archakov.im/post/telegram-bot-on-nodejs.html
  • https://habr.com/ru/post/510760/
  • https://habr.com/post/443876/
  • https://habr.com/post/447006/

Оцените статью
Рейтинг автора
5
Материал подготовил
Илья Коршунов
Наш эксперт
Написано статей
134
Добавить комментарий