Взаимодействие с ботами является основой современной автоматизации‚ интеграции сервисов и создания чат-интерфейсов. Под «запросом к боту» обычно понимают два сценария:
- Клиентский сценарий: Пользователь или внешняя программа отправляет команду/данные боту (через мессенджер‚ виджет на сайте‚ API).
- Серверный сценарий (Bot-to-Bot / Server-to-Bot): Один бот или бэкенд-сервис отправляет запрос другому боту через API мессенджера (например‚ Telegram Bot API).
В этой статье мы подробно разберем технические способы отправки запросов‚ используя пример Telegram Bot API (наиболее популярный для разработки)‚ а также затронем общие принципы‚ применимые к другим платформам (WhatsApp Business API‚ Viber‚ Slack‚ Discord).
Фундаментальные концепции
Прежде чем писать код‚ нужно понять‚ как бот получает обновления (Updates). Существует два основных архитектурных подхода:
Long Polling (Долгий опрос) - Принцип: Ваш сервер (бот) периодически отправляет HTTP-запрос к API мессенджера (метод
getUpdates в Telegram) с таймаутом (например‚ 30–60 секунд). - Плюсы: Простота настройки‚ не требует публичного IP/домена/SSL‚ идеально для разработки и небольших проектов.
- Минусы: Задержка получения сообщений (зависит от интервала опроса)‚ нагрузка на сервер бота‚ сложнее масштабировать.
Webhooks (Вебхуки) - Принцип: Вы регистрируете публичный HTTPS-URL вашего сервера в настройках бота (метод
setWebhook). Мессенджер сам отправляет POST-запрос с JSON-телом обновления на этот URL сразу при событии. - Плюсы: Мгновенная доставка‚ меньшая нагрузка на ресурсы бота‚ стандарт для продакшена и высоконагруженных систем.
- Минусы: Требует публичного домена‚ валидного SSL-сертификата (TLS 1.2+)‚ открытого порта (обычно 443‚ 80‚ 88‚ 8443).
Отправка запросов от имени бота (Server-to-Bot API)
getUpdates в Telegram) с таймаутом (например‚ 30–60 секунд).- Принцип: Вы регистрируете публичный HTTPS-URL вашего сервера в настройках бота (метод
setWebhook). Мессенджер сам отправляетPOST-запрос с JSON-телом обновления на этот URL сразу при событии. - Плюсы: Мгновенная доставка‚ меньшая нагрузка на ресурсы бота‚ стандарт для продакшена и высоконагруженных систем.
- Минусы: Требует публичного домена‚ валидного SSL-сертификата (TLS 1.2+)‚ открытого порта (обычно 443‚ 80‚ 88‚ 8443).
Отправка запросов от имени бота (Server-to-Bot API)
Это самый частый кейс для разработчиков: ваш бэкенд должен отправить сообщение‚ фото‚ файл или выполнить действие (например‚ изменить меню) в чат пользователя.
Базовая структура запроса (Telegram Bot API)
Все методы Telegram Bot API вызываются по HTTPS URL следующего формата:
https://api.telegram.org/bot<TOKEN>/<METHOD_NAME> - <TOKEN> — уникальный токен вашего бота (получается у @BotFather). Формат:
123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ. - <METHOD_NAME> — имя метода (например‚
sendMessage‚sendPhoto‚editMessageText).
Метод sendMessage — отправка текстового сообщения
Самый базовый метод. Принимает параметры в теле POST-запроса (Content-Type: application/json или application/x-www-form-urlencoded).
Обязательные параметры: - chat_id (Integer или String) — уникальный идентификатор целевого чата или username канала (в формате
@channelusername). - text (String) — текст сообщения (макс. после форматирования).
Важные опциональные параметры: - disable_web_page_preview (Boolean) — отключить превью ссылок.
- disable_notification (Boolean) — отправить без звука (тихо).
- reply_to_message_id (Integer) — ID сообщения‚ на которое отвечаем.
- reply_markup (Object) — клавиатуры:
InlineKeyboardMarkup‚ ReplyKeyboardMarkup‚ ReplyKeyboardRemove‚ ForceReply.
Пример HTTP-запроса (cURL) curl -X POST "https://api.telegram.org/bot/sendMessage"
-H "Content-Type: application/json"
-d '{
"chat_id": "123456789"‚
"text": "Привет! Это жирный и курсив текст."‚ "disable_web_page_preview": true
}'
Пример на Python (библиотека requests) import requests
import json
BOT_TOKEN = "ВАШ_ТОКЕН"
CHAT_ID = "ID_ЧАТА_ИЛИ_ЮЗЕРНЕЙМ"
API_URL = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
payload = {
"chat_id": CHAT_ID‚
"text": "Сообщение отправлено через Python скрипт!"‚}
response = requests.post(API_URL‚ json=payload)
if response.status_code == 200:
print("Успешно отправлено:"‚ response.json)
else:
print("Ошибка:"‚ response.status_code‚ response.text)
Пример на Node.js (нативный fetch) const BOT_TOKEN = 'ВАШ_ТОКЕН';
const CHAT_ID = 'ID_ЧАТА';
const URL = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
async function sendMessage(text) {
const response = await fetch(URL‚ {
method: 'POST'‚
headers: { 'Content-Type': 'application/json' }‚
body: JSON.stringify({
chat_id: CHAT_ID‚
text: text‚ })
});
const data = await response.json;
if (!data.ok) throw new Error(data.description);
return data.result;
}
sendMessage('Привет из Node.js!').catch(console.error);
Работа с файлами и медиа (multipart/form-data)
@channelusername).- disable_web_page_preview (Boolean) — отключить превью ссылок.
- disable_notification (Boolean) — отправить без звука (тихо).
- reply_to_message_id (Integer) — ID сообщения‚ на которое отвечаем.
- reply_markup (Object) — клавиатуры:
InlineKeyboardMarkup‚ReplyKeyboardMarkup‚ReplyKeyboardRemove‚ForceReply.
Пример HTTP-запроса (cURL) curl -X POST "https://api.telegram.org/bot/sendMessage"
-H "Content-Type: application/json"
-d '{
"chat_id": "123456789"‚
"text": "Привет! Это жирный и курсив текст."‚ "disable_web_page_preview": true
}'
Пример на Python (библиотека requests) import requests
import json
BOT_TOKEN = "ВАШ_ТОКЕН"
CHAT_ID = "ID_ЧАТА_ИЛИ_ЮЗЕРНЕЙМ"
API_URL = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
payload = {
"chat_id": CHAT_ID‚
"text": "Сообщение отправлено через Python скрипт!"‚}
response = requests.post(API_URL‚ json=payload)
if response.status_code == 200:
print("Успешно отправлено:"‚ response.json)
else:
print("Ошибка:"‚ response.status_code‚ response.text)
Пример на Node.js (нативный fetch) const BOT_TOKEN = 'ВАШ_ТОКЕН';
const CHAT_ID = 'ID_ЧАТА';
const URL = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
async function sendMessage(text) {
const response = await fetch(URL‚ {
method: 'POST'‚
headers: { 'Content-Type': 'application/json' }‚
body: JSON.stringify({
chat_id: CHAT_ID‚
text: text‚ })
});
const data = await response.json;
if (!data.ok) throw new Error(data.description);
return data.result;
}
sendMessage('Привет из Node.js!').catch(console.error);
Работа с файлами и медиа (multipart/form-data)
curl -X POST "https://api.telegram.org/bot/sendMessage"
-H "Content-Type: application/json"
-d '{
"chat_id": "123456789"‚
"text": "Привет! Это жирный и курсив текст."‚ "disable_web_page_preview": true
}' requests) import requests
import json
BOT_TOKEN = "ВАШ_ТОКЕН"
CHAT_ID = "ID_ЧАТА_ИЛИ_ЮЗЕРНЕЙМ"
API_URL = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
payload = {
"chat_id": CHAT_ID‚
"text": "Сообщение отправлено через Python скрипт!"‚}
response = requests.post(API_URL‚ json=payload)
if response.status_code == 200:
print("Успешно отправлено:"‚ response.json)
else:
print("Ошибка:"‚ response.status_code‚ response.text) Пример на Node.js (нативный fetch) const BOT_TOKEN = 'ВАШ_ТОКЕН';
const CHAT_ID = 'ID_ЧАТА';
const URL = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
async function sendMessage(text) {
const response = await fetch(URL‚ {
method: 'POST'‚
headers: { 'Content-Type': 'application/json' }‚
body: JSON.stringify({
chat_id: CHAT_ID‚
text: text‚ })
});
const data = await response.json;
if (!data.ok) throw new Error(data.description);
return data.result;
}
sendMessage('Привет из Node.js!').catch(console.error);
Работа с файлами и медиа (multipart/form-data)
const BOT_TOKEN = 'ВАШ_ТОКЕН';
const CHAT_ID = 'ID_ЧАТА';
const URL = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
async function sendMessage(text) {
const response = await fetch(URL‚ {
method: 'POST'‚
headers: { 'Content-Type': 'application/json' }‚
body: JSON.stringify({
chat_id: CHAT_ID‚
text: text‚ })
});
const data = await response.json;
if (!data.ok) throw new Error(data.description);
return data.result;
}
sendMessage('Привет из Node.js!').catch(console.error);Для отправки фото‚ документов‚ видео‚ аудио или стикеров нельзя использовать чистый JSON. Необходимо использовать multipart/form-data.
Отправка фото по URL (проще)
Если файл уже лежит в интернете‚ передайте URL в поле photo (строка). JSON работает нормально.
Загрузка локального файла (Python пример) import requests
BOT_TOKEN = "ВАШ_ТОКЕН"
CHAT_ID = "ID_ЧАТА"
URL = f"https://api.telegram.org/bot{BOT_TOKEN}/sendPhoto"
files = {
'photo': open('image.png'‚ 'rb')
}
data = {
'chat_id': CHAT_ID‚ 'parse_mode': 'HTML'
}
response = requests.post(URL‚ data=data‚ files=files)
print(response.json)
import requests
BOT_TOKEN = "ВАШ_ТОКЕН"
CHAT_ID = "ID_ЧАТА"
URL = f"https://api.telegram.org/bot{BOT_TOKEN}/sendPhoto"
files = {
'photo': open('image.png'‚ 'rb')
}
data = {
'chat_id': CHAT_ID‚ 'parse_mode': 'HTML'
}
response = requests.post(URL‚ data=data‚ files=files)
print(response.json)Важно: Максимальный размер файла для ботов — 50 МБ. Для больших файлов используйте ссылки или загрузку через серверную часть (MTProto API / Userbot)‚ но это выходит за рамки Bot API.
Отправка запросов от пользователя к боту (Client-side)
Если вы пишете клиентское приложение (Web App‚ Mini App‚ сайт)‚ которое должно триггерить бота:
Deep Linking (Глубокие ссылки)
Самый простой способ — дать пользователю ссылку‚ которая откроет Telegram и запустит бота с параметром.
- Запуск с параметром:
https://t.me/YourBotName?start=payload123 - В группе (добавление бота):
https://t.me/YourBotName?startgroup=payload
Бот получит обновление /start payload123. Это используется для авторизации‚ реферальных программ‚ оплаты.
Telegram Web Apps (Mini Apps)
Современный стандарт. Ваше веб-приложение открывается внутри Telegram. Обмен данными происходит через Telegram.WebApp SDK:
// Отправка данных боту (закрывает веб-апп и шлет данные в чат)
Telegram.WebApp.sendData(JSON.stringify({ action: "buy"‚ item_id: 42 })); Бот получает объект web_app_data в сообщении.
Login Widget (Виджет входа)
Для авторизации на сайте через Telegram. Пользователь нажимает кнопку‚ подтверждает вход‚ сайт получает хэшированные данные (id‚ first_name‚ username‚ photo_url‚ auth_date‚ hash). Проверка подлинности происходит на бэкенде с использованием токена бота.
Bot-to-Bot: Как один бот пишет другому
Сценарий из предоставленного вами источника: Бот-Админ отправляет уведомление Боту-Уведомителю‚ или Бот-Агрегатор пересылает сообщение в Бот-Канал.
Главное ограничение
Боты не могут инициировать диалог с другими ботами или пользователями первыми. Бот Б может написать Боту А только если:
- Бот А добавил Бота Б в группу/канал как администратора/участника.
- Бот А ранее писал Боту Б (есть история чата)‚ и Бот Б знает
chat_idБота А (обычно это ID пользователя-владельца или ID чата).
Алгоритм (на примере источника mcn.ru) - Узнайте
chat_id получателя (бота или чата‚ где он есть). Самый простой способ, переслать сообщение от целевого бота/чата сервису вроде @userinfobot или @getmyid_bot. - Используйте токен отправителя (Бота Б).
- Вызовите метод
sendMessage с chat_id получателя.
Пример URL (как в источнике): https://api.telegram.org/bot/sendMessage?chat_id=&text=Текст_сообщения
chat_id получателя (бота или чата‚ где он есть). Самый простой способ, переслать сообщение от целевого бота/чата сервису вроде @userinfobot или @getmyid_bot.sendMessage с chat_id получателя.https://api.telegram.org/bot/sendMessage?chat_id=&text=Текст_сообщения Лучшая практика: Всегда используйте POST с JSON-телом‚ а не GET с параметрами в строке (длина URL ограничена‚ плюс проблемы с кодировкой спецсимволов).
Обработка ошибок и лимиты (Rate Limits)
Telegram API возвращает JSON-объект с полем ok (boolean). Если false, смотрите error_code и description.
| Код ошибки | Описание | Решение |
|---|---|---|
| 400 Bad Request | Проверьте валидацию входных данных‚ экранируйте спецсимволы для parse_mode. | |
| 401 Unauthorized | Неверный токен бота | Проверьте токен‚ не перегенерировали ли вы его у @BotFather. |
| 403 Forbidden | Бот заблокирован пользователем / нет прав в чате / бот не может писать боту | Нельзя заставить пользователя разблокировать; В группах дайте права админа. |
| 429 Too Many Requests | Превышен лимит запросов (Flood control) | Обязательно обрабатывайте параметр retry_after (секунды) в ответе и ждите перед повтором. |
| 500/502/503 | Ошибки сервера Telegram | Экспоненциальный бэкоф (повтор через 1с‚ 2с‚ 4с…). |
Основные лимиты (неофициальные‚ но проверенные): - В личку: ~30 сообщений в секунду (но не более 1 сообщ/сек для одного пользователя‚ иначе 429).
- В группу/канал: ~20 сообщений в минуту (для одного чата).
- Глобально: ~30 запросов в секунду на токен.
Совет: Используйте очереди сообщений (RabbitMQ‚ Redis Streams‚ BullMQ) с rate-limiter’ом для массовых рассылок.
Безопасность и лучшие практики - Никогда не публикуйте токен в GitHub‚ логах‚ фронтенде. Используйте переменные окружения (
.env‚ Docker secrets‚ K8s Secrets). - Проверяйте Webhook Secret Token: При настройке вебхука передайте параметр
secret_token. Telegram будет присылать заголовок X-Telegram-Bot-Api-Secret-Token. Проверяйте его на входе — это защита от поддельных запросов. - Валидация
chat_id: Убедитесь‚ что бот отвечает только разрешенным пользователям/чатам (whitelist)‚ если это приватный бот. - Идемпотентность: Для критических действий (оплата‚ запись на прием) используйте уникальные ID операций‚ чтобы повторная отправка запроса (ретрай) не создала дубликат.
Альтернативы и продвинутые инструменты Библиотеки-обертки (Рекомендуется для продакшена)
.env‚ Docker secrets‚ K8s Secrets).secret_token. Telegram будет присылать заголовок X-Telegram-Bot-Api-Secret-Token. Проверяйте его на входе — это защита от поддельных запросов.chat_id: Убедитесь‚ что бот отвечает только разрешенным пользователям/чатам (whitelist)‚ если это приватный бот.Библиотеки-обертки (Рекомендуется для продакшена)
Писать чистые HTTP-запросы вручную утомительно и чревато ошибками. Используйте проверенные фреймворки:
- Python:
aiogram 3.x(async‚ современный)‚python-telegram-bot(sync/async‚ очень зрелый)‚telebot (pyTelegramBotAPI)(простой‚ синхронный). - Node.js:
Telegraf(стандарт де-факто)‚Grammy(быстрый‚ типизированный‚ современный). - Go:
telebot(tucnak/telebot)‚telego. - .NET:
Telegram.Bot. - Java/Kotlin:
TelegramBots‚Kotlin Telegram Bot.
Они сами управляют Long Polling/Webhooks‚ сериализацией‚ ретраями и предоставляют удобные методы: bot.send_message(...).
MTProto API (Userbot / Client API)
Если Bot API не хватает (нужно работать с историями‚ удалять чужие сообщения без админки‚ обходить лимит 50МБ‚ парсить чаты без участия бота) — используйте MTProto (библиотеки: Telethon‚ Pyrogram для Python‚ GramJS для JS).
Внимание: Это API пользователей. Автоматизация через него строго регулируется ToS Telegram. Риск бана аккаунта выше. Для легальных ботов всегда предпочитайте Bot API.
Чек-лист перед запуском в продакшн - [ ] Токен бота хранится в секретах‚ не в коде.
- [ ] Настроен Webhook (для продакшена) с валидным SSL и секретным токеном.
- [ ] Реализована обработка ошибки
429 (retry_after). - [ ] Тексты сообщений экранируются под используемый
parse_mode. - [ ] Логируются входящие обновления и исходящие ошибки (без токенов и PII).
- [ ] Настроен Graceful Shutdown (корректное завершение: удаление вебхука / остановка поллинга при деплое).
- [ ] Протестирована отправка медиа (фото‚ документы) через
multipart/form-data. - [ ] Реализована очередь для рассылок (Broadcast) с соблюдением лимитов.
429 (retry_after).parse_mode.multipart/form-data.Отправка запроса боту — это стандартный HTTP-взаимодействие с REST API мессенджера. Ключевые моменты успеха:
- Понимание разницы между получением обновлений (Polling/Webhook) и отправкой методов (sendMessage и др.).
- Правильное формирование
chat_idи токена. - Учет лимитов частоты (Rate Limits) и реализация ретраев с бэкофом.
- Использование проверенных библиотек вместо ручного
curl/fetchв бизнес-логике.
Начните с простого скрипта на Python/Node.js с библиотекой aiogram/Grammy‚ разверните на сервере с Webhook’ом — и у вас будет надежная основа для любых бот-сценариев.