Больше не нужно искать работу мечты — присоединяйтесь к команде Клауда

Как создать телеграм-бота на Python: инструкция

Илья Ушаков
Илья Ушаков
Технический писатель
07 февраля 2023 г.
33043
6 минут чтения
Средний рейтинг статьи: 4.2

Наверняка вам уже приходилось сталкиваться с ботами в Telegram. Боты помогают автоматизировать рутинные задачи как для обычных пользователей (например, боты-планировщики или боты для учета финансов), так и для компаний. Последние могут использовать ботов-рекламщиков, которые занимаются рассылками по клиентской базе, ботов-ассистентов, которые выполняют роль технической поддержки, и так далее.

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

Как создать бота в Telegram на Python пошагово 

Шаг 1. Регистрация бота в BotFather

В первую очередь зарегистрируйте бота в Telegram. Для этого введите в поисковой строке мессенджера @BotFather и перейдите к нему, как это показано на картинке ниже.

Image4

После нажмите кнопку «Запустить» в нижней части окна и выберите в открывшемся списке команду /newbot. Бот предложит указать имя создаваемого бота. В нашем случае укажем TimewebCloudBot, и его же продублируем в качестве короткого имени.

После этого бот будет создан. 

Надежно сохраните токен бота — в будущем он понадобится для авторизации и работы с ботом.

Шаг 2. Подготовка необходимых компонентов

Переходим к подготовке необходимых компонентов. На вашем компьютере должен быть установлен Python и среда разработки (в нашем случае это PyCharm).

Установить Python на Windows 10 можно по нашей инструкции, а после скачать PyCharm с сайта разработчика и установить его.

В качестве библиотеки мы будем использовать pyTelegramBotAPI. Установить ее можно, с помощью следующей команды:

pip install pyTelegramBotAPI

Все необходимые компоненты установлены. Переходим к следующему шагу.

Cloud server

Шаг 3. Написание кода

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

import telebot

botTimeWeb = telebot.TeleBot('Уникальный токен')

from telebot import types

Вместо Уникальный токен укажите токен, который вы получили при регистрации бота. Кавычки необходимо сохранить.

Теперь реализуем так называемые обработчики сообщений. Они отвечают за фильтрацию входящих сообщений бота и вызов указанной функции для этих сообщений. 

С помощью кода ниже реализуйте команду /start, которая будет отвечать за запуск бота:

@botTimeWeb.message_handler(commands=['start'])
def startBot(message):
  first_mess = f"<b>{message.from_user.first_name} {message.from_user.last_name}</b>, привет!\nХочешь расскажу немного о нашей компании?"
  markup = types.InlineKeyboardMarkup()
  button_yes = types.InlineKeyboardButton(text = 'Да', callback_data='yes')
  markup.add(button_yes)
  botTimeWeb.send_message(message.chat.id, first_mess, parse_mode='html', reply_markup=markup)

Разберем написанный выше код по порядку. 

Первые две строчки объявляют метод обработки входящих сообщений. В нашем случае в качестве параметра передается команда /start

Далее объявляется переменная first_mess, хранящая указанную строку. Она будет отображаться пользователю после вызова команды /start. Здесь также используется объект Message, необходимый для определения имени (first_name) и фамилии (last_name) пользователя. 

Далее следуют 3 строчки кода, отвечающие за добавление кнопки, которая в будущем будет перенаправлять пользователя на следующее сообщение. Тип данной кнопки — Inline. Это значит, что такая кнопка будет отображаться прямо под сообщением. Для ее создания необходимо использовать метод InlineKeyboardButton. Параметр text отвечает за имя кнопки, а callback_data — за возвращаемую строку при нажатии. Второй параметр понадобится для реализации функционала кнопки.

И наконец, добавляется метод send_message, необходимый для отправки сообщения пользователю. У него указаны 4 параметра:

  • message.chat.id отвечает за синхронизацию сообщения с чатом бота;
  • first_mess передает ранее указанное сообщение;
  • parse_mode необходим для указания режима разметки сообщений;
  • reply_markup отвечает за добавление созданной кнопки.

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

@botTimeWeb.callback_query_handler(func=lambda call:True)
def response(function_call):
  if function_call.message:
     if function_call.data == "yes":
        second_mess = "Мы облачная платформа для разработчиков и бизнеса. Более детально можешь ознакомиться с нами на нашем сайте!"
        markup = types.InlineKeyboardMarkup()
        markup.add(types.InlineKeyboardButton("Перейти на сайт", url="https://timeweb.cloud/"))
        botTimeWeb.send_message(function_call.message.chat.id, second_mess, reply_markup=markup)
        botTimeWeb.answer_callback_query(function_call.id)

В начале объявляется метод для обработки запросов обратного вызова. Выполняется проверка на соответствие строки, указанной после == и возвращенной после нажатия кнопки. Так как ранее мы указали значение параметра callback_data = 'yes', то проверка пройдет успешно. 

После проверки реализован функционал кнопки. Переменная second_mess хранит текст ответного сообщения. А далее описана реализация кнопки, которая хранит ссылку на сайт компании Timeweb Cloud.

Последним шагом будет указать боту на то, что обработка команды закончена. Для этого указываем команду answer_callback_query.

После всех методов необходимо добавить последнюю строчку, которая отвечает за непрерывное продолжение работы бота:

botTimeWeb.infinity_polling()

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

Image 2023 11 28 10 38 28

Бот создан. Сохраните файл с кодом и переходите к его запуску. 

Шаг 4. Запуск бота

Откройте терминал и выполните запуск проекта:

python main.py

Image1

Теперь бот запущен, можно переходить в Telegram и тестировать его.

Для дополнительной безопасности и стабильности рекомендуется запускать бота на виртуальном сервере. Арендовать надежный облачный сервер можно на Timeweb Cloud

Шаг 5. Тестирование бота

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

Для начала работы нажмем «Запустить» внизу экрана.

Image3

Бот обработает команду и выведет приветственное сообщение. 

Image2

Для продолжения работы с ботом нажмем кнопку под сообщением.

Image5

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

Image6

В ответ на нажатие кнопки бот предложит перейти по ссылке. Нажимаем «Перейти» и переходим на сайт компании.

Запустите бота на облачном сервере Timeweb Cloud

Заключение

Мы рассмотрели, как создать бота в Telegram на Python пошагово — от его регистрации до запуска. Вы можете не останавливаться на достигнутом, а подробно изучить возможности используемой библиотеки и продолжить наполнять свой первый бот необходимым функционалом. 

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
07 февраля 2023 г.
33043
6 минут чтения
Средний рейтинг статьи: 4.2
Комментарии 32
Ольга Инчина
Ольга Инчина
30.06.2024, 13:40

async def check_username(update: Update, context: ContextTypes.DEFAULT_TYPE):

    username = update.message.text

    if username in users_db:

        context.user_data['username'] = username

        keyboard = [

            [

                InlineKeyboardButton("Написать заявку", callback_data='write_request'),

                InlineKeyboardButton("Посмотреть данные", callback_data='view_data')

            ]

        ]

        reply_markup = InlineKeyboardMarkup(keyboard)

        await update.message.reply_text('Выберите действие:', reply_markup=reply_markup)

    else:

        await update.message.reply_text('Имя пользователя не найдено. Попробуйте снова.')

async def button_pressed(update: Update, context: ContextTypes.DEFAULT_TYPE):

    query = update.callback_query

    await query.answer()

   

    username = context.user_data.get('username')

    if query.data == 'write_request':

        await query.message.reply_text(f'Введите текст заявки:')

        context.user_data['action'] = 'writing_request'

    elif query.data == 'view_data':

        user_data = users_db[username]['data']

        await query.message.reply_text(f'Данные пользователя {username}: {user_data}')

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):

    if context.user_data.get('action') == 'writing_request':

        request_text = update.message.text

        await context.bot.send_message(

            chat_id=TARGET_USER_ID,

            text=f'Заявка от {context.user_data["username"]}: {request_text}'

        )

        await update.message.reply_text('Ваша заявка отправлена.')

        context.user_data['action'] = None

Почему бот не отправляет мне заявку после нажатия на кнопку Написать заявку, а продолжает сверять имя пользователя

Timeweb
Timeweb
02.07.2024, 08:38

Здравствуйте! Попробуйте добавить следующее условие в handle_message:

else:
        await check_username(update, context)

Чтобы получилось:

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):

    if context.user_data.get(&#39;action&#39;) == &#39;writing_request&#39;:
        request_text = update.message.text
        await context.bot.send_message(
            chat_id=TARGET_USER_ID,
            text=f&#39;Заявка от {context.user_data[&#34;username&#34;]}: {request_text}&#39;
        )
        await update.message.reply_text(&#39;Ваша заявка отправлена.&#39;)
        context.user_data[&#39;action&#39;] = None
    else:
        await check_username(update, context)
Cotowik
Cotowik
30.06.2024, 12:26

Здравствуйте, переписал код 1 в 1, нажал старт в боте, бот написал сообщение, но кнопки inline нет, хотя в настройках bot Father он включен

Timeweb
Timeweb
02.07.2024, 09:08

Добрый день! Если один в один, то все должно работать :thinking_face: Пришлите, пожалуйста, свой код целиком — посмотрим.

Марк Романов
Марк Романов
31.05.2024, 10:58

После активации main.py файл на секунду появляется и закрывается

Марк Романов
Марк Романов
31.05.2024, 11:08

починил уже

Mr. creature
Mr. creature
21.05.2024, 16:55

когда я ввожув кмд python main.py, ничего не происходит, путь указан правильно, ошибок не появляется, просто ничего не происходит, что с этим делать? image.png

Timeweb
Timeweb
22.05.2024, 07:49

Добрый день! Проверьте, что в коде бота есть директива botTimeWeb.infinity_polling() — при ее отсутствии сервер Телеграм не слушает поступающие команды и не дает ответы. Ее добавление описано на Шаге 3, в самом конце подраздела.

Дима Боярчук
Дима Боярчук
10.05.2024, 13:08

2024-05-10 20:07:18,944 (init.py:1083 MainThread) ERROR - TeleBot: "Threaded polling exception: A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: can't parse entities: Unsupported start tag "3" at byte offset 3" 2024-05-10 20:07:18,945 (init.py:1085 MainThread) ERROR - TeleBot: "Exception traceback: Traceback (most recent call last): File "C:\Users\Пользователь\AppData\Local\Programs\Python\Python311\Lib\site-packages\telebot_init_.py", line 1074, in _threaded_polling self.worker_pool.raise_exceptions() File "C:\Users\Пользователь\AppData\Local\Programs\Python\Python311\Lib\site-packages\telebot\util.py", line 147, in raise_exceptions raise self.exception_info File "C:\Users\Пользователь\AppData\Local\Programs\Python\Python311\Lib\site-packages\telebot\util.py", line 90, in run task(*args, **kwargs) File "C:\Users\Пользователь\AppData\Local\Programs\Python\Python311\Lib\site-packages\telebot_init.py", line 6770, in run_middlewares_and_handler result = handler'function' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "c:\Users\Пользователь\Desktop\Bot\bot.py", line 13, in startBot botTimeWeb.send_message(message.chat.id, first_mess, parse_mode='html', reply_markup=markup) File "C:\Users\Пользователь\AppData\Local\Programs\Python\Python311\Lib\site-packages\telebot_init.py", line 1549, in send_message apihelper.send_message( File "C:\Users\Пользователь\AppData\Local\Programs\Python\Python311\Lib\site-packages\telebot\apihelper.py", line 264, in send_message return _make_request(token, method_url, params=payload, method='post') ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Пользователь\AppData\Local\Programs\Python\Python311\Lib\site-packages\telebot\apihelper.py", line 162, in _make_request json_result = _check_result(method_name, result) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ что это????

Timeweb
Timeweb
16.05.2024, 05:49

Добрый день! Первая ошибка указывает на то, что в сообщении, отправляемом через Telegram API, есть проблема с разметкой HTML - "Unsupported start tag «3» at byte offset 3". Все остальные ошибки, скорее всего, вызваны ошибкой выше. Проверьте, что у вас используются только поддерживаемые HTML-теги.

lil_d9xe
lil_d9xe
09.05.2024, 10:44

здравствуйте а как например дополнительно прикрепить фото к этому тексту ? second_mess = "Мы облачная платформа для разработчиков и бизнеса. Более детально можешь ознакомиться с нами на нашем сайте!"

Timeweb
Timeweb
16.05.2024, 05:14

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

photo_url = &#34;URL_ВАШЕГО_ИЗОБРАЖЕНИЯ&#34;

Замените метод send_message на send_photo со следующими параметрами:

botTimeWeb.send_photo(function_call.message.chat.id, photo_url, caption=second_mess, reply_markup=markup)

Здесь photo_url — это URL нашей фотографии, а caption — это подпись к фотографии (second_mess).

Для наглядности — изменения кода на скриншоте.

image_2024-05-16_10-00-47.png

Babidaffi 2004
Babidaffi 2004
03.05.2024, 04:59

Здравствуйте, я переписал ваш код но он все равно не работает. Терминал жалуется на «telebot», выдает ошибку о том что такого не существует. И еще вопрос вместо названия вашего сервиса в коде нужно вводить название моего бота?

Timeweb
Timeweb
06.05.2024, 03:01

Добрый день! Если у вас возникает ошибка, связанная с отсутствием модуля 'telebot', скорее всего библиотека 'pyTelegramBotAPI' не установлена в вашем проекте PyCharm. Для решения этой проблемы выполните следующие шаги:

  1. Откройте PyCharm и перейдите в меню: 'File' → 'Settings'.
  2. В открывшемся окне настроек выберите 'Project: ваше_имя_проекта' → 'Python Interpreter'.
  3. Нажмите на знак '+', чтобы добавить новый пакет.
  4. В появившемся окне поиска введите 'pyTelegramBotAPI' и нажмите 'Install Package'.
  5. После установки закройте окно настроек и попробуйте снова запустить вашего бота.

В коде Python, который управляет вашим Telegram-ботом, переменная, содержащая экземпляр бота, может быть названа как угодно. Это никак не влияет на функциональность. А вот токен бота, полученный от @BotFather в Telegram, должен быть уникальным. Не забудьте поменять его в скопированном коде.

Кирилл Дрожжин (z3nck)
Кирилл Дрожжин (z3nck)
28.03.2024, 14:25

No such file or directory вылетает в терминале после команды python main.py

Timeweb
Timeweb
29.03.2024, 07:12

Добрый день! Ошибка "No such file or directory" указывает на то, что интерпретатор Python не может найти файл main.py в текущей директории, из которой вы пытаетесь запустить команду.

Возможные пути решения:

  1. Убедитесь, что вы находитесь в той директории, где фактически расположен файл main.py. Если это не так, то воспользуйтесь командой cd для перемещения в правильную директорию.
  2. Убедитесь, что у вас есть права на чтение и выполнение файла main.py.
  3. Также вы можете не использовать терминал, а запустить файл прямо из IDE. Большинство интегрированных сред разработки, таких как PyCharm, Visual Studio Code или Atom, позволяют запускать скрипты Python напрямую.
Storm
Storm
10.03.2024, 08:47

Добрый день,помогите пожалуйста. Ввожу код,нажимаю старт и бот выдаёт сообщение как нужно,но когда нажимаю на инлайн кнопку ничего не происходит и в консоле пишет telebot.apihelper.ApiTelegramException: A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: can't parse inline keyboard button: Text buttons are unallowed in the inline keyboard import telebot

bot = telebot.TeleBot('7189232956:AAGTAMNwjX54k1lSjls78vXZ-iKy597OqPI')

from telebot import types @bot.message_handler(commands=['start']) def startBot(message): first_mess = f"{message.from_user.first_name} {message.from_user.last_name}, привет!\nчто ты хотел?" markup = types.InlineKeyboardMarkup() button_project = types.InlineKeyboardButton(text = 'проект', callback_data='project') markup.add(button_project) bot.send_message(message.chat.id, first_mess, parse_mode='html', reply_markup=markup)

@bot.callback_query_handler(func=lambda call:True) def response(function_call): if function_call.message: if function_call.data == 'project': second_mess = "Вот такие проекты есть" markup = types.InlineKeyboardMarkup() markup.add(types.InlineKeyboardButton("Самый кайфовый трек")) bot.send_message(function_call.message.chat.id, second_mess, reply_markup=markup) bot.answer_callback_query(function_call.id)

bot.infinity_polling() вот код,помогите пожалуйста

Timeweb
Timeweb
20.03.2024, 06:26

Добрый день! Необходимо добавить параметр callback_data для кнопки "Самый кайфовый трек": markup.add(types.InlineKeyboardButton(&#34;Самый кайфовый трек&#34;, callback_data=&#39;track&#39;))

Проблема с неработающей кнопкой 'project' не была напрямую связана с этой кнопкой. На самом деле, сложность возникла из-за отсутствия параметра callback_data у кнопки "Самый кайфовый трек", которая добавлялась в ответное сообщение после выбора 'project'. Telegram требует, чтобы каждая кнопка во встроенной клавиатуре имела callback_data или другой параметр, определяющий её функцию. Добавление callback_data=&#39;track&#39; к этой кнопке решает проблему, позволяя Telegram корректно обрабатывать и отображать встроенную клавиатуру.

John Ford
John Ford
01.03.2024, 05:12

Здравствуйте, я переписал в точь-в-точь как у Вас, но мне выдает ошибку "Traceback (most recent call last):", и дальше ниже идут ошибки. Что мне делать?

Timeweb
Timeweb
04.03.2024, 07:19

Добрый день! Сообщение об ошибке «Traceback (most recent call last)» появляется в случае, когда интерпретатор Python сталкивается с проблемой, которую он не может обработать, и начинает выводить путь, по которому возникла ошибка. Следующие строки после этого сообщения будут содержать детальную информацию о том, где именно в коде возникла ошибка, поэтому тщательно изучите их.

Если вы не сможете самостоятельно решить проблему, пожалуйста, предоставьте точное сообщение об ошибке, которое вы видите после строки «Traceback (most recent call last):». Это поможет определить проблему и предложить конкретное решение.

Также убедитесь, пожалуйста, что библиотека pyTelegramBotAPI установлена и обновлена до последней версии.

Pav Pav
Pav Pav
26.01.2024, 17:56

Здравствуйте а если закрыть среду разработки бот будет работать?

Timeweb
Timeweb
29.01.2024, 03:43

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

Горячев Даниил
Горячев Даниил
27.11.2023, 14:40

Помогите пожалуйста Вот код: import telebot

botTimeWeb = telebot.TeleBot('6965411102:AAGU2vtAYnDjh1hZbI2usVftxAL1Hk-Wx9k')

from telebot import types

@botTimeWeb.message_handler(commands=['start']) def startBot(message): first_mess = f"{message.from_user.first_name} {message.from_user.last_name}, привет!\nХочешь расскажу немного о нашей компании?" markup = types.InlineKeyboardMarkup() button_yes = types.InlineKeyboardButton(text = 'Да', callback_data='yes') markup.add(button_yes) botTimeWeb.send_message(message.chat.id, first_mess, parse_mode='html', reply_markup=markup)

@botTimeWeb.callback_query_handler(func=lambda call: True) def response(function_call): if function_call.message: if function_call.data == "yes": second_mess = "Мы облачная платформа для разработчиков и бизнеса. Более детально можешь ознакомиться с нами на нашем сайте!" markup = types.InlineKeyboardMarkup() markup.add(types.InlineKeyboardButton("Перейти на сайт", url="https://timeweb.cloud/&#34;)) botTimeWeb.send_message(function_call.message.chat.id, second_mess, reply_markup=markup) botTimeWeb.answer_callback_query(function_call.id) botTimeWeb.infinity_polling()

В терминале ввожу python main.py, но ничего не работает

Timeweb
Timeweb
28.11.2023, 04:53

Добрый день! Проверьте, пожалуйста, что у вас правильная структура кода. Скорее всего, вы добавили команду для непрерывной работы бота в блок кода с вложенным условием if function_call.data == &#34;yes&#34;. Прикладываем скриншот с правильной структурой. image_2023-11-28_10-38-28.png

Даниил Потапов
Даниил Потапов
27.10.2023, 06:27

В функции startBot сделал две кнопки да/нет и в функции response проверку callback.data == yes/no в случае выбора no - выпадает ответ и кнопка "вернуться". Как реализовать возврат на стартовое сообщение при нажатии на кнопку "вернуться" ? Запустить функцию startBot не могу, т.к ей необходимо передать параметр message далее из которого берется ферстнейм и ластнейм, на что можно заменить ?

Timeweb
Timeweb
30.10.2023, 06:41

Добрый день! Чтобы реализовать возврат на стартовое сообщение при нажатии на кнопку «вернуться», вы можете просто отправить начальное сообщение с помощью новой функции send_start_message без вызова startBot.

send_start_message — это дополнительная функция, которая будет отвечать за отправку начального сообщения с кнопками в чате. Она вызывается в функции startBot при обработке команды /start. При этом, она должна принимать параметры chat_id, first_name и last_name, чтобы формировать начальное сообщение для конкретного пользователя. После создания send_start_message, вы можете вызвать ее из функции response для кнопки «вернуться».

ZXCzenitsu
ZXCzenitsu
26.08.2023, 08:17

botTimeWeb = telebot.TeleBot(6479951707:AAErB1vaKcsDcXs0YzqSwlRsRYg8jRuoKYE) ^ SyntaxError: invalid syntax как исправить эту ошибку?

Timeweb
Timeweb
28.08.2023, 05:35

Добрый день! Токен необходимо обернуть кавычками, чтобы получилось:

botTimeWeb = telebot.TeleBot(&#39;6479951707:AAErB1vaKcsDcXs0YzqSwlRsRYg8jRuoKYE&#39;)

Отдельно уточнили этот момент в статье ????

GOPNIC 228
GOPNIC 228
23.05.2023, 16:26

не работает скопировал всё отредактировал как надо и нет пишет что команда pip не найдена(я и сам такой не знаю) install тоже самое может я тупой может лыжи не едут я хз

GOPNIC 228
GOPNIC 228
23.05.2023, 16:34

виртуалку нормально поставь анскилл

Liberal Natural
Liberal Natural
26.06.2023, 21:34

pip пропиши сначала в среде

Timeweb
Timeweb
11.08.2023, 09:36

Добавили в инструкцию ссылку на гайд по установке необходимой библиотеки ????