Разработка телеграм бота на Python
Для создания телеграм бота на языке python есть две основных библиотеки: это telebot и aiogram. Я буду использовать первую.
Как сделать бота в телеграм?
В телеграме необходимо найти официального бота BotFather. Жмем старт и вылезает стена текста, нам нужна команда /newbot
.
Нас попросят придумать имя для нашего бота, оно может быть любым. Далее нам нужно придумать имя пользователя. Тут
немного сложнее: нужно придумать уникальное имя которое заканчивается на bot. После этого нас поздравят, дадут адрес
бота, предложат добавить описание и установить аватарку, но самое главное это токен. Он позволяет подключаться к боту,
программировать его и, в целом, самая важная его часть.
Установка telebot
Необходимо создать виртуальное окружение, активировать его и установить нашу библиотеку.
python3 -m venv venv
source venv/bin/activate
pip install pyTelegramBotAPI
Написание первого бота
Импортируем библиотеку telebot, создаем экземпляр класса TeleBot и в параметр token передаем наш токен в
виде строки. Сам токен я рекомендую хранить в отдельном файле, например создать файл config.py
и записать его уже
туда, а потом просто импортировать в основной файл.
import telebot
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def hello(message):
bot.send_message(message.chat.id, "Привет")
bot.polling(non_stop=True)
Мы используем декоратор @bot.message_handler
(не путать с @bot.message_handlers) и в параметр commands
передаем
массив (обязательно) с командами на которые будет реагировать функция. Команды могут быть любыми, то есть можно сделать
так:
@bot.message_handler(commands=["start", "test", "help", "kak"])
и т.д. Если данный параметр не указывать, функция
будет срабатывать на любой текст. Далее идет наша функция. Имя может быть любым, но она всегда должна принимать
параметр message
в котором хранятся все данные о сообщении. И наконец сама отправка сообщения. Метод send_message
первым параметром принимает id чата, а вторым сам текст. Он способен отправлять только текстовые данные, для отправки
других типов данных есть другие методы. Строка bot.polling(non_stop=True)
запускает самого бота. non_stop=True
означает что пока работает код, работает и бот. Если сейчас запустить код и перейти в чат с нашим ботом и написать
/start
нам выведется Привет
.
Что за параметр message?
import telebot
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def hello(message):
print(message)
bot.polling(non_stop=True)
Если просто вывести параметр message, то будет примерно это:
{
'content_type': 'text',
'id': 8,
'message_id': 8,
'from_user': {
'id': 0,
'is_bot': False,
'first_name': '_',
'username': '_',
'last_name': '_',
'language_code': 'ru',
'can_join_groups': None,
'can_read_all_group_messages': None,
'supports_inline_queries': None,
'is_premium': None,
'added_to_attachment_menu': None,
'can_connect_to_business': None
},
'date': _,
'chat': {
'id': _,
'type': 'private',
'title': None,
'username': '_',
'first_name': '_',
'last_name': '_',
'is_forum': None,
'max_reaction_count': None,
'photo': None,
'bio': None,
'join_to_send_messages': None,
'join_by_request': None,
'has_private_forwards': None,
'has_restricted_voice_and_video_messages': None,
'description': None,
'invite_link': None,
'pinned_message': None,
'permissions': None,
'slow_mode_delay': None,
'message_auto_delete_time': None,
'has_protected_content': None,
'sticker_set_name': None,
'can_set_sticker_set': None,
'linked_chat_id': None,
'location': None,
'active_usernames': None,
'emoji_status_custom_emoji_id': None,
'has_hidden_members': None,
'has_aggressive_anti_spam_enabled': None,
'emoji_status_expiration_date': None,
'available_reactions': None,
'accent_color_id': None,
'background_custom_emoji_id': None,
'profile_accent_color_id': None,
'profile_background_custom_emoji_id': None,
'has_visible_history': None,
'unrestrict_boost_count': None,
'custom_emoji_sticker_set_name': None,
'business_intro': None,
'business_location': None,
'business_opening_hours': None,
'personal_chat': None,
'birthdate': None
},
'sender_chat': None,
'is_automatic_forward': None,
'reply_to_message': None,
'via_bot': None,
'edit_date': None,
'has_protected_content': None,
'media_group_id': None,
'author_signature': None,
'text': '/kak',
'entities': [
<telebot.types.MessageEntity
object
at
0x7f7d0dbd1390>
],
'caption_entities': None,
'audio': None,
'document': None,
'photo': None,
'sticker': None,
'video': None,
'video_note': None,
'voice': None,
'caption': None,
'contact': None,
'location': None,
'venue': None,
'animation': None,
'dice': None,
'new_chat_members': None,
'left_chat_member': None,
'new_chat_title': None,
'new_chat_photo': None,
'delete_chat_photo': None,
'group_chat_created': None,
'supergroup_chat_created': None,
'channel_chat_created': None,
'migrate_to_chat_id': None,
'migrate_from_chat_id': None,
'pinned_message': None,
'invoice': None,
'successful_payment': None,
'connected_website': None,
'reply_markup': None,
'message_thread_id': None,
'is_topic_message': None,
'chat_background_set': None,
'forum_topic_created': None,
'forum_topic_closed': None,
'forum_topic_reopened': None,
'has_media_spoiler': None,
'forum_topic_edited': None,
'general_forum_topic_hidden': None,
'general_forum_topic_unhidden': None,
'write_access_allowed': None,
'users_shared': None,
'chat_shared': None,
'story': None,
'external_reply': None,
'quote': None,
'link_preview_options': None,
'giveaway_created': None,
'giveaway': None,
'giveaway_winners': None,
'giveaway_completed': None,
'forward_origin': None,
'boost_added': None,
'sender_boost_count': None,
'reply_to_story': None,
'sender_business_bot': None,
'business_connection_id': None,
'is_from_offline': None,
'effect_id': None,
'show_caption_above_media': None,
'json': {
'message_id': 8,
'from': {
'id': _,
'is_bot': False,
'first_name': '_',
'last_name': '_',
'username': '_',
'language_code': 'ru'
},
'chat': {
'id': _,
'first_name': '_',
'last_name': '_',
'username': '_',
'type': 'private'
},
'date': _,
'text': '/kak',
'entities': [
{
'offset': 0,
'length': 4,
'type': 'bot_command'
}
]
}
}
*Данный кусок кода был отформатирован для более удобного чтения.
Тут собрана вся информация о сообщении. Есть тип, id и сам текст сообщения и т.д, также есть некоторый данные о самом отправителе, например его имя, id, язык который он использует. И это не словарь как может показаться, а экземпляр класса Message. В это можно убедится если вывести его тип.
import telebot
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def hello(message):
print(type(message))
#<class 'telebot.types.Message'>
bot.polling(non_stop=True)
И соответственно обращаться к нему надо не так: message.get(“chat”).get(“id”), а так message.chat.id
.
Зная это можно написать бота, который будет приветствовать нас по имени.
import telebot
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def hello(message):
bot.send_message(message.chat.id, f"Привет, {message.from_user.first_name}")
bot.polling(non_stop=True)
Добавление кнопок
Inline Button
Данный вид кнопок крепится непосредственно к самому сообщению. При нажатии на кнопку может вызываться какое-либо событие.
import telebot
from telebot import types
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def start(message):
markup = types.InlineKeyboardMarkup()
button = types.InlineKeyboardButton(text="Наш сайт", url="https://it-teh.com/ru/")
markup.add(button)
bot.send_message(message.chat.id, text=f"Привет, {message.from_user.first_name}", reply_markup=markup)
bot.polling(non_stop=True)
Здесь я создаю экземпляр класса InlineKeyboardMarkup и называю его markup. Это что-то вроде каркаса, на который будет крепиться кнопка. Дальше я создаю саму кнопку. Тут я уже использую класс InlineKeyboardButton. Первым параметром передаю текст, который будет написан на кнопке. А вторым событие происходящие после нажатия. В данном случае это ссылка на сайт. Далее добавляю кнопку на наш ‘каркас’ c помощью метода add(). При отправке сообщения необходимо указать параметр reply_markup и в него передать наш markup.
Keyboard Button
Reply кнопки отличаются от Inline тем, что они крепятся под клавиатуру пользователя.
Еще особенность этих кнопок то, что при нажатии на них текст кнопки отправляется в чат. По сути это шаблон с готовыми вариантами ответа.
import telebot
from telebot import types
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def start(message):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
button1 = types.KeyboardButton("Наш сайт")
button2 = types.KeyboardButton("Привет")
markup.add(button1, button2)
bot.send_message(message.chat.id,
text=f"Привет, {message.from_user.first_name}",
reply_markup=markup)
@bot.message_handler(content_types=["text"])
def text(m):
if m.text == "Наш сайт":
bot.send_message(m.chat.id, text="Наш сайт: https://it-teh.com/ru")
if m.text == "Привет":
bot.send_message(m.chat.id, text="Еще раз привет, "
f"{m.from_user.first_name}")
Способ создание данных кнопок очень похож на предыдущий. Создается экземпляр класса ReplyKeyboardMarkup. При создании желательно указать параметр resize_keyboard=True что бы кнопка не была слишком большой.
Похожее
Если вас заинтересовала данная тема, пожалуйста свяжитесь с нами.