Найти в Дзене
Записки сисадмина

Python. MAX бот. Создаем своего бота

Ну что же, настал тот момент, когда в нашем мессенджере MAX открыли регистрацию ботов. Да, на момент написания статьи - только для юридических лиц, но все же. Давайте сразу определимся: я все-таки технический специалист, и буду придерживаться своей сугубо технической точки зрения. Как бы кто ни относился к нашему мессенджеру, мы здесь собрались для того, чтобы обсудить именно функционал, дать бизнесу еще один инструмент для рекламы, взаимодействия с клиентами, и чего он еще пожелает.  Однако, лирических отступлений все равно будет достаточно много, хочется поделиться своими мыслями по поводу и без. Итак, вы (или ответственный проджект менеджер) прошли все круги ада, чтобы зарегистрироваться в платформе и создать собственного бота. Вот токен у вас на руках, и вы начинаете свое увлекательное путешествие в api отечественного мессенджера. Если пройти по ссылке на официальный github аккаунт мессенджера, мы увидим, что разработчики создали собственные библиотеки для взаимодействия с api то
Оглавление

Ну что же, настал тот момент, когда в нашем мессенджере MAX открыли регистрацию ботов. Да, на момент написания статьи - только для юридических лиц, но все же.

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

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

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

Если пройти по ссылке на официальный github аккаунт мессенджера, мы увидим, что разработчики создали собственные библиотеки для взаимодействия с api только на typescript и golang. Грусть и печаль, но также официальный аккаунт форкнул библиотеку python с названием maxapi. Клонировали - значит признали.

Сразу оговорюсь - ставить эту библиотеку нужно с гитхаба ее разработчика, т.к. форкнутая версия устарела (в api мессенджера сменили адрес и метод авторизации).

Устанавливаем библиотеку:

pip install maxapi

Лирическое отступление:

Есть у разработчиков две болезни: асинхроншина и докера. Суют и то, и другое куда ни попадя. Я бы поверил, что библиотека писалась асинхронной, поскольку рассчитывалась сразу на ботов для организаций, и на продакшен решения. Однако, создана она была намного заранее. В большинстве случаев, это добавит лишних проблем, но имеем что имеем. Даже так, хочу выразить огромную благодарность человеку, который ее создал. Будем честны, это огромный труд.

По опыту статей по телеграм ботам, мы будем создавать бота на long polling, не используя webhook. Просто потому что :)

Создание бота.

По классике, создаем нашего файл с нашим ботом и инициализируем его:

-2
import asyncio
from maxapi import Bot, Dispatcher
from config import bot_token
bot = Bot(token=bot_token)
dp = Dispatcher()
async def main():
await dp.start_polling(bot)
if __name__ == '__main__':
asyncio.run(main())

В данной конструкции нам нужен dispatcher для обработки событий (все взаимодействия пользователей с ботом).

Функция main() запускает polling нашего dispatcher с сессией бота внутри.

Открываем диалог с нашим ботом и видим такую картину:

-3

Первое отличие от телеграмма - в MAX событие, срабатывающее по нажатии кнопки "Начать" не является тем же событием, что и команда start.

Если мы напишем простенькую конструкцию:

-4

И нажмем на кнопку "Начать", ничего не произойдет.

Создаем первые обработчики событий.

Для события "Пользователь начал диалог с ботом" существует тип событий "BotStarted".

Импортируем необходимые модули:

from maxapi.types import Command, MessageCreated, BotStarted

Прописываем сразу обработку события начала чата и команды /start:

-5
@dp.bot_started()
async def bot_started(event: BotStarted):
await event.bot.send_message(
chat_id=event.chat_id,
text='Ты начал диалог с ботом'
)
@dp.message_created(Command('start'))
async def start_message(event: MessageCreated):
await event.message.answer(f"Обработка команды start")

Запускаем нашего бота и проверяем, что все работает:

-6

Напоследок, в этой же статье мы создадим себе на будущее команду /id, которая будет выводить пользователю его user_id в MAX:

-7

Разберем этот блок кода подробнее:

@dp.message_created(Command('id'))

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

Поскольку мы указываем в нем явно Command, он ищет в полученном json поле command.

async def hello(event: MessageCreated):

Асинхронная функция, которая срабатывает, когда получает из декоратора выше сообщение. Событие MessageCreated сигнализирует о том, что мы получили новое сообщение.

await event.message.answer(f'''Привет, {event.from_user.first_name}!

Твой ID в мессенджере: {event.from_user.user_id}''')

Все полученное сообщение помещается в переменную event. Далее, мы можем оперировать данным json объектом точно так же, как мы это делали с телеграм ботами.

Пример json объекта сообщения:

bot=<maxapi.bot.Bot object at 0x752e18d91c60> update_type=<UpdateType.MESSAGE_CREATED: 'message_created'> timestamp=1766852914532
from_user=User(user_id='ID пользователя', first_name='Имя', last_name='Фамилия', username=None, is_bot=False, last_activity_time=1766852388000, description=None, avatar_url=None, full_avatar_url=None, commands=None)
body=MessageBody(mid='mid.0000000006aaa00e019b60a3ed64795e', seq=115792472606800222, text='/id', attachments=[], markup=[]), stat=None, url=None)

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

Итоговая конструкция бота:

-8

В следующей статье будем учиться отправлять сообщения сами, а не просто отвечать на пришедшие.