diff --git a/src/bot/bot.rs b/src/bot/bot.rs index 24d32e8..d5c8214 100644 --- a/src/bot/bot.rs +++ b/src/bot/bot.rs @@ -1,4 +1,6 @@ use anyhow; +use rust_i18n::t; +use teloxide::types::UpdateKind; use std::env; use std::fmt; use std::str; @@ -7,14 +9,13 @@ use std::time::Duration; use teloxide::dispatching::{dialogue, dialogue::InMemStorage, UpdateHandler}; use teloxide::{prelude::*, update_listeners::Polling, utils::command::BotCommands}; use tracing::{event, Level}; -use rust_i18n::t; use super::types::*; use crate::db::DbPool; -use super::start::cmd_start; use super::dl::cmd_download; use super::op::cmd_op; +use super::start::{cmd_start, handle_my_chat_member}; fn parse_env(name: &str) -> T where @@ -67,6 +68,16 @@ fn schema() -> UpdateHandler { dialogue::enter::, (), _>() .branch(message_handler) .branch(raw_message_handler) + .endpoint(handle_update) +} + +async fn handle_update(_bot: Bot, upd: Update, db: DbPool) -> HandlerResult { + match upd.kind { + UpdateKind::MyChatMember(upd) => handle_my_chat_member(db, upd).await, + _ => event!(Level::WARN, "unhandled update {:?}", upd) + } + + Ok(()) } #[derive(BotCommands, Clone)] diff --git a/src/bot/op.rs b/src/bot/op.rs index d837f23..a580b6a 100644 --- a/src/bot/op.rs +++ b/src/bot/op.rs @@ -1,7 +1,7 @@ +use rust_i18n::t; use sqlx::Row; use teloxide::prelude::*; use tracing::{event, Level}; -use rust_i18n::t; use super::types::HandlerResult; use crate::db::user::{create_user, find_or_create_user}; @@ -37,12 +37,10 @@ pub async fn cmd_op(bot: Bot, msg: Message, db: DbPool) -> HandlerResult { event!(Level::INFO, "opped {}", target); bot.send_message(msg.chat.id, "opped").await?; } else { - bot.send_message(msg.chat.id, t!("has_to_reply")) - .await?; + bot.send_message(msg.chat.id, t!("has_to_reply")).await?; } } else { - bot.send_message(msg.chat.id, t!("cant_do_that")) - .await?; + bot.send_message(msg.chat.id, t!("cant_do_that")).await?; } } } diff --git a/src/bot/start.rs b/src/bot/start.rs index da99af8..0fc3a72 100644 --- a/src/bot/start.rs +++ b/src/bot/start.rs @@ -1,9 +1,10 @@ +use rust_i18n::t; use teloxide::prelude::*; use tracing::{event, Level}; -use rust_i18n::t; use super::types::HandlerResult; use crate::db::user::find_or_create_user; +use crate::db::chat::find_or_create_chat; use crate::db::DbPool; pub async fn cmd_start(bot: Bot, msg: Message, db: DbPool) -> HandlerResult { @@ -15,9 +16,21 @@ pub async fn cmd_start(bot: Bot, msg: Message, db: DbPool) -> HandlerResult { .execute(&db) .await?; - event!(Level::INFO, "user {} has started private chat with bot", user); - bot.send_message(msg.chat.id, t!("started_private_chat")).await?; + event!( + Level::INFO, + "user {} has started private chat with bot", + user + ); + bot.send_message(msg.chat.id, t!("started_private_chat")) + .await?; } } Ok(()) } + +pub async fn handle_my_chat_member(db: DbPool, upd: ChatMemberUpdated) { + match find_or_create_chat(&db, &upd.chat).await { + Ok(chat) => event!(Level::INFO, "started public chat {}", chat), + Err(e) => event!(Level::ERROR, "{}", e) + } +} \ No newline at end of file diff --git a/src/db.rs b/src/db.rs index a916382..9fbd3e4 100644 --- a/src/db.rs +++ b/src/db.rs @@ -41,6 +41,18 @@ pub struct Chat { pub can_download: i64, } +impl fmt::Display for Chat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} - {}", self.tg_id, self.username_or_title()) + } +} + +impl Chat { + pub fn username_or_title(&self) -> &String { + self.username.as_ref().unwrap_or(&self.title) + } +} + pub mod chat; #[derive(sqlx::FromRow)] diff --git a/src/db/chat.rs b/src/db/chat.rs new file mode 100644 index 0000000..9b710f0 --- /dev/null +++ b/src/db/chat.rs @@ -0,0 +1,31 @@ +use teloxide::types; + +use super::{Chat, DbPool}; +use crate::unwrap_or_create; + +pub async fn create_chat(db: &DbPool, chat: &types::Chat) -> Result { + sqlx::query( + "INSERT INTO chat (tg_id,title,username,can_download) + VALUES ($1,$2,$3,$4)", + ) + .bind(chat.id.0 as i64) + .bind(chat.title()) + .bind(chat.username()) + .bind(0) + .execute(db) + .await?; + + let chat: Chat = sqlx::query_as("SELECT * FROM chat WHERE tg_id = $1 LIMIT 1;") + .bind(chat.id.0 as i64) + .fetch_one(db).await?; + Ok(chat) +} + +pub async fn find_or_create_chat(db: &DbPool, chat: &types::Chat) -> Result { + let res: Result = sqlx::query_as( + "SELECT * FROM chat WHERE tg_id = $1 LIMIT 1;") + .bind(chat.id.0 as i64) + .fetch_one(db).await; + + unwrap_or_create!(db, chat, res, create_chat) +} \ No newline at end of file