Бортовой журнал
Бортовой журнал

Чат-боты давно перестали быть просто развлечением — сегодня они помогают компаниям автоматизировать сервис, а пользователям экономить время. Один из самых удобных способов создать собственного бота — использовать Node.js. Этот инструмент позволяет быстро запускать проекты, легко подключать нужные библиотеки и работать с популярными платформами вроде Telegram.

В этой статье разберемся, как с нуля написать простого телеграм-бота на Node.js, какие инструменты для этого понадобятся и на что обратить внимание в процессе разработки.

Зачем создавать бота на Node.js

Node.js — один из самых популярных инструментов для разработки ботов, и на это есть несколько причин:

  • Высокая скорость работы. Node.js построен на движке V8 от Google, что позволяет обрабатывать запросы пользователей быстро и без задержек. Для ботов это особенно важно, так как они должны отвечать мгновенно.
  • Асинхронная обработка. Благодаря неблокирующей архитектуре Node.js способен одновременно обрабатывать множество запросов. А значит, бот сможет работать стабильно даже при высокой нагрузке.
  • Большое количество готовых библиотек. В экосистеме Node.js есть десятки модулей для работы с разными мессенджерами (включая Telegram и WhatsApp), а также для интеграций с API и базами данных. Это ускоряет разработку и позволяет сосредоточиться на логике бота, а не на рутинных задачах.
  • Кроссплатформенность. Бот на Node.js легко запускается на любой системе: и на локальном компьютере, и на облачном сервере.
  • Активное сообщество. Node.js поддерживает большое сообщество разработчиков, поэтому для большинства задач можно найти готовые решения, документацию или примеры.

В каких случаях бот полезнее, чем приложение или сайт

Боты не заменяют приложения и сайты полностью, но во многих ситуациях они оказываются более удобным и быстрым решением:

  • Быстрый доступ к информации. Пользователю не нужно устанавливать приложение или искать сайт — достаточно открыть привычный мессенджер и написать боту.
  • Минимальный порог входа. Не нужно проходить сложную регистрацию или разбираться в интерфейсе: диалоговое взаимодействие интуитивно понятно большинству людей.
  • Экономия ресурсов. Создать и поддерживать бота дешевле, чем полноценное приложение, в особенности если функционал ограничивается справочной информацией, заказами или уведомлениями.
  • Доступность на разных устройствах. Бот работает в мессенджере, который уже установлен на смартфоне или компьютере, а значит, пользователю не нужно ничего дополнительно скачивать.
  • Персонализированное общение. Бот может обращаться к пользователю по имени, учитывать историю запросов и выдавать более релевантные ответы.
  • Удобные уведомления. В отличие от сайтов, бот может напрямую присылать напоминания, обновления и важные сообщения в чат.

Таким образом, бот оказывается полезнее там, где важна скорость взаимодействия, простота и доступность, а разработка полноценного приложения или сайта не оправдана по затратам.

Подготовка к созданию бота

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

На этом этапе важно установить необходимые инструменты, выбрать подходящие библиотеки и продумать структуру проекта.

Установка Node.js и настройка окружения

Первый шаг в создании бота — установка Node.js. Это среда выполнения JavaScript, которая позволит запускать ваш код вне браузера. Скачать Node.js можно с официального сайта nodejs.org, где доступны версии для Windows, macOS и Linux.

После установки проверьте, все ли прошло успешно, выполнив команды:

node -v
npm -v

Первая команда покажет текущую версию Node.js, а вторая — версию npm (менеджера пакетов, который устанавливается автоматически вместе с Node.js).

Изображение 1
Теперь создайте рабочую директорию, где будет располагаться проект. Например, вы можете назвать ее weather-bot:
mkdir weather-bot
cd weather-bot

Затем запустите проект с помощью npm:

npm init
Изображение 2

В командной строке система задаст несколько вопросов о проекте — имя, версию, описание и так далее. Для тестового бота можно оставить большинство значений по умолчанию. Можете изменить только имя пакета (например, weather-bot), а остальное прожмите через Enter.

Изображение 3

После завершения процесса в корне проекта появится файл package.json. В нем будут сохранены все настройки проекта и список зависимостей, которые мы будем добавлять дальше:

{
  "name": "weather-bot",
  "version": "1.0.0",
  "description": "Telegram-бот для получения погоды",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "",
  "license": "ISC"
}
Изображение 4

Автоматизация перезапуска бота

Во время разработки неудобно вручную перезапускать бота после каждого изменения кода. Эту задачу можно автоматизировать с помощью пакета nodemon, который сам отслеживает изменения файлов и перезапускает приложение.

Установите его:

npm i nodemon --save-dev

Теперь в package.json можно изменить команду запуска:

"scripts": {
  "start": "nodemon src/index.js"
}

После этого достаточно выполнить:

npm start

Бот будет автоматически перезапускаться при каждом сохранении файла.

Выбор библиотек для разработки

Когда проект уже инициализирован, нужно подключить библиотеки, которые помогут нам быстро и удобно разработать погодного бота. Главная задача — упростить работу с Telegram API, чтобы не писать все вручную.

Для этого есть несколько популярных решений:

  • node-telegram-bot-api — одна из самых старых и проверенных временем библиотек для создания ботов. Ее часто выбирают новички, потому что по ней легко найти множество примеров, статей и готовых решений. Код в ней может получаться более громоздким по сравнению с Telegraf и grammY, зато библиотека остается максимально простой и понятной.
  • Telegraf — мощная библиотека с поддержкой middleware, сцен и других полезных инструментов. Она особенно хорошо подходит для сложных проектов, где нужно гибко управлять логикой диалога и добавлять расширенные функции. Минус только в том, что порог входа здесь чуть выше: новичку может потребоваться время, чтобы разобраться с архитектурой и подходами Telegraf.
  • grammY — современная и лаконичная библиотека, которая быстро набирает популярность. Она проще и компактнее, чем Telegraf, но при этом функциональнее, чем node-telegram-bot-api. В grammY есть всё необходимое для разработки: удобные хендлеры команд и сообщений, поддержка плагинов, работа с клавиатурами и inline-кнопками. Благодаря этому библиотека сама по себе остается простой, но позволяет строить ботов любой сложности. Именно поэтому ее все чаще выбирают для новых проектов.

В качестве примера мы с вами создадим простого бота — Weather Helper, который будет присылать пользователю текущую погоду по названию города. Для него остановимся на grammY — он позволит писать чистый и короткий код без лишних конструкций.

Кроме того, нам нужно где-то хранить секретный токен, который выдает BotFather, поэтому понадобится использовать библиотеку dotenv. Она позволяет держать токены и ключи в файле .env, не добавляя их в код напрямую.

Установим необходимые пакеты:

npm i grammy dotenv

После установки в проекте появятся:

  • папка node_modules с зависимостями,
  • файл package-lock.json с подробным описанием версий библиотек,
  • обновленный package.json, где в разделе dependencies будут добавлены grammY и dotenv.

Создание структуры проекта

Чтобы код было удобно поддерживать и развивать, стоит заранее продумать структуру проекта. Даже у простого погодного бота со временем могут появиться новые функции — например, сохранение избранных городов, прогноз на несколько дней или уведомления.

Минимальная структура может выглядеть так:

weather-bot/
│── src/
│   ├── index.js       # основной файл, точка входа
│   ├── config.js      # подключение dotenv и работа с переменными окружения
│   ├── bot.js         # логика бота (команды, обработчики сообщений)
│   └── services/
│       └── weather.js # отдельный модуль для работы с API погоды
│── .env               # секретные данные (токен бота, ключ API погоды)
│── package.json
│── package-lock.json
│── .gitignore

Где:

  • index.js — запускает приложение и импортирует бота.
  • config.js — отдельный файл, чтобы удобно подключать переменные окружения.
  • bot.js — здесь будем описывать команды (/start, /weather) и ответы.
  • services/weather.js — модуль для работы с внешним API (например, OpenWeatherMap или wttr.in).
  • .env — хранит секреты: BOT_TOKEN, ключи для погодного API. Этот файл нельзя загружать в GitHub.
  • .gitignore — исключает .env, node_modules и другие временные файлы.

Создание Telegram-бота

Но прежде чем написать код, нужно зарегистрировать самого бота в Telegram. Для этого существует специальный сервисный бот — @BotFather. Он отвечает за создание и управление всеми ботами в экосистеме.

  • Откройте в Telegram профиль BotFather.
  • Нажмите «Старт».
Изображение 5
  • В списке команд выберите /newbot.
  • BotFather попросит придумать имя бота — это будет отображаемое название, которое пользователи будут видеть в списке чатов. Например, «Weather Helper».
Изображение 6
  • Далее нужно указать имя бота. Оно должно быть уникальным и обязательно заканчиваться словом bot. Например:
  • WeatherHelperBot
  • Weather_Helper_bot
  • OurWeatherHelper_Bot

Если имя свободно, BotFather зарегистрирует бота и пришлет вам сообщение с токеном. Это длинная строка символов, которая используется для доступа к API. Храните его в секрете — по этому токену можно управлять вашим ботом.

Изображение 7

Теперь у вас есть пустой бот в Telegram, который готов к работе. Дальше можно написать для него код. Но прежде чем писать хоть строчку кода для бота, нужно позаботиться о безопасности.

Разработка Telegram-бота

Шаг 1. Создайте файл .env и настройте .gitignore

Самое уязвимое место — это токен, который вы получили у BotFather. Если он случайно попадет в открытый доступ, ваш бот станет уязвим: кто угодно сможет управлять им.

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

В корне проекта создайте файл с именем .env (без расширений). Запишите в него токен в формате:

BOT_TOKEN=1234567890:ABC-MySecretToken

Чтобы .env случайно не оказался в репозитории (например, на GitHub), добавьте файл .gitignore в корень проекта:

touch .gitignore 

Его задача — подсказать Git, какие файлы нужно игнорировать.

Содержимое файла будет следующим:

node_modules
.env

Здесь node_modules — это папка с установленными библиотеками, ее обычно не хранят в репозиториях, а .env содержит токен и другие приватные данные.

Шаг 2. Минимальный запуск бота в index.js

Теперь, когда токен хранится в .env, можно написать самый простой код для запуска бота. Наша цель — проверить, что бот отвечает хотя бы на команду /start.

В корне проекта заведите папку src и в ней файл index.js:

mkdir src
cd src
touch index.js

Перейдите в него:

nano index.js

Вставьте код:

// Загружаем переменные окружения из .env
require('dotenv').config();
// Подключаем класс Bot из библиотеки grammY
const { Bot } = require('grammy');
// Забираем токен из переменной окружения
const token = process.env.BOT_TOKEN;
// Проверяем наличие токена
if (!token) {
  console.error('BOT_TOKEN не найден. Укажите его в .env');
  process.exit(1);
}
// Создаем экземпляр бота
const bot = new Bot(token);
// Настраиваем реакцию на команду /start
bot.command('start', async (ctx) => {
  await ctx.reply(
    'Привет! Я погодный бот ????\n' +
    'Пока умею только здороваться, но скоро начну показывать погоду.'
  );
});
// Запускаем бота в режиме long polling
bot.start();
console.log('Бот запущен и ждет сообщений');

Затем откройте package.json и в раздел "scripts" добавьте:

"start": "node src/index.js"
Изображение 8

В терминале выполните:

npm start

Если все настроено правильно, в консоли появится сообщение:

Бот запущен и ждет сообщений
Изображение 9

Откройте чат с вашим ботом и отправьте команду «Старт». В ответ вы получите заданное приветствие.

Изображение 10

Шаг 3. Добавьте команды /setcity и /weather

На этом этапе бот начнет выполнять первые полезные функции: запоминать выбранный город и показывать погоду по нему.

  • Создайте папку src/services. Внутри нее будут отдельные модули для работы с внешними API и данными.
mkdir -p src/services
  • Создайте файл src/services/weather.js:
touch src/services/weather.js

В нем будет функция, которая обращается к API погоды. Чтобы было проще, можно использовать бесплатный сервис wttr.in, который работает без ключей.

Вставьте код:

// src/services/weather.js
async function getWeather(city) {
  const url = `https://wttr.in/${encodeURIComponent(city)}?format=3`;
  const res = await fetch(url);
  const text = await res.text();
  // Если сервис вернул ошибку
  if (!text || text.toLowerCase().includes('unknown location')) {
    return 'Не удалось найти такой город. Попробуйте другой.';
  }
  return text;
}
module.exports = { getWeather };
Изображение 11
  • Создайте файл src/services/storage.js.
touch src/services/storage.js

Чтобы бот показывал погоду не только по введённому городу, но и запоминал выбор для каждого человека, нам нужно где-то хранить эти данные. Самый простой способ — использовать обычный объект в памяти.

В src/services/storage.js добавьте:
// src/services/storage.js
const users = {};
function setCity(userId, city) {
  users[userId] = city;
}
function getCity(userId) {
  return users[userId];
}
module.exports = { setCity, getCity };
Изображение 12
  • Обновите файл src/index.js. Подключите новые сервисы и добавьте команды:
require('dotenv').config();
const { Bot } = require('grammy');
const { getWeather } = require('./services/weather');
const { setCity, getCity } = require('./services/storage');
const token = process.env.BOT_TOKEN;
if (!token) {
  console.error('BOT_TOKEN не найден. Укажите его в .env');
  process.exit(1);
}
const bot = new Bot(token);
// /start
bot.command('start', async (ctx) => {
  await ctx.reply('Привет! Я погодный бот ????\nИспользуй /setcity, чтобы выбрать город.');
});
// /setcity
bot.command('setcity', async (ctx) => {
  // Достаем аргумент после команды
  const parts = ctx.message.text.split(' ');
  const city = parts.slice(1).join(' ');
  if (!city) {
    return ctx.reply('Укажите город после команды. Например: /setcity Москва');
  }
  setCity(ctx.from.id, city);
  await ctx.reply(`Город сохранен: ${city}`);
});
// /weather
bot.command('weather', async (ctx) => {
  const city = getCity(ctx.from.id);
  if (!city) {
    return ctx.reply('Сначала укажите город через /setcity');
  }
  const weather = await getWeather(city);
  await ctx.reply(`Погода для ${city}: ${weather}`);
});
// Запускаем
bot.start();
console.log('Бот запущен и ждет сообщений');
Изображение 13
  • Проверьте работу бота:
npm start
  • В Telegram отправьте:
/setcity Москва

Ответ должен быть следующим:

Город сохранен: Москва
  • Затем выполните:
/weather

Ответ будет примерно таким:

Москва: ☀️ +8°C
Изображение 14

Шаг 4. Добавьте обработку геолокации и удобную клавиатуру

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

  • Обновите src/services/weather.js. Добавьте функцию, которая получает погоду по координатам. Для этого используем wttr.in — он поддерживает запросы вида .
// src/services/weather.js
async function getWeather(city) {
  const url = `https://wttr.in/${encodeURIComponent(city)}?format=3`;
  const res = await fetch(url);
  const text = await res.text();
  if (!text || text.toLowerCase().includes('unknown location')) {
    return 'Не удалось найти такой город. Попробуйте другой.';
  }
  return text;
}
// Новый метод для координат
async function getWeatherByCoords(lat, lon) {
  const url = `https://wttr.in/${lat},${lon}?format=3`;
  const res = await fetch(url);
  return await res.text();
}
module.exports = { getWeather, getWeatherByCoords };
Изображение 15
  • Обновите src/index.js. Нужно добавить обработку сообщений с геолокацией и сделать клавиатуру для удобства:
require('dotenv').config();
const { Bot, Keyboard } = require('grammy');
const { getWeather, getWeatherByCoords } = require('./services/weather');
const { setCity, getCity } = require('./services/storage');
const token = process.env.BOT_TOKEN;
if (!token) {
  console.error('BOT_TOKEN не найден. Укажите его в .env');
  process.exit(1);
}
const bot = new Bot(token);
// /start
bot.command('start', async (ctx) => {
  const keyboard = new Keyboard()
    .requestLocation('???? Отправить геолокацию')
    .resized();
  await ctx.reply(
    'Привет! Я погодный бот ????\n' +
    '— Используй /setcity <город>, чтобы выбрать город\n' +
    '— Или нажми кнопку, чтобы отправить геолокацию',
    { reply_markup: keyboard }
  );
});
// /setcity
bot.command('setcity', async (ctx) => {
  const parts = ctx.message.text.split(' ');
  const city = parts.slice(1).join(' ');
  if (!city) {
    return ctx.reply('Укажите город после команды. Например: /setcity Казань');
  }
  setCity(ctx.from.id, city);
  await ctx.reply(`Город сохранен: ${city}`);
});
// /weather
bot.command('weather', async (ctx) => {
  const city = getCity(ctx.from.id);
  if (!city) {
    return ctx.reply('Сначала укажите город через /setcity или отправьте геолокацию.');
  }
  const weather = await getWeather(city);
  await ctx.reply(`Погода для ${city}: ${weather}`);
});
// Обработка геолокации
bot.on('message:location', async (ctx) => {
  const { latitude, longitude } = ctx.message.location;
  const weather = await getWeatherByCoords(latitude, longitude);
  await ctx.reply(`Погода по твоей геопозиции: ${weather}`);
});
// Запуск
bot.start();
console.log('Бот запущен и ждет сообщений');
Изображение 16
  • Снова запустите бота:
npm start
  • И наконец, отправьте боту команду /start. Он пришлет приветствие и кнопку «???? Отправить геолокацию»:
Изображение 17
  • Нажмите на нее и подтвердите отправку геопозиции. В ответ бот вернет погоду для вашего местоположения.
Изображение 18

Важно! Отправка геопозиции не доступна через Telegram Desktop. Но вы можете отправить ее через мобильное приложение.

Деплой бота на сервере

Чтобы бот работал не только на вашем компьютере, но и был доступен постоянно, его нужно развернуть на сервере. Мы рассмотрим вариант с VPS от SpaceWeb, где есть готовые образы с Node.js.

Шаг 1. Загрузка проекта на GitHub

Чтобы развернуть бота на сервере, сначала нужно перенести код в удаленный репозиторий. Удобнее всего использовать GitHub.

  • Перейдите в корень проекта и выполните:
git init

Эта команда создаст скрытую папку .git, и проект станет репозиторием.

  • Добавьте файлы в индекс:
git add .
  • Создайте первый коммит:
git commit -m "first commit"

Так вы зафиксируете текущее состояние проекта.

  • Создайте новый репозиторий на GitHub. Для этого перейдите на  и нажмите New repository.
  • Задайте имя, например, weather-bot и нажмите Create repository. GitHub покажет адрес репозитория:
https://github.com/username/weather-bot.git
  • Привяжите локальный проект к GitHub:
git branch -M main
git remote add origin https://github.com/username/weather-bot.git

6. Отправьте код на GitHub:

git push -u origin main

После этого ваш проект появится на GitHub.

Шаг 2. Создание сервера

Чтобы бот работал постоянно, нужен удаленный сервер. В SpaceWeb можно арендовать VDS с уже предустановленным Node.js, что значительно упрощает настройку.

Мы рекомендуем:

  • для начала выбрать тариф VPS с минимальной конфигурацией (1 CPU, 1 ГБ RAM, SSD 10–20 ГБ) — этого достаточно для простого бота;
  • указать ближайший дата-центр, чтобы снизить задержку;
  • подключить публичный IP, чтобы можно было подключаться по SSH;
  • хранить доступы в надежном месте.

После активации в панели управления вы получите данные для подключения, включая IP-адрес, логин и пароль.

Шаг 3. Клонирование проекта и установка зависимостей

  • Создав сервер, подключитесь к нему по SSH:
ssh root@<ваш-ip>
  • Введите пароль, выданный в панели управления. Обратите внимание: при вводе пароль не отображается — это нормально.
  • Обновите систему
sudo apt-get update
  • Создайте папку для проекта
cd /
sudo mkdir weather-bot
cd weather-bot
  • Проверьте, что Git установлен:
git --version

Если все в порядке, клонируйте свой репозиторий:

git clone https://github.com/username/weather-bot.git
cd weather-bot

Важно!

  • Установите зависимости проекта:
npm install
  • Так как .env не хранится в репозитории, создайте его вручную:
nano .env
  • Вставьте в файл ваш токен:
BOT_TOKEN=1234567890:ABC-MySecretToken

Сохраните (Ctrl+O, затем Enter) и закройте (Ctrl+X).

  • Запустите бота для проверки:
npm start

В консоли должно появиться сообщение:

Бот запущен и ждет сообщений

Теперь можно открыть Telegram и убедиться, что бот отвечает.

Шаг 4. Автоматический запуск через pm2

Когда бот запущен напрямую через npm start, он перестает работать после выхода из консоли или перезагрузки сервера. Чтобы этого не происходило, используют менеджер процессов pm2. Он позволяет запускать бота в фоне и автоматически поднимать его при сбоях или перезапуске сервера.

  • Установите pm2 глобально:
sudo npm install pm2 -g
  • Запустите бота через pm2. Перейдите в папку проекта и выполните:
sudo pm2 start src/index.js --name "weather-bot" --watch

Где:

  • src/index.js — путь к вашему боту;
  • --name — имя процесса (можете указать любое, например weather-bot);
  • --watch — следить за изменениями файлов и перезапускать бота автоматически.
  • Настройте автозапуск pm2. Чтобы бот запускался даже после перезагрузки сервера, пропишите:
sudo pm2 startup
sudo pm2 save

Теперь ваш бот будет работать в фоне и автоматически запускаться при перезагрузке сервера. Это финальный штрих деплоя — бот готов к круглосуточной работе.

Как гарантировать безопасность бота

Даже простой Telegram-бот должен быть защищен, ведь токен или уязвимость в коде могут привести к тому, что злоумышленники получат доступ к управлению. Чтобы снизить риски, стоит соблюдать несколько правил:

  • Храните токен в .env. Никогда не вставляйте ключ напрямую в код. Всегда используйте переменные окружения и файл .env. Сам файл должен быть добавлен в .gitignore, чтобы он не попал в публичный репозиторий. Для продакшена можно использовать менеджеры секретов (например, Vault или встроенные решения облачных платформ).
  • Ограничьте доступ к исходному коду. Репозиторий с ботом лучше держать приватным, особенно если в нем используются внешние API-ключи, токены или тестовые данные.
  • Используйте HTTPS при запросах к API. Если бот обращается к внешним сервисам (например, для получения погоды), всегда используйте защищенное соединение (https://). Это исключает возможность перехвата данных.
  • Обрабатывайте ошибки. В коде нужно предусмотреть отлов ошибок: в частности, сетевых, которые связаны с API или Telegram. Это не только улучшает стабильность, но и предотвращает падение всего бота из-за одной проблемы.
  • Регулярно обновляйте зависимости. Многие уязвимости связаны со старыми версиями библиотек. Следите за обновлениями grammy, dotenv, nodemon и других пакетов, которые используете.
  • Не храните секреты в коде. Если помимо токена вы используете другие ключи (например, для API погоды), они тоже должны храниться в .env, а не в исходниках.
  • Настройте контроль доступа на сервере. Если бот работает на удаленном сервере, ограничьте доступ к нему (например, через SSH-ключи) и не храните пароли в открытом виде.
  • Добавьте защиту от спама и атак. Полезно ограничивать частоту запросов от одного пользователя, фильтровать подозрительные сообщения и игнорировать массовые повторные вызовы. Так вы сможете защитить бота от перегрузки.
  • Ограничьте доступ к функциям. Если в боте есть административные команды, убедитесь, что выполнять их могут только определенные пользователи. Для этого проверяйте user_id и разрешайте доступ только доверенным аккаунтам.

Заключение

Мы прошли путь от установки Node.js и подготовки окружения до деплоя рабочего Telegram-бота на сервер. В качестве примера сделали погодного бота, который умеет запоминать город, показывать прогноз и принимать геолокацию. На его основе можно экспериментировать дальше: добавить другие источники данных, встроить клавиатуры или расширить список команд.

Главное, чтобы теперь вам был понятен общий процесс: как устроена структура проекта, какие библиотеки помогают в разработке и каким образом бот может работать круглосуточно. Этот пример можно взять за основу и адаптировать под свои задачи.