Refactoring, minor fixes in karma handler (multiple messages)
This commit is contained in:
		
							
								
								
									
										7
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -157,6 +157,12 @@ dependencies = [
 | 
			
		||||
 "syn",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[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"
 | 
			
		||||
@ -347,6 +353,7 @@ dependencies = [
 | 
			
		||||
name = "godette"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "dotenv",
 | 
			
		||||
 "lazy_static",
 | 
			
		||||
 "log",
 | 
			
		||||
 "pretty_env_logger",
 | 
			
		||||
 | 
			
		||||
@ -12,3 +12,4 @@ pretty_env_logger = "0.4"
 | 
			
		||||
tokio = { version =  "1.8", features = ["rt-multi-thread", "macros"] }
 | 
			
		||||
lazy_static = "1.4.0"
 | 
			
		||||
url = "2.3.1"
 | 
			
		||||
dotenv = "0.15.0"
 | 
			
		||||
							
								
								
									
										122
									
								
								src/godette.rs
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								src/godette.rs
									
									
									
									
									
								
							@ -1,17 +1,18 @@
 | 
			
		||||
use teloxide::{
 | 
			
		||||
    prelude::*,
 | 
			
		||||
    types::{InlineKeyboardButton, InlineKeyboardMarkup},
 | 
			
		||||
};
 | 
			
		||||
use teloxide::{dispatching::DpHandlerDescription, prelude::*, RequestError};
 | 
			
		||||
 | 
			
		||||
pub mod commands;
 | 
			
		||||
mod dispatchers;
 | 
			
		||||
mod handlers;
 | 
			
		||||
mod utils;
 | 
			
		||||
use commands::{AdminCommand, Command};
 | 
			
		||||
use url::Url;
 | 
			
		||||
 | 
			
		||||
use utils::get_text_or_empty;
 | 
			
		||||
pub struct Godette {
 | 
			
		||||
    pub bot: Bot,
 | 
			
		||||
    pub triggers: Vec<Trigger>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Trigger {
 | 
			
		||||
    pub words: Vec<String>,
 | 
			
		||||
    pub callback: fn(&Bot, &Message) -> ResponseResult<()>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct KarmaTrigger {
 | 
			
		||||
@ -31,87 +32,36 @@ impl Godette {
 | 
			
		||||
    pub fn new() -> Godette {
 | 
			
		||||
        Godette {
 | 
			
		||||
            bot: Bot::from_env(),
 | 
			
		||||
            triggers: vec![],
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn commands_dispatcher(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> {
 | 
			
		||||
        match cmd {
 | 
			
		||||
            Command::Help => handlers::show_help(bot, msg).await?,
 | 
			
		||||
            Command::Me(quote) => handlers::me(bot, msg, quote).await?,
 | 
			
		||||
        };
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn admin_dispatcher(bot: Bot, msg: Message, cmd: AdminCommand) -> ResponseResult<()> {
 | 
			
		||||
        let mut is_admin = true;
 | 
			
		||||
        if msg.chat.is_group() || msg.chat.is_supergroup() {
 | 
			
		||||
            let sender = msg.from().unwrap();
 | 
			
		||||
            let admins = bot.get_chat_administrators(msg.chat.id).await?;
 | 
			
		||||
            is_admin = admins.iter().any(|member| member.user.id == sender.id);
 | 
			
		||||
        }
 | 
			
		||||
        if !is_admin {
 | 
			
		||||
            return Ok(());
 | 
			
		||||
        }
 | 
			
		||||
        match cmd {
 | 
			
		||||
            AdminCommand::HelpAdmin => handlers::show_adminhelp(bot, msg).await?,
 | 
			
		||||
            AdminCommand::Say(quote) => handlers::say(bot, msg, quote).await?,
 | 
			
		||||
            AdminCommand::Warn(reason) => handlers::warn(bot, msg, reason).await?,
 | 
			
		||||
            AdminCommand::Unwarn => handlers::unwarn(bot, msg).await?,
 | 
			
		||||
        };
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn message_dispatcher(bot: Bot, msg: Message) -> ResponseResult<()> {
 | 
			
		||||
        // Checking if it's a reply
 | 
			
		||||
        let reply = msg.reply_to_message();
 | 
			
		||||
        match reply {
 | 
			
		||||
            Some(reply) => {
 | 
			
		||||
                Godette::reply_dispatcher(bot.clone(), msg.clone(), reply.to_owned()).await?
 | 
			
		||||
            }
 | 
			
		||||
            None => (),
 | 
			
		||||
        };
 | 
			
		||||
        let text = utils::get_text_or_empty(&msg).to_lowercase();
 | 
			
		||||
        match text.find("оффтоп") {
 | 
			
		||||
            Some(_) => {
 | 
			
		||||
                bot.send_message(msg.chat.id, "Вот вам ссылка на оффтоп")
 | 
			
		||||
                    .reply_to_message_id(msg.id)
 | 
			
		||||
                    .reply_markup(Godette::make_offtop_keyboard())
 | 
			
		||||
                    .await?;
 | 
			
		||||
            }
 | 
			
		||||
            None => (),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn reply_dispatcher(bot: Bot, msg: Message, reply: Message) -> ResponseResult<()> {
 | 
			
		||||
        let triggers = vec![
 | 
			
		||||
            KarmaTrigger::new("спс", 1),
 | 
			
		||||
            KarmaTrigger::new("спасибо", 1),
 | 
			
		||||
            KarmaTrigger::new("+", 1),
 | 
			
		||||
            KarmaTrigger::new("благодарю", 1),
 | 
			
		||||
            KarmaTrigger::new("пасиб", 1),
 | 
			
		||||
            KarmaTrigger::new("-", -1),
 | 
			
		||||
            KarmaTrigger::new("👍", 1),
 | 
			
		||||
            KarmaTrigger::new("👎", -1),
 | 
			
		||||
        ];
 | 
			
		||||
        let text = get_text_or_empty(&msg);
 | 
			
		||||
        println!("{:?}", text);
 | 
			
		||||
        for trigger in triggers {
 | 
			
		||||
            match text.to_lowercase().find(&trigger.text) {
 | 
			
		||||
                Some(_id) => {
 | 
			
		||||
                    println!("It's a thanks!");
 | 
			
		||||
                    return handlers::karma(&bot, &msg, &reply, trigger.value).await;
 | 
			
		||||
                }
 | 
			
		||||
                None => (),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn make_offtop_keyboard() -> InlineKeyboardMarkup {
 | 
			
		||||
        let link = Url::parse("https://t.me/Godot_Engine_Offtop").unwrap();
 | 
			
		||||
        let button = InlineKeyboardButton::url("Godot Engine оффтоп чат".to_owned(), link);
 | 
			
		||||
        return InlineKeyboardMarkup::new(vec![[button]]);
 | 
			
		||||
    pub fn create_handler(
 | 
			
		||||
        &self,
 | 
			
		||||
    ) -> Handler<'static, DependencyMap, Result<(), RequestError>, DpHandlerDescription> {
 | 
			
		||||
        Update::filter_message()
 | 
			
		||||
            // User commands
 | 
			
		||||
            .branch(
 | 
			
		||||
                dptree::entry()
 | 
			
		||||
                    .filter_command::<commands::Command>()
 | 
			
		||||
                    .endpoint(Godette::commands_dispatcher),
 | 
			
		||||
            )
 | 
			
		||||
            // Admin commands
 | 
			
		||||
            .branch(
 | 
			
		||||
                dptree::entry()
 | 
			
		||||
                    .filter_command::<commands::AdminCommand>()
 | 
			
		||||
                    .endpoint(Godette::admin_dispatcher),
 | 
			
		||||
            )
 | 
			
		||||
            // Replies
 | 
			
		||||
            // .branch(Message::filter_reply_to_message().endpoint(Godette::reply_dispatcher))
 | 
			
		||||
            // Messages
 | 
			
		||||
            .branch(
 | 
			
		||||
                dptree::filter(|msg: Message| {
 | 
			
		||||
                    msg.from()
 | 
			
		||||
                        .map(|user| user.id == UserId(60441930))
 | 
			
		||||
                        .unwrap_or_default()
 | 
			
		||||
                })
 | 
			
		||||
                .endpoint(Godette::message_dispatcher),
 | 
			
		||||
            )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										58
									
								
								src/godette/dispatchers.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/godette/dispatchers.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
			
		||||
use teloxide::prelude::*;
 | 
			
		||||
 | 
			
		||||
use super::{handlers, utils, Godette, KarmaTrigger, Trigger};
 | 
			
		||||
use crate::commands::{AdminCommand, Command};
 | 
			
		||||
 | 
			
		||||
impl Godette {
 | 
			
		||||
    pub async fn commands_dispatcher(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> {
 | 
			
		||||
        match cmd {
 | 
			
		||||
            Command::Help => handlers::show_help(bot, msg).await?,
 | 
			
		||||
            Command::Me(quote) => handlers::me(bot, msg, quote).await?,
 | 
			
		||||
        };
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn admin_dispatcher(bot: Bot, msg: Message, cmd: AdminCommand) -> ResponseResult<()> {
 | 
			
		||||
        let mut is_admin = true;
 | 
			
		||||
        if msg.chat.is_group() || msg.chat.is_supergroup() {
 | 
			
		||||
            let sender = msg.from().unwrap();
 | 
			
		||||
            let admins = bot.get_chat_administrators(msg.chat.id).await?;
 | 
			
		||||
            is_admin = admins.iter().any(|member| member.user.id == sender.id);
 | 
			
		||||
        }
 | 
			
		||||
        if !is_admin {
 | 
			
		||||
            return Ok(());
 | 
			
		||||
        }
 | 
			
		||||
        match cmd {
 | 
			
		||||
            AdminCommand::HelpAdmin => handlers::show_adminhelp(bot, msg).await?,
 | 
			
		||||
            AdminCommand::Say(quote) => handlers::say(bot, msg, quote).await?,
 | 
			
		||||
            AdminCommand::Warn(reason) => handlers::warn(bot, msg, reason).await?,
 | 
			
		||||
            AdminCommand::Unwarn => handlers::unwarn(bot, msg).await?,
 | 
			
		||||
        };
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn message_dispatcher(bot: Bot, msg: Message) -> ResponseResult<()> {
 | 
			
		||||
        // Checking if it's a reply and send it to Reply dispatcher
 | 
			
		||||
        let reply = msg.reply_to_message();
 | 
			
		||||
        match reply {
 | 
			
		||||
            Some(reply) => {
 | 
			
		||||
                Godette::reply_dispatcher(bot.clone(), msg.clone(), reply.to_owned()).await?
 | 
			
		||||
            }
 | 
			
		||||
            None => (),
 | 
			
		||||
        };
 | 
			
		||||
        let text = utils::get_text_or_empty(&msg).to_lowercase();
 | 
			
		||||
        match text.find("оффтоп") {
 | 
			
		||||
            Some(_) => handlers::offtop(&bot, &msg).await?,
 | 
			
		||||
            None => (),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn reply_dispatcher(bot: Bot, msg: Message, reply: Message) -> ResponseResult<()> {
 | 
			
		||||
        let text = utils::get_text_or_empty(&msg);
 | 
			
		||||
        handlers::karma(&bot, &msg, &reply, &text).await?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -8,6 +8,8 @@ use teloxide::{
 | 
			
		||||
 | 
			
		||||
use crate::commands::{AdminCommand, Command};
 | 
			
		||||
 | 
			
		||||
use super::{utils, KarmaTrigger};
 | 
			
		||||
 | 
			
		||||
pub async fn show_help(bot: Bot, msg: Message) -> ResponseResult<Message> {
 | 
			
		||||
    bot.send_message(msg.chat.id, Command::descriptions().to_string())
 | 
			
		||||
        .await
 | 
			
		||||
@ -67,22 +69,48 @@ pub async fn unwarn(bot: Bot, msg: Message) -> ResponseResult<Message> {
 | 
			
		||||
        .await
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn karma(bot: &Bot, msg: &Message, reply: &Message, change: i8) -> ResponseResult<()> {
 | 
			
		||||
    let giver = msg.from().unwrap();
 | 
			
		||||
    let reciever = reply.from().unwrap();
 | 
			
		||||
    let change_text = match change {
 | 
			
		||||
        1 => "повысил",
 | 
			
		||||
        -1 => "понизил",
 | 
			
		||||
        _ => "изменил",
 | 
			
		||||
    };
 | 
			
		||||
    let text = format!(
 | 
			
		||||
        "*{}* {} карму *{}*",
 | 
			
		||||
        escape(&giver.first_name),
 | 
			
		||||
        change_text,
 | 
			
		||||
        escape(&reciever.first_name)
 | 
			
		||||
    );
 | 
			
		||||
    bot.send_message(msg.chat.id, text)
 | 
			
		||||
        .parse_mode(MarkdownV2)
 | 
			
		||||
pub async fn karma(bot: &Bot, msg: &Message, reply: &Message, text: &String) -> ResponseResult<()> {
 | 
			
		||||
    let triggers = vec![
 | 
			
		||||
        KarmaTrigger::new("спс", 1),
 | 
			
		||||
        KarmaTrigger::new("спасибо", 1),
 | 
			
		||||
        KarmaTrigger::new("+", 1),
 | 
			
		||||
        KarmaTrigger::new("благодарю", 1),
 | 
			
		||||
        KarmaTrigger::new("пасиб", 1),
 | 
			
		||||
        KarmaTrigger::new("-", -1),
 | 
			
		||||
        KarmaTrigger::new("👍", 1),
 | 
			
		||||
        KarmaTrigger::new("👎", -1),
 | 
			
		||||
    ];
 | 
			
		||||
    for trigger in triggers {
 | 
			
		||||
        match text.to_lowercase().find(&trigger.text) {
 | 
			
		||||
            Some(_id) => {
 | 
			
		||||
                let giver = msg.from().unwrap();
 | 
			
		||||
                let reciever = reply.from().unwrap();
 | 
			
		||||
                let change_text = match trigger.value {
 | 
			
		||||
                    1 => "повысил",
 | 
			
		||||
                    -1 => "понизил",
 | 
			
		||||
                    _ => "изменил",
 | 
			
		||||
                };
 | 
			
		||||
                let text = format!(
 | 
			
		||||
                    "*{}* {} карму *{}*",
 | 
			
		||||
                    escape(&giver.first_name),
 | 
			
		||||
                    change_text,
 | 
			
		||||
                    escape(&reciever.first_name)
 | 
			
		||||
                );
 | 
			
		||||
                bot.send_message(msg.chat.id, text)
 | 
			
		||||
                    .parse_mode(MarkdownV2)
 | 
			
		||||
                    .await?;
 | 
			
		||||
                return Ok(());
 | 
			
		||||
            }
 | 
			
		||||
            None => (),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn offtop(bot: &Bot, msg: &Message) -> ResponseResult<()> {
 | 
			
		||||
    bot.send_message(msg.chat.id, "Вот вам ссылка на оффтоп")
 | 
			
		||||
        .reply_to_message_id(msg.id)
 | 
			
		||||
        .reply_markup(utils::make_offtop_keyboard())
 | 
			
		||||
        .await?;
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,14 @@
 | 
			
		||||
use teloxide::types::Message;
 | 
			
		||||
use teloxide::types::{InlineKeyboardButton, InlineKeyboardMarkup, Message};
 | 
			
		||||
use url::Url;
 | 
			
		||||
 | 
			
		||||
pub fn get_text_or_empty(msg: &Message) -> String {
 | 
			
		||||
    msg.text()
 | 
			
		||||
        .unwrap_or(msg.caption().unwrap_or(""))
 | 
			
		||||
        .to_string()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn make_offtop_keyboard() -> InlineKeyboardMarkup {
 | 
			
		||||
    let link = Url::parse("https://t.me/Godot_Engine_Offtop").unwrap();
 | 
			
		||||
    let button = InlineKeyboardButton::url("Godot Engine оффтоп чат".to_owned(), link);
 | 
			
		||||
    return InlineKeyboardMarkup::new(vec![[button]]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/main.rs
									
									
									
									
									
								
							@ -5,35 +5,15 @@ use teloxide::prelude::*;
 | 
			
		||||
use godette::commands;
 | 
			
		||||
use godette::Godette;
 | 
			
		||||
 | 
			
		||||
use dotenv::dotenv;
 | 
			
		||||
 | 
			
		||||
#[tokio::main]
 | 
			
		||||
async fn main() {
 | 
			
		||||
    dotenv().ok();
 | 
			
		||||
    pretty_env_logger::init();
 | 
			
		||||
 | 
			
		||||
    let bot = Godette::new();
 | 
			
		||||
    let handler = Update::filter_message()
 | 
			
		||||
        // User commands
 | 
			
		||||
        .branch(
 | 
			
		||||
            dptree::entry()
 | 
			
		||||
                .filter_command::<commands::Command>()
 | 
			
		||||
                .endpoint(Godette::commands_dispatcher),
 | 
			
		||||
        )
 | 
			
		||||
        // Admin commands
 | 
			
		||||
        .branch(
 | 
			
		||||
            dptree::entry()
 | 
			
		||||
                .filter_command::<commands::AdminCommand>()
 | 
			
		||||
                .endpoint(Godette::admin_dispatcher),
 | 
			
		||||
        )
 | 
			
		||||
        // Replies
 | 
			
		||||
        // .branch(Message::filter_reply_to_message().endpoint(Godette::reply_dispatcher))
 | 
			
		||||
        // Messages
 | 
			
		||||
        .branch(
 | 
			
		||||
            dptree::filter(|msg: Message| {
 | 
			
		||||
                msg.from()
 | 
			
		||||
                    .map(|user| user.id == UserId(60441930))
 | 
			
		||||
                    .unwrap_or_default()
 | 
			
		||||
            })
 | 
			
		||||
            .endpoint(Godette::message_dispatcher),
 | 
			
		||||
        );
 | 
			
		||||
    let handler = bot.create_handler();
 | 
			
		||||
    Dispatcher::builder(bot.bot, handler)
 | 
			
		||||
        .default_handler(|upd| async move {
 | 
			
		||||
            log::warn!("Unhandled update: {:?}", upd);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user