npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vvlad1973/telegram-bot-client

v2.0.4

Published

This package provides Telegram Bot API client

Readme

@vvlad1973/telegram-bot-client

Мощная и типобезопасная библиотека для создания Telegram ботов на TypeScript с поддержкой нескольких токенов, системой событий и расширенной фильтрацией.

Основные возможности

  • Полная типизация TypeScript - автоматически сгенерированные типы из OpenAPI спецификации Telegram Bot API 9.2.0
  • Event-driven архитектура - гибкая система событий для обработки обновлений
  • Middleware система - цепочка обработчиков для pre-processing обновлений
  • Расширенная фильтрация - мощная система фильтров с поддержкой RegExp
  • Поддержка нескольких токенов - управление несколькими ботами одновременно
  • Long Polling Manager - встроенный менеджер с worker threads и автоматическими перезапусками
  • Обертки (Wrappers) - удобные методы для работы с сообщениями и callback query
  • Построители (Builders) - fluent API для создания клавиатур и команд
  • Обработка ошибок - иерархия специализированных классов ошибок
  • Интеграция с логированием - поддержка LoggerTree и SimpleLogger
  • Native Fetch API - использует встроенный fetch без внешних зависимостей

Установка

npm install @vvlad1973/telegram-bot-client

Быстрый старт

Создание и инициализация бота

Библиотека поддерживает три режима работы с Telegram Bot API:

  1. Inactive - неактивный режим (только для отправки запросов)
  2. LongPolling - получение обновлений через long polling
  3. Webhook - получение обновлений через webhook

Жизненный цикл маршрута (route)

Каждый бот проходит следующие этапы:

  1. Создание - конфигурация маршрута (route) с токеном и режимом
  2. Инициализация - вызов getMe для получения информации о боте
  3. Активация - установка режима работы (webhook/polling)
  4. Работа - обработка обновлений
  5. Деактивация - остановка получения обновлений
  6. Завершение - закрытие всех ресурсов

Режим 1: Inactive (только отправка)

Используйте этот режим, когда нужно только отправлять сообщения без получения обновлений:

import { TelegramBotClient, RouteMode } from '@vvlad1973/telegram-bot-client';

// Создание клиента
const bot = new TelegramBotClient({
  routes: {
    token: 'YOUR_BOT_TOKEN',
    mode: RouteMode.Inactive
  }
});

// Инициализация (получает информацию о боте через getMe)
await bot.init();

// Отправка сообщения без получения обновлений
await bot.sendMessage({
  chat_id: 123456789,
  text: 'Привет! Это одностороннее сообщение.'
});

// Завершение работы
await bot.shutdown();

Режим 2: Long Polling (получение обновлений)

Long polling - рекомендуемый режим для разработки и небольших ботов:

import { TelegramBotClient, RouteMode } from '@vvlad1973/telegram-bot-client';

// Шаг 1: Создание клиента с конфигурацией
const bot = new TelegramBotClient({
  routes: {
    token: 'YOUR_BOT_TOKEN',
    mode: RouteMode.LongPolling,
    longPolling: {
      timeout: 30,           // Таймаут long polling запроса (сек)
      limit: 100,            // Максимальное количество обновлений
      allowedUpdates: [      // Типы обновлений (опционально)
        'message',
        'callback_query'
      ]
    }
  }
});

// Шаг 2: Установка обработчиков событий (до инициализации)
bot.on('/start', (params, wrapper) => {
  wrapper.replyMessage('Добро пожаловать! Я бот в режиме Long Polling.');
});

bot.on('message.text', (wrapper) => {
  wrapper.replyMessage(`Эхо: ${wrapper.text}`);
});

bot.on('callback_query', (wrapper) => {
  wrapper.answer('Кнопка нажата!');
});

// Шаг 3: Инициализация (вызывает getMe, сохраняет информацию о боте)
await bot.init();

// Шаг 4: Запуск long polling (начинает получать обновления)
await bot.startPolling();

console.log('Бот запущен в режиме Long Polling');

// Шаг 5: Graceful shutdown
process.on('SIGINT', async () => {
  console.log('Остановка бота...');
  await bot.stopPolling();
  await bot.shutdown();
  process.exit(0);
});

Режим 3: Webhook (для продакшена)

Webhook режим рекомендуется для продакшен-окружения:

import { TelegramBotClient, RouteMode } from '@vvlad1973/telegram-bot-client';
import express from 'express';

// Шаг 1: Создание клиента с webhook конфигурацией
const bot = new TelegramBotClient({
  routes: {
    token: 'YOUR_BOT_TOKEN',
    mode: RouteMode.Webhook,
    webhook: {
      path: '/webhook/bot',           // Путь для webhook
      secretToken: 'your-secret-123',  // Секретный токен для защиты
      maxConnections: 100,             // Макс. одновременных соединений
      allowedUpdates: [                // Типы обновлений
        'message',
        'callback_query'
      ]
    }
  },
  webhookBaseUrl: 'https://your-domain.com'  // Базовый URL (обязательно HTTPS!)
});

// Шаг 2: Установка обработчиков
bot.on('/start', (params, wrapper) => {
  wrapper.replyMessage('Привет! Я бот в режиме Webhook.');
});

bot.on('message.text', (wrapper) => {
  wrapper.replyMessage(`Получено: ${wrapper.text}`);
});

// Шаг 3: Инициализация
await bot.init();

// Шаг 4: Активация (устанавливает webhook через setWebhook)
await bot.activate();

// Шаг 5: Настройка Express для обработки webhook
const app = express();
app.use(express.json());

app.post('/webhook/bot', async (req, res) => {
  // Проверка секретного токена (опционально)
  const secretToken = req.headers['x-telegram-bot-api-secret-token'];
  if (secretToken !== 'your-secret-123') {
    return res.status(403).send('Forbidden');
  }

  // Обработка обновления
  try {
    await bot.processUpdate(req.body);
    res.status(200).send('OK');
  } catch (error) {
    console.error('Error processing update:', error);
    res.status(500).send('Error');
  }
});

// Шаг 6: Запуск сервера
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Webhook сервер запущен на порту ${PORT}`);
});

// Graceful shutdown
process.on('SIGINT', async () => {
  console.log('Остановка сервера...');
  await bot.deactivate();  // Удаляет webhook через deleteWebhook
  await bot.shutdown();
  process.exit(0);
});

Режим 4: Переключение между режимами

Вы можете создать бота в одном режиме и переключить его в другой:

import { TelegramBotClient, RouteMode } from '@vvlad1973/telegram-bot-client';

// Создание в неактивном режиме
const bot = new TelegramBotClient({
  routes: {
    token: 'YOUR_BOT_TOKEN',
    mode: RouteMode.Inactive
  }
});

// Инициализация
await bot.init();

// Переключение на Long Polling
await bot.activate(undefined, RouteMode.LongPolling);
await bot.startPolling();

// Работа в режиме Long Polling...
console.log('Работаем в Long Polling...');
await new Promise(resolve => setTimeout(resolve, 10000));

// Остановка polling и переключение на Webhook
await bot.stopPolling();
await bot.deactivate();

// Обновление конфигурации маршрута
bot.setRoute('default', {
  token: 'YOUR_BOT_TOKEN',
  mode: RouteMode.Webhook,
  webhook: { path: '/webhook' }
});

// Активация в режиме Webhook
await bot.activate(undefined, RouteMode.Webhook);

// Теперь бот работает через webhook

Режим 5: Автоматическая активация

Для упрощения можно использовать автоматическую активацию:

import { TelegramBotClient, RouteMode } from '@vvlad1973/telegram-bot-client';

const bot = new TelegramBotClient({
  routes: {
    token: 'YOUR_BOT_TOKEN',
    mode: RouteMode.LongPolling,
    autoActivate: true  // Автоматическая активация при инициализации
  }
});

// Обработчики
bot.on('message.text', (wrapper) => {
  wrapper.replyMessage(`Эхо: ${wrapper.text}`);
});

// Только инициализация - активация произойдет автоматически
await bot.init();

// Для Long Polling все равно нужно запустить polling
await bot.startPolling();

Работа с клавиатурами

import { InlineKeyboardBuilder } from '@vvlad1973/telegram-bot-client';

// Создание inline клавиатуры
const keyboard = new InlineKeyboardBuilder()
  .appendRows(2)
  .appendTextButton('Помощь', 'help', 0)
  .appendTextButton('Настройки', 'settings', 0)
  .appendUrlButton('Наш сайт', 'https://example.com', 1)
  .build();

bot.on('/menu', (params, wrapper) => {
  wrapper.replyMessage('Выберите действие:', {
    reply_markup: keyboard
  });
});

// Обработка callback
bot.on('callback_query', (wrapper) => {
  if (wrapper.data === 'help') {
    wrapper.editMessageText('Справка по боту...');
    wrapper.answer();
  }
});

Фильтрация обновлений

// Фильтр по приватным чатам
bot.onFilter({
  type: 'message.text',
  chat: 'private'
}, (wrapper) => {
  wrapper.replyMessage('Это приватный чат');
});

// Фильтр с RegExp
bot.onFilter({
  type: 'message.text',
  contents: /^\/admin/,
  user: /^(111111|222222)$/ // Только определенные пользователи
}, (wrapper) => {
  wrapper.replyMessage('Админ-команда');
});

// Фильтр по типу чата
bot.onFilter({
  type: 'message.text',
  chat_type: 'group'
}, (wrapper) => {
  console.log('Сообщение из группы');
});

Middleware

// Логирование всех обновлений
bot.use((update, next, client) => {
  console.log('Update ID:', update.update_id);
  next();
});

// Аутентификация
bot.use((update, next, client) => {
  const userId = update.message?.from?.id;
  if (isAuthorized(userId)) {
    next(); // Продолжить обработку
  }
  // Если не вызвать next(), обработка остановится
});

// Обработка ошибок
bot.use(async (update, next, client) => {
  try {
    next();
  } catch (error) {
    console.error('Error processing update:', error);
  }
});

Документация

Архитектура

TelegramBotClient (клиентский слой)
    ↓ наследует
BaseTelegramApi (сгенерированные методы API)
    ↓ использует
TelegramTransport (транспортный слой)
    ↓ использует
TelegramHttpClient (HTTP-клиент)
    ↓ использует
Native Fetch API

Основные компоненты

  • TelegramBotClient - основной клиент с системой событий и фильтрацией
  • TelegramTransport - транспортный слой для HTTP-запросов
  • TelegramHttpClient - HTTP-клиент с автоматическими повторами
  • TokensManager - управление несколькими токенами ботов
  • LongPollingManager - менеджер long polling с worker threads
  • MessageWrapper - обертка для удобной работы с сообщениями
  • CallbackQueryWrapper - обертка для callback query
  • InlineKeyboardBuilder - построитель inline-клавиатур
  • ReplyKeyboardBuilder - построитель обычных клавиатур

Примеры использования

Несколько токенов

import { TelegramBotClient, RouteMode } from '@vvlad1973/telegram-bot-client';

// Создание клиента с несколькими маршрутами
const bot = new TelegramBotClient({
  routes: [
    {
      token: 'TOKEN_1',
      mode: RouteMode.LongPolling
    },
    {
      token: 'TOKEN_2',
      mode: RouteMode.Webhook,
      webhook: { path: '/webhook/support' }
    }
  ],
  defaultRouteId: 'default',
  webhookBaseUrl: 'https://example.com'
});

// Инициализация всех маршрутов
await bot.init();

// Активация конкретного маршрута
await bot.managers.lifecycle.activateRoute('default', RouteMode.LongPolling);

// Отправка от конкретного бота
await bot.sendMessage(
  { chat_id: 123, text: 'Hello from main bot!' },
  { routeId: 'default' }
);

await bot.sendMessage(
  { chat_id: 456, text: 'Hello from support!' },
  { routeId: 'route_1' }
);

// Запуск polling для всех маршрутов в режиме LongPolling
await bot.startPolling();

Работа с менеджерами (Advanced)

TelegramBotClient использует три менеджера для управления маршрутами:

1. RouteConfigManager - управление конфигурацией

// Доступ к менеджеру
const configManager = bot.managers.config;

// Получение списка всех маршрутов
const routeIds = configManager.getRouteIds();
console.log('Доступные маршруты:', routeIds);

// Получение конфигурации маршрута
const config = configManager.getRoute('default');
console.log('Режим:', config.mode);
console.log('Токен:', config.token);

// Установка/обновление конфигурации маршрута
bot.setRoute('bot2', {
  token: 'NEW_TOKEN',
  mode: RouteMode.LongPolling,
  longPolling: {
    timeout: 30,
    limit: 100
  }
});

// Получение ID маршрута по умолчанию
const defaultRouteId = configManager.getDefaultRouteId();

// Проверка существования маршрута
if (configManager.hasRoute('bot2')) {
  console.log('Маршрут bot2 существует');
}

2. RouteLifecycleManager - управление жизненным циклом

// Доступ к менеджеру
const lifecycleManager = bot.managers.lifecycle;

// Инициализация конкретного маршрута (вызывает getMe)
await lifecycleManager.initRoute('bot1');

// Активация маршрута в указанном режиме
await lifecycleManager.activateRoute('bot1', RouteMode.LongPolling);

// Деактивация маршрута (удаляет webhook, останавливает polling)
await lifecycleManager.deactivateRoute('bot1');

// Получение информации о боте (после init)
const botInfo = lifecycleManager.getBotInfo('bot1');
console.log('Имя бота:', botInfo.username);
console.log('ID бота:', botInfo.id);

// Получение статуса маршрута
const status = lifecycleManager.getRouteStatus('bot1');
console.log('Статус:', status.state);        // 'initialized', 'active', 'inactive'
console.log('Режим:', status.mode);           // RouteMode
console.log('Последняя ошибка:', status.lastError);

// Переключение режима (деактивирует текущий и активирует новый)
await lifecycleManager.switchMode('bot1', RouteMode.Webhook);

// Горячая перезагрузка конфигурации (применяет новые настройки)
await lifecycleManager.hotReload('bot1');

3. PollingIntegrationManager - управление polling

// Доступ к менеджеру
const pollingManager = bot.managers.polling;

// Запуск polling для конкретного маршрута
await pollingManager.startPolling();

// Остановка polling
await pollingManager.stopPolling();

// Проверка активности polling для маршрута
const isActive = pollingManager.isPollingActive('bot1');
console.log('Polling активен:', isActive);

// Получение текущего offset для маршрута
const offset = pollingManager.getOffset('bot1');
console.log('Текущий offset:', offset);

// Получение статистики polling для маршрута
const stats = pollingManager.getStats('bot1');
console.log('Всего получено обновлений:', stats.totalUpdates);
console.log('Последнее обновление:', stats.lastUpdate);
console.log('Статус worker:', stats.workerStatus);

Полный пример с менеджерами

import { TelegramBotClient, RouteMode } from '@vvlad1973/telegram-bot-client';

// Создание клиента с несколькими маршрутами
const bot = new TelegramBotClient({
  routes: new Map([
    ['main', {
      token: 'MAIN_BOT_TOKEN',
      mode: RouteMode.Inactive
    }],
    ['support', {
      token: 'SUPPORT_BOT_TOKEN',
      mode: RouteMode.Inactive
    }]
  ]),
  defaultRouteId: 'main'
});

// 1. Инициализация обоих ботов
console.log('Инициализация ботов...');
await bot.managers.lifecycle.initRoute('main');
await bot.managers.lifecycle.initRoute('support');

// Проверка информации о ботах
const mainInfo = bot.managers.lifecycle.getBotInfo('main');
const supportInfo = bot.managers.lifecycle.getBotInfo('support');
console.log('Основной бот:', mainInfo.username);
console.log('Бот поддержки:', supportInfo.username);

// 2. Активация основного бота в Long Polling
console.log('Активация основного бота...');
await bot.managers.lifecycle.activateRoute('main', RouteMode.LongPolling);
await bot.startPolling();

// 3. Активация бота поддержки в Webhook
console.log('Активация бота поддержки...');
bot.setRoute('support', {
  token: 'SUPPORT_BOT_TOKEN',
  mode: RouteMode.Webhook,
  webhook: { path: '/webhook/support' }
});
await bot.managers.lifecycle.activateRoute('support', RouteMode.Webhook);

// 4. Мониторинг состояния
setInterval(() => {
  // Статус маршрутов
  const mainStatus = bot.managers.lifecycle.getRouteStatus('main');
  const supportStatus = bot.managers.lifecycle.getRouteStatus('support');

  console.log('Основной бот - состояние:', mainStatus.state, 'режим:', mainStatus.mode);
  console.log('Бот поддержки - состояние:', supportStatus.state, 'режим:', supportStatus.mode);

  // Статистика polling для основного бота
  if (bot.managers.polling.isPollingActive('main')) {
    const stats = bot.managers.polling.getStats('main');
    console.log('Получено обновлений:', stats.totalUpdates);
  }
}, 30000);

// 5. Переключение режима основного бота (с Long Polling на Webhook)
setTimeout(async () => {
  console.log('Переключение основного бота на Webhook...');
  await bot.stopPolling();
  bot.setRoute('main', {
    token: 'MAIN_BOT_TOKEN',
    mode: RouteMode.Webhook,
    webhook: { path: '/webhook/main' }
  });
  await bot.managers.lifecycle.switchMode('main', RouteMode.Webhook);
}, 60000);

// Graceful shutdown
process.on('SIGINT', async () => {
  console.log('Остановка всех ботов...');

  // Деактивация всех маршрутов
  for (const routeId of bot.managers.config.getRouteIds()) {
    await bot.managers.lifecycle.deactivateRoute(routeId);
  }

  await bot.shutdown();
  process.exit(0);
});

Обработка ошибок

import { TelegramRateLimitError, TelegramBadRequestError } from '@vvlad1973/telegram-bot-client';

try {
  await bot.sendMessage({
    chat_id: chatId,
    text: 'Hello!'
  });
} catch (error) {
  if (error instanceof TelegramRateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
    // Автоматическая задержка
    await new Promise(resolve => setTimeout(resolve, error.getRetryDelay()));
  } else if (error instanceof TelegramBadRequestError) {
    console.error('Bad request:', error.description);
  }
}

Логирование

import { SimpleLogger } from '@vvlad1973/simple-logger';

const logger = new SimpleLogger({
  level: 'info',
  prettyPrint: true
});

const transport = new TelegramTransport({
  tokens: { default: token },
  logger
});

const bot = new TelegramBotClient({
  transport,
  logger
});

// Логи автоматически выводятся на всех уровнях

MessageWrapper методы

bot.on('message.text', async (wrapper) => {
  // Ответ на сообщение
  await wrapper.replyMessage('Hello!');

  // Отправка в тот же чат
  await wrapper.answerMessage('Message sent!');

  // Редактирование
  await wrapper.editText('Updated text');

  // Удаление
  await wrapper.delete();

  // Пересылка
  await wrapper.forward(otherChatId);

  // Закрепление
  await wrapper.pin();

  // Chat action
  await wrapper.answerChatAction('typing');

  // Отправка фото
  await wrapper.replyPhoto('file_id_or_url', {
    caption: 'Photo caption'
  });
});

ReplyKeyboardBuilder

import { ReplyKeyboardBuilder } from '@vvlad1973/telegram-bot-client';

const keyboard = new ReplyKeyboardBuilder()
  .appendRows(3)
  .appendTextButton('Начать', 0)
  .appendTextButton('Помощь', 0)
  .appendRequestContactButton('Отправить контакт', 1)
  .appendRequestLocationButton('Отправить локацию', 2)
  .setResizeKeyboard(true)
  .setOneTimeKeyboard(true)
  .build();

await bot.sendMessage({
  chat_id: chatId,
  text: 'Выберите действие:',
  reply_markup: keyboard
});

Требования

  • Node.js >= 18.0.0
  • npm >= 9.0.0
  • TypeScript >= 5.0 (для разработки)

Зависимости

Основные зависимости:

  • @vvlad1973/base-api - базовый API класс
  • @vvlad1973/data-validator - валидация данных
  • @vvlad1973/logger-tree - система логирования
  • @vvlad1973/simple-logger - простой логгер
  • @vvlad1973/utils - утилиты
  • ajv - JSON Schema валидация

Скрипты

# Сборка проекта
npm run build

# Тестирование
npm test
npm run test:coverage

# Линтинг
npm run lint
npm run lint:fix
npm run lint:md
npm run lint:md:fix

# Генерация документации
npm run docs

# Обновление API
npm run fetch-api      # Скачать спецификацию Telegram Bot API
npm run generate-api   # Сгенерировать типы и методы
npm run update-api     # Скачать и сгенерировать

Разработка

Генерация API

Типы и методы автоматически генерируются из OpenAPI спецификации:

# Скачать актуальную спецификацию
npm run fetch-api

# Сгенерировать классы и типы
npm run generate-api

# Или всё вместе
npm run update-api

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

telegram-bot-client/
├── src/
│   ├── api/                    # Сгенерированные API классы
│   │   ├── BaseTelegramApi.generated.ts
│   │   └── types/              # Сгенерированные типы
│   ├── client/                 # TelegramBotClient
│   ├── transport/              # Транспортный слой
│   ├── builders/               # Построители клавиатур
│   ├── wrappers/               # Обертки для Message и CallbackQuery
│   ├── agents/                 # Long Polling Manager
│   ├── errors/                 # Классы ошибок
│   ├── helpers/                # Вспомогательные функции
│   └── types/                  # Общие типы
├── scripts/                    # Скрипты генерации
├── docs/                       # Документация
├── examples/                   # Примеры
└── models/                     # OpenAPI спецификация

Примеры

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

Changelog

См. CHANGELOG.md для полной истории изменений.

Лицензия

MIT with Commercial Use License

Автор

Vladislav Vnukovskiy [email protected]

Ссылки

Поддержка

Если у вас возникли проблемы или вопросы:

  1. Проверьте документацию
  2. Посмотрите примеры
  3. Создайте issue на GitHub

Благодарности

  • Telegram Team за отличный Bot API
  • Сообщество разработчиков Telegram ботов