Explorar el Código

Рефакторинг роутинга сообщений и добавление инструкций

colon1al hace 4 meses
padre
commit
64f7e1c262

+ 4 - 0
deploy.zsh

@@ -0,0 +1,4 @@
+cd target
+tar -acf release.tar.gz release
+scp release.tar.gz colon1al.ru:/home/colonial/coffeesheetbot/release.tar.gz
+ssh colon1al.ru

+ 10 - 0
migration/src/db_enums.rs

@@ -34,3 +34,13 @@ pub enum ItemsPrices {
     UserCreatedId,
     TimeCreated,
 }
+
+#[derive(DeriveIden)]
+pub enum KeyValueStorage {
+    Table,
+    Id,
+    Key,
+    Value,
+    Active,
+}
+

+ 5 - 1
migration/src/lib.rs

@@ -1,12 +1,16 @@
 pub use sea_orm_migration::prelude::*;
 
 mod m20220101_000001_create_table;
+mod m20250621_101738_key_value_storage;
 pub mod db_enums;
 pub struct Migrator;
 
 #[async_trait::async_trait]
 impl MigratorTrait for Migrator {
     fn migrations() -> Vec<Box<dyn MigrationTrait>> {
-        vec![Box::new(m20220101_000001_create_table::Migration)]
+        vec![
+            Box::new(m20220101_000001_create_table::Migration),
+            Box::new(m20250621_101738_key_value_storage::Migration),
+        ]
     }
 }

+ 30 - 0
migration/src/m20250621_101738_key_value_storage.rs

@@ -0,0 +1,30 @@
+use sea_orm_migration::{prelude::*, schema::*};
+
+use crate::db_enums::KeyValueStorage;
+
+#[derive(DeriveMigrationName)]
+pub struct Migration;
+
+#[async_trait::async_trait]
+impl MigrationTrait for Migration {
+    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
+        // Replace the sample below with your own migration scripts
+
+        manager.create_table(
+            Table::create()
+                .table(KeyValueStorage::Table)
+                .if_not_exists()
+                .col(pk_auto(KeyValueStorage::Id).big_integer())
+                .col(text_uniq(KeyValueStorage::Key))
+                .col(text(KeyValueStorage::Value))
+                .to_owned()
+        )
+        .await
+    }
+
+    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
+        // Replace the sample below with your own migration scripts
+        manager.drop_table(Table::drop().table(KeyValueStorage::Table).to_owned())
+        .await
+    }
+}

+ 99 - 26
msg_handler/src/lib.rs

@@ -1,5 +1,8 @@
 use telegram_bot::{telegram_types::{TelegramMessage}, TelegramBot};
-use orm::{db_func::{create_new_item_price, create_new_user, get_user_by_chat_id, set_chat_id_by_token}, users};
+use orm::{db_func::{
+    create_new_item_price, create_new_user, get_user_by_chat_id, set_chat_id_by_token, get_from_key_value,
+
+}, users};
 use sea_orm::{DatabaseConnection, DbErr};
 use regex::Regex;
 use log::{warn, error, debug};
@@ -14,6 +17,26 @@ enum AuthResult {
     Fail
 }
 
+enum MsgType {
+    Start,
+    Register,
+    ItemPrice,
+    Undefined
+}
+
+fn msg_router(msg: &TelegramMessage) -> MsgType{
+    let regex_message = Regex::new(
+        r"token:(?P<token>[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12})"
+    ).unwrap();
+    let msg_text = msg.text.as_str();
+    match msg_text {
+        msg_text if msg_text == "/start" => MsgType::Start,
+        msg_text if regex_message.is_match(msg_text) => MsgType::Register,
+        msg_text if msg_text.split('!').count() > 1 => MsgType::ItemPrice,
+        _ => MsgType::Undefined,
+    }
+
+}
 
 
 pub async fn handle_message(
@@ -21,40 +44,90 @@ pub async fn handle_message(
     gs_hub: &Sheets<hyper_rustls::HttpsConnector<hyper_util::client::legacy::connect::HttpConnector>>,
     sheet_id: &str
 ) {
-    let auth_res = match check_authentication(msg, db).await {
-        Ok(res) => res,
-        Err(err) => {
-            error!("DATABASE ERROR {err}");
-            AuthResult::Fail
-        }
-    };
-    match auth_res {
-        AuthResult::Register => {
+    let usr = get_user_by_chat_id(db, msg.chat.id).await.unwrap_or(None);
+
+    match msg_router(msg) {
+        MsgType::Start => {
+            let mut key = "start_msg";
+            if usr.is_some() {
+                key = "guide_msg"
+            }
+
+            let text =match get_from_key_value(db, key).await {
+                Ok(val) => val,
+                Err(err) => {
+                    error!("Error getting from key_value {err}");
+                    String::from("Произошла ошибка обратитесь к администратору MH_HM_GKV")
+                }
+            };
             match tg_bot.send_message(
                 msg.chat.id,
-                format!("Успешная авторизация {}", msg.chat.username).as_str(),
+                text.as_str(),
                 None
-            ).await { Ok(_) => (), Err(_) => ()}
+            ).await {
+                Ok(_) => (),
+                Err(err) => {
+                    error!("Telegram api unavaliable or request is broken {err}");
+                }
+            };
+        }
+        MsgType::Register => {
+            let reg_res = match register(msg, db).await {
+                Ok(val) => val,
+                Err(err) => {
+                    error!("Error registering {err}");
+                    AuthResult::Fail
+                }
+            };
+            match reg_res {
+                AuthResult::Register => {
+                    let text =match get_from_key_value(db, "guide_msg").await {
+                        Ok(val) => val,
+                        Err(err) => {
+                            error!("Error getting from key_value {err}");
+                            String::from("Произошла ошибка обратитесь к администратору MH_RG_GKV")
+                        }
+                    };
+
+                    match tg_bot.send_message(
+                        msg.chat.id,
+                        format!("Успешная авторизация {}", msg.chat.username).as_str(),
+                        None
+                    ).await { Ok(_) => (), Err(err) => error!("Error sending msg {err}")};
+
+                    match tg_bot.send_message(
+                        msg.chat.id,
+                        text.as_str(),
+                        None
+                    ).await { Ok(_) => (), Err(err) => error!("Error sending msg {err}")}
+                },
+                _ => warn!("Error registering {}", msg.text)
+            };
         },
-        AuthResult::Success => {
-            match handle_item_price(msg, tg_bot, db, gs_hub, sheet_id).await {
-                Ok(range) => match range {
-                    Some(range) => {
-                        match tg_bot.send_message(
-                            msg.chat.id,
-                            format!("Добавлена строка {range}, {}", msg.text).as_str(),
-                            None
-                        ).await { Ok(_) => (), Err(_) => ()}
-                    }, None => ()
+        MsgType::ItemPrice => {
+            match usr {
+                Some(_user) => {
+                    match handle_item_price(msg, tg_bot, db, gs_hub, sheet_id).await {
+                        Ok(range) => match range {
+                            Some(range) => {
+                                match tg_bot.send_message(
+                                    msg.chat.id,
+                                    format!("Добавлена строка {range}, {}", msg.text).as_str(),
+                                    None
+                                ).await { Ok(_) => (), Err(err) => error!("Error sending msg {err}")}
+                            }, None => ()
+                        },
+                        Err(_) => ()
+                    }
                 },
-                Err(_) => ()
+                None => ()
             }
         }
-        AuthResult::Fail => return
-    };
+        MsgType::Undefined => {},
+    }
 }
 
-async fn check_authentication(
+async fn register(
     msg: &TelegramMessage, db: &DatabaseConnection
 ) -> Result<AuthResult, DbErr> {
     let regex_message = Regex::new(

+ 16 - 2
orm/src/db_func.rs

@@ -1,6 +1,6 @@
 use sea_orm::{sea_query::{Expr}, DatabaseConnection, DbErr, *};
 use super::{prelude::*, *};
-use log::debug;
+use log::{debug, kv::Key};
 
 pub async fn get_user_by_chat_id(
     db: &DatabaseConnection, chat_id: i64
@@ -8,7 +8,8 @@ pub async fn get_user_by_chat_id(
     let q = Users::find()
         .join(JoinType::InnerJoin, users::Relation::UserTokens.def())
         .filter(user_tokens::Column::ChatId.eq(chat_id))
-        .filter(users::Column::TimeDeleted.is_null());
+        .filter(users::Column::TimeDeleted.is_null())
+        .filter(user_tokens::Column::TimeDeleted.is_null());
     let user = match q.one(db).await? {
         Some(usr) => usr,
         None => return Ok(None)
@@ -78,4 +79,17 @@ pub async fn create_new_item_price(
     };
     item_price.insert(db).await?;
     Ok(())
+}
+
+
+pub async fn get_from_key_value(
+    db: &DatabaseConnection,
+    key: &str
+) -> Result<String, DbErr> {
+    match KeyValueStorage::find().filter(key_value_storage::Column::Key.eq(key)).one(db).await? {
+        Some(val) => return Ok(val.value),
+        None => {
+            return Err(DbErr::RecordNotFound(format!("by key {}", key)))
+        }
+    }
 }

+ 19 - 0
orm/src/key_value_storage.rs

@@ -0,0 +1,19 @@
+//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
+
+use sea_orm::entity::prelude::*;
+
+#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
+#[sea_orm(table_name = "key_value_storage")]
+pub struct Model {
+    #[sea_orm(primary_key)]
+    pub id: i64,
+    #[sea_orm(column_type = "Text", unique)]
+    pub key: String,
+    #[sea_orm(column_type = "Text")]
+    pub value: String,
+}
+
+#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
+pub enum Relation {}
+
+impl ActiveModelBehavior for ActiveModel {}

+ 2 - 0
orm/src/lib.rs

@@ -3,6 +3,8 @@
 pub mod prelude;
 
 pub mod items_prices;
+pub mod key_value_storage;
 pub mod user_tokens;
 pub mod users;
+
 pub mod db_func;

+ 1 - 0
orm/src/prelude.rs

@@ -1,5 +1,6 @@
 //! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.11
 
 pub use super::items_prices::Entity as ItemsPrices;
+pub use super::key_value_storage::Entity as KeyValueStorage;
 pub use super::user_tokens::Entity as UserTokens;
 pub use super::users::Entity as Users;