Итак, мы уже написали телеграм бота для отправки наших же сообшений нам в личные сообщения. Время повысить сложность кода и функциональность бота. Как я уже упоминала, возможности бота зависят не только от Telegram-API, но также и от языка программирования, на котором мы пишем. Все популярные языки программирования обладают примерно одинаковыми возможностями, отличается только реализация и сложность выполнения определенных узконаправленных команд. Также каждый язык программирования обладает своим уклоном, так называемой сильной стороной. Сильная сторона python – простота написания и чтения кода. Давайте же воспользуемся некотоыми функциями питона для расширения возможностей бота.

Второй бот

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

import telebot
 
 from random import randint
 
 bot=telebot.TeleBot(“token”, parse_mode=None)
 
 @bot.message_handler(commands=[“pic”])
 
 def send_pic(message):
 
    photo = open(f’pics/{randint(1, 5)}.png’, ‘rb’)
 
    bot.send_photo(message.chat.id, photo)
 
 @bot.message_handler(func=lambda m: True)
 
 def advice(message):
 
    bot.reply_to(message, “У бота есть команда /pic, опробуй её”)
 
 bot.polling()

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

import telebot – импортирую библиотку для работы с Telegram-API

from random import randint – здесь я импортировала в мой файл не всю библиотеку со всеми функциями, а только функцию, которую я буду использовать, это позволяет программе выполняться быстрее и не загружать компьютер.

bot=telebot.TeleBot(“token”, parse_mode=None) – передаю исполнение всех следующих команд для бота переменной bot путем написания токена (замените token на свой bot token, который вы должны получить у бота @botfather)

@bot.message_handler(commands=[“pic”]) – указываю декоратор. Благодаря нему, бот будет реагировать на команду /pic и исполнять следующую функцию.

Следующую строку моей программы я разобью на три фрагмента, так как она достаточно сложна.

photo = open(…) – записываю в переменную photo (имя может быть любое) одну фотографию путем ее открытия в папке pics. Данная папка должна находиться в той же папке, что и наша программа.

f’pics/{…}.png’, ‘rb’<b> – во вторых кавычках я использую файл для чтения (r), а также я использую этот файл, как фото (b). префикс f означает, что выражение в кавычках является форматированным, то есть внутрь строки вы можете вставлять значения переменных с помощью имен переменных. Приведу маленький пример, чтобы все было понятно. 

a = 4

b = ‘a’ # значение переменной b равно ‘a’

c = f‘{a}’ # значение переменной c равно 4

randint(1, 5) – В фигурных скобках я использую импортированную из библиотеки random команду randint, возвращающую одно псевдослучайное число из диапазона в скобках, то есть мне должно вернуться число от 1 до 5 всключительно.

photo = open(f’pics/{randint(1, 5)}.png’, ‘rb’) – таким образом, в переменную photo должна скопироваться одна из пяти картинок (1.png, 2png, 3.png, 4.png или 5.png). Если же формат ваших фото, например, jpeg, то поменяйте в этой строке соответствующую часть кода.

bot.send_photo(message.chat.id, photo) – я использую команду отправки фото. В скобках указываются чат, в который это фото нужно отправить, а также само фото.

@bot.message_handler(func=lambda m: True)
 def advice(message):
 bot.reply_to(message, “У бота есть команда /pic, опробуй её”)

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

В конце стандартно пишем bot.polling() для связи программы с серверами телеграм.

После написания кода и сохранения в файл с окончанием .py надо запустить его. Я запущу код через командную строку. 

После этого я захожу в своего бота и пишу любой текст:

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

Если я введу нужную команду, то бот отошлет мне одну из заготовленных картинок:

Я специально не добавила картинку с названием 5.png, чтобы показать вам, что будет, если неправильно указать число картинок.

В терминале появляется огромное количество текста, сообщающего об одной ошибке “нет такого файла!”. Если вы запустили вашу программу не в терминале, а в специальной среде разработки, то результат будет тем же самым, и в диалоговом окне появятся те же строки, что у меня на картинке. Важно отметить, что при обнаружении в коде критической ошибки, программа останавливается и бот перестает работать, чтобы его перезапустить, достаточно перезапустить файл, предварительно исправив ошибку.

В этой программе мы использовали форматированную строку, открытие файла, а также функцию библиотеки random. Все это аспекты именно языка python, а не Telegram-API или библиотеки telebot.

Теория

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

@bot.message_handler(regexp=“слово”) данный декоратор реагирует на слово “слово”. Чтобы использовать свои слова, просто замените “слово” на свои выражения. Также тут можно использовать специальные комбинации регулярных выражений, например \d означает любую цифру, \d{4} уже будет  4 любые цифры в ряд и так далее. \s – это пробелы, а символ “.” это любой возможный символ. * означает “от 0 до бесконечности повторений символа перед звездой). Тогда выражение “.*” будет принимать любую входящую строку точно также, как и второй декоратор из второго написанного бота. 

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

bot.send_message(message.chat.id, “ваш текст”)

Также бот позволяет добавить немного интерактива, путем добавления в меню бота кнопок.

Разберем пример бота с кнопками, выполняющего определенные действия по их нажатию.

Третий бот

import telebot
 from telebot import types
 from random import randint
 bot=telebot.TeleBot(«token», parse_mode=None)
 markup = types.ReplyKeyboardMarkup(row_width=2)
 btn1 = types.KeyboardButton(‘random picture’)
 btn2 = types.KeyboardButton(‘lucky number’)
 markup.add(btn1, btn2)
 @bot.message_handler(regexp=»random picture»)
 def send_pic(message):
     photo = open(f’pics/{randint(1, 5)}.png’, ‘rb’)
     bot.send_photo(message.chat.id, photo)
 @bot.message_handler(regexp=»lucky number»)
 def num(message):
     bot.reply_to(message, f»Your lucky number for now is {randint(1, 100)}»)
 @bot.message_handler(func=lambda m: True)
 def inst(message):
     bot.send_message(message.chat.id, «Choose one bot function:», reply_markup=markup)
 bot.polling()

Как можно видеть, бот работает отлично:

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

Разберу только ту часть, которую еще не объясняла:

from telebot import types – помимо полного импорта телебота добавляю отдельно функцию types, чтобы вызывать ее по команде types, а не telebot.types. Таким образом, я оптимизировала код и сделал его более читаемым.

markup = types.ReplyKeyboardMarkup(row_width=2) – присваиваю переменной markup значение клавиатуры из двух кнопок.

btn1 = types.KeyboardButton(‘random picture’)

btn2 = types.KeyboardButton(‘lucky number’) добавляю эти кнопки. Такие кнопки выводят то же значение, что написано на них при их появлении.

markup.add(btn1, btn2) – сопоставила места для пустых кнопок с новонаписанными кнопками.

bot.send_message(message.chat.id, «Choose one bot function:», reply_markup=markup) – В последнем, собирающем все остальные введенные строки, декораторе бот сообщает о выборе функций бота и показывает клавиатуру с кнопками. 

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