Боты в Телеграме — это уже давно не новинка: каждый уважающий себя интернет-магазин внутри социальной сети обладает возможностью удобной навигации по меню, и даже некоторые новостные каналы настраивают таргет по пожеланиям пользователя с помощью автоматизированных систем.
Вопрос остается в другом: как сделать бота так, чтобы не растратить миллионы на отладку и работу? Несмотря на то, что существует огромное количество автоматических конструктов, все равно нужно потратить немало времени на разбор алгоритма и итогового кода. К тому же они не могут гарантировать корректную работу абсолютно всех функций. Например, когда кто-то захочет связать курс доллара с днями проигрышей «Спартака», ему придется самостоятельно настраивать логику в собственной программе.
Программирование — вот, за чем стоит создание качественного бота. И мы попросту не могли обойти эту тему стороной, потому что с помощью Python создать автоматизированную систему в Телеграме проще простого. Копируем код, исследуем каждую строчку и удивляемся результатам!
В первую очередь необходимо понять, каким образом бот будет производить отправку сообщений с прочтением ответов от пользователей.
Разработчики Telegram создали функционал для удобного использования API HTML. Он, в свою очередь, зависит от URL, общий вид функции:
https://api.telegram.org/bot/#названиеметода#
При этом #названиеметода# — может быть как getChat (открыть чат), sendMessage (отправить сообщение), так и getUpdates (обновление). Для подтверждения подлинности бота в системе внутри каждой программной строки указывается токен — специальные символы, создающиеся при формировании бота.
Общий вид токена представлен далее:
200223:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
При этом стоит понимать, что большая часть методов требует предоставления дополнительных параметров. В случае с sendMessage — непосредственный текст и chat_id. Именно поэтому внутри ботов реализуются как POST, так и GET запросы, которые передаются как URL-строки (например, application/#x-www-form-urlencoded#) и могут быть представлены только в кодировке UTF-8.
После того, как API-функция получает запрос, бот отправляет ответ формата JSOM. Предположим, что ранее был выполнен запрос данных при помощи метода getME, в таком случае пользователь получит ответ следующего вида:
GET https://api.telegram.org/bot/getMe
{
ok: true,
result: {
id: 231757398,
first_name: "Hello Bot",
username: "hellotestbot"
}
}
В том случае, если значение поля «ok» равно true, результат обработки появится в поле, именованном «field». В ином случае текст ошибки можно будет найти в «description».
Второй вопрос, который необходимо изучить — каким образом бот будет получать сообщения от пользователей, и как реализуется дальнейшая обработка?
Несмотря на то, что во многих языках программирования поддерживаются многомиллионные библиотеки со схожими алгоритмами, разработчики остановились на двух методах:
Первый — ручная обработка методов при помощи getUpdates. То есть, бот будет получать объекты-массив формата Update. При этом сама функция работает как длинный опрос, то есть, изначально пользователи отправляют запросы, система обрабатывает их, выдает результат, и идет откат к первому действию, пока не закончится работа бота. Если не хочется производить повторную работу и тратить вычислительные мощности, лучше задуматься над параметром offset.
Метод getUpdates настоятельно рекомендуется использовать, если:
Второй — использование метода setWebhooks. Таким образом Телеграм будет автоматически перенаправлять все запросы на конкретно указанный URL сразу же, как они будут появляться. При этом необходимо заранее позаботиться о подготовке HTTPS-сертификата, либо создать новые, но обязательно их заверить.
Метод Webhooks является одним из оптимальных в том случае, если:
Третий, не менее важный вопрос: каким образом производится регистрация бота внутри социальной сети Телеграм?
Для работы со всеми ботами необходимо ознакомиться с официальным каналом @BotFather. Он не только формирует базовую настройку для всех ботов, но и помогает с персонализацией, например, встроенной поддержкой, фотографией, описанием и тому подобным.
Касательно Python, одна из наиболее часто используемых библиотек — PyTelegramBotAPI. Она написана в соответствии с базовыми принципами ООП и является лишь оболочкой для HTML-запросов. При этом все типы данных представляют собой отдельные классы.
Основа бота на Python — новейшая библиотека PyTelegramBotAPI (в простонародье «Телебот»). Прежде чем начинать работу непосредственно с программированием, необходимо убедиться, что на компьютере установлена актуальная версия программного обеспечения. Функция для Linux:
sudo apt-get install python python-pip
После этого при помощи командной строки (Windows) или терминала (Linux) необходимо произвести установку библиотеки:
pip install pytelegrambotapi
На этом все приготовления закончены — настоятельно рекомендуется использовать версию Python 3-го поколения (3.7+). Это избавит от проблем с совместимостью, наиболее актуальные версии расположены на официальном сайте.
Вне зависимости от того, в какой именно среде будет писаться код (блокнот, Jupyter Notebook), программирование будет одинаковым — использование long pool, много упорства и немало фантазии под соусом из функционала библиотеки Телебота.
В первую очередь производится импорт библиотеки с подключением токена (получить его можно у @BotFather):
import telebot;
bot = telebot.TeleBot('#токен#');
Для получения сообщений от бота необходимо дополнительно подключить метод:
@bot.message_handler(content_types=['text']) //Получатель сообщения
def get_text_messages(message): //Метод обработки сообщения
При этом стоит понимать, что поле «content_types» может принимать различные значения в зависимости от ситуаций — это может быть набор-массив, числа, знаки и тому подобное. Например:
@bot.message_handler(content_types=['text', 'video', 'audio'])
Благодаря указанной функции бот будет реагировать на все присланные текстовые, видео- и аудиосообщения. Более подробно о рассматриваемых типах мессенджей можно прочитать в официальной документации Телебота.
Дальнейший код является сугубо демонстрационным и лишь описывает основной синтаксис взаимодействия библиотеки Телебот и Python. Постараемся создать такую программу, чтобы пользователь писал «Привет», а в ответ получал эксклюзивный «Привет от Партнеркина!».
if message.text == "Привет":
bot.send_message(message.from_user.id, "Привет от Партнеркина!")
elif message.text == "/help":
bot.send_message(message.from_user.id, "Напиши «Привет»)")
else:
bot.send_message(message.from_user.id, "Партнеркин помогает с /help")
Каждая из указанных функций характеризует поведение пользователя — что именно он может ввести, и как на это должен реагировать бот. Остается добавить только одну строку, которая работает только с методом long pool:
bot.polling(none_stop=True, interval=0)
Вне зависимости от того будет ли находиться пользователь в диалоге, каждую секунду бот будет спрашивать непосредственно у социальной сети «Пишет ли мне этот пользователь в этом диалоге?». Постепенно расширяясь на множество диалогов, возможно увеличение времени задержки.
Взаимодействие с пользователем посредством угадывания каждой его фразы — это, конечно, весело. Однако мы постараемся расширить функционал, введя количество покупок, наименования и стоимость. В этом нам потребуется следующий метод register_next_step_handler:
name = '';
count = 0;
price = 0;
@bot.message_handler(content_types=['text'])
def start(message):
if message.text == '/reg':
bot.send_message(message.from_user.id, "Что хочешь купить?");
bot.register_next_step_handler(message, get_name); //следующий шаг — функция get_name
else:
bot.send_message(message.from_user.id, 'Напиши /reg');
def get_name(message):
global name;
name = message.text;
bot.send_message(message.from_user.id, 'Сколько товара ты хочешь купить?');
bot.register_next_step_handler(message, get_surnme);
def get_surname(message):
global surname;
surname = message.text;
bot.send_message(‘Итоговая стоимость составит');
bot.register_next_step_handler(message, get_price;
def get_price(message):
global price;
while price == 0: #проверка, что цена не равна 0
try:
price = count*100 #проверка, что
except Exception:
bot.send_message(message.from_user.id, Некорректное количество товара);
bot.send_message(message.from_user.id, 'Итоговая стоимость '+str(age)+' за '+name+' в количестве '+price+)
Это один из наиболее простых способов взаимодействия с ботом, не используя дополнительно базы данных, то есть, не храня значения и не передавая их. Для того, чтобы взаимодействие с пользователем стало более продуктивным и красочным, попробуем попросить его подтвердить заказ при помощи кнопок. Для этого потребуется внести небольшие коррективы в функцию get_price:
def get_price(message):
global price;
while price == 0: #проверка, что цена не равна 0
try:
price = count*100 #проверка, что
except Exception:
bot.send_message(message.from_user.id, Некорректное количество товара);
keyboard = types.InlineKeyboardMarkup(); //кнопочки
key_yes = types.InlineKeyboardButton(text='Да', callback_data='yes'); #кнопка «Да»
keyboard.add(key_yes); #добавление кнопки в клавиатуру
key_no= types.InlineKeyboardButton(text='Нет', callback_data='no');
keyboard.add(key_no);
question= 'Итоговая стоимость '+str(age)+' за '+name+' в количестве '+price+’?’)
bot.send_message(message.from_user.id, text=question, reply_markup=keyboard)
Вне зависимости от того, что именно нажмет пользователь, настоящий код не будет переводить его куда-либо дальше. А все потому, что до сих пор не был прописан код-обработчик:
@bot.callback_query_handler(func=lambda call: True)
def callback_worker(call):
if call.data == "yes":
.... //обработка или сохранение результата
bot.send_message(call.message.chat.id, 'Принято');
elif call.data == "no":
... #код начинает работу сначала
Самый последний шаг — добавить типы из начальной библиотеки:
from telebot import types
Функционал Телебота поистине безграничен — постоянно добавляются новые фишки, пользователи демонстрируют исключительные функции, которые в режиме реального времени позволяют не столько взаимодействовать с пользователями, сколько снимают данные и фиксируют сигналы для работы (с валютами, например).
Но касательно работы с пользователями, разработчики постарались по максимуму, добавив, например, целых два типа кнопок:
Классическая RelpyKeyboardMarkup — кнопки расположены непосредственно под полем ввода сообщения:
Современная InlineKeyboardMarkup — кнопки привязаны к конкретному сообщению:
Также стоит понимать, что полноценные проекты все равно рано или поздно потребуют дополнений в виде активных баз данных. Для организации подобного функционала рекомендуется использовать docker-compose — он объединяет множество массивов в один контейнер. Данная библиотека позволяет не только создавать новые базы данных, но и налаживает связь между существующими.
Телеграм-боты могут всё, что угодно?
Вынужден разочаровать тех, кто представляет ботов, как инструмент исключительно для автоответов и искусственной активности. Думайте о Telegram боте как об автоматизированной учетной записи, которая может выполнять для вас некоторые действия. Например, вы хотите поделиться ссылкой YouTube в групповом чате, но у вас пока нет ссылки.
Если планируется работа с достаточно крупными проектами, рекомендуется также начать работу с виртуальным выделенным сервером (VPS). В отличие от стандартного AWS он обладает большими возможностями для гибкого программирования, а также устанавливается в процессе использования библиотеки Docker.
Вывод
Написать свой собственный код для бота — значит, быть уверенным в его полной работоспособности, предполагать всевозможные тесты и уметь отлаживать нерабочие куски в режиме реального времени. Различные курсы и современные технологии позволяют овладеть языком программирования за считанные часы — так почему бы не воспользоваться такой возможностью для автоматизации работы в Телеграме?