Телеграм-бот — это программа, которая через официальный Bot API Telegram получает сообщения от пользователей и отправляет ответы. На Python такого бота собирают за один вечер: логику пишете вы, а доставку сообщений и хранение чатов берет на себя сервер Telegram.
Содержание
- Что нужно различать: бот, Bot API и библиотека
- Шаг 1. Получаем токен у BotFather
- Шаг 2. Устанавливаем библиотеку
- Шаг 3. Минимальный рабочий бот целиком
- Шаг 4. Разбираем по строкам
- Шаг 5. Добавляем команды
- Шаг 6. Добавляем кнопки
- Если бот молчит: диагностика по симптому
- Альтернатива: pyTelegramBotAPI
- Выводы
- Где применяется / связь с практикой
- FAQ
Ниже — рабочий маршрут до конкретного результата: получить токен у BotFather, установить библиотеку, запустить минимального бота целиком, а потом по строкам разобрать, как он устроен, и добавить команды и кнопки. Пример базовый: без баз данных, генерации картинок и контейнеров — только каркас, на который потом наращивают функции.
Что нужно различать: бот, Bot API и библиотека
Три вещи, которые новички путают:
- Bot API — это HTTP-интерфейс на стороне Telegram. Именно он принимает и отдает сообщения.
- Библиотека (aiogram, pyTelegramBotAPI) — это обертка на Python над Bot API, чтобы не писать HTTP-запросы руками.
- Ваш код — это обработчики (handlers): функции, которые решают, что ответить на конкретное сообщение или команду.
Сервер Telegram хранит очередь сообщений, а программа их забирает и отвечает. Забирать можно двумя способами: long polling (программа сама опрашивает сервер) или webhook (сервер сам шлет обновления на ваш адрес). В туториале используем polling — он не требует домена и HTTPS и запускается прямо на ноутбуке.
Шаг 1. Получаем токен у BotFather
Токен — это ключ доступа к вашему боту. Порядок действий:
- В Telegram найдите аккаунт @BotFather (с синей галочкой).
- Отправьте команду
/newbot. - Введите отображаемое имя бота (любое) и username — он должен заканчиваться на
botи быть уникальным, напримерmy_first_echo_bot. - BotFather пришлет строку вида
123456789:AAExampleTokenStringHere— это и есть токен.
Токен дает полный контроль над ботом, поэтому не публикуйте его в коде, репозитории или скриншотах. Если токен утек — в чате с BotFather выполните /revoke: старый ключ отключится и вы получите новый.
Шаг 2. Устанавливаем библиотеку
Для новых проектов беру aiogram — это современная асинхронная библиотека (актуальная ветка — aiogram 3.x). Асинхронность важна, когда бот обрабатывает много чатов одновременно: пока один запрос ждет ответа сети, обрабатываются другие.
Установка в отдельное виртуальное окружение:
python -m venv venv
source venv/bin/activate
pip install aiogram
В Windows активация окружения — venv\Scripts\activate.
Токен не хардкодим, а читаем из переменной окружения. Перед запуском задайте ее в терминале (Linux, macOS):
export BOT_TOKEN="123456789:AAExampleTokenStringHere"
В Windows PowerShell — $env:BOT_TOKEN="...". Так секрет остается вне кода: файл со скриптом можно спокойно коммитить.
Шаг 3. Минимальный рабочий бот целиком
Сначала — законченный файл, который копируется и запускается. Это эхо-бот: на /start он здоровается, на любой текст отвечает тем же текстом.
import os
import asyncio
from aiogram import Bot, Dispatcher
from aiogram.filters import CommandStart
from aiogram.types import Message
bot = Bot(token=os.environ["BOT_TOKEN"])
dp = Dispatcher()
@dp.message(CommandStart())
async def start_handler(message: Message):
await message.answer("Привет! Я эхо-бот. Напиши мне что-нибудь.")
@dp.message()
async def echo_handler(message: Message):
await message.answer(f"Ты написал: {message.text}")
async def main():
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
Сохраните как bot.py и запустите python bot.py. Консоль останется занятой — это нормально, бот работает и ждет сообщений. Откройте своего бота в Telegram, нажмите Start: придет «Привет! Я эхо-бот…». Напишите «тест» — бот ответит «Ты написал: тест». Остановить бота — Ctrl+C.
Шаг 4. Разбираем по строкам
Теперь тот же код по частям.
import os— доступ к переменным окружения, из них берем токен.Bot(token=os.environ["BOT_TOKEN"])— объект бота.os.environ["BOT_TOKEN"]читает ранее заданную переменную; если ее нет, программа сразу упадет сKeyError, и это правильнее, чем работать без токена.Dispatcher()— диспетчер: он смотрит на входящее сообщение и выбирает подходящий обработчик.@dp.message(CommandStart())— декоратор-фильтр. Функция под ним сработает только на команду/start.@dp.message()без фильтра — ловит все остальные сообщения. Порядок важен: обработчики проверяются сверху вниз, поэтому более узкий фильтр/startстоит выше общего.async defиawait message.answer(...)— функции асинхронные, аmessage.answerотправляет ответ в тот же чат.awaitждет завершения отправки, не блокируя другие чаты.dp.start_polling(bot)— запускает опрос сервера в цикле.asyncio.run(main())— точка входа: запускает асинхронный цикл.
Ключевая идея: вы описываете обработчики, а диспетчер сам маршрутизирует к ним входящие сообщения.
Шаг 5. Добавляем команды
Команды — это сообщения, начинающиеся с /. Добавим /help. Дописать нужно импорт Command и новый обработчик выше общего echo_handler:
from aiogram.filters import Command
@dp.message(Command("help"))
async def help_handler(message: Message):
await message.answer(
"Я умею:\n"
"/start - начать\n"
"/help - эта справка\n"
"Любой текст я повторю в ответ."
)
Чтобы команды показывались в меню слева от поля ввода, их список задают у BotFather командой /setcommands, либо программно через bot.set_my_commands(...). Это удобство для пользователя, а не обязательный шаг.
Шаг 6. Добавляем кнопки
Кнопки бывают двух видов, их часто путают:
| Тип | Класс | Где появляется | Что шлет при нажатии |
|---|---|---|---|
| Reply-кнопки | ReplyKeyboardMarkup | вместо клавиатуры | обычное текстовое сообщение |
| Inline-кнопки | InlineKeyboardMarkup | под самим сообщением | callback (скрытые данные) |
Inline-кнопки не засоряют чат текстом, поэтому для действий берут их. Добавим кнопку в ответ на /help. Нужны импорты клавиатуры, тип CallbackQuery и «магический фильтр» F для разбора callback:
from aiogram import F
from aiogram.types import (
CallbackQuery,
InlineKeyboardButton,
InlineKeyboardMarkup,
)
@dp.message(Command("menu"))
async def menu_handler(message: Message):
keyboard = InlineKeyboardMarkup(
inline_keyboard=[
[InlineKeyboardButton(text="Поздороваться", callback_data="say_hi")]
]
)
await message.answer("Нажми кнопку:", reply_markup=keyboard)
@dp.callback_query(F.data == "say_hi")
async def hi_callback(callback: CallbackQuery):
await callback.message.answer("Привет из кнопки!")
await callback.answer()
Разбор:
callback_data="say_hi"— метка, которая придет обратно при нажатии. По ней и различают кнопки, если их несколько.@dp.callback_query(F.data == "say_hi")— обработчик срабатывает, когда пришел callback именно с этой меткой.await callback.answer()в конце обязателен: без него у кнопки останется «часики» загрузки. Этот вызов гасит индикатор и ничего не пишет в чат.
Добавьте команду /menu к обработчикам, перезапустите бота — появится сообщение с кнопкой, а по нажатию придет ответ.
Если бот молчит: диагностика по симптому
KeyError: 'BOT_TOKEN'при старте — переменная окружения не задана в этом же терминале. Экспортируйте токен и запускайте бота в том же окне.TokenValidationErrorили ошибка 401 Unauthorized — токен неверный или отозван. Скопируйте его заново у BotFather без пробелов.- Бот запустился, но не отвечает — вероятно, запущены две копии одного бота (например, в двух терминалах). Telegram отдает обновление только одному потребителю; закройте лишние процессы. Также проверьте, что пишете именно тому боту, чей токен используете.
- Отвечает на текст, но не на команду — общий обработчик
@dp.message()стоит выше обработчика команды и перехватывает ее. Поднимите фильтры команд выше.
Альтернатива: pyTelegramBotAPI
Если асинхронность пока избыточна и нужен простой синхронный код, берут pyTelegramBotAPI (импортируется как telebot). Тот же эхо-бот на ней короче:
import os
import telebot
bot = telebot.TeleBot(os.environ["BOT_TOKEN"])
@bot.message_handler(commands=["start"])
def start(message):
bot.send_message(message.chat.id, "Привет! Я эхо-бот.")
@bot.message_handler(content_types=["text"])
def echo(message):
bot.send_message(message.chat.id, f"Ты написал: {message.text}")
bot.infinity_polling()
Выбор между библиотеками:
| Критерий | aiogram 3.x | pyTelegramBotAPI |
|---|---|---|
| Модель | асинхронная (async/await) | по умолчанию синхронная |
| Порог входа | чуть выше | ниже |
| Много чатов сразу | обрабатывает эффективно | упирается в блокировки |
| Когда брать | боты «на вырост», нагрузка | быстрый прототип, учеба |
Для нового проекта, который будет расти, разумнее сразу aiogram. Для первого учебного бота подойдет любая.
Выводы
- Телеграм-бот на Python — это ваши обработчики поверх Bot API; доставку сообщений берет на себя сервер Telegram.
- Токен получают у BotFather и хранят в переменной окружения, а не в коде; при утечке отзывают через
/revoke. - Минимальный рабочий бот на aiogram 3.x — это объект
Bot,Dispatcherи пара обработчиков подstart_polling. - Команды задают фильтром
Command, а действия удобнее вешать на inline-кнопки сcallback_dataи обязательнымcallback.answer(). - Polling запускается локально без домена; webhook нужен позже, для боевого размещения.
Где применяется / связь с практикой
Телеграм-боты — частая первая рабочая задача Python-джуна: автоответчик поддержки, уведомления из CI, напоминания, сбор заявок. Каркас из этой статьи масштабируется до таких проектов, если добавить хранение данных, обработку ошибок и вынос токена в конфигурацию.
Освойте тему на практике
Системно разобраться с синтаксисом, функциями, окружениями и асинхронностью помогает курс Python Basic: на нем как раз доводят учебные проекты до запускаемого результата. Посмотреть формат занятий и задать вопросы преподавателю можно на открытых уроках Otus — они бесплатные.
FAQ
Нужен ли сервер, чтобы бот работал постоянно?
Для учебы — нет, хватает вашего компьютера с запущенным скриптом. Как только закрываете программу, бот перестает отвечать. Для круглосуточной работы бота размещают на VPS или в облаке и запускают как сервис.
Можно ли писать боту на русском и распознавать русские команды?
Текст сообщений может быть любым, в том числе русским, и вы сравниваете его в коде как обычную строку. Но сами команды-слэши (/start) Telegram ждет латиницей, поэтому русские «команды» реализуют как обычный текст или кнопки.
Чем polling отличается от webhook и что выбрать новичку?
При polling программа сама опрашивает сервер Telegram и не требует домена — берите его для старта. Webhook — это когда Telegram сам шлет обновления на ваш HTTPS-адрес; он нужен для боевого размещения и требует настроенного сервера с сертификатом.



