Add register functions

This commit is contained in:
2023-01-17 20:36:11 +01:00
parent 4eb42a4405
commit c7d115f9ce
8 changed files with 216 additions and 4 deletions

View File

@@ -10,13 +10,13 @@ use self::{
modules::{ modules::{
annotations::get_annotations_handler, book::get_book_handler, annotations::get_annotations_handler, book::get_book_handler,
download::get_download_hander, help::get_help_handler, random::get_random_hander, download::get_download_hander, help::get_help_handler, random::get_random_hander,
search::get_search_hanlder, settings::get_settings_handler, support::get_support_handler, search::get_search_handler, settings::get_settings_handler, support::get_support_handler,
update_history::get_update_log_handler, update_history::get_update_log_handler,
}, },
services::user_settings::{get_user_or_default_lang_codes, update_user_activity}, services::user_settings::{get_user_or_default_lang_codes, update_user_activity},
}; };
use super::{ignore_channel_messages, BotCommands, BotHandler}; use super::{ignore_channel_messages, BotCommands, BotHandler, bots_manager::get_manager_handler};
async fn _update_activity(me: teloxide::types::Me, user: teloxide::types::User) -> Option<()> { async fn _update_activity(me: teloxide::types::Me, user: teloxide::types::User) -> Option<()> {
tokio::spawn(async move { tokio::spawn(async move {
@@ -78,7 +78,8 @@ pub fn get_approved_handler() -> (BotHandler, BotCommands) {
.branch(get_annotations_handler()) .branch(get_annotations_handler())
.branch(get_book_handler()) .branch(get_book_handler())
.branch(get_update_log_handler()) .branch(get_update_log_handler())
.branch(get_search_hanlder()), .branch(get_manager_handler())
.branch(get_search_handler()),
Some(vec![ Some(vec![
BotCommand { BotCommand {
command: String::from("random"), command: String::from("random"),

View File

@@ -261,7 +261,7 @@ pub async fn message_handler(message: Message, bot: AutoSend<Bot>) -> BotHandler
} }
} }
pub fn get_search_hanlder() -> crate::bots::BotHandler { pub fn get_search_handler() -> crate::bots::BotHandler {
dptree::entry().branch( dptree::entry().branch(
Update::filter_message() Update::filter_message()
.endpoint(|message, bot| async move { message_handler(message, bot).await }), .endpoint(|message, bot| async move { message_handler(message, bot).await }),

View File

@@ -0,0 +1,59 @@
use teloxide::prelude::*;
use std::error::Error;
use self::{strings::format_registered_message, utils::get_token};
use crate::config;
pub mod register;
pub mod strings;
pub mod utils;
pub async fn message_handler(
message: Message,
bot: AutoSend<Bot>,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let from_user = message.from().unwrap();
let text = message.text().unwrap_or("");
let result = register::register(from_user.id, text).await;
let message_text = match result {
register::RegisterStatus::Success { ref username } => format_registered_message(&username),
register::RegisterStatus::NoToken => strings::HELP_MESSAGE.to_string(),
register::RegisterStatus::WrongToken => strings::ERROR_MESSAGE.to_string(),
register::RegisterStatus::RegisterFail => strings::ALREADY_REGISTERED.to_string(),
};
#[allow(unused_must_use)]
{
bot.send_message(message.chat.id, message_text)
.reply_to_message_id(message.id)
.await;
}
if let register::RegisterStatus::Success { .. } = result {
#[allow(unused_must_use)]
{
bot.send_message(
config::CONFIG.admin_id.clone(),
strings::BOT_REGISTERED_TO_ADMIN,
)
.await;
}
}
return Ok(());
}
pub fn get_manager_handler() -> Handler<
'static,
dptree::di::DependencyMap,
Result<(), Box<dyn Error + Send + Sync>>,
teloxide::dispatching::DpHandlerDescription,
> {
Update::filter_message().branch(
Message::filter_text()
.chain(dptree::filter(|message: Message| { get_token(message.text().unwrap()).is_some() })).endpoint(message_handler),
)
}

View File

@@ -0,0 +1,76 @@
use std::collections::HashMap;
use teloxide::prelude::*;
use crate::config;
#[derive(Debug)]
pub enum RegisterStatus {
Success {username: String},
NoToken,
WrongToken,
RegisterFail,
}
async fn get_bot_username(token: &str) -> Option<String> {
match Bot::new(token).get_me().send().await {
Ok(v) => v.username.clone(),
Err(_) => None
}
}
async fn make_register_request(user_id: UserId, username: &str, token: &str) -> Result<(), ()> {
let user_id = &user_id.to_string();
let data = HashMap::from([
("token", token),
("user", user_id),
("username", username),
("status", "pending"),
("cache", "no_cache")
]);
let client = reqwest::Client::new();
let response = client
.post(config::CONFIG.manager_url.clone())
.header("Authorization", config::CONFIG.manager_api_key.clone())
.json(&data)
.send()
.await;
let status_code = match response {
Ok(v) => v.status(),
Err(_) => return Err(()),
};
log::debug!("make_register_request status_code={}", status_code);
if status_code != 200 {
return Err(());
}
Ok(())
}
pub async fn register(user_id: UserId, message_text: &str) -> RegisterStatus {
let token = match super::utils::get_token(message_text) {
Some(v) => v,
None => return RegisterStatus::NoToken
};
let bot_username = match get_bot_username(token).await {
Some(v) => v,
None => return RegisterStatus::WrongToken
};
let register_request_status = make_register_request(user_id, &bot_username, token).await;
if register_request_status.is_err() {
return RegisterStatus::RegisterFail;
}
return RegisterStatus::Success { username: bot_username };
}

View File

@@ -0,0 +1,15 @@
pub const HELP_MESSAGE: &str = "
Зарегистрируй бота в @BotFather .
И перешли сюда сообщение об успешной регистрации.
(Начинается с: Done! Congratulations on your new bot.)
";
pub fn format_registered_message(username: &str) -> String {
return format!("@{username} зарегистрирован и через несколько минут будет подключен!", username = username);
}
pub const ALREADY_REGISTERED: &str= "Ошибка! Возможно бот уже зарегистрирован!";
pub const ERROR_MESSAGE: &str = "Ошибка! Что-то не так с ботом!";
pub const BOT_REGISTERED_TO_ADMIN: &str = "Новый бот зарегистрирован!";

View File

@@ -0,0 +1,56 @@
use regex::Regex;
pub fn get_token(message_text: &str) -> Option<&str> {
let re = Regex::new("(?P<token>[0-9]+:[0-9a-zA-Z-_]+)").unwrap();
match re.find(message_text) {
Some(v) => Some(v.as_str()),
None => None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn check_token_fail() {
let message = "wrong_token";
let result = get_token(message);
assert!(result.is_none())
}
#[test]
fn check_token_short() {
let message = "
Done! Congratulations on your new bot. You will find it at t.me/aaaa_bot.
You can now add a description, about section and profile picture for your bot,
see /help for a list of commands.
By the way, when you've finished creating your cool bot, ping our Bot Support if you want a better username for it.
Just make sure the bot is fully operational before you do this. \
\
Use this token to access the HTTP API: \
5555555555:AAF-AAAAAAAA1239AA2AAsvy13Axp23RAa \
Keep your token secure and store it safely, it can be used by anyone to control your bot. \
\
For a description of the Bot API, see this page: https://core.telegram.org/bots/api \
";
let result = get_token(message);
assert_eq!(result.unwrap(), "5555555555:AAF-AAAAAAAA1239AA2AAsvy13Axp23RAa");
}
#[test]
fn check_token_long() {
let message = "5555555555:AAF-AAAAAAAA1239AA2AAsvy13Axp23RAa";
let result = get_token(message);
assert_eq!(result.unwrap(), message);
}
}

View File

@@ -1,4 +1,5 @@
mod approved_bot; mod approved_bot;
pub mod bots_manager;
use std::error::Error; use std::error::Error;

View File

@@ -3,6 +3,8 @@ pub struct Config {
pub webhook_base_url: String, pub webhook_base_url: String,
pub admin_id: String,
pub bot_token: String,
pub manager_url: String, pub manager_url: String,
pub manager_api_key: String, pub manager_api_key: String,
@@ -32,6 +34,8 @@ impl Config {
webhook_base_url: get_env("WEBHOOK_BASE_URL"), webhook_base_url: get_env("WEBHOOK_BASE_URL"),
admin_id: get_env("ADMIN_ID"),
bot_token: get_env("BOT_TOKEN"),
manager_url: get_env("MANAGER_URL"), manager_url: get_env("MANAGER_URL"),
manager_api_key: get_env("MANAGER_API_KEY"), manager_api_key: get_env("MANAGER_API_KEY"),