Einen neuen Telegram-Befehl einbinden
Der Telegram-Bot ist in vier Schichten aufgebaut, alle in server/src/interfaces/telegram/ und
server/src/app/i18n/. Führe die folgenden Schritte der Reihe nach aus.
-
Befehlsvariante deklarieren.
Öffne
commands.rsund füge demCommand-Enum (abgeleitet mitteloxide::utils::command::BotCommands) eine Variante hinzu:#[command(description = "Einzeilige Hilfe, die bei /help angezeigt wird")]MyCommand(String), // String = der rohe Argumentstring; () für keine Argumente verwendenDas Attribut
rename_rule = "lowercase"am Enum bewirkt, dassMyCommandals/mycommandregistriert wird. -
Eine Route-Variante zu
LinkedCommandRoutehinzufügen.Direkt unterhalb des
Command-Enums befindet sich ein privatesLinkedCommandRoute-Enum. Füge einen passenden Zweig hinzu:MyCommand { args: &'a str },Dann in
linked_command_routeverdrahten:Command::MyCommand(args) => Some(LinkedCommandRoute::MyCommand { args }), -
An einen Handler weiterleiten.
Im
match linked_command_route(...)-Block innerhalb vonhandle_commandeinen Zweig hinzufügen, der deinen Handler aufruft:LinkedCommandRoute::MyCommand { args } => {super::commands_workspace_handlers::handle_my_command(&bot, chat_id, &state, user_id, locale, args,).await?}Den Handler selbst im passenden Dispatch-Modul platzieren:
- Einfache Lese-/Aktionsbefehle kommen in
commands_dispatch.rs. - Workspace-bezogene oder Feature-Auflistungsbefehle kommen in
commands_workspace_handlers.rs.
Ein typischer Handler delegiert direkt an eine Service-Funktion und nutzt den gemeinsamen
send_service_result-Helper:pub(super) async fn handle_my_command(bot: &Bot,chat_id: ChatId,state: &AppState,user_id: Uuid,locale: Locale,args: &str,) -> ResponseResult<()> {send_service_result(bot,chat_id,locale,crate::chat::command::my_command(state, user_id, locale, args).await,).await}send_service_resultsendet bei Erfolg denResponsePlan-Text (plain oder HTML) und fällt im Fehlerfall auf dieTelegramCommandFailed-Nachricht zurück — der Handler muss Fehler daher nie selbst formatieren. - Einfache Lese-/Aktionsbefehle kommen in
-
Fluent-Nachrichtenschlüssel hinzufügen.
Jeder für Nutzer sichtbare String muss über den typisierten Fluent-Katalog laufen — keine fest codierten Strings in Handlern.
a. Den Schlüssel in
server/src/app/i18n/keys.rsregistrieren:pub enum MessageKey {// ...vorhandene Schlüssel...TelegramMyCommandResult,TelegramMyCommandUsage,}Dieselben Varianten dem
ALL-Slice und demid-Match-Zweig im Kebab-Case hinzufügen:Self::TelegramMyCommandResult => "telegram-my-command-result",Self::TelegramMyCommandUsage => "telegram-my-command-usage",Der Unit-Test
message_key_ids_are_unique_kebab_case_entriesinkeys.rsschlägt fehl, wenn eine ID doppelt vorkommt oder ein Nicht-Kebab-Zeichen enthält.b. Die Nachricht in beiden Locale-Dateien schreiben:
server/locales/en/telegram.ftl:telegram-my-command-result = Result: { $value }telegram-my-command-usage = Usage: /mycommand <argument>server/locales/de/telegram.ftl:telegram-my-command-result = Ergebnis: { $value }telegram-my-command-usage = Nutzung: /mycommand <argument>c. Den Schlüssel in der Service-Funktion verwenden:
// Keine dynamischen Argumente — einfacher Text:i18n::text(locale, MessageKey::TelegramMyCommandResult)// Mit Substitutionsvariablen:i18n::with_args(locale, MessageKey::TelegramMyCommandResult,i18n::arg("value", some_string))Wenn derselbe formatierte String an mehreren Stellen wiederverwendet wird, einen typisierten Helper in
server/src/app/i18n/format.rshinzufügen (siehe vorhandene Helpers wietelegram_intervention_sentals Vorlage). -
Überprüfen.
Terminal window cd servercargo checkcargo test archcargo test -- i18ncargo test -- i18nführt den Katalog-Validierungstest (fluent_catalogs_contain_all_typed_keys) aus, der prüft, ob jedeMessageKey-Variante einen entsprechenden Eintrag in beiden Locale-Dateien hat.
Siehe auch
Abschnitt betitelt „Siehe auch“server/src/interfaces/telegram/commands.rs—Command-Enum undhandle_command-Dispatcherserver/src/app/i18n/keys.rs—MessageKey-Registrierungserver/locales/en/telegram.ftl— Englischer Fluent-Katalog