Чтобы написать Telegram-бота на Python, нужны три вещи: токен от @BotFather, библиотека pyTelegramBotAPI и файл bot.py на полтора десятка строк. Токен выдаёт сам Telegram за пару минут, библиотека ставится одной командой pip install pyTelegramBotAPI, а запускается бот командой python bot.py в терминале. Пока скрипт работает, бот отвечает в чате.
Ниже весь путь по шагам: от регистрации до кнопок, запроса во внешний API и запуска на сервере. Код рассчитан на Python 3.11 и новее и pyTelegramBotAPI 4.37.1. Если нужен бот без программирования, вам в соседнюю инструкцию по BotFather и настройке команд.
SkillboxПрофессия «Python-разработчик»157 335 ₽10 месяцев
НетологияFullstack-разработчик на Python145 100 ₽21 месяц
GeekBrainsДО Профессия Python-разработчик149 001 ₽10 месяцев
SkillFactoryПрофессия Python-разработчик154 044 ₽10 месяцев
Академия СинергияPython-разработчик + ИИ77 900 ₽6 месяцев
ЭдюсонPython-разработчик119 892 ₽9 месяцев
Что понадобится до начала

- Python 3.11 или новее. Свежая pyTelegramBotAPI 4.37.1 (вышла 17 октября 2026 года) требует именно его, это указано на странице библиотеки на PyPI. Если Python ещё нет, вот как установить его на Windows, macOS и Linux. А если сам язык пока незнаком, основы дают онлайн-курсы Python.
- Аккаунт в Telegram на телефоне или компьютере: через него вы получите токен.
- Редактор кода. Подойдёт любой, мы пишем в VS Code: как создать и запустить в нём файл Python.
- Минут 20 на первую версию и ещё столько же на кнопки.
Шаг 1: получите токен у BotFather
Токен служит паролем: по нему ваш скрипт управляет ботом. Его выдаёт официальный бот Telegram @BotFather.
- Найдите в поиске Telegram @BotFather, проверьте написание имени до буквы и начните с ним чат.
- Отправьте команду
/newbot. - Введите имя бота. Его увидят в шапке чата, писать можно по-русски: «Курс и погода».
- Введите username, то есть адрес вида @kurs_pogoda_bot. Правила из документации Telegram: от 5 до 32 символов, только латиница, цифры и подчёркивание, в конце обязательно
bot. Поменять username потом нельзя, имя можно. - BotFather пришлёт токен вида
110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw. Скопируйте его целиком, вместе с цифрами до двоеточия.
Токен никому не показывайте и не выкладывайте в открытый репозиторий: с ним любой может писать от имени вашего бота. Если токен утёк, отправьте BotFather команду
/token: как сказано в справке по BotFather, она выпускает новый токен, его нужно вписать в.env.
Сайты документации Telegram из России открываются не всегда, поэтому главные правила мы переписали сюда.
Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединитьсяШаг 2: создайте проект и установите библиотеку
Сделайте папку проекта и виртуальное окружение в ней. Окружение нужно, чтобы библиотеки бота не смешивались с другими проектами.
# macOS и Linux
mkdir tgbot && cd tgbot
python3 -m venv .venv
source .venv/bin/activate
# Windows (PowerShell)
mkdir tgbot; cd tgbot
python -m venv .venv
.venv\Scripts\Activate.ps1
# дальше одинаково
pip install pyTelegramBotAPI python-dotenv requests
Рядом с будущим bot.py создайте файл .env и положите туда токен:
BOT_TOKEN=110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw
Так токен не попадёт в код. Если будете хранить проект в Git, допишите строку .env в файл .gitignore.
Какую библиотеку выбрать
Библиотек для Telegram на Python три популярных. Для первого бота мы взяли самую простую по синтаксису:
| Библиотека | Как пишется код | Кому подойдёт |
|---|---|---|
| pyTelegramBotAPI | Обычные функции, есть и асинхронный вариант AsyncTeleBot | Первый бот, учебные и небольшие проекты |
| aiogram | Полностью асинхронный, на asyncio, Python 3.10+ | Ботам с большой нагрузкой и сложными сценариями |
| python-telegram-bot | Асинхронный интерфейс, Python 3.10+ | Тем, кому нужны готовые сокращения и обёртки поверх Bot API |
Асинхронность нужна, когда бот обслуживает много людей одновременно и не ждёт ответа на каждый запрос. Боту на десятки пользователей она ни к чему, а читать такой код новичку тяжелее.
Шаг 3: напишите эхо-бота

Эхо-бот повторяет всё, что ему пишут. На нём видно, как устроен любой бот: получил сообщение → выбрал обработчик → ответил. Создайте bot.py:
import os
import telebot
from dotenv import load_dotenv
load_dotenv()
bot = telebot.TeleBot(os.getenv("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, message.text)
print("Бот запущен")
bot.infinity_polling()
Что здесь происходит:
load_dotenv()читает файл.env, аos.getenv("BOT_TOKEN")достаёт из него токен.@bot.message_handler(...)называется декоратором. Он говорит библиотеке, какие сообщения отдавать функции под ним. Обработчики при этом остаются обычными функциями Python, объявленными через def. Первый ловит команду /start, второй любой текст.message.chat.idхранит номер чата, куда отправлять ответ.bot.infinity_polling()раз за разом спрашивает у Telegram, нет ли новых сообщений. По описанию в библиотеке, это опрос в бесконечном цикле с обработкой исключений, чтобы бот не останавливался из-за сбоя.
Запустите скрипт из папки проекта командой python bot.py. В терминале появится «Бот запущен», а в Telegram бот начнёт отвечать:
Вы: /start
Бот: Привет! Напишите что-нибудь, и я повторю
Вы: Привет, бот
Бот: Привет, бот
Остановить бота можно сочетанием Ctrl+C в терминале. Пока скрипт не запущен, бот не отвечает.
Шаг 4: добавьте команды, кнопки и внешний API
Дальше расширяем того же бота. Приветствие теперь обращается к человеку по имени: его подставляет f-строка f"Привет, {message.from_user.first_name}!". Полный код в конце раздела, его можно скопировать целиком.
Меню команд
Чтобы при вводе «/» пользователь видел подсказки, список команд нужно зарегистрировать. Это делается командой /setcommands у BotFather или одной строкой из кода:
from telebot import types
bot.set_my_commands([
types.BotCommand("start", "Начать"),
types.BotCommand("help", "Подсказка"),
types.BotCommand("site", "Ссылка на сайт"),
])
Telegram хранит список у себя, текущий отдаёт метод getMyCommands (документация Telegram из России открывается не всегда). Поэтому вызывать set_my_commands при каждом запуске не нужно, хватит одного раза после изменения списка.
Кнопки под полем ввода
ReplyKeyboardMarkup заменяет клавиатуру телефона набором кнопок. Нажатие кнопки отправляет её текст как обычное сообщение, поэтому ловится оно фильтром по тексту: func=lambda m: m.text == "Помощь".
Кнопки под сообщением
InlineKeyboardMarkup прикрепляет кнопки к конкретному сообщению. Кнопка бывает ссылкой (url=) или отправляет боту скрытые данные (callback_data=), их ловит callback_query_handler.
В обработчике нажатия обязательно вызывайте bot.answer_callback_query(call.id). По описанию CallbackQuery в Bot API, пока бот этого не сделал, приложение показывает на кнопке индикатор загрузки (страница документации из России открывается не всегда).
Запрос во внешний API: курс доллара
Бот умеет не только отвечать заготовками. Для примера возьмём официальный курс Банка России: ЦБ отдаёт его в формате XML по адресу cbr.ru/scripts/XML_daily.asp, ключ не нужен.
Библиотека requests скачивает ответ, а модуль xml.etree из стандартной поставки Python находит в нём доллар. Как вообще устроены такие запросы, мы разбирали в статье про API простыми словами.
Полный код бота
import os
import xml.etree.ElementTree as ET
from datetime import datetime
import requests
import telebot
from dotenv import load_dotenv
from telebot import types
load_dotenv()
bot = telebot.TeleBot(os.getenv("BOT_TOKEN"))
@bot.message_handler(commands=["start"])
def start(message):
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
keyboard.add("Курс доллара", "Помощь")
bot.send_message(
message.chat.id,
f"Привет, {message.from_user.first_name}! Я бот-попугай: повторю всё, что напишете.",
reply_markup=keyboard,
)
@bot.message_handler(commands=["help"])
@bot.message_handler(func=lambda m: m.text == "Помощь")
def help_command(message):
bot.send_message(message.chat.id, "Команды: /start — начать, /help — подсказка, /site — ссылка на сайт")
@bot.message_handler(func=lambda m: m.text == "Курс доллара")
def usd_rate(message):
try:
response = requests.get("https://www.cbr.ru/scripts/XML_daily.asp", timeout=10)
root = ET.fromstring(response.content)
value = root.find("Valute[CharCode='USD']/Value").text
text = f"Курс ЦБ на {root.get('Date')}: 1 $ = {value} ₽"
except (requests.RequestException, ET.ParseError, AttributeError):
text = "Сайт ЦБ сейчас не ответил, попробуйте через минуту"
bot.send_message(message.chat.id, text)
@bot.message_handler(commands=["site"])
def site(message):
markup = types.InlineKeyboardMarkup()
markup.add(types.InlineKeyboardButton("Открыть сайт", url="https://checkroi.ru/"))
markup.add(types.InlineKeyboardButton("Показать время", callback_data="time"))
bot.send_message(message.chat.id, "Выберите действие:", reply_markup=markup)
@bot.callback_query_handler(func=lambda call: call.data == "time")
def show_time(call):
bot.answer_callback_query(call.id)
bot.send_message(call.message.chat.id, datetime.now().strftime("Сейчас %H:%M"))
@bot.message_handler(content_types=["text"])
def echo(message):
bot.send_message(message.chat.id, message.text)
if __name__ == "__main__":
print("Бот запущен")
bot.infinity_polling()
Так бот ответил нам 21 октября 2026 года:
Вы: /start
Бот: Привет, Аня! Я бот-попугай: повторю всё, что напишете.
[Курс доллара] [Помощь]
Вы: Курс доллара
Бот: Курс ЦБ на 21.10.2026: 1 $ = 82,8879 ₽
Вы: /site
Бот: Выберите действие:
[Открыть сайт]
[Показать время]
(нажатие «Показать время») → Сейчас 20:16
Порядок обработчиков важен. Библиотека проверяет их сверху вниз и отдаёт сообщение первому подходящему. Эхо-обработчик ловит любой текст, поэтому он стоит последним.
Блок try/except в usd_rate нужен на случай, если сайт ЦБ не ответил за 10 секунд: тогда бот пришлёт понятную фразу и продолжит работать.
Почему бот не отвечает: ошибки по симптомам
Ниже ошибки, из-за которых первый бот обычно не запускается или не отвечает, с тем текстом, что пишет терминал.
| Что видите | Причина | Что сделать |
|---|---|---|
ModuleNotFoundError: No module named 'telebot' |
Библиотека установлена в другой Python, чаще всего не активировано окружение | Активируйте .venv и поставьте библиотеку заново: python -m pip install pyTelegramBotAPI |
TypeError: 'NoneType' object is not iterable на строке с TeleBot |
Токен не прочитался: нет файла .env или скрипт запущен из другой папки |
Запускайте из папки проекта, проверьте имя переменной BOT_TOKEN |
ValueError: Token must contain a colon |
Скопирована только часть токена | Скопируйте токен у BotFather заново, вместе с цифрами до двоеточия |
Error code: 401. Description: Unauthorized |
Токен неверный: опечатка, лишний символ или токен от другого бота | Возьмите актуальный токен в BotFather |
ConnectTimeout или «Connection timed out» |
Компьютер или сервер не может связаться с api.telegram.org | Проверьте связь командой ниже, код тут ни при чём |
| На /start бот отвечает «/start» | Эхо-обработчик стоит выше остальных и забирает все сообщения | Перенесите его в конец файла |
| В группе бот не видит обычные сообщения | Режим приватности: по умолчанию бот в группе получает только команды и ответы себе | Сделайте бота админом группы или выключите режим через /setprivacy у BotFather, после чего добавьте бота в группу заново |
| Бот работал, а после экспериментов перестал получать сообщения | Для бота включён вебхук, а при нём опрос getUpdates не работает |
Вызовите bot.remove_webhook() перед infinity_polling() |
Про режим приватности и вебхуки подробно написано в разделе Privacy Mode и в описании getUpdates. Оба раздела из России открываются не всегда, главное из них уже в таблице.
Проверить связь с Telegram
В феврале 2026 года Роскомнадзор объявил о замедлении Telegram в России, и с части машин api.telegram.org не отвечает. Проверьте это с того компьютера, где запускаете бота:
curl -sS -m 10 -o /dev/null -w '%{http_code}\n' https://api.telegram.org/
Ответ 302 значит, что связь есть и искать ошибку нужно в коде. curl: (28) Connection timed out значит, что эта машина до Telegram не достаёт и бот на ней работать не будет.
Как оставить бота работать без вашего компьютера

Бот живёт, пока работает скрипт. Закрыли ноутбук, и бот перестал отвечать. Сообщения при этом не теряются сразу: по разделу Getting updates в Bot API Telegram хранит их не дольше 24 часов (сайт документации из России открывается не всегда). Если запустите бота за это время, он их получит.
Чтобы бот отвечал круглосуточно, его переносят на сервер с Linux. Код туда удобно возить через Git, а файл .env с токеном создать прямо на сервере. Дальше скрипт оформляют как службу systemd, тогда он сам перезапустится после сбоя или перезагрузки.
- Заведите на сервере отдельного пользователя
bot, скопируйте проект в/home/bot/tgbot, создайте там окружение и поставьте библиотеки, как в шаге 2. - Создайте файл
/etc/systemd/system/tgbot.service:[Unit] Description=Telegram bot After=network-online.target Wants=network-online.target [Service] User=bot WorkingDirectory=/home/bot/tgbot ExecStart=/home/bot/tgbot/.venv/bin/python bot.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target - Включите службу и посмотрите журнал:
sudo systemctl daemon-reload sudo systemctl enable --now tgbot journalctl -u tgbot -f
Перед переносом прогоните на сервере проверку связи из предыдущего раздела.
У способа, которым мы получаем сообщения, есть альтернатива, вебхук. При нём Telegram сам присылает каждое сообщение на ваш сервер, и для этого нужен публичный HTTPS-адрес. Для первого бота опроса через infinity_polling() хватает.
Где освоить Python, чтобы бот вырос
Эхо-бот с кнопками собирается за вечер. Следующий уровень сложнее: база данных для пользователей, оплата, подключение нейросети (например, GigaChat API на Python), тесты и деплой. Здесь уже не обойтись копированием примеров, нужен уверенный Python.
Если боты вам интересны как работа, почитайте, кто такой разработчик чат-ботов и как стать Python-разработчиком с нуля, а программы именно по ботам собраны на странице курсов для разработчиков Telegram-ботов. А курсы, где Python учат системно, есть в каталоге:
| Курс | Школа | Стоимость со скидкой | В рассрочку | Длительность | Обзор курса от Checkroi |
|---|---|---|---|---|---|
| Профессия «Python-разработчик» Перейти на сайт курса | 157 335 ₽ | 5987 ₽/мес. | 10 месяцев | Обзор курса | |
| Fullstack-разработчик на Python Перейти на сайт курса | 145 100 ₽ | 7125 ₽/мес. | 21 месяц | Обзор курса | |
| ДО Профессия Python-разработчик Перейти на сайт курса | 149 001 ₽ | 3167 ₽/мес. | 10 месяцев | Обзор курса | |
| Автоматизированное тестирование на Python Перейти на сайт курса | 122 226 ₽ | 4108 ₽/мес. | 9 месяцев | Обзор курса | |
| Программирование на Python ПРО Перейти на сайт курса | 119 600 ₽ | - | 17 месяцев | Обзор курса |
Больше программ — в полном каталоге курсов по Python




