Bots erstellen¶
Grundlegende Struktur¶
Ein minimaler LXMFy-Bot umfasst:
- Import von
LXMFBot. - Instanziierung von
LXMFBotmit der gewünschten Konfiguration. - Definition von Befehlen oder Ereignis-Handlern.
- Start des Bots mit
bot.run().
from lxmfy import LXMFBot
# 1. Bot instanziieren
bot = LXMFBot(
name="SimpleBot",
command_prefix="!",
storage_path="simple_data"
)
# 2. Befehle definieren
@bot.command(name="ping", description="Responds with pong")
def ping_command(ctx):
# ctx ist ein Kontextobjekt mit Informationen zur Nachricht
# ctx.sender: LXMF-Hash des Absenders
# ctx.content: vollständiger Nachrichteninhalt
# ctx.args: Liste der Argumente nach dem Befehl
# ctx.reply(message): Funktion zum Senden einer Antwort
# (akzeptiert auch Schlüsselwortargumente wie title="My Title", lxmf_fields=some_fields)
ctx.reply("Pong!")
# Für lang laufende Aufgaben können Threaded-Befehle verwendet werden:
# import time
# @bot.command(name="long_op", description="Performs a long operation in a separate thread", threaded=True)
# def long_op_command(ctx):
# ctx.reply("Starting long operation...")
# time.sleep(10) # Simuliert eine lang laufende Operation
# ctx.reply("Long operation complete!")
# Wichtig: Threaded-Befehle sollten nicht direkt mit RNS oder lxmfy.transport.py interagieren.
@bot.command(name="greet", description="Greets the user")
def greet_command(ctx):
if ctx.args:
name = " ".join(ctx.args)
ctx.reply(f"Hello, {name}!")
else:
ctx.reply("Hello there! Tell me your name: !greet <your_name>")
# 3. Bot starten
if __name__ == "__main__":
print(f"Starting bot: {bot.config.name}")
print(f"Bot LXMF Address: {bot.local.hash}")
bot.run()
Verwendung von Vorlagen¶
LXMFy stellt mehrere Vorlagen für gängige Bot-Typen bereit. Mit der CLI kann eine Bot-Datei auf Basis einer Vorlage generiert werden.
# Echo-Bot erstellen
lxmfy create --template echo my_echo_bot
# Reminder-Bot erstellen (verwendet SQLite-Speicher)
lxmfy create --template reminder my_reminder_bot
# Notizen-Bot erstellen (verwendet JSON-Speicher)
lxmfy create --template note my_note_bot
# Cog-Test-Bot erstellen (testet das Laden von Cogs)
lxmfy create --template cogtest my_cog_test_bot
# RRC-Raum-Bot erstellen (tritt Hubs bei und antwortet auf @mentions)
lxmfy create --template rrc my_rrc_bot
# Oder die Vorlage direkt ausführen
lxmfy run rrc
Diese Befehle erzeugen eine Python-Datei (z. B. my_echo_bot.py), die
die gewählte Vorlage importiert und ausführt. Anschließend können Sie
die generierte Datei oder den Vorlagencode selbst anpassen
(lxmfy/templates/...).
Beispiel einer generierten Datei (my_cog_test_bot.py):
from lxmfy.templates import CogTestBot
if __name__ == "__main__":
bot = CogTestBot() # Erstellt eine Instanz der Vorlage CogTestBot
# Der Standardname kann optional überschrieben werden:
# bot.bot.name = "My Cog Test Bot"
bot.run()
Bot-Konfiguration¶
Beim Erstellen einer LXMFBot-Instanz können verschiedene
Schlüsselwortargumente übergeben werden, um das Verhalten zu
konfigurieren. Eine Liste gängiger Optionen finden Sie im Abschnitt
BotConfig der API-Referenz oder im
Schnellstart.
from lxmfy import LXMFBot
bot = LXMFBot(
name="ConfiguredBot",
announce=3600, # Jede Stunde announcen
admins={"your_admin_hash_here"}, # Admin-Benutzer festlegen
command_prefix="$", # '$' als Präfix verwenden
storage_type="sqlite", # SQLite-Datenbank verwenden
storage_path="data/my_bot_data.db", # Pfad zur DB-Datei angeben
rate_limit=10, # 10 Nachrichten / Minute erlauben
cooldown=30, # Cooldown von 30 Sekunden
permissions_enabled=True # Rollenbasierte Berechtigungen aktivieren
)
if __name__ == "__main__":
# Die Konfiguration kann auch nach der Instanziierung geändert werden
# Hinweis: Manche Einstellungen setzt man am besten bei der Initialisierung
bot.config.max_warnings = 5
bot.spam_protection.config.max_warnings = 5 # Spamschutz ebenfalls aktualisieren
bot.run()
Ein Bot-Icon setzen (LXMF-Feld)¶
Sie können Ihrem Bot ein eigenes Icon geben, das in kompatiblen
LXMF-Clients angezeigt wird. Dabei wird
LXMF.FIELD_ICON_APPEARANCE verwendet, das beim Senden von Nachrichten
gesetzt werden kann.
Zuerst die benötigten Importe:
Anschließend können Sie das Icon definieren und verwenden:
# In der Bot-Klasse oder beim Setup
icon_data = IconAppearance(
icon_name="robot_2", # Auswahl aus Material Symbols
fg_color=b'\x00\xFF\x00', # Grün
bg_color=b'\x33\x33\x33' # Dunkelgrau
)
self.bot_icon_field = pack_icon_appearance_field(icon_data)
# Beim Senden einer Nachricht oder Antwort:
ctx.reply("Message from your bot!", lxmf_fields=self.bot_icon_field)
# oder
# bot.send(destination, "Another message", lxmf_fields=self.bot_icon_field)
Dieses self.bot_icon_field kann vorausberechnet und für alle vom Bot
gesendeten Nachrichten wiederverwendet werden.
Strukturierte Befehle über LXMF-Felder¶
Neben textbasierten Befehlen unterstützt LXMFy Befehle, die über
LXMF-Nachrichtenfelder mit FIELD_COMMANDS (0x09) gesendet werden.
Das ist nützlich für strukturierte Anfrage/Antwort-Workflows zwischen
LXMF-Clients und Bots.
Enthält eine Nachricht FIELD_COMMANDS, extrahiert der Bot
Befehlsname und Argumente, leitet sie über dieselbe
Befehlsregistrierung wie Textbefehle und fügt der Antwort automatisch
FIELD_RESULTS (0x0A) hinzu.
Empfang strukturierter Befehle
from lxmfy import LXMFBot
bot = LXMFBot(name="FieldBot")
@bot.command(name="add", description="Add two numbers")
def add_command(ctx):
if len(ctx.args) >= 2:
try:
result = float(ctx.args[0]) + float(ctx.args[1])
ctx.reply(str(result))
except ValueError:
ctx.reply("Invalid numbers")
else:
ctx.reply("Usage: add <a> <b>")
Das ctx-Objekt in Feldbefehl-Callbacks enthält:
ctx.fields: das rohe LXMF-Felder-Dict der eingehenden Nachrichtctx.request_id: dierequest_idaus dem eingehendenFIELD_COMMANDS(falls vorhanden)
Senden eines strukturierten Befehls von einem LXMF-Client
import LXMF
from lxmfy import FIELD_COMMANDS
lxm = LXMF.LXMessage(
destination,
source,
b"", # Inhalt kann bei reinen Feldbefehlen leer sein
desired_method=LXMF.LXMessage.DIRECT,
)
lxm.fields[FIELD_COMMANDS] = {
"command": "add",
"args": ["3", "5"],
"request_id": "req-42", # optional, zur Korrelation
}
router.handle_outbound(lxm)
Feldbefehle deaktivieren
Wenn der Bot FIELD_COMMANDS ignorieren und nur Textbefehle
verarbeiten soll:
Cogs verwenden (Erweiterungen)¶
Cogs erlauben es, Befehle und Ereignis-Listener in separaten Dateien (Module) zu organisieren, damit die Haupt-Bot-Datei übersichtlich bleibt.
- Erstellen Sie ein
cogs-Verzeichnis (oder das Verzeichnis, das Sie inBotConfigalscogs_dirgesetzt haben). - Erstellen Sie Python-Dateien im
cogs-Verzeichnis (z. B.utility.py). - Definieren Sie eine Klasse, die von
lxmfy.Cogerbt (optional, aber gute Praxis), oder eine gewöhnliche Klasse. - Definieren Sie Befehle als Methoden der Klasse mit dem
@Command-Dekorator. - Erstellen Sie eine
setup(bot)-Funktion in der Cog-Datei, die LXMFy zur Registrierung des Cogs aufruft.
Beispiel (cogs/utility.py):
from lxmfy import Command
from lxmfy.commands import Cog # Cog importieren, falls geerbt wird
import time
class UtilityCog: # Oder class UtilityCog(Cog):
def __init__(self, bot):
self.bot = bot
self.start_time = time.time()
@Command(name="uptime", description="Shows bot uptime")
# Hinweis: Methoden in Cogs nehmen oft 'self' und 'ctx' entgegen
def uptime_command(self, ctx):
uptime_seconds = time.time() - self.start_time
ctx.reply(f"Bot has been running for {uptime_seconds:.2f} seconds.")
@Command(name="info", description="Shows bot info")
def info_command(self, ctx):
info = (
f"Bot Name: {self.bot.config.name}\n"
f"Owner(s): {', '.join(self.bot.config.admins) or 'None'}\n"
f"Prefix: {self.bot.config.command_prefix}"
)
ctx.reply(info)
@Command(name="threaded_cog_task", description="Performs a long task in a cog thread", threaded=True)
def threaded_cog_task(self, ctx):
ctx.reply("Starting a long cog task... this will run in a separate thread.")
time.sleep(7) # Simuliert eine lang laufende Operation
ctx.reply("Long cog task completed!")
# Diese Funktion ist erforderlich, damit der Cog geladen wird
def setup(bot):
cog_instance = UtilityCog(bot)
bot.add_cog(cog_instance) # Cog-Instanz beim Bot registrieren
Haupt-Bot-Datei (my_bot.py):
from lxmfy import LXMFBot
bot = LXMFBot(
name="CogBot",
cogs_enabled=True, # Sicherstellen, dass Cogs aktiviert sind (Standard)
cogs_dir="cogs" # Auf das Verzeichnis verweisen
)
if __name__ == "__main__":
# Cogs werden automatisch während der LXMFBot-Initialisierung geladen,
# wenn cogs_enabled True ist.
bot.run()
Beim Start findet der Bot automatisch utility.py, ruft dessen
setup-Funktion auf, die eine Instanz von UtilityCog erstellt und mit
bot.add_cog() registriert. Die im Cog definierten Befehle (uptime,
info) stehen dann zur Verfügung.
Externe Skript-Cogs (Unterstützung mehrerer Sprachen)¶
Bot-Erweiterungen können auch in anderen Sprachen als Python geschrieben werden (z. B. Bash, Ruby, Perl, Go, C), über externe Skript-Cogs.
- Erstellen Sie ein ausführbares Skript in Ihrem
cogs-Verzeichnis. - Fügen Sie einen Shebang am Anfang des Skripts hinzu (z. B.
#!/bin/bash). - Stellen Sie sicher, dass das Skript ausführbar ist
(
chmod +x your_script).
Beim Start registriert der Bot automatisch jede ausführbare Datei im
cogs-Verzeichnis (die nicht auf .py endet) als Bot-Befehl.
Argumentprotokoll:
$1: LXMF-Hash des Absenders.$2: Vollständiger Nachrichteninhalt.$3,$4, ...: Einzelne Befehlsargumente.
Umgebungsvariablen:
LXMFY_SENDER: Der Identitäts-Hash des Absenders.LXMFY_CONTENT: Der vollständige Nachrichteninhalt.LXMFY_HAS_ADMIN:trueoderfalse, je nach Admin-Status des Absenders.
Beispiel eines Bash-Cogs (cogs/greet.sh):
Wenn ein Benutzer /greet hello sendet, führt der Bot dieses Skript
aus und antwortet mit dessen stdout:
Hello from Bash! You sent: /greet hello.
Lokale NLP-Intent-Klassifizierung¶
LXMFy enthält einen lokalen Intent-Klassifizierer. Er ordnet Nachrichtentext markierten Beispielphrasen zu, wenn der Text nicht exakt einem Befehlspräfix entspricht.
- Aktivieren Sie NLP in der Bot-Konfiguration:
nlp_enabled=True. - Definieren Sie Intents mit dem
@bot.intent-Dekorator.
@bot.intent("help", examples=["how do I use this?", "show me commands", "help me please"])
def help_intent(msg):
msg.reply("I can help! Try typing /help to see a list of commands.")
Der Abgleich nutzt TF-IDF-Vektoren und Kosinus-Ähnlichkeit. Die gesamte Bewertung läuft auf dem Bot-Host. Es wird kein Text an eine externe API gesendet.
Modell exportieren und importieren
Exportieren und importieren Sie ein trainiertes Modell, damit größere Bots nicht bei jedem Start neu trainieren müssen:
# Modell exportieren
model_data = bot.nlp.export_model()
# model_data in einer Datei oder Datenbank speichern
# Später wieder importieren
bot.nlp.import_model(model_data)
RNS-Link-Unterstützung¶
Bots können direkte RNS-Links aufbauen und beantworten, für zustandsbehafteten, streaming- oder höherbandbreitigen Verkehr als einzelne LXMF-Pakete.
- Aktivieren Sie die Link-Unterstützung in der Konfiguration:
link_support_enabled=True. - Link anfordern:
bot.request_link(destination_hash). Optional mit eigenem App-Namen und Aspekten:bot.request_link(dest, callback, "my_app", "aspect1"). - Eingehende Links behandeln: Einen Callback mit
bot.on_link(handler)registrieren.
def handle_link(link):
print(f"Link established with {RNS.hexrep(link.destination.hash)}")
# Der Link kann nun für direkte RNS-Kommunikation genutzt werden
bot.on_link(handle_link)
Sicherheit und Sandboxing:
- Timeouts: Externe Cogs haben einen Standard-Timeout (30 s)
gegen Hängenbleiben. Konfigurierbar über
external_cogs_timeout. - Threading: Alle externen Cogs laufen in separaten Threads und blockieren den Bot nicht.
- Sandbox des Bot-Prozesses (nur Linux): Wenn
landlock_enabled=True(Standard) und der Kernel Landlock LSM unterstützt (5.13+), wendet der Bot nach dem Start eine Dateisystem-Sandbox auf den eigenen Prozess an. Schreibbare Pfade sind auf Speicher, Konfiguration, Cogs, Reticulum-Konfiguration und Temp-Verzeichnisse beschränkt. Mit der UmgebungsvariablenLXMFY_LANDLOCK=0deaktivieren oder mitLXMFY_LANDLOCK=1einen Versuch erzwingen. - Sandbox für externe Cogs (nur Linux): Wenn
external_cogs_sandbox_enabled=True(Standard), laufen ausführbare Skript-Cogs in einer eingeschränkten Umgebung. Setzen Sieexternal_cogs_sandbox_typeauf einen der folgenden Werte: auto(Standard): Landlock bevorzugen, wenn unterstützt, sonstbubblewrap(bwrap), sonstfirejaillandlock: reine Landlock-Sandbox überpreexec_fn(engere Regeln als die Sandbox des Bot-Prozesses)bwrap: bubblewrap-Sandbox mit Read-Only-Bindsfirejail: privates firejail-Profil ohne Netzwerknone: keine Subprozess-Sandbox- Status:
bot.get_landlock_status()aufrufen, um Kernel-Unterstützung, ob Landlock angefordert wurde und ob die Sandbox des Bot-Prozesses aktiv ist, zu prüfen.
Nachrichten verarbeiten¶
LXMFy bietet mehrere Wege, eingehende Nachrichten in verschiedenen Verarbeitungsstufen zu behandeln.
Handler für erste Nachrichten¶
Die erste Nachricht jedes neuen Benutzers verarbeiten (nützlich für Willkommensnachrichten):
from lxmfy import LXMFBot
bot = LXMFBot(
name="WelcomeBot",
first_message_enabled=True # Muss True sein (Standard)
)
@bot.on_first_message()
def welcome_new_user(sender, message):
content = message.content.decode("utf-8")
bot.send(
sender,
f"Welcome to the bot! You said: {content}\n\n"
"Type /help to see available commands."
)
return True # True zurückgeben, um die weitere Verarbeitung dieser Nachricht zu stoppen
if __name__ == "__main__":
bot.run()
Allgemeiner Nachrichten-Handler¶
Alle eingehenden Nachrichten vor der Befehlsverarbeitung verarbeiten:
from lxmfy import LXMFBot
bot = LXMFBot(name="EchoBot")
@bot.on_message()
def echo_non_commands(sender, message):
content = message.content.decode("utf-8").strip()
# Prüfen, ob dies ein Befehl ist - wenn ja, den Befehls-Handler verarbeiten lassen
if content.startswith(bot.config.command_prefix):
command_name = content.split()[0][len(bot.config.command_prefix):]
if command_name in bot.commands:
return False # Dem Befehls-Handler überlassen
# Kein Befehl, als Echo zurücksenden
bot.send(sender, f"You said: {content}")
return False # False zurückgeben, um die Verarbeitung fortzusetzen (es wird ohnehin kein Befehl passen)
@bot.command(name="hello", description="Say hello")
def hello_command(ctx):
ctx.reply("Hello! This is a command response.")
if __name__ == "__main__":
bot.run()
Verarbeitungsreihenfolge der Nachrichten-Handler:
- Handler für erste Nachrichten (wenn
first_message_enabled=Trueund dies die erste Nachricht des Absenders ist) - Allgemeine Nachrichten-Handler (registriert mit
@bot.on_message()) - Befehlsverarbeitung (wenn die Nachricht zu einem registrierten Befehl passt)
Handler können True zurückgeben, um die weitere Verarbeitung zu
stoppen, oder False, um mit der nächsten Stufe fortzufahren.
Ereignisse verarbeiten¶
Für verschiedene Bot-Ereignisse können Handler mit dem
@bot.events.on()-Dekorator registriert werden.
from lxmfy import LXMFBot
from lxmfy.events import EventPriority # Optional für die Priorität
bot = LXMFBot(name="EventBot")
@bot.events.on("message_received")
def log_message(event):
# Das Ereignisobjekt enthält Details
sender = event.data.get("sender")
message_content = event.data.get("message").content.decode('utf-8', errors='ignore')
print(f"Received message from {sender}: {message_content}")
# Die Ereignisverarbeitung kann abgebrochen werden (z. B. Nachrichtenverarbeitung stoppen)
# if sender == "some_blocked_hash":
# event.cancel()
@bot.events.on("command_executed", priority=EventPriority.LOW)
def log_command(event):
# Beispiel: event.data könnte {'command_name': 'ping', 'sender': '...', ...} enthalten
command_name = event.data.get('command_name', 'unknown')
sender = event.data.get('sender', 'unknown')
print(f"Command '{command_name}' executed by {sender}")
# Es können auch eigene Ereignisse definiert werden
@bot.command(name="special")
def special_command(ctx):
ctx.reply("Doing something special!")
# Ein eigenes Ereignis auslösen
bot.events.dispatch(Event("special_action_taken", data={"user": ctx.sender}))
@bot.events.on("special_action_taken")
def handle_special(event):
user = event.data.get("user")
print(f"Special action was taken by user: {user}")
if __name__ == "__main__":
bot.run()
Weitere Details zur Event-Struktur und zu Prioritäten finden Sie in
lxmfy/events.py.
Speicher¶
LXMFy bietet JSON-, SQLite- und In-Memory-Speicher-Backends.
- JSON: Einfach, menschenlesbar. Gut für kleine Datenmengen.
Konfiguration mit
storage_type="json"undstorage_path="your_data_dir". - SQLite: Effizienter bei größeren Datenmengen oder häufigen
Schreibvorgängen. Konfiguration mit
storage_type="sqlite"undstorage_path="your_db_file.db". - Memory: Speicher vollständig im RAM. Zustand geht beim
Herunterfahren verloren. Konfiguration mit
storage_type="memory".
Auf die Speicherschnittstelle greifen Sie über bot.storage zu:
# Daten speichern
bot.storage.set("user_prefs:" + ctx.sender, {"theme": "dark"})
# Daten abrufen (mit Standardwert)
prefs = bot.storage.get("user_prefs:" + ctx.sender, {})
theme = prefs.get("theme", "light")
# Prüfen, ob Daten existieren
if bot.storage.exists("some_key"):
print("Key exists!")
# Daten löschen
bot.storage.delete("old_data_key")
# Schlüssel mit einem Präfix durchsuchen (nützlich zum Auflisten von Benutzerdaten)
user_keys = bot.storage.scan("user_prefs:")
for key in user_keys:
user_data = bot.storage.get(key)
print(f"Data for {key}: {user_data}")
Weitere Details in lxmfy/storage.py und in der API-Referenz.
Berechtigungen¶
LXMFy enthält ein optionales rollenbasiertes Berechtigungssystem.
Aktivierung mit permissions_enabled=True bei der
LXMFBot-Initialisierung.
- Rollen: Rollen mit bestimmten Berechtigungen definieren (z. B.
DefaultPerms.MANAGE_USERS). - Berechtigungen: Granulare Flags in
DefaultPerms(z. B.USE_COMMANDS,BYPASS_SPAM). - Zuweisung: Rollen werden Benutzer-Hashes zugewiesen.
Details zur Verwendung finden Sie in lxmfy/permissions.py, in der
API-Referenz und gegebenenfalls in Beispiel-Cogs.
Signaturprüfung¶
LXMFy bietet Konfiguration für die in LXMF eingebaute kryptografische Nachrichtensignierung und -prüfung. Alle LXMF-Nachrichten werden vom LXMF/RNS-Stack automatisch signiert. LXMFy erlaubt lediglich die Durchsetzung von Prüfrichtlinien.
Konfiguration:
Aktivieren Sie die Signaturprüfung in der Bot-Konfiguration:
bot = LXMFBot(
name="SecureBot",
signature_verification_enabled=True, # Signaturprüfung aktivieren
require_message_signatures=False # Auf True setzen, um unsignierte Nachrichten abzulehnen
)
Funktionsweise:
LXMF führt alle kryptografischen Operationen automatisch aus:
- Ausgehende Nachrichten: LXMF signiert alle Nachrichten beim Packen automatisch mit der RNS-Identität des Absenders.
- Eingehende Nachrichten: LXMF validiert Signaturen automatisch anhand der RNS-Identität des Absenders und liefert Validierungsergebnisse.
- Rolle von LXMFy: LXMFy prüft die Validierungsergebnisse von
LXMF und setzt Ihre Richtlinie durch:
- Bei
signature_verification_enabled=False: Alle Nachrichten werden akzeptiert (Standard) - Bei
signature_verification_enabled=Trueundrequire_message_signatures=False: Nachrichten werden akzeptiert, aber unsignierte/ungültige Signaturen werden protokolliert - Bei
signature_verification_enabled=Trueundrequire_message_signatures=True: Unsignierte oder ungültige Nachrichten werden abgelehnt
- Bei
- Integration der Berechtigungen: Benutzer mit der Berechtigung
BYPASS_SPAMkönnen die Signaturprüfung umgehen.
Verwaltung über die CLI:
Die Einstellungen der Signaturprüfung lassen sich über die CLI verwalten:
# Signaturprüfung testen
lxmfy signatures test
# Signaturprüfung aktivieren
lxmfy signatures enable
# Signaturprüfung deaktivieren
lxmfy signatures disable
Technische Details:
LXMF verwendet Ed25519-Signaturen aus dem RNS-Kryptosystem. Jede
LXMF-Nachricht enthält die Signatur des Absenders, die gegen die
bekannte RNS-Identität validiert wird. LXMFy liest lediglich die
LXMF-Eigenschaften message.signature_validated und
message.unverified_reason, um die Sicherheitsrichtlinie Ihres Bots
durchzusetzen.
Nachrichtenzustellung¶
Propagationsknoten verwenden¶
Nachrichten über bestimmte LXMF-Propagationsknoten senden:
from lxmfy import LXMFBot
bot = LXMFBot(name="PropagationBot")
@bot.command(name="send", description="Send via propagation node")
def send_command(ctx):
# Einen bestimmten Propagationsknoten einmalig setzen (Konfigurationsebene)
bot.set_propagation_node("<propagation_node_hash_here>")
# Mit konfigurierter Zustellstrategie senden
bot.send(
ctx.sender,
"This message will use direct delivery with propagation fallback as configured"
)
Verwenden Sie einen Propagationsknoten, wenn das Ziel offline ist oder die Direktzustellung auf dem aktuellen Pfad wiederholt fehlschlägt.
Wiederholungsversuche konfigurieren¶
Automatische Wiederholungsversuche für fehlgeschlagene Nachrichtenzustellungen über die Bot-Konfiguration einstellen:
from lxmfy import LXMFBot
bot = LXMFBot(name="ReliableBot")
bot = LXMFBot(
name="ReliableBot",
direct_delivery_retries=5, # Direktzustellung bis zu 5-mal wiederholen
propagation_fallback_enabled=True
)
@bot.command(name="important", description="Send important message with retries")
def important_command(ctx):
bot.send(ctx.sender, "This is an important message")
@bot.command(name="normal", description="Send with default retries")
def normal_command(ctx):
# direct_delivery_retries ist standardmäßig 3
bot.send(ctx.sender, "This message uses default retry settings")
Das Wiederholungssystem:
- Verfolgt Zustellversuche automatisch pro Ziel
- Wiederholt fehlgeschlagene Direktzustellungen bis zu
direct_delivery_retries-mal - Setzt den Wiederholungszähler nach erfolgreicher Zustellung zurück
- Protokolliert Wiederholungsversuche und Fehler zur Fehlersuche
Reticulum Relay Chat (RRC)¶
LXMFy-Bots können RRC-Hubs als gewöhnliche Clients über RNS-Links mit CBOR-Envelopes beitreten. Kompatibel mit Hubs im NomadNet- und rrcd-Stil (einschließlich MeshChatX, wenn es denselben Hub hostet oder ihm beitritt).
Die Reticulum-Konfiguration ist wichtig¶
Der Bot muss dasselbe Reticulum-Netzwerk wie der Hub verwenden.
MeshChatX nutzt üblicherweise ~/.reticulum mit Backbone- oder
TCP-Interfaces. Das projektlokale config/-Verzeichnis verwendet oft
einen isolierten Instanznamen und nur AutoInterface, sodass
Hub-Announces nie ankommen und Sie Hub identity unknown sehen.
Bevorzugen Sie eines davon:
reticulum_config_dirauf Ihre Benutzerkonfiguration setzen (üblicherweise~/.reticulum)- Oder
LXMFY_RETICULUM_CONFIG_DIR=~/.reticulumexportieren - MeshChatX oder
rnsdlaufen lassen, damit die geteilte Instanz vor dem Bot-Start aktiv ist
Die rrc-Vorlage verwendet standardmäßig ~/.reticulum, wenn dieses
Verzeichnis existiert.
Schnellstart mit der Vorlage¶
Standardwerte:
- Hub:
664fc0e8d2e448658e37bb3f34e6c88f - Raum:
#general - Reticulum-Konfiguration:
~/.reticulum(oderLXMFY_RETICULUM_CONFIG_DIR)
Im Log sollten Einträge für Hub-Verbindung, Welcome, Auto-Join und
RRC joined #general erscheinen.
Programmgesteuerter RRC-Bot¶
from lxmfy import LXMFBot, RRCMessage
bot = LXMFBot(
name="RoomBot",
reticulum_config_dir="~/.reticulum",
rrc_enabled=True,
rrc_hubs=["your_rrc_hub_destination_hash"],
rrc_rooms=["general"],
rrc_nick="RoomBot",
rrc_auto_reconnect=True,
rrc_persist_sessions=True,
)
@bot.on_rrc
def on_rrc(event, client, payload):
if event == "welcome":
bot.logger.info("Welcomed by hub")
return
if event != "msg" or not isinstance(payload, RRCMessage):
return
if payload.mention and payload.room:
client.send_message(
payload.room,
f"Heard you, {payload.nick}",
)
bot.run()
Oder zur Laufzeit verbinden:
bot.connect_rrc("hub_destination_hash", rooms=["general"])
bot.rrc.send_message("general", "hello room")
bot.rrc.send_action("general", "waves")
bot.disconnect_rrc()
Sitzungsverhalten¶
- HELLO / WELCOME, JOIN / PART, MSG / NOTICE / ACTION, PING / PONG, ERROR, RESOURCE_ENVELOPE
- Auto-Reconnect mit erneutem Raum-Beitritt nach WELCOME
- Clientseitige Durchsetzung von Hub-Limit und Rate-Limit
- Persistenz der Sitzungen über Neustarts hinweg
(
rrc_persist_sessions, standardmäßig aktiviert) - Persistenz der ausgehenden LXMF-Warteschlange ist separat
(
message_persistence_enabled)