Core Components¶
LXMFBot¶
The main bot class that handles message routing, command processing, and bot lifecycle management.
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
)
Key Methods¶
run(delay=10)
: Start the bot’s main loopsend(destination, message, title="Reply", lxmf_fields=None)
: Send a message to a destination, optionally with custom LXMF fields.send_with_attachment(destination, message, attachment, title="Reply")
: Send a message with an attachmentcommand(name, description="No description provided", admin_only=False, threaded=False)
: Decorator for registering commands. Setthreaded=True
to run the command’s callback in a separate thread.on_first_message()
: Decorator for handling first messages from usersvalidate()
: Run validation checks on the bot configuration
Storage¶
The framework provides two storage backends:
JSONStorage¶
from lxmfy import JSONStorage
storage = JSONStorage("data")
SQLiteStorage¶
from lxmfy import SQLiteStorage
storage = SQLiteStorage("data/bot.db")
Commands¶
Command registration and handling:
@bot.command(name="hello", description="Says hello")
def hello(ctx):
ctx.reply(f"Hello {ctx.sender}!")
Threaded Commands¶
For long-running or blocking operations that do not interact with the Reticulum Network Stack directly, you can run commands in a separate thread to keep the bot responsive.
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!")
Important: Functions marked as threaded=True
must not directly interact with the Reticulum Network Stack (RNS) or any components that rely on lxmfy.transport.py
, as these are generally not thread-safe. Use ctx.reply()
for sending messages back to the user from within a threaded command.
Events¶
Event system for handling various bot events:
@bot.events.on("message_received", EventPriority.HIGHEST)
def handle_message(event):
# Handle message event
pass
Permissions¶
Permission system for controlling access to bot features:
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")
Middleware¶
Middleware system for processing messages and events:
@bot.middleware.register(MiddlewareType.PRE_COMMAND)
def pre_command_middleware(ctx):
# Process before command execution
pass
Attachments¶
Support for sending files, images, and audio:
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)
Icon Appearance (LXMF Field)¶
You can set a custom icon for your bot that compliant LXMF clients can display. This uses the 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)
Scheduler¶
Task scheduling system:
@bot.scheduler.schedule(name="daily_task", cron_expr="0 0 * * *")
def daily_task():
# Run daily at midnight
pass
Signatures¶
Cryptographic message signing and verification for enhanced security:
from lxmfy import SignatureManager
# SignatureManager is automatically available as bot.signature_manager
# when signature_verification_enabled=True
# Manual usage (rarely needed):
sig_manager = SignatureManager(bot, verification_enabled=True, require_signatures=False)
Key Methods¶
sign_message(message, identity)
: Sign an LXMF message using the provided RNS identityverify_message_signature(message, signature, sender_hash, sender_identity=None)
: Verify a message signature against a sender identityshould_verify_message(sender)
: Determine if a message from the given sender should be verifiedhandle_unsigned_message(sender, message_hash)
: Handle messages that lack valid signatures
Signature Fields¶
LXMFy uses custom LXMF field 0xFA
(FIELD_SIGNATURE) to store cryptographic signatures. Messages are canonicalized by sorting and concatenating fields in the following order:
source hash (prefixed with “source:”)
destination hash (prefixed with “dest:”)
content (prefixed with “content:”)
title (prefixed with “title:”)
timestamp (prefixed with “timestamp:”)
custom fields (excluding signature field, prefixed with “field_{id}:”)
Templates¶
The framework includes several ready-to-use bot templates:
EchoBot¶
Simple echo bot that repeats messages:
from lxmfy.templates import EchoBot
bot = EchoBot()
bot.run()
MemeBot¶
Bot for sending random memes:
from lxmfy.templates import MemeBot
bot = MemeBot()
bot.run()
NoteBot¶
Note-taking bot with JSON storage:
from lxmfy.templates import NoteBot
bot = NoteBot()
bot.run()
ReminderBot¶
Reminder bot with SQLite storage:
from lxmfy.templates import ReminderBot
bot = ReminderBot()
bot.run()
CLI Tools¶
The framework provides command-line tools for bot management:
# 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
Error Handling¶
The framework provides comprehensive error handling:
try:
bot.run()
except KeyboardInterrupt:
bot.cleanup()
except Exception as e:
logger.error(f"Error running bot: {str(e)}")