From 05592396e75e1c61c877f011a2d193e60e123985 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 11 Jul 2024 08:24:29 +0200 Subject: [PATCH] Refactor services again to use traits and to allow bot to update its own command list --- src/main.rs | 5 ++-- src/services/mod.rs | 12 +-------- src/services/telegram/commands/mod.rs | 16 +++++++++++- src/services/telegram/mod.rs | 35 +++++++++++++++++++++------ 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/main.rs b/src/main.rs index 583dd889..8ed47f54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use services::telegram; use crate::services::RoyalnetService; pub(crate) mod database; @@ -15,12 +14,12 @@ async fn main() -> Result<()> { // Telegram setup log::trace!("Setting up Telegram bot service..."); - let telegram = telegram::init(); + let telegram = services::telegram::BotService::from_config(); // Run all services concurrently log::info!("Starting services..."); let result = tokio::try_join![ - telegram.run_royalnet(), + telegram.run(), ]; // This should never happen, but just in case... diff --git a/src/services/mod.rs b/src/services/mod.rs index de9c2351..59577a22 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -4,15 +4,5 @@ use anyhow::Result; pub mod telegram; pub trait RoyalnetService { - async fn run_royalnet(self) -> Result; -} - -impl RoyalnetService for teloxide::dispatching::Dispatcher { - async fn run_royalnet(mut self) -> Result { - log::info!("Starting Telegram service..."); - self.dispatch().await; - - log::error!("Telegram dispatcher has exited, bailing out..."); - anyhow::bail!("Telegram dispatcher has exited.") - } + async fn run(self) -> Result; } diff --git a/src/services/telegram/commands/mod.rs b/src/services/telegram/commands/mod.rs index 38fd564f..1df6c70b 100644 --- a/src/services/telegram/commands/mod.rs +++ b/src/services/telegram/commands/mod.rs @@ -1,7 +1,7 @@ // See the following link for an example of how to use this file: // https://github.com/teloxide/teloxide/blob/master/crates/teloxide/examples/dispatching_features.rs -use anyhow::{Context, Error}; +use anyhow::{Context, Error, Result}; use teloxide::{Bot, dptree}; use teloxide::dispatching::{DefaultKey, Dispatcher, HandlerExt, UpdateFilterExt}; use teloxide::dptree::entry; @@ -37,6 +37,20 @@ pub enum Command { Reminder(reminder::ReminderArgs), } +impl Command { + pub async fn set_commands(bot: &mut Bot) -> Result<()> { + log::trace!("Determining bot commands..."); + let commands = Self::bot_commands(); + + log::trace!("Setting commands on {bot:?}: {commands:#?}"); + let reply = bot.set_my_commands(commands).await + .context("Impossibile aggiornare l'elenco comandi del bot.")?; + + log::trace!("Setting commands on {bot:?} successful: {reply:#?}"); + Ok(()) + } +} + async fn handle_command(bot: Bot, command: Command, message: Message) -> CommandResult { log::trace!("Received command: {command:?}"); diff --git a/src/services/telegram/mod.rs b/src/services/telegram/mod.rs index f4a24461..5d6d5e28 100644 --- a/src/services/telegram/mod.rs +++ b/src/services/telegram/mod.rs @@ -1,14 +1,33 @@ -use anyhow::Error; +use std::convert::Infallible; use teloxide::Bot; -use teloxide::dispatching::{DefaultKey, Dispatcher}; +use super::RoyalnetService; mod config; mod commands; -pub fn init() -> Dispatcher { - commands::dispatcher( - Bot::new( - config::TELEGRAM_BOT_TOKEN() - ) - ) +pub struct BotService { + pub bot: Bot +} + +impl BotService { + pub fn from_config() -> Self { + Self { + bot: Bot::new(config::TELEGRAM_BOT_TOKEN()) + } + } +} + +impl RoyalnetService for BotService { + async fn run(mut self) -> anyhow::Result { + log::info!("Starting Telegram service..."); + + log::debug!("Setting bot commands..."); + commands::Command::set_commands(&mut self.bot).await?; + + log::debug!("Starting Telegram dispatcher..."); + commands::dispatcher(self.bot).dispatch().await; + + log::error!("Telegram dispatcher has exited, bailing out..."); + anyhow::bail!("Telegram dispatcher has exited.") + } }