improved architecture

This commit is contained in:
doryan04 2024-03-04 23:09:59 +04:00
parent 6348a7b413
commit 6d7024f7dd
8 changed files with 336 additions and 89 deletions

2
.env Normal file
View File

@ -0,0 +1,2 @@
BOT_TOKEN=6941223962:AAG4SVKKlUOPlgJTINLfxtD09duB_YSkHOw
URL_WEBHOOK=https://api.telegram.org/bot6941223962:AAG4SVKKlUOPlgJTINLfxtD09duB_YSkHOw/sendMessage?chat_id=-1001753166710&message_thread_id=

178
Cargo.lock generated
View File

@ -54,12 +54,72 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "async-trait"
version = "0.1.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "axum"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
dependencies = [
"async-trait",
"axum-core",
"bitflags 1.3.2",
"bytes",
"futures-util",
"http",
"http-body",
"hyper",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "axum-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http",
"http-body",
"mime",
"rustversion",
"tower-layer",
"tower-service",
]
[[package]]
name = "backtrace"
version = "0.3.69"
@ -209,12 +269,20 @@ name = "doryan-facker"
version = "0.1.0"
dependencies = [
"chrono",
"dotenv",
"log",
"pretty_env_logger",
"teloxide",
"tokio",
"url",
]
[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "dptree"
version = "0.3.0"
@ -479,6 +547,12 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "http-range-header"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f"
[[package]]
name = "httparse"
version = "1.8.0"
@ -648,6 +722,12 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "matchit"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "memchr"
version = "2.7.1"
@ -836,6 +916,12 @@ version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "pretty_env_logger"
version = "0.5.0"
@ -888,6 +974,36 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "rc-box"
version = "1.2.0"
@ -1006,6 +1122,12 @@ dependencies = [
"base64",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.16"
@ -1087,6 +1209,16 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c"
dependencies = [
"itoa",
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -1213,6 +1345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c63345cf32a8850ebddcdd769dc2d5193d5e231262d5dada264b79da01a664da"
dependencies = [
"aquamarine",
"axum",
"bytes",
"derive_more",
"dptree",
@ -1220,6 +1353,7 @@ dependencies = [
"log",
"mime",
"pin-project",
"rand",
"serde",
"serde_json",
"serde_with_macros",
@ -1229,6 +1363,8 @@ dependencies = [
"tokio",
"tokio-stream",
"tokio-util",
"tower",
"tower-http",
"url",
]
@ -1395,6 +1531,47 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"pin-project",
"pin-project-lite",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-http"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858"
dependencies = [
"bitflags 1.3.2",
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http-range-header",
"pin-project-lite",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
[[package]]
name = "tower-service"
version = "0.3.2"
@ -1407,6 +1584,7 @@ version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"log",
"pin-project-lite",
"tracing-core",
]

View File

@ -6,8 +6,13 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
teloxide = { version = "0.12", features = ["macros"] }
teloxide = { version = "0.12.2", features = ["macros", "webhooks", "webhooks-axum"] }
log = "0.4"
pretty_env_logger = "0.5.0"
tokio = { version = "1.8", features = ["rt-multi-thread", "macros"] }
chrono = "0.4.34"
chrono = "0.4.34"
url = "2.5.0"
dotenv = "0.15.0"
[env]
BOT_TOKEN = "6941223962:AAG4SVKKlUOPlgJTINLfxtD09duB_YSkHOw"

View File

@ -0,0 +1,20 @@
#[path="../utils/is_admin.rs"]
mod is_admin;
pub mod decorators {
use super::*;
use std::future::Future;
use is_admin::is_admin::is_admin_check;
use teloxide::{Bot, types::Message, requests::Requester};
pub async fn admin_access(bot: Bot, msg: Message, callback: impl Future){
if is_admin_check(&msg, &bot).await {
callback.await;
} else {
bot.send_message(msg.chat.id, "Команда доступна только администраторам")
.await
.unwrap();
}
}
}

View File

@ -1,73 +1,39 @@
pub mod main_handler {
use std::future::Future;
use teloxide::Bot;
use teloxide::types::Message;
use crate::ban::ban::ban_user;
use crate::mute::mute::mute_user;
use crate::unmute::unmute::unmute;
use teloxide::requests::Requester;
use teloxide::prelude::ResponseResult;
use teloxide::utils::command::BotCommands;
use crate::commands::enum_commands::Commands;
use crate::is_admin::is_admin::is_admin_check;
use teloxide::{Bot, types::Message};
use std::{future::Future, error::Error};
async fn admin_command(bot: Bot, msg: Message, callback: impl Future){
if is_admin_check(&msg, &bot).await {
callback.await;
}
}
#[path="../enums/commands.rs"]
mod commands;
#[path= "main_handler_endpoints.rs"]
mod main_handler_endpoints;
pub async fn handler(bot: Bot, msg: Message, commands: Commands) -> ResponseResult<()> {
let chat_id = msg.chat.id;
use main_handler_endpoints::main_handler_endpoints::*;
match commands {
Commands::Facker => {
bot.send_message(msg.chat.id, Commands::descriptions().to_string()).await?;
},
Commands::Tribunal(reason) => {
let reason_result = if reason.is_empty() { None } else { Some(reason) };
admin_command(bot.clone(), msg.clone(), ban_user(
msg.reply_to_message(),
reason_result,
&bot,
chat_id,
)).await;
},
Commands::DemocracyMute(multiplier, time) => {
if let 1i32..=10i32 = multiplier{
admin_command(bot.clone(), msg.clone(), mute_user(
msg.clone().reply_to_message(),
multiplier,
time.to_string(),
&bot,
chat_id,
)).await;
} else if let 10i32..=i32::MAX = multiplier{
bot.send_message(
msg.chat.id,
"Вы ввели слишком большой множитель, пожалуйста, \
выберите множитель из промежутка [1; 10]"
).await
.expect("Вы ввели слишком большой множитель, пожалуйста, \
выберите множитель из промежутка [1; 10]");
} else {
bot.send_message(
msg.chat.id,
"Вы ввели нулевой или отрицательный множитель, пожалуйста, \
выберите множитель из промежутка [1; 10]"
).await
.expect("Вы ввели нулевой или отрицательный множитель, пожалуйста, \
выберите множитель из промежутка [1; 10]");
}
}
Commands::DemocracyUnmute => {
admin_command(bot.clone(), msg.clone(), unmute(
msg.clone().reply_to_message(),
&bot,
chat_id,
)).await;
}
};
Ok(())
pub mod main_handler{
use std::error::Error;
use super::{*, commands::enum_commands::Commands};
use teloxide::{dptree::case, filter_command, types::Update, dispatching::{Dispatcher, UpdateFilterExt}};
pub async fn main_handler_spawn(bot: Bot) -> () {
let command_handler = filter_command::<Commands, Result<(), Box<(dyn Error + Send + Sync + 'static)>>>()
.branch(case![Commands::Facker].endpoint(facker))
.branch(
case![Commands::DemocracyMute(multiplier, time_type)]
.endpoint(|bot : Bot, msg : Message, args : (i32, String)| async move {
democracy_mute(bot, msg, args.0, args.1).await
}))
.branch(case![Commands::DemocracyUnmute].endpoint(democracy_unmute))
.branch(case![Commands::Tribunal(reason)]
.endpoint(|bot : Bot, msg : Message, args| async move {
tribunal(bot, msg, args).await
}));
let message_handler = Update::filter_message()
.branch(command_handler);
Dispatcher::builder(bot, message_handler)
.build()
.dispatch()
.await;
}
}

View File

@ -0,0 +1,84 @@
use teloxide::{Bot, types::Message};
use std::{future::Future, error::Error};
#[path="../bot_functions/ban.rs"]
mod ban;
#[path="../bot_functions/mute.rs"]
mod mute;
#[path="../bot_functions/unmute.rs"]
mod unmute;
#[path="../enums/commands.rs"]
mod commands;
#[path= "decorators.rs"]
mod decorators;
pub mod main_handler_endpoints {
use super::*;
use super::ban::ban::ban_user;
use super::mute::mute::mute_user;
use super::unmute::unmute::unmute;
use super::commands::enum_commands::Commands;
use super::decorators::decorators::admin_access;
use teloxide::{requests::Requester, utils::command::BotCommands};
pub(crate) type CommandHandleResult = Result<(), Box<dyn Error + Send + Sync>>;
pub(crate) async fn facker(bot : Bot, msg : Message) -> CommandHandleResult {
bot.send_message(msg.chat.id, Commands::descriptions().to_string()).await?;
Ok(())
}
pub(crate) async fn democracy_unmute(bot : Bot, msg : Message) -> CommandHandleResult {
admin_access(bot.clone(), msg.clone(), unmute(
msg.clone().reply_to_message(),
&bot,
msg.chat.id,
)).await;
Ok(())
}
pub(crate) async fn democracy_mute(
bot : Bot,
msg : Message,
multiplier : i32,
time : String
) -> CommandHandleResult {
if let 1i32..=10i32 = multiplier{
admin_access(bot.clone(), msg.clone(), mute_user(
msg.clone().reply_to_message(),
multiplier,
time.to_string(),
&bot,
msg.chat.id,
)).await;
} else if let 10i32..=i32::MAX = multiplier{
let except_text = "Вы ввели слишком большой множитель, пожалуйста, \
выберите множитель из промежутка [1; 10]";
bot.send_message(msg.chat.id, except_text)
.await
.expect(except_text);
} else {
let except_text = "Вы ввели нулевой или отрицательный множитель, пожалуйста, \
выберите множитель из промежутка [1; 10]";
bot.send_message(msg.chat.id, except_text)
.await
.expect(except_text);
}
Ok(())
}
pub(crate) async fn tribunal(bot : Bot, msg : Message, reason : String) -> CommandHandleResult {
let reason_result = if reason.is_empty() { None } else { Some(reason) };
admin_access(bot.clone(), msg.clone(), ban_user(
msg.reply_to_message(),
reason_result,
&bot,
msg.chat.id,
)).await;
Ok(())
}
}

View File

@ -1,26 +1,21 @@
use teloxide::prelude::*;
use crate::commands::enum_commands::Commands;
use crate::main_handler::main_handler::handler;
use std::env;
use dotenv::dotenv;
use std::error::Error;
use teloxide::{prelude::*};
use teloxide::error_handlers::ErrorHandler;
#[path="bot_functions/ban.rs"]
mod ban;
#[path="bot_functions/mute.rs"]
mod mute;
#[path="bot_functions/unmute.rs"]
mod unmute;
#[path="utils/is_admin.rs"]
mod is_admin;
#[path="enums/commands.rs"]
mod commands;
#[path="handlers/main_handler.rs"]
mod main_handler;
#[tokio::main]
async fn main() {
pretty_env_logger::init();
log::info!("Starting throw dice bot...");
dotenv().ok();
let bot = Bot::new("6941223962:AAG4SVKKlUOPlgJTINLfxtD09duB_YSkHOw".to_string());
let token = env::var("BOT_TOKEN").unwrap();
let bot = Bot::new(token);
main_handler::main_handler::main_handler_spawn(bot).await;
Commands::repl(bot, handler).await;
}

View File

@ -20,9 +20,6 @@ pub mod is_admin{
if chat_member.is_administrator() || chat_member.is_owner() {
return true;
} else {
bot.send_message(message.chat.id, "Команда доступна только администраторам")
.await
.unwrap();
return false;
}
}