Рубріки: ОсновыТеория

Telegram API: наглядный разбор с примерами

Сергій Бондаренко

Для любого бизнеса важно установить канал общения с клиентами. Но сделать это не так просто. Психология людей такова, что они не хотят захламлять память своего смартфона новым фирменным приложением из того места, которое они посетили. Совсем другое дело — чат-бот. Ненавязчивый и дружелюбный. А кроме того — со всеми необходимыми фишками: рекламными акциями, скидками и быстрым заказом. И уведомления в одном единственном удобном мессенджере. Почему бы его не реализовать в своем бизнесе? Тем более, что это не так сложно, как вы думаете.

Сегодня мы поговорим о ботах и их API (telegram api) на базе популярного мессенджера Telegram.

Содержание

Telegram Bot API и Telegram API
BotFather: быстрый StartПростой эхо-бот
aiogram — асинхронная библиотека
Создаем эхо-бота
Оформление сообщений
Учим бот-модерации
Делаем бота админом
Заключение

Telegram Bot API и Telegram API

Все началось с того, что Николай Дуров совместно с командой программистов создал криптографический протокол. Его движок задействовал комбинацию симметричного шифрования AES, протокол Диффи-Хеллмана для обмена ключами шифрования между клиентами и ряд хеш-функций. На основе этого протокола был построен MTProto — механизм, позволяющий пользователям сегодня использовать Telegram-мессенджеры. 

На данный момент есть два основных инструмента API, с помощью которых можно задействовать сервисы Telegram — Telegram Bot API и Telegram API. Первый служит для разработки чат-ботов, второй позволяет делать полностью кастомные Telegram-клиенты. Разработчикам также доступна открытая библиотека TDLib (Telegram Database Library), с помощью которой можно создавать свою версию мессенджера с уникальными опциями (как например, Telegram X, построенный именно на TDLib). Telegram Bot API является надстройкой над Telegram API, поэтому пользоваться Bot API можно без знаний о механизме используемого протокола MTProto

Бизнес активно использует чат-боты при работе с клиентами, это направление будет приоритетным в ближайшее время в особенности для интернет-маркетинга. Наши друзья из Laba организовали хорошие курсы по лидогенерации, они будут полезны как владельцам бизнеса, так и маркетологам.

Для его работы задействован промежуточный сервер с HTTPS-интерфейсом, который шифрует трафик и обеспечивает связь с Telegram API. Bot API позволяет легко создавать программы, которые используют интерфейс Telegram для выполнения кода на локальном сервере. Пользователи могут взаимодействовать с ботами, отправляя им сообщения, команды и встроенные запросы. 

Принцип работы любого бота заключается в том, что он перманентно направляет запросы на сервер и регулярно получает обновления. Получать их можно двумя способами. Во-первых, можно использовать вебхуки, когда сервер делает обратный вызов на указанный URL. А во-вторых, можно просто «забрасывать» запросами Telegram, получая постоянные ответы. 

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

В отличие от Bot API, где получать обновление можно только один раз, в Telegram API это ограничение можно обойти, если использовать несколько клиентов. В таком случае бот будет получать все обновления на каждом из запущенных клиентов. Также в Bot API нет возможности рассылки сообщений всем юзерам одновременно. 

На GitHub (https://github.com/tdlib/telegram-bot-api) можно найти исходники сервера Bot API. Развернув такой сервер вы получите HTTP URL с возможностью организации работы через вебхуки. Также сможете загружать файлы (до двух терабайт) на локальный сервер. Сервер Bot API имеет возможность настройки порта и локального IP-адреса для вебхука, а также поддерживает до 100000 одновременных подключений — более чем достаточно для большинства задач.

BotFather: быстрый Start

Чтобы приступить к созданию собственного бота, необходимо получить токен для авторизации и подключения через API. Делается это при помощи служебного бота. Введите в поиске Telegram его имя — BotFather. Далее следует выбрать команду /newbot и дать имя боту.

Затем BotFather спросит вас имя, которое обязательно должно заканчиваться на bot, например, shop_serge_bot. Далее для бота будет сгенерирован уникальный токен, который будет выглядеть примерно так — 2093336709:AAGiH64Ec1R8r222sM9IywvlIGFkb7wFqyo.

Всего можно генерировать не более 20 ботов на одного пользователя. Управление ботами также происходит через меню команд служебного бота BotFather. Например, если вам потребуется настроить какой-то из ваших ботов, вы должны перейти по командам /mybots и затем нажать на кнопку Edit Bot. Здесь вы сможете настроить имя — Edit Name и указать описание — Edit Description

Настраивая description для бота вы задаете текст, который будет показываться пользователям под сообщением «Что может делать этот бот?» когда они его будут подключать. В профиле бота также будут показаны сведения, которые вы задали в поле «About» (команда Edit About). В меню команд имеется возможность установить аватар — BotPic.

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

Если Telegram использовать в коммерческих целях, чат-бот можно вооружить средствами для приема платежей. Стоит обратить внимание, что сам Telegram не занимается проведением транзакций, он лишь дает возможность подключить услуги длинного списка провайдеров.

В их числе такие платежные системы, как Stripe, YooMoney, Сбербанк, PayMaster, PSB, Tranzzo, Payme, CLICK, LiqPay, Portmone, Paymega, ECOMMPAY и др. Разумеется, чтобы использовать эти платежные системы, нужно быть юридическим лицом. 

aiogram — асинхронная библиотека

Реализовывать свой проект удобнее при помощи библиотек, таких как aiogram — это, пожалуй, лучшая стабильная асинхронная библиотека для Python (https://pypi.org/project/aiogram/). 

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

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

pip install -U aiogram. 

Создаем эхо-бот

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

Создаем конфигурационный файл config.py и указываем в нем значение, сгенерированное ботом BotFather. Приступаем к написанию кода самого чат-бота. 

Для начала импортируем конфигурацию и систему логирования. Затем подключаем все необходимые модули из aiogram. Указываем уровень логирования, а затем инициализируем бота, создав две переменные — Bot и Dispatcher.

Первая отвечает за прямой доступ к методам API и обеспечивает общее взаимодействие с ботом. Вторая, Dispatcher — простой обработчик событий. Мы обращаемся к этому обработчику событий и вызываем декоратор message_handler, который будет вызываться тогда, когда приходит событие о новом сообщении. 

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

import config
import logging
from aiogram import Bot, Dispatcher, executor, types
logging.basicConfig(level=logging.INFO)
bot = Bot(token=config.TOKEN)
dp = Dispatcher(bot)
@dp.message_handler()
async def echo(message: types.Message):
    await message.answer(message.text)
if __name__ == "__main__":
    executor.start_polling(dp, skip_updates=True)

Как уже говорилось ранее, обработка событий в Telegram может происходить двумя способами — long polling, когда мы со своей стороны постоянно запрашиваем сервер, а второй вариант — более мощное и быстрое решение вебхук. Реализация long polling на Linux имеет большой минус — бот часто зависает и его приходится постоянно перезапускать. 

В случае с webhook бот загружается на сервер, у бота появляется API с url-адресом, сервер Teleram посылает нашему боту сообщения, как только они появляются. По сути, бот на вебхуках постоянно не работает, а включается лишь тогда, когда получает запрос с сервера. Этот метод предпочтительнее, он быстрее, но для тестов обычно используется long polling

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

Оформление: кнопки и текст

Все сообщения в Telegram можно форматировать, используя различные варианты оформления текста — жирный, курсив и т.д. В Bot API разметка сообщений может создаваться в HTML и Markdown. Для удобства в ботах применяются кнопки, которые ставят под сообщениями. Их называют инлайн-клавиатурой или инлайн-кнопками, и они бывают разных видов. 

Например, URL button — простая кнопка со ссылкой на какой-то веб-ресурс. Вариант кнопки Callback запрашивает обновление. Она может применяться, скажем, для уведомлений или предупреждений (с окном notification или окном alert). Кнопка для перехода в режим инлайн может открывать меню для выбора чата. 

Другой тип кнопок — клавиатурный. Он дают возможность использовать подсказки бота. Например, они могут содержать наиболее частые запросы, ожидаемые от пользователя («как к вам проехать», «время работы» и т.д.)

Один из примеров такой клавиатуры — бот в кафе для дистанционного принятия заказов:

import config
import logging
from aiogram.dispatcher.filters import Text
from aiogram import Bot, Dispatcher, executor, types

logging.basicConfig(level=logging.INFO)
bot = Bot(token=config.TOKEN)
dp = Dispatcher(bot)


@dp.message_handler(commands="start")
async def cmd_start(message: types.Message):
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    buttons = ["С сахаром", "Без сахара"]
    keyboard.add(*buttons)
    await message.answer("Вам кофе с сахаром?", reply_markup=keyboard)

@dp.message_handler(Text(equals="Конечно"))
async def with_puree(message: types.Message):
    await message.reply("Эспрессо с сахаром!")

@dp.message_handler(lambda message: message.text == "Без сахара")
async def without_puree(message: types.Message):
    await message.reply("Эспрессо без сахара!")
if __name__ == "__main__":
    executor.start_polling(dp, skip_updates=True)

Инструмент для оформления текста выбирается аргументом функции parse_mode.

from aiogram import types
   await message.answer("Жирное  <b>начертание HTML-разметкой</b>", parse_mode=types.ParseMode.HTML)
    await message.answer("Оформление *текста MarkdownV2*\!", parse_mode="MarkdownV2")

Когда текст всех сообщений одинаково оформлен, это удобно — при этом можно сразу передать нужный тип Bot. Если все-таки для какого-то сообщения разметка не понадобится, то в этом месте ставится пустое значение parse_mode="".

bot = Bot(token="2093336701:AAGiH64eA1R8g222sF9IywvlIGFkb7wFqyo", parse_mode=types.ParseMode.HTML)

await message.answer("Текстовый блок с <u>HTML-разметкой</u>")
await message.answer("Текстовый блок без <s>применения разметки</s>", parse_mode="")

Используя модуль markdown из aiogram.utils по ходу текста можно менять форматирование. Тип форматирования определяется функцией с дописанной к ней букве h, которая означает поддержку HTML. 

import aiogram.utils.markdown as LPT
   await message.answer(
       LPT.text(
           LPT.text(LPT.hunderline("Смартфон Samsаng"), ", год выпуска 2021"),
           LPT.text("Стоимость без скидки:", LPT.hstrikethrough(888), "долларов"),
           LPT.text("Новая цена:", LPT.hbold(777), "долларов"),
           sep="\n"), parse_mode="HTML")

Учим бот-модерации

Как видите, эхо-бот, код которого написан выше, отвечает нам теми же сообщениями, которые мы отсылаем. Однако, если мы добавим бот в какую-нибудь тестовую группу, то возвращать текстовые сообщения он уже не будет. Причина этого очевидна — боты Telegram не имеют доступа к сообщениям в групповых чатах. Чтобы изменить это, необходимо снова вернуться к меню BotFather и разделе меню Group Privacy выбрать Turn OFF.

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

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

import config
import logging

from aiogram import Bot, Dispatcher, executor, types

logging.basicConfig(level=logging.INFO)

bot = Bot(token=config.TOKEN)
dp = Dispatcher(bot)


@dp.message_handler()
async def filter_messages(message: types.Message):
    if "плохое_слово" in message.text:
        await message.delete()

if __name__ == "__main__":
    executor.start_polling(dp, skip_updates=True)

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

Кстати, аналогичным образом можно удалять надоедливые информационные сообщения о том, что к чату присоединился какой-то пользователь. В этом случае код будет практически идентичным. Мы вызываем тот же декоратор message_handler, только указываем в аргументах content_types в значении new_chat_memebers.

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

import config
import logging
from aiogram import Bot, Dispatcher, executor, types
logging.basicConfig(level=logging.INFO)
bot = Bot(token=config.TOKEN)
dp = Dispatcher(bot)
@dp message_handler(content_types=["new_chat_members"])
async def on_user joined(message: types.Message):
@dp.message_handler()
async def filter_messages(message: types.Message):
    if "плохое_слово" in message.text:
        await message.delete()

if __name__ == "__main__":
    executor.start_polling(dp, skip_updates=True)

Даем возможность бана в группе

Помимо основного кода нам понадобится сделать файл filters.py, который поместим рядом с главным файлом нашего бота:

from aiogram import types
from aiogram.dispatcher.filters import BoundFilter

class IsAdminFilter(BoundFilter):
    key = "is_admin"
    def __init__(self, is_admin):
        self.is_admin = is_admin
    async def check(self, message: types.Message):
        member = await message.bot.get_chat_member(message.chat.id, message.from_user.id)
        return member.is_chat_admin()

В коде бота мы его импортируем:

import config
import logging

from aiogram import Bot, Dispatcher, executor, types
from filters import IsAdminFilter
logging.basicConfig(level=logging.INFO)

bot = Bot(token=config.TOKEN)
dp = Dispatcher(bot)

dp.filters_factory.bind(IsAdminFilter)
@dp.message_handler(is_admin=True, commands=["бан"], commands_prefix="!/")
async def cmd_ban(message: types.Message):
    if not message.reply_to_message:
        await message.reply("это должен быть ответ на сообщение")
        return

    await bot.kick_chat_member(chat_id=message.chat.id, user_id=message.reply_to_message.from_user.id)
    await message.delete()

    await message.reply_to_message.reply("пользователь наказан!")


@dp.message_handler()
async def filter_messages(message: types.Message):
    if "мат" in message.text:
        await message.delete()


if __name__ == "__main__":
    executor.start_polling(dp, skip_updates=True)

Также необходимо в конфигурационном файле config.py указать id чата (GROUP_ID).

Все пользователи Telegram имеют свой id. Он постоянный, и поэтому по нему можно идентифицировать чаты. Если вдруг вы не знаете id, вы можете воспользоваться ботом @username_to_id_bot, который покажет это значение. 

В токене бота первая часть — это его id. Например, токен 110301514:AмHdqTcvCG1vGWDxfyeDfSAs0K5PALDsaw принадлежит боту с id 110301514. В Bot API перед id супергрупп и каналов добавляется -100 (например, id 1322414430 превращается в -1001322414430).

Заключение

Как видите, сложного ничего нет и все трудности при разработке чат-ботов сводятся к тому, чтобы найти оптимальный API и библиотеку под Python, C#, PHP и другие языки программирования. Сегодня это явный тренд, чат-боты могут создавать воронки продаж не хуже опытных менеджеров, а кроме того берут на себя массу функций, требовавших ранее человеческих ресурсов, — запись на прием к врачу, продажа билетов и так далее.

Более сложные боты обладают искусственным интеллектом и умеют использовать нейронные сети. Возможности таких чат-ботов ограничены только вашей фантазией, но об этом — в следующий раз. А пока посмотрите дополнительное видео по технике создания ботов на JavaScript для Telegram API:

 

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023