Cluster · руководства

Как создать модуль для юзербота Cluster на Python

Модуль добавляет юзерботу свои команды и другие обработчики. Начнём с одной команды hello: она получает имя из сообщения и отвечает приветствием. Напишем код, укажем права, соберём архив и установим его через каталог Cluster.

Нужны основы Python, редактор и профиль Cluster с подтверждённой почтой. Для запуска экземпляра нужна действующая подписка. Для проверки команд подключи Telegram-аккаунт, а для проверки через бота ещё и личного бота. Подключение описано отдельно.

Файлы модуля

Создай каталог hello с двумя файлами:

hello/
    main.py
    manifest.json

В main.py находится код, в manifest.json описание версии. Готовые файлы: main.py и manifest.json.

Команда hello

Содержимое main.py:

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING: from router import Event

class Module:
    @loader.command("hello", access="owner", source="both")
    async def hello(self, ctx: Event) -> None:
        name = ctx.args.strip() or "friend"
        await ctx.reply(f"Hello, {name}!")

Основной класс называется Module. Объект loader предоставляет среда Cluster: импортировать его из стороннего пакета не нужно. Декоратор @loader.command добавляет обработчик команды.

По порядку о параметрах:

Для аргумента ctx указан тип Event, результат метода None. Импорт внутри TYPE_CHECKING нужен редактору, а from __future__ import annotations позволяет не выполнять его при загрузке модуля.

ctx.args содержит текст после команды. Убираем пробелы по краям и используем friend, если ничего не передано. ctx.reply отправляет ответ через тот источник, из которого пришла команда.

!hello Cluster
Hello, Cluster!

!hello
Hello, friend!

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

Описание версии

Содержимое manifest.json:

{
    "name": "Hello",
    "description": "Команда hello для аккаунта и личного бота. Отвечает приветствием, доступна только овнерам.",
    "version": "1.0.0",
    "permissions": {
        "telegram.read": {},
        "telegram.send": {},
        "bot.read": {},
        "bot.send": {}
    },
    "dependencies": [],
    "changes": "Первая версия команды hello.",
    "source": true,
    "interface": {
        "commands": [
            {"id": "hello", "alias": "hello", "access": "owner", "source": "both"}
        ]
    }
}

name и description описывают модуль, version задаёт номер выпуска, changes перечисляет изменения. Для первой версии используем 1.0.0.

В permissions перечислены четыре права. telegram.read и telegram.send нужны для получения событий и ответа через аккаунт, bot.read и bot.send для личного бота. Сеть, файлы, хранилище и полный Telegram API этому примеру не нужны.

Пустой объект у конкретного права означает отсутствие дополнительных ограничений автора для этого права. Пользователь при установке может сузить доступ, например оставить только тестовый чат. Если оставить сам permissions пустым, модуль не получит этих прав.

dependencies содержит зависимости от других модулей. Здесь их нет. Сторонние пакеты Python тоже не используются. Если они понадобятся, для них есть отдельное поле requirements, описанное в справочнике публикации.

source=true разрешает показывать исходники в сравнении версий. Поле относится к показу кода, условия лицензии задаются отдельно.

Описание команды

В объекте interface повторяется описание, по которому ядро регистрирует команду:

{
    "commands": [
        {"id": "hello", "alias": "hello", "access": "owner", "source": "both"}
    ]
}

id должен совпадать с именем в декораторе. alias является исходным названием для вызова. access и source тоже должны совпасть с кодом.

Ядро сверяет описание с обработчиками при запуске. Если в форме публикации указать owner, а в коде заменить его на public, экземпляр не запустится с таким несоответствием.

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

Проверка и архив

Открой терминал в каталоге hello. Для проверки синтаксиса:

python3 -m py_compile main.py

Эта команда не запускает модуль и не проверяет соединение с Telegram. Обычный запуск python3 main.py тоже не заменяет запуск в Cluster: в нём нет предоставленного средой объекта loader.

Собери архив только из двух нужных файлов:

python3 -m zipfile -c ../hello.zip main.py manifest.json
python3 -m zipfile -l ../hello.zip

В списке должны быть main.py и manifest.json в корне. Дополнительный каталог hello внутри архива не нужен. __pycache__, пароли, токены и файлы Telegram-сессий в пакет не добавляются.

Публикация в каталоге

Открой «Каталог модулей» и нажми «Опубликовать модуль». Выбери hello.zip в поле «Архив с компьютера».

Далее заполни описание. Файл manifest.json внутри архива не заполняет форму автоматически. Перенеси его значения в поля сайта:

В поле «Описание команд, полей и страниц» открой редактор и нажми «Вставить JSON». Помести туда только объект interface, показанный выше, затем нажми «Применить значение». Весь manifest.json сюда не вставляется.

В блоке «Запрашиваемые права» отметь telegram.read, telegram.send, bot.read и bot.send. Наличие этих прав в файле архива не выбирает их в форме.

Для первой проверки выключи «Показывать модуль в общем каталоге». Так публикация будет доступна тебе и добавленным тестерам. Затем нажми «Опубликовать версию модуля».

После сообщения «Версия опубликована» открой страницу модуля. У первой публикации появится собственный ID. Для следующих версий используй эту же публикацию, создавать новую каждый раз не требуется.

Установка и запуск

  1. На странице своего модуля нажми «Установить» и выбери 1.0.0.
  2. Получи список прав и отметь необходимые разрешения.
  3. Для первой проверки ограничь Telegram своим тестовым чатом, например «Избранным», а бота своим диалогом с ним.
  4. Укажи название экземпляра, например main.
  5. Если hello уже занят, выбери другое название команды.
  6. Нажми «Установить с выбранными правами».
  7. Открой «Мои модули» и нажми «Запустить» у нового экземпляра.

Успешная публикация проверяет пакет и описание, но не выполняет твой Python-код в ядре. Окончательная проверка обработчиков происходит при запуске экземпляра.

Проверка в Telegram

Из подключённого аккаунта отправь в разрешённый чат:

!hello Cluster

В ответ должно прийти Hello, Cluster!. Если префикс или название менялись, используй новые значения.

В диалоге с подключённым личным ботом проверь:

/hello Cluster

Команда доступна только овнерам. Посторонний отправитель не должен получить ответ. Если команда отключилась или не отвечает, посмотри состояние экземпляра, принятые права и «Журнал событий».

В этом примере не выполняется произвольный код из сообщения: аргумент команды используется только как текст приветствия.

Изменения модуля

Если меняется код, выпускается новая версия. Исправь файлы, подними номер, например до 1.0.1, и укажи изменения. На странице публикации открой управление и добавь новую версию с новым архивом и соответствующим описанием.

Если появились новые команды, поля или права, перенеси их в описание версии. Старый установленный экземпляр не получает новые права только потому, что ты изменил файл на компьютере.

Для смены пользовательского названия hello новая версия не нужна: это настройка команды.

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