Привет, Хабр! Эту статью написал Тарас Голомозый, fullstack web-разработчик и преподаватель в школе программирования Эльбрус Буткемп. Хотя про ботов рассказано уже немало, эта тема по-прежнему интересует начинающих разработчиков, — и опыт наших студентов это подтверждает. Позволим себе написать еще одну инструкцию по созданию простого бота на JavaScript с возможностью расширения функционала. В базовом варианте его задача — показывать текущую погоду по геолокации пользователя.

Пару слов ��б уровне знаний, на который рассчитан этот текст. Для создания бота достаточно иметь базовое представления о JavaScript, а также знать, как работает API. Перед началом работы нужно установить библиотеку telegraf.js, которая работает на базе официального API Telegram, и библиотеку для выполнения HTTP-запросов (например, axios).
Шаг первый: базовый функционал
Откроем редактор кода и инициализируем проект через терминал с помощью команды npm -y. После этого в проекте появится файл package.json. Теперь мы можем добавить все необходимые библиотеки командой npm i, после которой через пробел прописываются названия необходимых нам библиотек. Все названия можно посмотреть в документации: в этом примере это будут telegraf и axios.
Стоит отметить, что API погоды отдельно устанавливать не нужно — она работает по архитектуре клиент-сервер, что позволяет просто отправлять запросы и получать ответы.
Пока устанавливаются библиотеки, можно прочитать документацию к ним. У telegraf.js есть несколько примеров готового бота. Можно взять первый пример и посмотреть, как он работает.
Для этого создадим новый файл с именем bot.js и добавим в него следующий код:
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();
// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));В package.json пропишем стартовый скрипт для этого файла. Для этого в разделе scripts добавим новый пункт со следующим содержанием:
"start": "node bot.js"Если мы запустим проект в терминале командой npm start, то увидим сообщение ”Bot token is required”. Получить токен можно через Telegram BotFather — официального бота мессенджера, который создает другие боты и управляет ими. В интерфейсе выбираем /start, затем — /newbot, и следом задаем имя и адрес. В этой инструкции это будет elbrusbootcampweatherbot.
После этого BotFather пришлет сообщение с токеном и ссылкой на бот. Копируем токен и вставляем его в третью строчку примера:
const bot = new Telegraf(process.env.BOT_TOKEN);Для проверки находим бота в поиске в Telegram по имени. Теперь бот запускается, но пока не выполняет никаких полезных функций. Чтобы разобраться, что именно нужно добавить, построчно разберем код из примера.
Первая строка отвечает за п��дключение библиотеки telegraf, которая непосредственно взаимодействует с API Telegram и позволяет нам использовать определенные методы для работы с ботом. В следующей строке создаем нового бота и указываем ключ доступа к нему.
Далее указано, как бот будет реагировать на различные команды: при нажатии /start он отправит сообщение welcome, при отправке стрикера — эмодзи и так далее. Последние две строчки нужны для того, чтобы выполнение ботом команд правильно завершалось в облачных сервисах.
Другие методы кроме /start нам не понадобятся, поэтому их можно смело удалить:
const { Telegraf } = require('telegraf');
const bot = new Telegraf(process.env.BOT_TOKEN);
bot.start((ctx) => ctx.reply('Welcome'));
bot.launch();
// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));Добавим собственные методы: при отправке геолокации бот отвечает актуальном прогнозом погоды для этой территории. Первым делом напишем обработчик, который будет принимать сообщение от пользователя и выводить его в консоль.
bot.on ('message',(ctx) => {
console.log('ctx.message');
} )Теперь при отправке боту геолокации в консоли мы увидим объект location, в котором содержится широта и долгота. Добавим проверку: если в сообщении пользователя содержится объект location, данные из него отправляются на сервер через API агрегатора прогнозов погоды.
bot.on ('message',(ctx) => {
if('ctx.message.location'){
console.log('ctx.message.location');
} )Шаг второй: подключаем API
Как и в предыдущем случае, используем пример из официальной документации OpenWeather. Нам нужно обратиться на специальный адрес и передать туда широту, долготу и API-ключ. В ответ мы получим текущую погоду.
Вставим пример в код, используя результат проверки ctx.message.location с указанием широты и долготы:
bot.on('message', (ctx) => {
if (ctx.message.location) {
const weatherAPIUrl = `https://openweathermap.org/data/2.5/weather?lat=${ctx.message.location.latitude}&lon=${ctx.message.location.longitude}&appid=439d4b8O4bc8187953eb36d2a8c26a02`;
}
});API-ключ можно создать в личном кабинете на сайте OpenWeather. Ключ указывается как параметр appid.
Следующим шагом нужно обратиться по адресу, предоставленному OpenWeather, и получить данные. Для этого используем библиотеку axios. Функция для подключения библиотеки указана в ее официальной документации и выглядит следующим образом:
const axios = require('axios');Поскольку все операции со сторонним сервером выполняются асинхронно, добавим async и await в метод bot.on:
bot.on('message', async (ctx) => {
if (ctx.message.location) {
const weatherAPIUrl = `https://openweathermap.org/data/2.5/weather?lat=${ctx.message.location.latitude}&lon=${ctx.message.location.longitude}&appid=439d4b8O4bc8187953eb36d2a8c26a02`;
const response = await axios.get(weatherAPIUrl);
}
});Теперь при отправке боту геолокации в консоли мы увидим информацию о погоде в текущем месте расположения пользователя. Остается только сформировать сообщение, которое бот отправит пользователю в качестве ответа. В тексте укажем название района и температуру в градусах Цельсия:
ctx.reply(`${response.data.name}: ${response.data.weather[0].main} ${response.data.main.temp} °C`);Заключение
На этом все: итоговый код проекта можно найти в репозитории на GitHub.
При желании можно указать дополнительные параметры, которые бот будет выводить в сообщении. Например, облачно на улице или солнечно, есть осадки или нет и другие. Также к боту можно подключить переводчика и переводить состояние погоды на русский язык.
