Основные компоненты

LXMFBot

Основной класс бота, который обрабатывает маршрутизацию сообщений, обработку команд и управление жизненным циклом бота.

from lxmfy import LXMFBot

bot = LXMFBot(
    name="MyBot",
    announce=600,
    announce_immediately=True,
    admins=set(),
    hot_reloading=False,
    rate_limit=5,
    cooldown=60,
    max_warnings=3,
    warning_timeout=300,
    command_prefix="/",
    cogs_dir="cogs",
    cogs_enabled=True,
    permissions_enabled=False,
    storage_type="json",
    storage_path="data",
    first_message_enabled=True,
    event_logging_enabled=True,
    max_logged_events=1000,
    event_middleware_enabled=True,
    announce_enabled=True,
    signature_verification_enabled=False,
    require_message_signatures=False
)

Ключевые методы

  • run(delay=10): Запустить основной цикл бота

  • send(destination, message, title="Reply", lxmf_fields=None, propagation_node=None, max_retries=3): Send a message to a destination, optionally with custom LXMF fields, specific propagation node, and retry configuration.

  • send_with_attachment(destination, message, attachment, title="Reply"): Отправить сообщение с вложением

  • command(name, description="No description provided", admin_only=False, threaded=False): Декоратор для регистрации команд. Установите threaded=True для запуска обратного вызова команды в отдельном потоке.

  • on_first_message(): Декоратор для обработки первых сообщений от пользователей

  • on_message(): Decorator for handling all messages (called before command processing)

  • validate(): Запустить проверочные тесты конфигурации бота

Хранилище

Фреймворк предоставляет два бэкенда для хранения данных:

JSONStorage

from lxmfy import JSONStorage

storage = JSONStorage("data")

SQLiteStorage

from lxmfy import SQLiteStorage

storage = SQLiteStorage("data/bot.db")

Команды

Регистрация и обработка команд:

@bot.command(name="hello", description="Says hello")
def hello(ctx):
    ctx.reply(f"Hello {ctx.sender}!")

Многопоточные команды

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

import time

@bot.command(name="long_task", description="Performs a long-running task in a separate thread", threaded=True)
def long_task_command(ctx):
    ctx.reply("Starting a long task... please wait.")
    time.sleep(10) # This runs in a separate thread
    ctx.reply("Long task completed!")

Важно: Функции, помеченные как threaded=True, не должны напрямую взаимодействовать с сетевым стеком Reticulum (RNS) или любыми компонентами, которые зависят от lxmfy.transport.py, так как они, как правило, не являются потокобезопасными. Используйте ctx.reply() для отправки сообщений пользователю из многопоточной команды.

События

Система событий для обработки различных событий бота:

@bot.events.on("message_received", EventPriority.HIGHEST)
def handle_message(event):
    # Handle message event
    pass

Разрешения

Система разрешений для контроля доступа к функциям бота:

from lxmfy import DefaultPerms

@bot.command(name="admin", description="Admin command", admin_only=True)
def admin_command(ctx):
    if ctx.is_admin:
        ctx.reply("Admin command executed")

Промежуточное ПО

Система промежуточного ПО для обработки сообщений и событий:

@bot.middleware.register(MiddlewareType.PRE_COMMAND)
def pre_command_middleware(ctx):
    # Process before command execution
    pass

Вложения

Поддержка отправки файлов, изображений и аудио:

from lxmfy import Attachment, AttachmentType

attachment = Attachment(
    type=AttachmentType.IMAGE,
    name="image.jpg",
    data=image_data,
    format="jpg"
)
bot.send_with_attachment(destination, "Here's an image", attachment)

Внешний вид иконки (поле LXMF)

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

from lxmfy import IconAppearance, pack_icon_appearance_field
import LXMF # Required for LXMF.FIELD_ICON_APPEARANCE

# Define the icon appearance
icon_data = IconAppearance(
    icon_name="smart_toy",  # Name from Material Symbols
    fg_color=b'\xFF\xFF\xFF',  # White foreground (3 bytes)
    bg_color=b'\x4A\x90\xE2'   # Blue background (3 bytes)
)

# Pack it into the LXMF field format
icon_lxmf_field = pack_icon_appearance_field(icon_data)

# Send a message with this icon
bot.send(
    destination_hash_str,
    "Hello from your friendly bot!",
    title="Bot Message",
    lxmf_fields=icon_lxmf_field
)

# You can also combine it with other fields, like attachments:
# attachment_field = pack_attachment(some_attachment)
# combined_fields = {**icon_lxmf_field, **attachment_field}
# bot.send(destination, "Message with icon and attachment", lxmf_fields=combined_fields)

Планировщик

Система планирования задач:

@bot.scheduler.schedule(name="daily_task", cron_expr="0 0 * * *")
def daily_task():
    # Run daily at midnight
    pass

Подписи

LXMFy предоставляет параметры конфигурации для встроенной в LXMF криптографической подписи и проверки сообщений:

from lxmfy import LXMFBot

bot = LXMFBot(
    name="SecureBot",
    signature_verification_enabled=True,  # Enable signature checks
    require_message_signatures=False      # Set to True to reject unsigned messages
)

Важно: LXMF автоматически обрабатывает все криптографические подписи и проверку с использованием идентификаторов RNS. SignatureManager в LXMFy - это слой конфигурации, который:

  • Контролирует, следует ли применять проверку подписи

  • Определяет политику для неподписанных сообщений (принять или отклонить)

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

Фактические криптографические операции выполняются LXMF/RNS, а не LXMFy.

SignatureManager Methods

SignatureManager доступен как bot.signature_manager, когда signature_verification_enabled=True:

  • should_verify_message(sender): Определить, следует ли проверять сообщение от данного отправителя

  • handle_unsigned_message(sender, message_hash): Handle messages that lack valid signatures based on policy

Как работают подписи LXMF

LXMF автоматически подписывает все исходящие сообщения, используя идентификатор RNS отправителя во время операции pack(). При получении сообщений LXMF проверяет подписи и предоставляет:

  • message.signature_validated: логическое значение, указывающее, действительна ли подпись

  • message.unverified_reason: код причины, если проверка не удалась (например, SIGNATURE_INVALID, SOURCE_UNKNOWN)

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

Доставка сообщений

LXMFy предоставляет расширенные функции доставки сообщений, включая узлы распространения и автоматические повторы:

Узлы распространения

Отправляйте сообщения через определенные узлы распространения для повышения надежности в сети Reticulum:

# Send via a specific propagation node
bot.send(
    destination_hash,
    "Message content",
    propagation_node="<propagation_node_hash>"
)

# The propagation node hash should be a valid LXMF propagation node
# on the Reticulum network

Автоматические повторы

Настройте автоматические повторные попытки для неудачных доставок сообщений:

# Send with custom retry count
bot.send(
    destination_hash,
    "Important message",
    max_retries=5  # Will retry up to 5 times on delivery failure
)

# Default max_retries is 3
# Retry logic automatically handles delivery callbacks

Система повторных попыток отслеживает попытки доставки для каждого получателя и автоматически повторяет неудачные доставки. Успешные доставки сбрасывают счетчик повторных попыток для этого получателя.

Обработчики сообщений

LXMFy предоставляет декораторы для обработки различных типов входящих сообщений:

Обработчик первого сообщения

Обработка первого сообщения от каждого пользователя:

@bot.on_first_message()
def welcome_user(sender, message):
    content = message.content.decode("utf-8")
    bot.send(sender, f"Welcome! You said: {content}")
    return True  # Return True to stop further processing

Общий обработчик сообщений

Обработка всех входящих сообщений перед обработкой команд:

@bot.on_message()
def handle_all_messages(sender, message):
    content = message.content.decode("utf-8").strip()

    # Custom logic here
    if content.startswith("echo:"):
        bot.send(sender, content[5:])
        return True  # Stop further processing

    return False  # Continue to command processing

Обработчики сообщений вызываются в следующем порядке: 1. Обработчик первого сообщения (если это первое сообщение от этого отправителя) 2. Общие обработчики сообщений (зарегистрированные с помощью on_message()) 3. Обработка команд (если сообщение начинается с префикса команды)

Шаблоны

Фреймворк включает в себя несколько готовых к использованию шаблонов ботов:

EchoBot

Простой эхо-бот, который повторяет сообщения:

from lxmfy.templates import EchoBot

bot = EchoBot()
bot.run()

MemeBot

Бот для отправки случайных мемов:

from lxmfy.templates import MemeBot

bot = MemeBot()
bot.run()

NoteBot

Бот для заметок с хранилищем JSON:

from lxmfy.templates import NoteBot

bot = NoteBot()
bot.run()

ReminderBot

Бот для напоминаний с хранилищем SQLite:

from lxmfy.templates import ReminderBot

bot = ReminderBot()
bot.run()

Инструменты командной строки

Фреймворк предоставляет инструменты командной строки для управления ботом:

# Create a new bot
lxmfy create mybot

# Create a bot from template
lxmfy create --template echo mybot

# Run a template bot
lxmfy run echo

# Analyze bot configuration
lxmfy analyze bot.py

# Verify package signature
lxmfy verify package.whl sigstore.json

# Test signature verification with a message
lxmfy signatures test

# Enable signature verification
lxmfy signatures enable

# Disable signature verification
lxmfy signatures disable

Обработка ошибок

Фреймворк предоставляет комплексную обработку ошибок:

try:
    bot.run()
except KeyboardInterrupt:
    bot.cleanup()
except Exception as e:
    logger.error(f"Error running bot: {str(e)}")