1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-25 12:34:19 +00:00

Only reply with unknown command to pseudo-commands

This commit is contained in:
Steffo 2024-07-11 11:57:36 +02:00
parent 8abd87ca6c
commit 4910611489
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
3 changed files with 86 additions and 64 deletions

2
Cargo.lock generated
View file

@ -1144,7 +1144,7 @@ dependencies = [
[[package]] [[package]]
name = "royalnet" name = "royalnet"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",

View file

@ -2,12 +2,10 @@
// https://github.com/teloxide/teloxide/blob/master/crates/teloxide/examples/dispatching_features.rs // https://github.com/teloxide/teloxide/blob/master/crates/teloxide/examples/dispatching_features.rs
use anyhow::{Context, Error, Result}; use anyhow::{Context, Error, Result};
use teloxide::{Bot, dptree}; use teloxide::Bot;
use teloxide::dispatching::{DefaultKey, Dispatcher, HandlerExt, UpdateFilterExt};
use teloxide::dptree::entry;
use teloxide::payloads::SendMessageSetters; use teloxide::payloads::SendMessageSetters;
use teloxide::requests::Requester; use teloxide::requests::Requester;
use teloxide::types::{ChatId, Message, MessageId, Update}; use teloxide::types::{ChatId, Message, MessageId};
use teloxide::utils::command::BotCommands; use teloxide::utils::command::BotCommands;
mod start; mod start;
@ -50,43 +48,43 @@ impl Command {
log::trace!("Setting commands successful!"); log::trace!("Setting commands successful!");
Ok(()) Ok(())
} }
}
async fn handle_command(bot: Bot, command: Command, message: Message) -> CommandResult { pub async fn handle(self, bot: Bot, message: Message) -> CommandResult {
log::trace!("Received command: {command:?}"); log::trace!("Handling command: {self:?}");
let result = match command { let result = match self {
Command::Start => start::handler(&bot, &message).await, Command::Start => start::handler(&bot, &message).await,
Command::Help(target) => match target.as_str() { Command::Help(target) => match target.as_str() {
"" => help::handler_all(&bot, &message).await, "" => help::handler_all(&bot, &message).await,
_ => help::handler_specific(&bot, &message, &target).await, _ => help::handler_specific(&bot, &message, &target).await,
}, },
Command::Fortune => fortune::handler(&bot, &message).await, Command::Fortune => fortune::handler(&bot, &message).await,
Command::Echo(text) => echo::handler(&bot, &message, &text).await, Command::Echo(text) => echo::handler(&bot, &message, &text).await,
Command::WhoAmI => whoami::handler(&bot, &message).await, Command::WhoAmI => whoami::handler(&bot, &message).await,
Command::Answer(_) => answer::handler(&bot, &message).await, Command::Answer(_) => answer::handler(&bot, &message).await,
Command::Reminder(args) => reminder::handler(&bot, &message, args).await, Command::Reminder(args) => reminder::handler(&bot, &message, args).await,
}; };
if result.is_ok() { if result.is_ok() {
return Ok(()) return Ok(())
}
let chat_id = message.chat.id;
let message_id = message.id;
let error = result.unwrap_err();
let result2 = error_command(&bot, chat_id, message_id, &error).await;
if result2.is_ok() {
return Ok(())
}
let error2 = result2.unwrap_err();
log::error!("Command message {message_id:?} in {chat_id:?} errored out with `{error}`, and it was impossible to handle the error because of `{error2}`\n\n{error2:?}");
Ok(())
} }
let chat_id = message.chat.id;
let message_id = message.id;
let error = result.unwrap_err();
let result2 = error_command(&bot, chat_id, message_id, &error).await;
if result2.is_ok() {
return Ok(())
}
let error2 = result2.unwrap_err();
log::error!("Command message {message_id:?} in {chat_id:?} errored out with `{error}`, and it was impossible to handle the error because of `{error2}`\n\n{error2:?}");
Ok(())
} }
async fn error_command(bot: &Bot, chat_id: ChatId, message_id: MessageId, error: &Error) -> CommandResult { async fn error_command(bot: &Bot, chat_id: ChatId, message_id: MessageId, error: &Error) -> CommandResult {
@ -103,7 +101,7 @@ async fn error_command(bot: &Bot, chat_id: ChatId, message_id: MessageId, error:
Ok(()) Ok(())
} }
async fn unknown_command(bot: Bot, message: Message) -> CommandResult { pub async fn unknown_command(bot: Bot, message: Message) -> CommandResult {
log::debug!("Received an unknown command."); log::debug!("Received an unknown command.");
bot.send_message(message.chat.id, "⚠️ Comando sconosciuto.") bot.send_message(message.chat.id, "⚠️ Comando sconosciuto.")
@ -114,21 +112,4 @@ async fn unknown_command(bot: Bot, message: Message) -> CommandResult {
Ok(()) Ok(())
} }
pub fn dispatcher(bot: Bot) -> Dispatcher<Bot, Error, DefaultKey> { type CommandResult = Result<()>;
Dispatcher::builder(
bot,
Update::filter_message()
.branch(
entry()
.filter_command::<Command>()
.endpoint(handle_command)
)
.endpoint(unknown_command)
)
.dependencies(
dptree::deps![] // No deps needed at the moment.
)
.build()
}
type CommandResult = anyhow::Result<()>;

View file

@ -1,7 +1,11 @@
use std::convert::Infallible; use std::convert::Infallible;
use teloxide::Bot; use teloxide::{Bot, dptree};
use anyhow::{Context, Result}; use anyhow::{Context, Error, Result};
use regex::Regex;
use teloxide::dispatching::{DefaultKey, Dispatcher, HandlerExt, UpdateFilterExt};
use teloxide::dptree::entry;
use teloxide::requests::Requester; use teloxide::requests::Requester;
use teloxide::types::{Me, Message, Update};
use super::RoyalnetService; use super::RoyalnetService;
pub(self) mod config; pub(self) mod config;
@ -18,14 +22,18 @@ impl BotService {
} }
} }
async fn send_start_notification(&mut self) -> Result<()> { async fn send_start_notification(&mut self, me: &Me) -> Result<()> {
let chat_id = config::TELEGRAM_NOTIFICATION_CHATID() let chat_id = config::TELEGRAM_NOTIFICATION_CHATID()
.context("Variabile d'ambiente TELEGRAM_NOTIFICATION_CHATID mancante.")?; .context("Variabile d'ambiente TELEGRAM_NOTIFICATION_CHATID mancante.")?;
let version = crate::utils::version::VERSION;
let username = &me.username.as_ref().unwrap();
let id = &me.user.id;
let text = format!( let text = format!(
"💠 Servizio Telegram avviato\n\ "💠 Servizio Telegram avviato\n\
Royalnet v{}", Royalnet v{version}\n\
crate::utils::version::VERSION, @{username} ({id})",
); );
self.bot.send_message(chat_id, text) self.bot.send_message(chat_id, text)
@ -40,6 +48,10 @@ impl RoyalnetService for BotService {
async fn run(mut self) -> Result<Infallible> { async fn run(mut self) -> Result<Infallible> {
log::info!("Starting Telegram service..."); log::info!("Starting Telegram service...");
log::debug!("Getting bot information...");
let me = self.bot.get_me().await
.context("Failed to get information about self")?;
log::debug!("Setting bot commands..."); log::debug!("Setting bot commands...");
match commands::Command::set_commands(&mut self.bot).await { match commands::Command::set_commands(&mut self.bot).await {
Err(e) => log::warn!("Failed to set bot commands: {e}"), Err(e) => log::warn!("Failed to set bot commands: {e}"),
@ -47,15 +59,44 @@ impl RoyalnetService for BotService {
} }
log::debug!("Sending start notification..."); log::debug!("Sending start notification...");
match self.send_start_notification().await { match self.send_start_notification(&me).await {
Err(e) => log::warn!("Failed to send start notification: {e}"), Err(e) => log::warn!("Failed to send start notification: {e}"),
_ => log::trace!("Start notification sent successfully!"), _ => log::trace!("Start notification sent successfully!"),
} }
log::debug!("Starting Telegram dispatcher..."); log::debug!("Starting Telegram dispatcher...");
commands::dispatcher(self.bot).dispatch().await; dispatcher(self.bot, me).dispatch().await;
log::error!("Telegram dispatcher has exited, bailing out..."); log::error!("Telegram dispatcher has exited, bailing out...");
anyhow::bail!("Telegram dispatcher has exited.") anyhow::bail!("Telegram dispatcher has exited.")
} }
} }
fn dispatcher(bot: Bot, me: Me) -> Dispatcher<Bot, Error, DefaultKey> {
let bot_name = me.user.username.unwrap();
log::trace!("Bot name is: {bot_name:?}");
let regex = Regex::new(&format!(r"^/[a-z0-9_]+(?:@{bot_name})?(?:\s+.*)?$")).unwrap();
log::trace!("Pseudo-command regex is: {regex:?}");
log::trace!("Building dispatcher...");
Dispatcher::builder(
bot,
Update::filter_message()
.branch(entry()
.filter(move |message: Message| -> bool {
message.text().is_some_and(|text| regex.is_match(text))
})
.branch(
entry()
.filter_command::<commands::Command>()
.endpoint(commands::Command::handle)
)
.endpoint(commands::unknown_command)
)
)
.dependencies(
dptree::deps![] // No deps needed at the moment.
)
.build()
}