mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-22 02:54:21 +00:00
Add /reminder
command
This commit is contained in:
parent
7a4be66a41
commit
cd4214cb4b
7 changed files with 128 additions and 1 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
@ -772,6 +772,12 @@ dependencies = [
|
||||||
"unicase",
|
"unicase",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
|
@ -815,6 +821,16 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
|
checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
|
@ -893,6 +909,17 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parse_datetime"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8720474e3dd4af20cea8716703498b9f3b690f318fa9d9d9e2e38eaf44b96d0"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"nom",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
@ -1124,8 +1151,11 @@ dependencies = [
|
||||||
"diesel",
|
"diesel",
|
||||||
"log",
|
"log",
|
||||||
"micronfig",
|
"micronfig",
|
||||||
|
"once_cell",
|
||||||
|
"parse_datetime",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"rand",
|
"rand",
|
||||||
|
"regex",
|
||||||
"teloxide",
|
"teloxide",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
|
@ -12,4 +12,7 @@ micronfig = "0.3.0"
|
||||||
pretty_env_logger = "0.5.0"
|
pretty_env_logger = "0.5.0"
|
||||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||||
teloxide = { version = "0.12.2", features = ["ctrlc_handler", "native-tls", "macros"], default-features = false }
|
teloxide = { version = "0.12.2", features = ["ctrlc_handler", "native-tls", "macros"], default-features = false }
|
||||||
tokio = { version = "1.38.0", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.38.0", features = ["macros", "rt-multi-thread", "time"] }
|
||||||
|
parse_datetime = "0.6.0"
|
||||||
|
regex = "1.10.5"
|
||||||
|
once_cell = "1.19.0"
|
||||||
|
|
|
@ -2,6 +2,7 @@ use anyhow::Result;
|
||||||
use crate::telegram::DispatchWithResult;
|
use crate::telegram::DispatchWithResult;
|
||||||
|
|
||||||
pub(crate) mod database;
|
pub(crate) mod database;
|
||||||
|
pub(crate) mod utils;
|
||||||
mod telegram;
|
mod telegram;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
|
|
@ -16,6 +16,7 @@ mod echo;
|
||||||
mod help;
|
mod help;
|
||||||
mod whoami;
|
mod whoami;
|
||||||
mod answer;
|
mod answer;
|
||||||
|
mod reminder;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, BotCommands)]
|
#[derive(Debug, Clone, PartialEq, Eq, BotCommands)]
|
||||||
#[command(rename_rule = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
|
@ -32,6 +33,8 @@ enum Command {
|
||||||
WhoAmI,
|
WhoAmI,
|
||||||
#[command(description = "Rispondi ad una domanda.")]
|
#[command(description = "Rispondi ad una domanda.")]
|
||||||
Answer(String),
|
Answer(String),
|
||||||
|
#[command(description = "Ricorda la chat di qualcosa che avverrà in futuro.")]
|
||||||
|
Reminder(reminder::ReminderArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_command(bot: Bot, command: Command, message: Message) -> CommandResult {
|
async fn handle_command(bot: Bot, command: Command, message: Message) -> CommandResult {
|
||||||
|
@ -47,6 +50,7 @@ async fn handle_command(bot: Bot, command: Command, message: Message) -> Command
|
||||||
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,
|
||||||
};
|
};
|
||||||
|
|
||||||
if result.is_ok() {
|
if result.is_ok() {
|
||||||
|
|
88
src/telegram/commands/reminder.rs
Normal file
88
src/telegram/commands/reminder.rs
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
use anyhow::Context;
|
||||||
|
use teloxide::Bot;
|
||||||
|
use teloxide::payloads::SendMessageSetters;
|
||||||
|
use teloxide::requests::Requester;
|
||||||
|
use teloxide::types::{Message};
|
||||||
|
use parse_datetime::parse_datetime_at_date;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use regex::Regex;
|
||||||
|
use super::{CommandResult};
|
||||||
|
|
||||||
|
|
||||||
|
fn determine_wait(target_chrono: chrono::DateTime<chrono::Local>) -> tokio::time::Duration {
|
||||||
|
let now_chrono = chrono::Local::now();
|
||||||
|
|
||||||
|
let duration_chrono = target_chrono.signed_duration_since(now_chrono);
|
||||||
|
let seconds = duration_chrono.num_seconds();
|
||||||
|
|
||||||
|
tokio::time::Duration::from_secs(seconds as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct ReminderArgs {
|
||||||
|
target: chrono::DateTime<chrono::Local>,
|
||||||
|
reminder: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ReminderArgs {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"\[(?<target>.*)]\s*(?<reminder>.+)$").unwrap());
|
||||||
|
|
||||||
|
let captures = REGEX.captures(s)
|
||||||
|
.context("Sintassi del comando incorretta.")?;
|
||||||
|
|
||||||
|
let target = captures.name("target")
|
||||||
|
.unwrap()
|
||||||
|
.as_str();
|
||||||
|
|
||||||
|
let reminder = captures.name("reminder")
|
||||||
|
.unwrap()
|
||||||
|
.as_str()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let target = parse_datetime_at_date(chrono::Local::now(), target)
|
||||||
|
.context("Impossibile determinare la data in cui l'attesa avrà termine.")?
|
||||||
|
.with_timezone(&chrono::Local);
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
ReminderArgs { target, reminder }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn handler(bot: &Bot, message: &Message, ReminderArgs { target, reminder}: ReminderArgs) -> CommandResult {
|
||||||
|
let text = format!(
|
||||||
|
"🕒 Promemoria per {} impostato\n\
|
||||||
|
{}",
|
||||||
|
target.format("%c"),
|
||||||
|
reminder
|
||||||
|
);
|
||||||
|
|
||||||
|
let _reply = bot
|
||||||
|
.send_message(message.chat.id, text)
|
||||||
|
.reply_to_message_id(message.id)
|
||||||
|
.await
|
||||||
|
.context("Non è stato possibile inviare la conferma.")?;
|
||||||
|
|
||||||
|
let wait_duration = determine_wait(target);
|
||||||
|
|
||||||
|
tokio::time::sleep(wait_duration).await;
|
||||||
|
|
||||||
|
let text = format!(
|
||||||
|
"🕒 Promemoria per {} attivato\n\
|
||||||
|
{}",
|
||||||
|
target.format("%c"),
|
||||||
|
reminder
|
||||||
|
);
|
||||||
|
|
||||||
|
let _reply = bot
|
||||||
|
.send_message(message.chat.id, text)
|
||||||
|
.reply_to_message_id(message.id)
|
||||||
|
.await
|
||||||
|
.context("Non è stato possibile inviare il promemoria.")?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
1
src/utils/mod.rs
Normal file
1
src/utils/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod time;
|
0
src/utils/time.rs
Normal file
0
src/utils/time.rs
Normal file
Loading…
Reference in a new issue