Документация для разработчиков
Полное руководство по созданию собственных модулей для Xioca
Философия Xioca
Xioca — это современный асинхронный Telegram-юзербот, построенный на Pyrogram. В его основе лежат три ключевых принципа:
- Модульность: Вся функциональность разделена на независимые модули. Это позволяет легко добавлять, удалять и обновлять возможности юзербота на лету, без перезагрузки.
- Автоматизация: Xioca берет на себя рутинные задачи. Автоматическая установка зависимостей и управление базой данных позволяют разработчику сосредоточиться на логике модуля, а не на его окружении.
- Удобство для разработчика: Продуманная архитектура и набор утилит делают процесс создания модулей максимально простым и интуитивно понятным.
Анатомия модуля
Каждый модуль в Xioca представляет собой Python-класс, унаследованный от loader.Module. Для корректной загрузки название класса должно заканчиваться на суффикс Mod.
# required: requests emoji
# О зависимостях читайте в соответствующем разделе
import requests
import emoji
from .. import loader, utils
@loader.module(author="YourName", version="1.0.0")
class ExampleMod(loader.Module):
"""Краткое описание вашего модуля. Оно будет видно в .help"""
# Код вашего модуля...
Декоратор @loader.module(...) является необязательным, но крайне рекомендуется. Он позволяет указать метаданные: автора (author) и версию (version), которые будут отображаться в списке модулей.
Жизненный цикл модуля
В модуле можно определить асинхронный метод on_load. Этот метод будет автоматически вызван один раз после успешной загрузки и инициализации модуля. Это идеальное место для выполнения подготовительных действий.
class ExampleMod(loader.Module):
"""Пример модуля с on_load"""
async def on_load(self):
# Этот код выполнится один раз при загрузке модуля
# Например, можно проверить API ключи или создать нужные записи в БД
await self.db.set("launch_count", self.db.get("launch_count", 0) + 1)
logging.info(f"Модуль ExampleMod загружен! Количество запусков: {await self.db.get('launch_count')}")
Управление зависимостями
Это одна из ключевых особенностей Xioca. Вам не нужно просить пользователя устанавливать библиотеки вручную через pip. Достаточно указать их в специальном комментарии в самом начале файла модуля.
# required: aiohttp pillow requests, перечислив нужные библиотеки через пробел. При загрузке модуля Xioca автоматически установит их, если они отсутствуют.
# required: beautifulsoup4
from bs4 import BeautifulSoup
from .. import loader
@loader.module(author="YourName", version="1.0.0")
class ParserMod(loader.Module):
"""Этот модуль требует beautifulsoup4 для работы"""
# ...
Создание команд
Команды — это основной способ взаимодействия с юзерботом. Чтобы создать команду, определите в классе асинхронный метод с суффиксом _cmd. Название метода без суффикса станет именем команды.
async def ping_cmd(self, app, message, args):
"""Проверяет пинг до серверов Telegram.
Использование: .ping"""
# app: экземпляр pyrogram.Client
# message: объект pyrogram.types.Message
# args: строка с аргументами после команды
await utils.answer(message, "🏓 Pong!")
Аргументы команды
Все, что пользователь напишет после команды, передается в метод в виде единой строки args. Для разделения аргументов удобно использовать utils.get_args_raw() или args.split().
Документация команд (Docstrings)
Содержимое docstring (строка документации) вашей команды автоматически используется для создания справки, доступной по команде .help <имя модуля>. Рекомендуется всегда описывать назначение команды и формат ее использования.
Обработчики событий
Помимо команд, модули могут реагировать на различные события в Telegram: новые сообщения, нажатия на инлайн-кнопки и т.д. Это позволяет создавать сложную интерактивную логику.
Обработчик сообщений (Message Handler)
Реагирует на сообщения, соответствующие определенным фильтрам. Метод должен иметь суффикс _message_handler. Используйте декоратор @loader.on_bot(...) с функцией-фильтром.
from pyrogram import filters
# Фильтр: личные сообщения, содержащие "привет"
@loader.on_bot(filters.private & filters.regex(r"(?i)привет"))
async def hello_message_handler(self, app, message):
"""Отвечает на 'привет' в личных сообщениях"""
await message.reply("И тебе привет! 👋")
Обработчик Callback-запросов (Inline Buttons)
Срабатывает при нажатии на инлайн-кнопку. Метод должен иметь суффикс _callback_handler. Фильтрация обычно происходит по полю call.data.
# Фильтр: callback data начинается с 'example_'
@loader.on_bot(filters.create(lambda _, __, q: q.data.startswith("example_")))
async def example_callback_handler(self, app, call):
"""Обрабатывает нажатия на кнопки с префиксом 'example_'"""
data_part = call.data.split("_")[1]
await call.answer(f"Вы выбрали опцию: {data_part}!", show_alert=True)
Наблюдатели (Watchers)
Watchers — это особый тип обработчиков, которые срабатывают на **все** входящие и исходящие сообщения в чатах, где вы состоите. Они выполняются раньше команд и идеально подходят для фонового мониторинга, сбора статистики или AFK-модулей. Название метода-наблюдателя должно начинаться с префикса watcher.
@loader.on(filters.mentioned)
async def watcher_mention(self, app, message):
"""Среагирует, если вас упомянули в чате"""
await app.send_message("me", f"Вас упомянули в чате «{message.chat.title}»!")
Работа с базой данных
Xioca предоставляет каждому модулю свою собственную, изолированную key-value базу данных. Вам не нужно заботиться о ее создании или подключении — просто используйте методы объекта self.db. Система автоматически преобразует списки и словари в JSON для хранения.
Сохранение значения
Используйте метод self.db.set(key, value).
# Сохранение строки
await self.db.set("api_key", "my-secret-key-123")
# Сохранение списка ID
await self.db.set("trusted_users", [12345, 54321])
# Сохранение словаря (конфигурации)
config = {"enabled": True, "level": "admin"}
await self.db.set("module_config", config)
Получение значения
Используйте метод self.db.get(key, default=None). Если ключ не найден, вернется значение по умолчанию.
# Получение строки
api_key = await self.db.get("api_key")
# Получение списка (если его нет, вернется пустой список)
trusted_users = await self.db.get("trusted_users", [])
# Получение словаря
config = await self.db.get("module_config", {})
Удаление значения
Используйте метод self.db.delete(key).
Логирование и отладка
Вместо использования print() для отладки, используйте встроенный в Python модуль logging. Xioca перехватывает его вывод и направляет в специальный лог-чат в вашем Telegram-аккаунте.
import logging
class DebugMod(loader.Module):
async def debug_cmd(self, app, message, args):
logging.info("Команда debug запущена.")
if not args:
logging.warning("Пользователь не ввел аргументы!")
return await utils.answer(message, "⚠️ Аргументы не указаны.")
try:
result = 10 / 0
except Exception:
logging.error("Произошла ошибка деления на ноль!", exc_info=True)
await utils.answer(message, "🚨 Произошла ошибка. Отчет отправлен в лог-чат.")
Полезные утилиты
Xioca поставляется с набором готовых функций-хелперов в модуле utils, которые упрощают рутинные задачи.
-
utils.answer(message, text, **kwargs)
Это основной способ отправки ответов. Он "умный": если вы отвечаете на свое же сообщение, он его отредактирует. В противном случае — отправит новое сообщение в ответ на исходное. Поддерживает все аргументы Pyrogram
send_message. -
utils.get_args_raw(message)
Возвращает строку с аргументами команды.
-
utils.get_chat_id(message)
Надежный способ получить ID текущего чата.
await asyncio.sleep() для асинхронных пауз вместо блокирующего time.sleep(), чтобы не останавливать работу всего юзербота.