diff --git a/Cargo.lock b/Cargo.lock
index f7f525ab9722b92b4f44ef29ba7f969579131646..a5684ab057a8e89a26b48dae4b7f7eca2f530302 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2151,6 +2151,7 @@ dependencies = [
  "futures",
  "grammers-client",
  "grammers-session",
+ "grammers-tl-types",
  "lazy_static",
  "log",
  "rand 0.8.5",
diff --git a/Cargo.toml b/Cargo.toml
index fbc8a78bd4d69a0e6911da6956149abfa7c15f45..421376d3ce48ea4f66008b50b1a88006cf9aa308 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,6 +19,7 @@ dyn-clone = "1.0.10"
 fern = { version = "0.6.1", features = ["chrono", "colored"] }
 futures = "0.3.26"
 grammers-client = { version = "0.4.0", features = ["markdown", "html"] }
+grammers-tl-types = { version = "0.4.0" }
 grammers-session = "0.4.0"
 lazy_static = "1.4.0"
 log = "0.4.17"
diff --git a/src/bot/filters/filtered_handler.rs b/src/bot/filters/filtered_handler.rs
index 44fd29f9d7426246dfce2b3862b6eb89565dde7d..85a59cd3856fe799ed3b4d49ef510e4fb2b79fcd 100644
--- a/src/bot/filters/filtered_handler.rs
+++ b/src/bot/filters/filtered_handler.rs
@@ -1,6 +1,6 @@
 use grammers_client::Update;
 
-use crate::bot::handlers::Handler;
+use crate::bot::{handlers::Handler, middlewares::base::Middleware};
 
 use super::base::Filter;
 
@@ -28,6 +28,12 @@ impl FilteredHandler {
         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.
     /// We run it not in parralel for fast fail strategy.
     pub fn check(&self, update: &Update) -> bool {
diff --git a/src/bot/handlers/fun/greeter.rs b/src/bot/handlers/fun/greeter.rs
index fc83bd3314217f75bf3a6ebef547cb15f52e6f59..f5ae4c8675253d6f047731f06a50df226b29ba66 100644
--- a/src/bot/handlers/fun/greeter.rs
+++ b/src/bot/handlers/fun/greeter.rs
@@ -20,17 +20,11 @@ pub struct Greeter;
 
 #[async_trait]
 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(())};
 
-        // 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.
-        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 {
             message.reply(text).await?;
diff --git a/src/bot/main.rs b/src/bot/main.rs
index 5241355e3ef4d91a127a62fe8d19481c545b56b0..1ea86239aa35e8ed016a6744d2c2ab22b58c8ef1 100644
--- a/src/bot/main.rs
+++ b/src/bot/main.rs
@@ -25,6 +25,7 @@ use super::{
         fun::{blyaficator::Blyaficator, greeter::Greeter, repeator::Repeator, rotator::Rotator},
         Handler,
     },
+    middlewares::members_count::MembersCount,
 };
 
 /// Authorization function.
@@ -103,7 +104,8 @@ async fn run(args: BotConfig, client: Client) -> anyhow::Result<()> {
             .add_filter(SilentFilter)
             .add_filter(ExcludedChatsFilter(vec![me.id()]))
             .add_filter(TextFilter(&["привет"], TextMatchMethod::IStartsWith))
-            .add_filter(ExcludedChatsFilter(args.excluded_chats)),
+            .add_filter(ExcludedChatsFilter(args.excluded_chats))
+            .add_middleware::<MembersCount<100>>(),
         // Getting chat id.
         FilteredHandler::new(GetChatId)
             .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(SilentFilter)
             .add_filter(ExcludedChatsFilter(args.currency_excluded_chats))
-            .add_filter(CurrencyTextFilter),
+            .add_filter(CurrencyTextFilter)
+            .add_middleware::<MembersCount<100>>(),
         // Simlpe rotator.
         FilteredHandler::new(Rotator)
             .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(SilentFilter)
             .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;
diff --git a/src/bot/middlewares/base.rs b/src/bot/middlewares/base.rs
new file mode 100644
index 0000000000000000000000000000000000000000..f441fd7975ebb887d60848820bb71f46a86d5aad
--- /dev/null
+++ b/src/bot/middlewares/base.rs
@@ -0,0 +1,5 @@
+use crate::bot::handlers::Handler;
+
+pub trait Middleware: Handler {
+    fn from_handler(handler: Box<dyn Handler>) -> Self;
+}
diff --git a/src/bot/middlewares/mark_unread.rs b/src/bot/middlewares/mark_unread.rs
new file mode 100644
index 0000000000000000000000000000000000000000..186983a94034e0d83be9a7496f286302154562d9
--- /dev/null
+++ b/src/bot/middlewares/mark_unread.rs
@@ -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 }
+    }
+}
diff --git a/src/bot/middlewares/members_count.rs b/src/bot/middlewares/members_count.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ef7d8aacff5aaa283ec6d5993b44af6684ca1fe9
--- /dev/null
+++ b/src/bot/middlewares/members_count.rs
@@ -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 }
+    }
+}
diff --git a/src/bot/middlewares/mod.rs b/src/bot/middlewares/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d0ec112ca7fa7eeacb0b70d9ad2db1c3665d67e9
--- /dev/null
+++ b/src/bot/middlewares/mod.rs
@@ -0,0 +1,3 @@
+pub mod base;
+pub mod mark_unread;
+pub mod members_count;
diff --git a/src/bot/mod.rs b/src/bot/mod.rs
index 340c21b88b137d6496011a71e68a0711e01a23a4..0aeb3946d3308e839e9929ead72b99b71117aab1 100644
--- a/src/bot/mod.rs
+++ b/src/bot/mod.rs
@@ -1,6 +1,7 @@
 mod filters;
 mod handlers;
 mod main;
+pub mod middlewares;
 pub mod utils;
 
 pub use main::start;