implement my chat member update handler so bot will know when added to chat or channel and will add record to database

This commit is contained in:
mykola2312 2024-03-03 16:58:17 +02:00
parent d0ea664ad3
commit 3dfbb6fd6e
5 changed files with 75 additions and 10 deletions

View file

@ -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<T>(name: &str) -> T
where
@ -67,6 +68,16 @@ fn schema() -> UpdateHandler<HandlerErr> {
dialogue::enter::<Update, InMemStorage<()>, (), _>()
.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)]

View file

@ -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?;
}
}
}

View file

@ -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)
}
}

View file

@ -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)]

31
src/db/chat.rs Normal file
View file

@ -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<Chat, sqlx::Error> {
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<Chat, sqlx::Error> {
let res: Result<Chat, sqlx::Error> = 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)
}