refactor: track fixer state per-chat rather than globally
This commit is contained in:
parent
c6121d69b6
commit
9cf2a70291
145
src/commands.rs
145
src/commands.rs
|
@ -1,15 +1,24 @@
|
|||
use crate::{message::BotExt, utils::parse_bool};
|
||||
use crate::{message::BotExt, utils::parse_bool, FIXER_STATE};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{env, error::Error, marker::Send};
|
||||
use teloxide::{
|
||||
payloads::SendMessageSetters,
|
||||
prelude::Requester,
|
||||
types::{Message, UserId},
|
||||
types::{ChatAction, Message, UserId},
|
||||
utils::command::BotCommands,
|
||||
Bot,
|
||||
};
|
||||
|
||||
pub(crate) type FilterState = String;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub(crate) struct FixerState {
|
||||
pub(crate) instagram: bool,
|
||||
pub(crate) medium: bool,
|
||||
pub(crate) twitter: bool,
|
||||
pub(crate) youtube: bool,
|
||||
}
|
||||
|
||||
static BOT_OWNER: Lazy<UserId> = Lazy::new(|| {
|
||||
let value = env::var("BOT_OWNER_ID").expect("BOT_OWNER_ID must be defined");
|
||||
let id = value
|
||||
|
@ -58,43 +67,77 @@ pub(crate) async fn handler(
|
|||
}
|
||||
#[cfg(feature = "ddinstagram")]
|
||||
Command::Instagram { filter_state } => {
|
||||
let admins = bot.get_chat_administrators(message.chat.id).await?;
|
||||
let admins = admins.iter().map(|c| c.user.clone()).collect::<Vec<_>>();
|
||||
if let Some(from) = message.from()
|
||||
&& from.id != *BOT_OWNER
|
||||
&& (from.id != *BOT_OWNER || admins.contains(from))
|
||||
{
|
||||
bot.send_chat_message(
|
||||
message,
|
||||
"You are not authorized for this action".to_string(),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
match parse_bool(&filter_state) {
|
||||
Ok(filter_state) => {
|
||||
crate::instagram::set_filter_state(bot, message, filter_state).await?;
|
||||
let new_state =
|
||||
if let Some(cur) = FIXER_STATE.lock().unwrap().get(&message.chat.id) {
|
||||
FixerState {
|
||||
instagram: filter_state,
|
||||
..*cur
|
||||
}
|
||||
} else {
|
||||
FixerState {
|
||||
instagram: filter_state,
|
||||
..Default::default()
|
||||
}
|
||||
};
|
||||
FIXER_STATE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(message.chat.id, new_state);
|
||||
}
|
||||
Err(error_message) => {
|
||||
bot.send_chat_message(message, error_message).await?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(message.chat.id, "You are not authorized for this action")
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Command::Medium { filter_state } => {
|
||||
let admins = bot.get_chat_administrators(message.chat.id).await?;
|
||||
let admins = admins.iter().map(|c| c.user.clone()).collect::<Vec<_>>();
|
||||
if let Some(from) = message.from()
|
||||
&& from.id != *BOT_OWNER
|
||||
&& (from.id != *BOT_OWNER || admins.contains(from))
|
||||
{
|
||||
bot.send_chat_message(
|
||||
message,
|
||||
"You are not authorized for this action".to_string(),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
match parse_bool(&filter_state) {
|
||||
Ok(filter_state) => {
|
||||
crate::medium::set_filter_state(bot, message, filter_state).await?;
|
||||
let new_state =
|
||||
if let Some(cur) = FIXER_STATE.lock().unwrap().get(&message.chat.id) {
|
||||
FixerState {
|
||||
medium: filter_state,
|
||||
..*cur
|
||||
}
|
||||
} else {
|
||||
FixerState {
|
||||
medium: filter_state,
|
||||
..Default::default()
|
||||
}
|
||||
};
|
||||
FIXER_STATE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(message.chat.id, new_state);
|
||||
}
|
||||
Err(error_message) => {
|
||||
bot.send_chat_message(message, error_message).await?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(message.chat.id, "You are not authorized for this action")
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Command::Ttv { names } => {
|
||||
|
@ -104,43 +147,77 @@ pub(crate) async fn handler(
|
|||
.await?;
|
||||
}
|
||||
Command::Twitter { filter_state } => {
|
||||
let admins = bot.get_chat_administrators(message.chat.id).await?;
|
||||
let admins = admins.iter().map(|c| c.user.clone()).collect::<Vec<_>>();
|
||||
if let Some(from) = message.from()
|
||||
&& from.id != *BOT_OWNER
|
||||
&& (from.id != *BOT_OWNER || admins.contains(from))
|
||||
{
|
||||
bot.send_chat_message(
|
||||
message,
|
||||
"You are not authorized for this action".to_string(),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
match parse_bool(&filter_state) {
|
||||
Ok(filter_state) => {
|
||||
crate::twitter::set_filter_state(bot, message, filter_state).await?;
|
||||
let new_state =
|
||||
if let Some(cur) = FIXER_STATE.lock().unwrap().get(&message.chat.id) {
|
||||
FixerState {
|
||||
twitter: filter_state,
|
||||
..*cur
|
||||
}
|
||||
} else {
|
||||
FixerState {
|
||||
twitter: filter_state,
|
||||
..Default::default()
|
||||
}
|
||||
};
|
||||
FIXER_STATE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(message.chat.id, new_state);
|
||||
}
|
||||
Err(error_message) => {
|
||||
bot.send_chat_message(message, error_message).await?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(message.chat.id, "You are not authorized for this action")
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Command::YouTube { filter_state } => {
|
||||
let admins = bot.get_chat_administrators(message.chat.id).await?;
|
||||
let admins = admins.iter().map(|c| c.user.clone()).collect::<Vec<_>>();
|
||||
if let Some(from) = message.from()
|
||||
&& from.id != *BOT_OWNER
|
||||
&& (from.id != *BOT_OWNER || admins.contains(from))
|
||||
{
|
||||
bot.send_chat_message(
|
||||
message,
|
||||
"You are not authorized for this action".to_string(),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
match parse_bool(&filter_state) {
|
||||
Ok(filter_state) => {
|
||||
crate::youtube::set_filter_state(bot, message, filter_state).await?;
|
||||
let new_state =
|
||||
if let Some(cur) = FIXER_STATE.lock().unwrap().get(&message.chat.id) {
|
||||
FixerState {
|
||||
youtube: filter_state,
|
||||
..*cur
|
||||
}
|
||||
} else {
|
||||
FixerState {
|
||||
youtube: filter_state,
|
||||
..Default::default()
|
||||
}
|
||||
};
|
||||
FIXER_STATE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(message.chat.id, new_state);
|
||||
}
|
||||
Err(error_message) => {
|
||||
bot.send_chat_message(message, error_message).await?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(message.chat.id, "You are not authorized for this action")
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
use crate::{message::BotExt, utils::scrub_urls};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::{
|
||||
error::Error,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use teloxide::{
|
||||
payloads::SendMessageSetters,
|
||||
prelude::Requester,
|
||||
types::{ChatAction, Message},
|
||||
utils::html::link,
|
||||
Bot,
|
||||
};
|
||||
use std::error::Error;
|
||||
use teloxide::{prelude::Requester, types::Message, utils::html::link, Bot};
|
||||
|
||||
const HOST_MATCH_GROUP: &str = "host";
|
||||
|
||||
|
@ -19,45 +10,6 @@ pub static MATCH_REGEX: Lazy<Regex> = Lazy::new(|| {
|
|||
Regex::new("https://(?:www.)?(?P<host>instagram.com)/(p|reel|tv)/[A-Za-z0-9]+.*/").unwrap()
|
||||
});
|
||||
|
||||
pub static FILTER_ENABLED: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
pub async fn set_filter_state(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
filter_state: Option<bool>,
|
||||
) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
|
||||
match filter_state {
|
||||
None => {
|
||||
let state = if FILTER_ENABLED.load(Ordering::Relaxed) {
|
||||
"enabled"
|
||||
} else {
|
||||
"disabled"
|
||||
};
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
format!("Instagram link replacement is {state}"),
|
||||
)
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
Some(state) => {
|
||||
FILTER_ENABLED.store(state, Ordering::Relaxed);
|
||||
let state = if state { "enabled" } else { "disabled" };
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
format!("Instagram link replacement has been {state}"),
|
||||
)
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn handler(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
|
|
97
src/main.rs
97
src/main.rs
|
@ -12,17 +12,24 @@ mod youtube;
|
|||
|
||||
use crate::commands::Command;
|
||||
use crate::logging::TeloxideLogger;
|
||||
use commands::FixerState;
|
||||
use dotenvy::dotenv;
|
||||
use std::sync::{atomic::Ordering, Arc};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use teloxide::{
|
||||
dispatching::{HandlerExt, UpdateFilterExt},
|
||||
dispatching::{dialogue::GetChatId, HandlerExt, UpdateFilterExt},
|
||||
dptree,
|
||||
prelude::Dispatcher,
|
||||
types::{Message, Update},
|
||||
types::{ChatId, Message, Update},
|
||||
update_listeners::Polling,
|
||||
Bot,
|
||||
};
|
||||
|
||||
pub(crate) static FIXER_STATE: Lazy<Mutex<HashMap<ChatId, FixerState>>> =
|
||||
Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
const REPLACE_SKIP_TOKEN: &str = "#skip";
|
||||
|
||||
async fn run() {
|
||||
|
@ -42,51 +49,77 @@ async fn run() {
|
|||
)
|
||||
.branch(
|
||||
dptree::filter(|msg: Message| {
|
||||
twitter::FILTER_ENABLED.load(Ordering::Relaxed)
|
||||
&& msg
|
||||
.text()
|
||||
.map(|text| {
|
||||
twitter::MATCH_REGEX.is_match(text)
|
||||
&& !text.contains(REPLACE_SKIP_TOKEN)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
if let Ok(ref mut map) = FIXER_STATE.try_lock()
|
||||
&& let Some(chat_id) = msg.chat_id()
|
||||
&& let Some(state) = map.get(&chat_id)
|
||||
{
|
||||
return state.twitter
|
||||
&& msg
|
||||
.text()
|
||||
.map(|text| {
|
||||
twitter::MATCH_REGEX.is_match(text)
|
||||
&& !text.contains(REPLACE_SKIP_TOKEN)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
}
|
||||
false
|
||||
})
|
||||
.endpoint(twitter::handler),
|
||||
);
|
||||
#[cfg(feature = "ddinstagram")]
|
||||
let handler = handler.branch(
|
||||
dptree::filter(|msg: Message| {
|
||||
instagram::FILTER_ENABLED.load(Ordering::Relaxed)
|
||||
&& msg
|
||||
.text()
|
||||
.map(|text| {
|
||||
instagram::MATCH_REGEX.is_match(text) && !text.contains(REPLACE_SKIP_TOKEN)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
if let Ok(ref mut map) = FIXER_STATE.try_lock()
|
||||
&& let Some(chat_id) = msg.chat_id()
|
||||
&& let Some(state) = map.get(&chat_id)
|
||||
{
|
||||
return state.instagram
|
||||
&& msg
|
||||
.text()
|
||||
.map(|text| {
|
||||
instagram::MATCH_REGEX.is_match(text)
|
||||
&& !text.contains(REPLACE_SKIP_TOKEN)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
}
|
||||
false
|
||||
})
|
||||
.endpoint(instagram::handler),
|
||||
);
|
||||
let handler = handler.branch(
|
||||
dptree::filter(|msg: Message| {
|
||||
youtube::FILTER_ENABLED.load(Ordering::Relaxed)
|
||||
&& msg
|
||||
.text()
|
||||
.map(|text| {
|
||||
youtube::MATCH_REGEX.is_match(text) && !text.contains(REPLACE_SKIP_TOKEN)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
if let Ok(ref mut map) = FIXER_STATE.try_lock()
|
||||
&& let Some(chat_id) = msg.chat_id()
|
||||
&& let Some(state) = map.get(&chat_id)
|
||||
{
|
||||
return state.youtube
|
||||
&& msg
|
||||
.text()
|
||||
.map(|text| {
|
||||
youtube::MATCH_REGEX.is_match(text)
|
||||
&& !text.contains(REPLACE_SKIP_TOKEN)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
}
|
||||
false
|
||||
})
|
||||
.endpoint(youtube::handler),
|
||||
);
|
||||
let handler = handler.branch(
|
||||
dptree::filter(|msg: Message| {
|
||||
medium::FILTER_ENABLED.load(Ordering::Relaxed)
|
||||
&& msg
|
||||
.text()
|
||||
.map(|text| {
|
||||
medium::MATCH_REGEX.is_match(text) && !text.contains(REPLACE_SKIP_TOKEN)
|
||||
})
|
||||
.unwrap_or_default()
|
||||
if let Ok(ref mut map) = FIXER_STATE.try_lock()
|
||||
&& let Some(chat_id) = msg.chat_id()
|
||||
&& let Some(state) = map.get(&chat_id)
|
||||
{
|
||||
return state.medium
|
||||
&& msg
|
||||
.text()
|
||||
.map(|text| {
|
||||
medium::MATCH_REGEX.is_match(text) && !text.contains(REPLACE_SKIP_TOKEN)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
}
|
||||
false
|
||||
})
|
||||
.endpoint(medium::handler),
|
||||
);
|
||||
|
|
|
@ -1,62 +1,14 @@
|
|||
use crate::{message::BotExt, utils::scrub_urls};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::{
|
||||
error::Error,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use teloxide::{
|
||||
payloads::SendMessageSetters,
|
||||
prelude::Requester,
|
||||
types::{ChatAction, Message},
|
||||
utils::html::link,
|
||||
Bot,
|
||||
};
|
||||
use std::error::Error;
|
||||
use teloxide::{prelude::Requester, types::Message, utils::html::link, Bot};
|
||||
|
||||
const HOST_MATCH_GROUP: &str = "host";
|
||||
|
||||
pub static MATCH_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new("https://(?P<host>(?:.*)?medium.com)/.*").unwrap());
|
||||
|
||||
pub static FILTER_ENABLED: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
pub async fn set_filter_state(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
filter_state: Option<bool>,
|
||||
) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
|
||||
match filter_state {
|
||||
None => {
|
||||
let state = if FILTER_ENABLED.load(Ordering::Relaxed) {
|
||||
"enabled"
|
||||
} else {
|
||||
"disabled"
|
||||
};
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
format!("Medium link replacement is {state}"),
|
||||
)
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
Some(state) => {
|
||||
FILTER_ENABLED.store(state, Ordering::Relaxed);
|
||||
let state = if state { "enabled" } else { "disabled" };
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
format!("Medium link replacement has been {state}"),
|
||||
)
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn handler(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
use crate::{message::BotExt, utils::scrub_urls};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::{
|
||||
error::Error,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use teloxide::{
|
||||
payloads::SendMessageSetters,
|
||||
prelude::Requester,
|
||||
types::{ChatAction, Message},
|
||||
utils::html::link,
|
||||
Bot,
|
||||
};
|
||||
use std::error::Error;
|
||||
use teloxide::{prelude::Requester, types::Message, utils::html::link, Bot};
|
||||
|
||||
const HOST_MATCH_GROUP: &str = "host";
|
||||
const ROOT_MATCH_GROUP: &str = "root";
|
||||
|
@ -21,45 +12,6 @@ pub static MATCH_REGEX: Lazy<Regex> = Lazy::new(|| {
|
|||
.unwrap()
|
||||
});
|
||||
|
||||
pub static FILTER_ENABLED: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
pub async fn set_filter_state(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
filter_state: Option<bool>,
|
||||
) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
|
||||
match filter_state {
|
||||
None => {
|
||||
let state = if FILTER_ENABLED.load(Ordering::Relaxed) {
|
||||
"enabled"
|
||||
} else {
|
||||
"disabled"
|
||||
};
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
format!("Twitter link replacement is {state}"),
|
||||
)
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
Some(state) => {
|
||||
FILTER_ENABLED.store(state, Ordering::Relaxed);
|
||||
let state = if state { "enabled" } else { "disabled" };
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
format!("Twitter link replacement has been {state}"),
|
||||
)
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn handler(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
|
|
|
@ -51,7 +51,7 @@ pub(crate) fn scrub_urls(msg: &Message) -> Option<String> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_bool(input: &str) -> Result<Option<bool>, String> {
|
||||
pub(crate) fn parse_bool(input: &str) -> Result<bool, String> {
|
||||
const TRUE_VALUES: [&str; 4] = ["true", "on", "yes", "enable"];
|
||||
const FALSE_VALUES: [&str; 4] = ["false", "off", "no", "disable"];
|
||||
static EXPECTED_VALUES: Lazy<String> = Lazy::new(|| {
|
||||
|
@ -72,9 +72,8 @@ pub(crate) fn parse_bool(input: &str) -> Result<Option<bool>, String> {
|
|||
}
|
||||
|
||||
match input[0].to_lowercase().as_str() {
|
||||
arg if TRUE_VALUES.contains(&arg) => Ok(Some(true)),
|
||||
arg if FALSE_VALUES.contains(&arg) => Ok(Some(false)),
|
||||
"" => Ok(None),
|
||||
arg if TRUE_VALUES.contains(&arg) => Ok(true),
|
||||
arg if FALSE_VALUES.contains(&arg) => Ok(false),
|
||||
arg => {
|
||||
let message = format!(
|
||||
"Unexpected argument '{arg}'. Expected one of: {}.",
|
||||
|
|
|
@ -1,61 +1,13 @@
|
|||
use crate::{message::BotExt, utils::scrub_urls};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::{
|
||||
error::Error,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use teloxide::{
|
||||
payloads::SendMessageSetters,
|
||||
prelude::Requester,
|
||||
types::{ChatAction, Message},
|
||||
utils::html::link,
|
||||
Bot,
|
||||
};
|
||||
use std::error::Error;
|
||||
use teloxide::{prelude::Requester, types::Message, utils::html::link, Bot};
|
||||
|
||||
pub static MATCH_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||
Regex::new("https://(?:www.)?youtube.com/(?P<shorts>shorts/)[A-Za-z0-9-_]{11}.*").unwrap()
|
||||
});
|
||||
|
||||
pub static FILTER_ENABLED: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
pub async fn set_filter_state(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
filter_state: Option<bool>,
|
||||
) -> Result<(), Box<dyn Error + Sync + Send + 'static>> {
|
||||
match filter_state {
|
||||
None => {
|
||||
let state = if FILTER_ENABLED.load(Ordering::Relaxed) {
|
||||
"enabled"
|
||||
} else {
|
||||
"disabled"
|
||||
};
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
format!("YouTube link replacement is {state}"),
|
||||
)
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
Some(state) => {
|
||||
FILTER_ENABLED.store(state, Ordering::Relaxed);
|
||||
let state = if state { "enabled" } else { "disabled" };
|
||||
bot.send_chat_action(message.chat.id, ChatAction::Typing)
|
||||
.await?;
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
format!("YouTube link replacement has been {state}"),
|
||||
)
|
||||
.reply_to_message_id(message.id)
|
||||
.await?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn handler(
|
||||
bot: Bot,
|
||||
message: Message,
|
||||
|
|
Loading…
Reference in New Issue