Added midlewares.
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2151,6 +2151,7 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"grammers-client",
|
"grammers-client",
|
||||||
"grammers-session",
|
"grammers-session",
|
||||||
|
"grammers-tl-types",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
@ -19,6 +19,7 @@ dyn-clone = "1.0.10"
|
|||||||
fern = { version = "0.6.1", features = ["chrono", "colored"] }
|
fern = { version = "0.6.1", features = ["chrono", "colored"] }
|
||||||
futures = "0.3.26"
|
futures = "0.3.26"
|
||||||
grammers-client = { version = "0.4.0", features = ["markdown", "html"] }
|
grammers-client = { version = "0.4.0", features = ["markdown", "html"] }
|
||||||
|
grammers-tl-types = { version = "0.4.0" }
|
||||||
grammers-session = "0.4.0"
|
grammers-session = "0.4.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use grammers_client::Update;
|
use grammers_client::Update;
|
||||||
|
|
||||||
use crate::bot::handlers::Handler;
|
use crate::bot::{handlers::Handler, middlewares::base::Middleware};
|
||||||
|
|
||||||
use super::base::Filter;
|
use super::base::Filter;
|
||||||
|
|
||||||
@ -28,6 +28,12 @@ impl FilteredHandler {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wraps a middleware around a handler.
|
||||||
|
pub fn add_middleware<M: Middleware + 'static>(mut self) -> Self {
|
||||||
|
self.handler = Box::new(M::from_handler(self.handler));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// This method performs checks for all filters we have.
|
/// This method performs checks for all filters we have.
|
||||||
/// We run it not in parralel for fast fail strategy.
|
/// We run it not in parralel for fast fail strategy.
|
||||||
pub fn check(&self, update: &Update) -> bool {
|
pub fn check(&self, update: &Update) -> bool {
|
||||||
|
@ -20,17 +20,11 @@ pub struct Greeter;
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Handler for Greeter {
|
impl Handler for Greeter {
|
||||||
async fn react(&self, client: &Client, update: &Update) -> anyhow::Result<()> {
|
async fn react(&self, _: &Client, update: &Update) -> anyhow::Result<()> {
|
||||||
let Update::NewMessage(message) = update else {return Ok(())};
|
let Update::NewMessage(message) = update else {return Ok(())};
|
||||||
|
|
||||||
// Check if chat has less than 100 participants.
|
|
||||||
let participants = client.iter_participants(message.chat()).total().await?;
|
|
||||||
if participants >= 100 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose random greeting from the list of greetings.
|
// Choose random greeting from the list of greetings.
|
||||||
let reply_text = GREETINGS.iter().choose(&mut rand::thread_rng()).copied();
|
let reply_text = GREETINGS.iter().choose(&mut rand::rngs::OsRng).copied();
|
||||||
|
|
||||||
if let Some(text) = reply_text {
|
if let Some(text) = reply_text {
|
||||||
message.reply(text).await?;
|
message.reply(text).await?;
|
||||||
|
@ -25,6 +25,7 @@ use super::{
|
|||||||
fun::{blyaficator::Blyaficator, greeter::Greeter, repeator::Repeator, rotator::Rotator},
|
fun::{blyaficator::Blyaficator, greeter::Greeter, repeator::Repeator, rotator::Rotator},
|
||||||
Handler,
|
Handler,
|
||||||
},
|
},
|
||||||
|
middlewares::members_count::MembersCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Authorization function.
|
/// Authorization function.
|
||||||
@ -103,7 +104,8 @@ async fn run(args: BotConfig, client: Client) -> anyhow::Result<()> {
|
|||||||
.add_filter(SilentFilter)
|
.add_filter(SilentFilter)
|
||||||
.add_filter(ExcludedChatsFilter(vec![me.id()]))
|
.add_filter(ExcludedChatsFilter(vec![me.id()]))
|
||||||
.add_filter(TextFilter(&["привет"], TextMatchMethod::IStartsWith))
|
.add_filter(TextFilter(&["привет"], TextMatchMethod::IStartsWith))
|
||||||
.add_filter(ExcludedChatsFilter(args.excluded_chats)),
|
.add_filter(ExcludedChatsFilter(args.excluded_chats))
|
||||||
|
.add_middleware::<MembersCount<100>>(),
|
||||||
// Getting chat id.
|
// Getting chat id.
|
||||||
FilteredHandler::new(GetChatId)
|
FilteredHandler::new(GetChatId)
|
||||||
.add_filter(TextFilter(&[".cid"], TextMatchMethod::IMatches)),
|
.add_filter(TextFilter(&[".cid"], TextMatchMethod::IMatches)),
|
||||||
@ -117,7 +119,8 @@ async fn run(args: BotConfig, client: Client) -> anyhow::Result<()> {
|
|||||||
.add_filter(UpdateTypeFilter(&[UpdateType::New]))
|
.add_filter(UpdateTypeFilter(&[UpdateType::New]))
|
||||||
.add_filter(SilentFilter)
|
.add_filter(SilentFilter)
|
||||||
.add_filter(ExcludedChatsFilter(args.currency_excluded_chats))
|
.add_filter(ExcludedChatsFilter(args.currency_excluded_chats))
|
||||||
.add_filter(CurrencyTextFilter),
|
.add_filter(CurrencyTextFilter)
|
||||||
|
.add_middleware::<MembersCount<100>>(),
|
||||||
// Simlpe rotator.
|
// Simlpe rotator.
|
||||||
FilteredHandler::new(Rotator)
|
FilteredHandler::new(Rotator)
|
||||||
.add_filter(UpdateTypeFilter(&[UpdateType::New]))
|
.add_filter(UpdateTypeFilter(&[UpdateType::New]))
|
||||||
@ -134,7 +137,8 @@ async fn run(args: BotConfig, client: Client) -> anyhow::Result<()> {
|
|||||||
.add_filter(MessageDirectionFilter(MessageDirection::Incoming))
|
.add_filter(MessageDirectionFilter(MessageDirection::Incoming))
|
||||||
.add_filter(SilentFilter)
|
.add_filter(SilentFilter)
|
||||||
.add_filter(ExcludedChatsFilter(vec![me.id()]))
|
.add_filter(ExcludedChatsFilter(vec![me.id()]))
|
||||||
.add_filter(RegexFilter(Regex::new("^[)0]+$")?)),
|
.add_filter(RegexFilter(Regex::new("^[)0]+$")?))
|
||||||
|
.add_middleware::<MembersCount<100>>(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut errors_count = 0;
|
let mut errors_count = 0;
|
||||||
|
5
src/bot/middlewares/base.rs
Normal file
5
src/bot/middlewares/base.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
use crate::bot::handlers::Handler;
|
||||||
|
|
||||||
|
pub trait Middleware: Handler {
|
||||||
|
fn from_handler(handler: Box<dyn Handler>) -> Self;
|
||||||
|
}
|
43
src/bot/middlewares/mark_unread.rs
Normal file
43
src/bot/middlewares/mark_unread.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use grammers_client::{Client, Update};
|
||||||
|
use grammers_tl_types::types::{InputDialogPeer, InputPeerChat};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
bot::{handlers::Handler, middlewares::base::Middleware},
|
||||||
|
utils::messages::get_message,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct MarkUnread {
|
||||||
|
handler: Box<dyn Handler>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl Handler for MarkUnread {
|
||||||
|
async fn react(&self, client: &Client, update: &Update) -> anyhow::Result<()> {
|
||||||
|
let res = self.handler.react(client, update).await;
|
||||||
|
|
||||||
|
if let Some(message) = get_message(update) {
|
||||||
|
let res = client
|
||||||
|
.invoke(&grammers_tl_types::functions::messages::MarkDialogUnread {
|
||||||
|
peer: grammers_tl_types::enums::InputDialogPeer::Peer(InputDialogPeer {
|
||||||
|
peer: grammers_tl_types::enums::InputPeer::Chat(InputPeerChat {
|
||||||
|
chat_id: message.chat().id(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
unread: true,
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
if let Err(err) = res {
|
||||||
|
log::warn!("Cannot mark dialog unread. Reason: {err}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Middleware for MarkUnread {
|
||||||
|
fn from_handler(handler: Box<dyn Handler>) -> Self {
|
||||||
|
Self { handler }
|
||||||
|
}
|
||||||
|
}
|
36
src/bot/middlewares/members_count.rs
Normal file
36
src/bot/middlewares/members_count.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use grammers_client::{Client, Update};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
bot::{handlers::Handler, middlewares::base::Middleware},
|
||||||
|
utils::messages::get_message,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct MembersCount<const MAX_COUNT: usize> {
|
||||||
|
handler: Box<dyn Handler>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl<const MAX_COUNT: usize> Handler for MembersCount<MAX_COUNT> {
|
||||||
|
async fn react(&self, client: &Client, update: &Update) -> anyhow::Result<()> {
|
||||||
|
if let Some(message) = get_message(update) {
|
||||||
|
let participants = client
|
||||||
|
.iter_participants(message.chat())
|
||||||
|
.total()
|
||||||
|
.await
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
if participants > MAX_COUNT {
|
||||||
|
log::warn!("Too many participants. Skipping.");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.handler.react(client, update).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const MAX_COUNT: usize> Middleware for MembersCount<MAX_COUNT> {
|
||||||
|
fn from_handler(handler: Box<dyn Handler>) -> Self {
|
||||||
|
Self { handler }
|
||||||
|
}
|
||||||
|
}
|
3
src/bot/middlewares/mod.rs
Normal file
3
src/bot/middlewares/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub mod base;
|
||||||
|
pub mod mark_unread;
|
||||||
|
pub mod members_count;
|
@ -1,6 +1,7 @@
|
|||||||
mod filters;
|
mod filters;
|
||||||
mod handlers;
|
mod handlers;
|
||||||
mod main;
|
mod main;
|
||||||
|
pub mod middlewares;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
pub use main::start;
|
pub use main::start;
|
||||||
|
Reference in New Issue
Block a user