1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-21 18:44:19 +00:00

Add rich text formatting features (#6)

* Add rich formatting to `/help`
* Create `EscapableInTelegramHTML` trait and implement it for types where `String: From<T>`
* Add rich formatting to `/reminder`
* Add rich formatting to `/whoami`
* Add rich formatting to the launch message
This commit is contained in:
Steffo 2024-07-14 09:46:20 +02:00 committed by GitHub
parent 3892070c5b
commit 2b31bb8c0a
Signed by: github
GPG key ID: B5690EEEBB952194
5 changed files with 53 additions and 16 deletions

View file

@ -2,17 +2,18 @@ use anyhow::Context;
use teloxide::Bot; use teloxide::Bot;
use teloxide::payloads::SendMessageSetters; use teloxide::payloads::SendMessageSetters;
use teloxide::requests::Requester; use teloxide::requests::Requester;
use teloxide::types::{BotCommand, Message}; use teloxide::types::{BotCommand, Message, ParseMode};
use teloxide::utils::command::BotCommands; use teloxide::utils::command::BotCommands;
use super::{CommandResult}; use super::{CommandResult};
pub async fn handler_all(bot: &Bot, message: &Message) -> CommandResult { pub async fn handler_all(bot: &Bot, message: &Message) -> CommandResult {
let descriptions = super::Command::descriptions().to_string(); let descriptions = super::Command::descriptions().to_string();
let text = format!("❓ Sono disponibili i seguenti comandi:\n\n{descriptions}"); let text = format!("❔ <b>Comandi disponibili</b>\n\n{descriptions}");
let _reply = bot let _reply = bot
.send_message(message.chat.id, text) .send_message(message.chat.id, text)
.parse_mode(ParseMode::Html)
.reply_to_message_id(message.id) .reply_to_message_id(message.id)
.await .await
.context("Non è stato possibile inviare la risposta.")?; .context("Non è stato possibile inviare la risposta.")?;
@ -62,10 +63,11 @@ pub async fn handler_specific(bot: &Bot, message: &Message, target: &str) -> Com
true => "", true => "",
}; };
let text = format!("❓ Il comando {}{}:\n\n{}", target.command, display_suffix, target.description); let text = format!("❔ <b>Comando {}{}</b>\n\n{}", target.command, display_suffix, target.description);
let _reply = bot let _reply = bot
.send_message(message.chat.id, text) .send_message(message.chat.id, text)
.parse_mode(ParseMode::Html)
.reply_to_message_id(message.id) .reply_to_message_id(message.id)
.await .await
.context("Non è stato possibile inviare la risposta.")?; .context("Non è stato possibile inviare la risposta.")?;

View file

@ -3,10 +3,11 @@ use anyhow::Context;
use teloxide::Bot; use teloxide::Bot;
use teloxide::payloads::SendMessageSetters; use teloxide::payloads::SendMessageSetters;
use teloxide::requests::Requester; use teloxide::requests::Requester;
use teloxide::types::{Message}; use teloxide::types::{Message, ParseMode};
use parse_datetime::parse_datetime_at_date; use parse_datetime::parse_datetime_at_date;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
use crate::services::telegram::escape::EscapableInTelegramHTML;
use super::{CommandResult}; use super::{CommandResult};
@ -55,14 +56,17 @@ impl FromStr for ReminderArgs {
pub async fn handler(bot: &Bot, message: &Message, ReminderArgs { target, reminder}: ReminderArgs) -> CommandResult { pub async fn handler(bot: &Bot, message: &Message, ReminderArgs { target, reminder}: ReminderArgs) -> CommandResult {
let text = format!( let text = format!(
"🕒 Promemoria per {} impostato\n\ "🕒 <b>Promemoria impostato</b>\n\
<i>{}</i>\n\
\n\
{}", {}",
target.format("%c"), target.format("%c").to_string().escape_telegram_html(),
reminder reminder.clone().escape_telegram_html()
); );
let _reply = bot let _reply = bot
.send_message(message.chat.id, text) .send_message(message.chat.id, text)
.parse_mode(ParseMode::Html)
.reply_to_message_id(message.id) .reply_to_message_id(message.id)
.await .await
.context("Non è stato possibile inviare la conferma.")?; .context("Non è stato possibile inviare la conferma.")?;
@ -72,14 +76,17 @@ pub async fn handler(bot: &Bot, message: &Message, ReminderArgs { target, remind
tokio::time::sleep(wait_duration).await; tokio::time::sleep(wait_duration).await;
let text = format!( let text = format!(
"🕒 Promemoria per {} attivato\n\ "🕒 <b>Promemoria attivato</b>\n\
<i>{}</i>\n\
\n\
{}", {}",
target.format("%c"), target.format("%c").to_string().escape_telegram_html(),
reminder reminder.escape_telegram_html()
); );
let _reply = bot let _reply = bot
.send_message(message.chat.id, text) .send_message(message.chat.id, text)
.parse_mode(ParseMode::Html)
.reply_to_message_id(message.id) .reply_to_message_id(message.id)
.await .await
.context("Non è stato possibile inviare il promemoria.")?; .context("Non è stato possibile inviare il promemoria.")?;

View file

@ -2,8 +2,9 @@ use anyhow::Context;
use teloxide::Bot; use teloxide::Bot;
use teloxide::payloads::SendMessageSetters; use teloxide::payloads::SendMessageSetters;
use teloxide::requests::Requester; use teloxide::requests::Requester;
use teloxide::types::{Message}; use teloxide::types::{Message, ParseMode};
use crate::database::models::{RoyalnetUser}; use crate::database::models::{RoyalnetUser};
use crate::services::telegram::escape::EscapableInTelegramHTML;
use super::{CommandResult}; use super::{CommandResult};
pub async fn handler(bot: &Bot, message: &Message) -> CommandResult { pub async fn handler(bot: &Bot, message: &Message) -> CommandResult {
@ -34,11 +35,13 @@ pub async fn handler(bot: &Bot, message: &Message) -> CommandResult {
let username = &royalnet_user.username; let username = &royalnet_user.username;
let text = format!( let text = format!(
"👤 Nel database RYG, tu hai l'username «{username}»." "👤 Nel database RYG, tu hai l'username <code>{}</code>.",
username.escape_telegram_html(),
); );
let _reply = bot let _reply = bot
.send_message(message.chat.id, text) .send_message(message.chat.id, text)
.parse_mode(ParseMode::Html)
.reply_to_message_id(message.id) .reply_to_message_id(message.id)
.await .await
.context("Non è stato possibile inviare la risposta.")?; .context("Non è stato possibile inviare la risposta.")?;

View file

@ -0,0 +1,15 @@
pub trait EscapableInTelegramHTML {
fn escape_telegram_html(self) -> String;
}
impl<T> EscapableInTelegramHTML for T
where String: From<T>
{
fn escape_telegram_html(self) -> String {
let s: String = String::from(self);
let s = s.replace("<", "&lt;");
let s = s.replace(">", "&gt;");
let s = s.replace("&", "&amp;");
s
}
}

View file

@ -4,13 +4,16 @@ use anyhow::{Context, Error, Result};
use regex::Regex; use regex::Regex;
use teloxide::dispatching::{DefaultKey, Dispatcher, HandlerExt, UpdateFilterExt}; use teloxide::dispatching::{DefaultKey, Dispatcher, HandlerExt, UpdateFilterExt};
use teloxide::dptree::entry; use teloxide::dptree::entry;
use teloxide::payloads::SendMessageSetters;
use teloxide::requests::Requester; use teloxide::requests::Requester;
use teloxide::types::{Me, Message, Update}; use teloxide::types::{Me, Message, ParseMode, Update};
use crate::services::telegram::escape::EscapableInTelegramHTML;
use super::RoyalnetService; use super::RoyalnetService;
#[allow(clippy::needless_pub_self)] #[allow(clippy::needless_pub_self)]
pub(self) mod config; pub(self) mod config;
mod commands; mod commands;
pub(self) mod escape;
pub struct BotService { pub struct BotService {
pub bot: Bot pub bot: Bot
@ -32,12 +35,19 @@ impl BotService {
let id = &me.user.id; let id = &me.user.id;
let text = format!( let text = format!(
"💠 Servizio Telegram avviato\n\ "💠 <b>Servizio Telegram avviato</b>\n\
Royalnet v{version}\n\ \n\
@{username} ({id})", Royalnet <a href='https://github.com/RYGhub/royalnet/releases/tag/v{}'>v{}</a>\n\
\n\
@{} [<code>{}</code>]",
version.escape_telegram_html(),
version.escape_telegram_html(),
username.escape_telegram_html(),
id.to_string().escape_telegram_html(),
); );
self.bot.send_message(chat_id, text) self.bot.send_message(chat_id, text)
.parse_mode(ParseMode::Html)
.await .await
.context("Invio della notifica di avvio non riuscito.")?; .context("Invio della notifica di avvio non riuscito.")?;