reinit git
This commit is contained in:
commit
7ec67cb6e4
|
@ -0,0 +1,16 @@
|
|||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
.env
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
[package]
|
||||
name = "dorya"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.86"
|
||||
async-trait = "0.1.80"
|
||||
chrono = "0.4.38"
|
||||
dashmap = "5.5.3"
|
||||
dotenvy = "0.15.7"
|
||||
futures = "0.3.30"
|
||||
telers = "1.0.0-alpha.18"
|
||||
tokio = { version="1.37.0", features=["rt-multi-thread"] }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = {version="0.3.18", features=["env-filter"]}
|
|
@ -0,0 +1,64 @@
|
|||
use telers::{
|
||||
event::{telegram::HandlerResult, EventReturn},
|
||||
types::{Message, User},
|
||||
Bot,
|
||||
};
|
||||
|
||||
use tokio::time::{sleep, Duration as DurationSleep};
|
||||
|
||||
use crate::{
|
||||
types::structs::{bot_entity::BotEntity, message_sender::MessageSender},
|
||||
utils::telegram::try_do_action::try_restrict,
|
||||
};
|
||||
|
||||
use crate::utils::telegram::ban_member::ban_chat_member;
|
||||
|
||||
pub async fn ban(bot_entity: BotEntity, delay: u64) -> HandlerResult {
|
||||
let (bot, message, sender): (Bot, Message, MessageSender) = (
|
||||
bot_entity.bot_instance,
|
||||
bot_entity.receive_message,
|
||||
bot_entity.message_sender,
|
||||
);
|
||||
|
||||
let reply_to: Message;
|
||||
let chat_id: i64 = message.chat().id();
|
||||
|
||||
if let Some(msg) = message.reply_to_message() {
|
||||
reply_to = msg.clone();
|
||||
} else {
|
||||
sender
|
||||
.reply_to(message.id())
|
||||
.text("Ответьте на сообщение, чтобы забанить.")
|
||||
.send(&bot)
|
||||
.await?;
|
||||
return Ok(EventReturn::Cancel);
|
||||
}
|
||||
|
||||
let user_data: &User = reply_to.from().unwrap();
|
||||
let user_id: i64 = user_data.id;
|
||||
|
||||
sleep(DurationSleep::from_millis(delay)).await;
|
||||
|
||||
let future = || async { ban_chat_member(&bot, user_id, chat_id).await };
|
||||
let demote_args: (&Bot, i64, i64) = (&bot, user_id, chat_id);
|
||||
let failure_sender: MessageSender = sender
|
||||
.clone()
|
||||
.text("Невозможно забанить участника чата, демотните и попробуйте снова");
|
||||
|
||||
if try_restrict(future, demote_args, failure_sender)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
Ok(EventReturn::Cancel)
|
||||
} else {
|
||||
let banned_user_name: String = reply_to.from().unwrap().clone().username.unwrap();
|
||||
|
||||
sender
|
||||
.reply_to(message.id())
|
||||
.text(format!("Пользователь {} забанен.", banned_user_name))
|
||||
.send(&bot)
|
||||
.await?;
|
||||
|
||||
Ok(EventReturn::Finish)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod ban;
|
||||
pub mod mute;
|
|
@ -0,0 +1,80 @@
|
|||
use futures::stream::futures_unordered;
|
||||
use telers::{
|
||||
event::{telegram::HandlerResult, EventReturn},
|
||||
types::{Message, User},
|
||||
Bot,
|
||||
};
|
||||
|
||||
use tokio::time::{sleep, Duration as DurationSleep};
|
||||
|
||||
use crate::{
|
||||
types::{
|
||||
enums::time_metrics::TimeMetrics,
|
||||
structs::{
|
||||
bot_entity::BotEntity, countable_time::CountableTime, message_sender::MessageSender,
|
||||
},
|
||||
traits::countable_interface::ICountable,
|
||||
},
|
||||
utils::telegram::try_do_action::try_restrict,
|
||||
};
|
||||
|
||||
use crate::utils::{general::unrestrict_date::unrestrict_date, telegram::restrict::restrict};
|
||||
|
||||
pub async fn mute(bot_entity: BotEntity, values: (TimeMetrics, u64)) -> HandlerResult {
|
||||
let (bot, message, sender): (Bot, Message, MessageSender) = (
|
||||
bot_entity.bot_instance,
|
||||
bot_entity.receive_message,
|
||||
bot_entity.message_sender,
|
||||
);
|
||||
|
||||
let reply_to: Message;
|
||||
let chat_id: i64 = message.chat().id();
|
||||
|
||||
if let Some(msg) = message.reply_to_message() {
|
||||
reply_to = msg.clone();
|
||||
} else {
|
||||
sender
|
||||
.reply_to(message.id())
|
||||
.text("Ответьте на сообщение, чтобы замьютить.")
|
||||
.send(&bot)
|
||||
.await?;
|
||||
return Ok(EventReturn::Cancel);
|
||||
}
|
||||
|
||||
let user_data: &User = reply_to.from().unwrap();
|
||||
let user_id: i64 = user_data.id;
|
||||
|
||||
sleep(DurationSleep::from_millis(values.1)).await;
|
||||
|
||||
let time_duration = values.0.extract();
|
||||
let unmute_date = unrestrict_date(time_duration);
|
||||
let postfix = CountableTime::from_value(time_duration)
|
||||
.get_postfix(values.0)
|
||||
.unwrap();
|
||||
|
||||
let future = || async { restrict(&bot, user_id, unmute_date, chat_id).await };
|
||||
let demote_args: (&Bot, i64, i64) = (&bot, user_id, chat_id);
|
||||
let failure_sender: MessageSender = sender
|
||||
.clone()
|
||||
.text("Невозможно замьютить участника чата, демотните и попробуйте снова");
|
||||
|
||||
if try_restrict(future, demote_args, failure_sender)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
Ok(EventReturn::Cancel)
|
||||
} else {
|
||||
let muted_user_name = reply_to.from().unwrap().clone().username.unwrap();
|
||||
|
||||
sender
|
||||
.reply_to(message.id())
|
||||
.text(format!(
|
||||
"Пользователь {} замьючен на {:?} {}.",
|
||||
muted_user_name, time_duration, postfix
|
||||
))
|
||||
.send(&bot)
|
||||
.await?;
|
||||
|
||||
Ok(EventReturn::Finish)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
use telers::{
|
||||
event::{telegram::HandlerResult, EventReturn},
|
||||
types::Message,
|
||||
Bot,
|
||||
};
|
||||
|
||||
use crate::types::structs::message_sender::MessageSender;
|
||||
|
||||
const HELP_TEXT: &str = "\
|
||||
/help - помощь по боту.\n\
|
||||
/unmute - снимает с человека мьют, нужно ответить на сообщение, чтобы команда сработала (\
|
||||
только для админов).\n\
|
||||
🎲 - выдаёт мут, для этого нужно отправить ТОЛЬКО эмодзи в ответ на сообщение участника. \
|
||||
чата, которого вы хотите замьютить (только для админов).\n\
|
||||
🎰 - выдаёт бан в случае джекпота, напротив, мьют, всё так же кидайте этот эмодзи в ответ \
|
||||
на сообщение участника чата, которого вы хотите замьютить/забанить (только для админов).";
|
||||
|
||||
pub async fn help(bot: Bot, message: Message) -> HandlerResult {
|
||||
println!("hi");
|
||||
MessageSender::new(message.chat().id())
|
||||
.text(HELP_TEXT)
|
||||
.send(&bot)
|
||||
.await
|
||||
.unwrap();
|
||||
Ok(EventReturn::Finish)
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod help;
|
||||
pub mod unmute;
|
|
@ -0,0 +1,60 @@
|
|||
use telers::{
|
||||
event::{telegram::HandlerResult, EventReturn},
|
||||
filters::CommandObject,
|
||||
methods::RestrictChatMember,
|
||||
types::User,
|
||||
types::{ChatPermissions, Message},
|
||||
Bot,
|
||||
};
|
||||
|
||||
use crate::types::structs::message_sender::MessageSender;
|
||||
|
||||
pub async fn unmute(bot: Bot, message: Message, command: CommandObject) -> HandlerResult {
|
||||
let sender = MessageSender::new(message.chat().id());
|
||||
|
||||
let reply_to: Message;
|
||||
let chat_id: i64 = message.chat().id();
|
||||
|
||||
if let Some(msg) = message.reply_to_message() {
|
||||
reply_to = msg.clone();
|
||||
} else {
|
||||
sender
|
||||
.reply_to(message.id())
|
||||
.text("Ответьте на сообщение, чтобы замьютить.")
|
||||
.send(&bot)
|
||||
.await?;
|
||||
return Ok(EventReturn::Cancel);
|
||||
}
|
||||
|
||||
let user_data: &User = reply_to.from().unwrap();
|
||||
let user_id: i64 = user_data.id;
|
||||
|
||||
let default_member_permissions = ChatPermissions::all()
|
||||
.can_change_info(false)
|
||||
.can_manage_topics(false)
|
||||
.can_invite_users(false)
|
||||
.can_pin_messages(false);
|
||||
|
||||
let bot_action = RestrictChatMember::new(chat_id, user_id, default_member_permissions);
|
||||
|
||||
let username = reply_to.from().unwrap().clone().username.unwrap();
|
||||
|
||||
if let Err(error) = bot.send(bot_action).await {
|
||||
sender
|
||||
.text(format!(
|
||||
"Невозможно снять мьют с участника чата по причине: {error:?}"
|
||||
))
|
||||
.send(&bot)
|
||||
.await?;
|
||||
return Ok(EventReturn::Cancel);
|
||||
} else {
|
||||
sender
|
||||
.reply_to(message.id())
|
||||
.text(format!("С пользователя {} был снят мьут.", username))
|
||||
.send(&bot)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
Ok(EventReturn::Finish)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod endpoints;
|
|
@ -0,0 +1,50 @@
|
|||
use telers::{
|
||||
event::{telegram::HandlerResult, EventReturn},
|
||||
types::{Dice, Message},
|
||||
Bot,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
handlers::actions::{ban::ban, mute::mute},
|
||||
types::{
|
||||
enums::time_metrics::TimeMetrics,
|
||||
structs::{bot_entity::BotEntity, message_sender::MessageSender},
|
||||
},
|
||||
};
|
||||
|
||||
const DICE_DELAY_MS: u64 = 4000u64;
|
||||
const CASINO_DELAY_MS: u64 = 1500u64;
|
||||
|
||||
pub async fn dice_handler(bot: Bot, message: Message) -> HandlerResult {
|
||||
let (chat_id, dice): (i64, Dice) = (message.chat().id(), message.dice().unwrap().clone());
|
||||
|
||||
let bot_entity: BotEntity = BotEntity {
|
||||
bot_instance: bot,
|
||||
receive_message: message,
|
||||
message_sender: MessageSender::new(chat_id),
|
||||
};
|
||||
|
||||
let (mute_time, emoji): (TimeMetrics, &str) = (TimeMetrics::Days(dice.value), &dice.emoji);
|
||||
|
||||
match emoji {
|
||||
"🎲" => {
|
||||
mute(bot_entity, (mute_time, DICE_DELAY_MS)).await?;
|
||||
}
|
||||
"🎰" => {
|
||||
if dice.value == 64 {
|
||||
ban(bot_entity, CASINO_DELAY_MS).await?;
|
||||
} else {
|
||||
mute(bot_entity, (mute_time, CASINO_DELAY_MS)).await?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
bot_entity
|
||||
.message_sender
|
||||
.text("Такой эмодзи не имеет привязки к какому либо действию бота.")
|
||||
.send(&bot_entity.bot_instance)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(EventReturn::Finish)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod dice;
|
|
@ -0,0 +1,3 @@
|
|||
pub mod actions;
|
||||
pub mod commands_handler;
|
||||
pub mod dice_handler;
|
|
@ -0,0 +1,83 @@
|
|||
use dotenvy::dotenv;
|
||||
use telers::{
|
||||
enums::ContentType,
|
||||
event::ToServiceProvider,
|
||||
filters::{content_type::ContentType as CT, Command},
|
||||
Bot, Dispatcher, Router,
|
||||
};
|
||||
|
||||
use tracing_subscriber::{fmt, layer::SubscriberExt as _, util::SubscriberInitExt as _, EnvFilter};
|
||||
|
||||
mod middlewares;
|
||||
mod types;
|
||||
mod utils;
|
||||
|
||||
use middlewares::admin_check_middleware::AdminCheck;
|
||||
|
||||
mod handlers;
|
||||
use handlers::{
|
||||
commands_handler::endpoints::{help::help, unmute::unmute},
|
||||
dice_handler::dice::dice_handler,
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::registry()
|
||||
.with(fmt::layer())
|
||||
.with(EnvFilter::from_env("RUST_LOG"))
|
||||
.init();
|
||||
|
||||
dotenv().ok();
|
||||
|
||||
let token_result = dotenvy::var("TOKEN");
|
||||
match token_result {
|
||||
Ok(token) => {
|
||||
let bot = Bot::new(token);
|
||||
|
||||
let mut route = Router::new("main");
|
||||
|
||||
let mut dice = Router::new("dice");
|
||||
|
||||
dice.message
|
||||
.register(dice_handler)
|
||||
.filter(CT::one(ContentType::Dice));
|
||||
|
||||
dice.message.inner_middlewares.register(AdminCheck {});
|
||||
|
||||
let mut command = Router::new("commands");
|
||||
let mut admin_commands = Router::new("admin_commands");
|
||||
let mut default_commands = Router::new("default_commands");
|
||||
|
||||
admin_commands
|
||||
.message
|
||||
.register(unmute)
|
||||
.filter(Command::one("unmute"));
|
||||
|
||||
admin_commands
|
||||
.message
|
||||
.inner_middlewares
|
||||
.register(AdminCheck {});
|
||||
|
||||
default_commands
|
||||
.message
|
||||
.register(help)
|
||||
.filter(Command::one("help"));
|
||||
|
||||
command.include(admin_commands).include(default_commands);
|
||||
|
||||
route.include(dice).include(command);
|
||||
|
||||
let dispatcher = Dispatcher::builder().main_router(route).bot(bot).build();
|
||||
|
||||
dispatcher
|
||||
.to_service_provider_default()
|
||||
.unwrap()
|
||||
.run_polling()
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
Err(error) => {
|
||||
println!("Error text: {:?}", error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
use async_trait::async_trait;
|
||||
use telers::{
|
||||
errors::{EventErrorKind, HandlerError},
|
||||
event::telegram::{HandlerRequest, HandlerResponse},
|
||||
middlewares::{InnerMiddleware, Next},
|
||||
};
|
||||
|
||||
use anyhow::Error as Reject;
|
||||
|
||||
use crate::{
|
||||
types::structs::message_sender::MessageSender,
|
||||
utils::telegram::{admin_check::is_admin, get_all_admins::get_all_admins},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AdminCheck {}
|
||||
|
||||
#[async_trait]
|
||||
impl InnerMiddleware for AdminCheck {
|
||||
async fn call(
|
||||
&self,
|
||||
request: HandlerRequest,
|
||||
next: Next,
|
||||
) -> Result<HandlerResponse, EventErrorKind> {
|
||||
let (bot, message) = (request.clone().bot, request.clone().update);
|
||||
|
||||
let admins_list = get_all_admins(&bot, message.chat().unwrap().id())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let chat_id: i64 = message.chat_id().unwrap();
|
||||
|
||||
if is_admin(&admins_list, message.from().unwrap()) {
|
||||
let response = next(request).await?;
|
||||
return Ok(response);
|
||||
} else {
|
||||
MessageSender::new(chat_id)
|
||||
.text("У вам нет прав администратора, чтобы использовать эту команду.")
|
||||
.send(&bot)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
return Err(EventErrorKind::Handler(HandlerError::new(Reject::msg(
|
||||
"User isn't admin.".to_string(),
|
||||
))));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod admin_check_middleware;
|
|
@ -0,0 +1 @@
|
|||
pub mod time_metrics;
|
|
@ -0,0 +1,30 @@
|
|||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum TimeMetrics {
|
||||
Minutes(i64),
|
||||
Hours(i64),
|
||||
Days(i64),
|
||||
Weeks(i64),
|
||||
Mounths(i64),
|
||||
}
|
||||
|
||||
impl TimeMetrics {
|
||||
pub fn extract(self) -> i64 {
|
||||
match self {
|
||||
Self::Minutes(min) => min,
|
||||
Self::Hours(hrs) => hrs,
|
||||
Self::Days(day) => day,
|
||||
Self::Weeks(wks) => wks,
|
||||
Self::Mounths(mon) => mon,
|
||||
}
|
||||
}
|
||||
pub fn get_word_declensions(self) -> (impl Into<String>, impl Into<String>, impl Into<String>) {
|
||||
match self {
|
||||
Self::Minutes(_) => ("минута", "минуты", "минут"),
|
||||
Self::Hours(_) => ("час", "часов", "часов"),
|
||||
Self::Days(_) => ("день", "дня", "дней"),
|
||||
Self::Weeks(_) => ("неделя", "недели", "недель"),
|
||||
Self::Mounths(_) => ("месяц", "месяца", "месяцев"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pub mod enums;
|
||||
pub mod structs;
|
||||
pub mod traits;
|
|
@ -0,0 +1,8 @@
|
|||
use crate::types::structs::message_sender::MessageSender;
|
||||
use telers::{types::Message, Bot};
|
||||
|
||||
pub struct BotEntity {
|
||||
pub bot_instance: Bot,
|
||||
pub receive_message: Message,
|
||||
pub message_sender: MessageSender,
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
use crate::types::{enums::time_metrics::TimeMetrics, traits::countable_interface::ICountable};
|
||||
|
||||
pub struct CountableTime(i64, i64);
|
||||
|
||||
impl ICountable<(i64, i64), TimeMetrics> for CountableTime {
|
||||
fn new() -> Self {
|
||||
Self(0, 0)
|
||||
}
|
||||
|
||||
fn from_value(value: i64) -> Self {
|
||||
Self((value / 10) % 10, value % 10)
|
||||
}
|
||||
|
||||
fn get_values(&self) -> (i64, i64) {
|
||||
(self.0, self.1)
|
||||
}
|
||||
|
||||
fn set_values(&self, value: i64) -> Self {
|
||||
Self((value / 10) % 10, value % 10)
|
||||
}
|
||||
|
||||
fn get_postfix(&self, metrics: TimeMetrics) -> Option<String> {
|
||||
let all_word_declensions = metrics.get_word_declensions();
|
||||
let (first, second, third): (String, String, String) = (
|
||||
all_word_declensions.0.into(),
|
||||
all_word_declensions.1.into(),
|
||||
all_word_declensions.2.into(),
|
||||
);
|
||||
|
||||
match self.get_values() {
|
||||
(0, 1) | (2..=9, 1) => Some(first),
|
||||
(0, 2..=4) | (2..=9, 2..=4) => Some(second),
|
||||
(0..=9, 0) | (0, 5..=9) | (1, 0..=9) | (2..=9, 5..=9) => Some(third),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
use core::convert::Into;
|
||||
use telers::{
|
||||
errors::session::ErrorKind,
|
||||
methods::SendMessage,
|
||||
types::{Message, ReplyParameters},
|
||||
Bot,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MessageSender {
|
||||
chat_id: i64,
|
||||
send_message: SendMessage,
|
||||
}
|
||||
|
||||
impl MessageSender {
|
||||
pub fn new(group_id: i64) -> Self {
|
||||
Self {
|
||||
chat_id: group_id,
|
||||
send_message: SendMessage::new(group_id, ""),
|
||||
}
|
||||
}
|
||||
pub fn group_id(mut self, val: i64) -> Self {
|
||||
self.chat_id = val;
|
||||
self.send_message = self.send_message.clone().chat_id(val);
|
||||
self
|
||||
}
|
||||
pub fn text(mut self, val: impl Into<String>) -> Self {
|
||||
self.send_message = self.send_message.clone().text(val);
|
||||
self
|
||||
}
|
||||
pub fn disable_notification(mut self, val: bool) -> Self {
|
||||
self.send_message = self.send_message.clone().disable_notification(val);
|
||||
self
|
||||
}
|
||||
pub fn reply_to(mut self, msg_id: i64) -> Self {
|
||||
let reply = ReplyParameters::new(msg_id).chat_id(self.chat_id);
|
||||
self.send_message = self.send_message.clone().reply_parameters(reply);
|
||||
self
|
||||
}
|
||||
pub async fn send(self, bot: &Bot) -> Result<Message, ErrorKind> {
|
||||
bot.send(self.send_message).await
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pub mod bot_entity;
|
||||
pub mod countable_time;
|
||||
pub mod message_sender;
|
|
@ -0,0 +1,12 @@
|
|||
#[allow(dead_code)]
|
||||
pub trait ICountable<T, M> {
|
||||
fn new() -> Self;
|
||||
|
||||
fn from_value(value: i64) -> Self;
|
||||
|
||||
fn set_values(&self, value: i64) -> Self;
|
||||
|
||||
fn get_values(&self) -> T;
|
||||
|
||||
fn get_postfix(&self, metrics: M) -> Option<String>;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod countable_interface;
|
|
@ -0,0 +1 @@
|
|||
pub mod unrestrict_date;
|
|
@ -0,0 +1,5 @@
|
|||
use chrono::{Duration, Local, NaiveDateTime};
|
||||
|
||||
pub fn unrestrict_date(days: i64) -> NaiveDateTime {
|
||||
Local::now().naive_utc() + Duration::days(days)
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod general;
|
||||
pub mod telegram;
|
|
@ -0,0 +1,11 @@
|
|||
use telers::types::{chat_member::ChatMember, User};
|
||||
|
||||
pub fn is_admin(all_admin_members: &Vec<ChatMember>, user: &User) -> bool {
|
||||
all_admin_members
|
||||
.iter()
|
||||
.any(|admin: &ChatMember| match admin {
|
||||
ChatMember::Administrator(admin) => &admin.user == user,
|
||||
ChatMember::Owner(owner) => &owner.user == user,
|
||||
_ => false,
|
||||
})
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
use telers::{errors::session::ErrorKind, methods::BanChatMember, Bot};
|
||||
|
||||
pub async fn ban_chat_member(bot: &Bot, chat_id: i64, user_id: i64) -> Result<bool, ErrorKind> {
|
||||
bot.send(BanChatMember::new(chat_id, user_id)).await
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
use telers::{errors::session::ErrorKind, methods::promote_chat_member::PromoteChatMember, Bot};
|
||||
|
||||
pub async fn demote_user(bot: &Bot, user_id: i64, chat_id: i64) -> Result<bool, ErrorKind> {
|
||||
bot.send(
|
||||
PromoteChatMember::new(chat_id, user_id)
|
||||
.can_manage_topics(false)
|
||||
.can_pin_messages(false)
|
||||
.can_invite_users(false)
|
||||
.can_change_info(false)
|
||||
.can_promote_members(false)
|
||||
.can_restrict_members(false)
|
||||
.can_manage_voice_chats(false)
|
||||
.can_delete_messages(false)
|
||||
.can_edit_messages(false)
|
||||
.can_post_messages(false)
|
||||
.can_manage_chat(false)
|
||||
.is_anonymous(false),
|
||||
)
|
||||
.await
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
use telers::{errors::SessionErrorKind, methods::get_chat_administrators, types::ChatMember, Bot};
|
||||
|
||||
pub async fn get_all_admins(bot: &Bot, chat_id: i64) -> Result<Vec<ChatMember>, SessionErrorKind> {
|
||||
bot.send(get_chat_administrators::GetChatAdministrators::new(chat_id))
|
||||
.await
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
pub mod admin_check;
|
||||
pub mod ban_member;
|
||||
pub mod demote;
|
||||
pub mod get_all_admins;
|
||||
pub mod restrict;
|
||||
pub mod try_do_action;
|
|
@ -0,0 +1,32 @@
|
|||
use chrono::NaiveDateTime;
|
||||
use telers::{errors::session::ErrorKind, methods::*, types::ChatPermissions, Bot};
|
||||
|
||||
pub async fn restrict(
|
||||
bot: &Bot,
|
||||
user_id: i64,
|
||||
duration: NaiveDateTime,
|
||||
chat_id: i64,
|
||||
) -> Result<bool, ErrorKind> {
|
||||
bot.send(
|
||||
restrict_chat_member::RestrictChatMember::new(
|
||||
chat_id,
|
||||
user_id,
|
||||
ChatPermissions::new()
|
||||
.can_send_photos(false)
|
||||
.can_send_polls(false)
|
||||
.can_send_audios(false)
|
||||
.can_send_videos(false)
|
||||
.can_change_info(false)
|
||||
.can_invite_users(false)
|
||||
.can_send_other_messages(false)
|
||||
.can_pin_messages(false)
|
||||
.can_send_messages(false)
|
||||
.can_send_voice_notes(false)
|
||||
.can_send_video_notes(false)
|
||||
.can_send_documents(false)
|
||||
.can_manage_topics(false),
|
||||
)
|
||||
.until_date(duration.and_utc().timestamp()),
|
||||
)
|
||||
.await
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
use telers::{errors::SessionErrorKind as ErrorKind, event::EventReturn, Bot};
|
||||
|
||||
use crate::types::structs::message_sender::MessageSender;
|
||||
use std::future::Future;
|
||||
|
||||
use super::demote::demote_user;
|
||||
|
||||
const DEMOTE_FAILURE_MESSAGE: &str = "\
|
||||
Нельзя выдать ограничение пользователю, т.к. невозможно демотнуть \
|
||||
участника посредством бота, если ему выдан админ при помощи других \
|
||||
админов или владельца чата.";
|
||||
|
||||
pub async fn try_restrict<F, R>(
|
||||
future_callback: F,
|
||||
demote_args: (&Bot, i64, i64),
|
||||
failure_sender: MessageSender,
|
||||
) -> Result<(), EventReturn>
|
||||
where
|
||||
R: Future<Output = Result<bool, ErrorKind>>,
|
||||
F: Copy + Fn() -> R,
|
||||
{
|
||||
let (bot, user_id, chat_id): (&Bot, i64, i64) = demote_args;
|
||||
|
||||
if future_callback().await.is_err() {
|
||||
if demote_user(bot, user_id, chat_id).await.is_err() {
|
||||
MessageSender::new(chat_id)
|
||||
.text(DEMOTE_FAILURE_MESSAGE)
|
||||
.send(bot)
|
||||
.await
|
||||
.unwrap();
|
||||
return Err(EventReturn::Cancel);
|
||||
}
|
||||
|
||||
if future_callback().await.is_err() {
|
||||
failure_sender.send(bot).await.unwrap();
|
||||
return Err(EventReturn::Cancel);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue