Skip to content

Commit

Permalink
index based off (chat_id, user_id)
Browse files Browse the repository at this point in the history
  • Loading branch information
m1guelpf committed Nov 15, 2023
1 parent 12c4386 commit fdd3a34
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 29 deletions.
28 changes: 16 additions & 12 deletions src/bot/join_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::Arc;

use teloxide::{
prelude::*,
types::{ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup, MessageId, User},
types::{ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup, User},
utils::html::escape,
};

Expand Down Expand Up @@ -46,7 +46,7 @@ pub async fn join_handler(
"Verify with World ID",
config
.app_url
.join(&format!("verify/{}/{}", msg.chat.id, msg.id))?,
.join(&format!("verify/{}/{}", msg.chat.id, user.id))?,
);

let msg_id = bot
Expand All @@ -57,23 +57,25 @@ pub async fn join_handler(
.await?
.id;

join_requests.insert((msg.chat.id, msg_id), JoinRequest::new(user.id));
join_requests.insert((msg.chat.id, user.id), JoinRequest::new(msg_id));

tokio::spawn({
let bot = bot.clone();
let ban_after = chat_cfg.ban_after;
async move {
tokio::time::sleep(ban_after).await;

if let Some((_, data)) = join_requests.remove(&(msg.chat.id, msg_id)) {
if let Some((_, data)) = join_requests.remove(&(msg.chat.id, user.id)) {
if !data.is_verified {
bot.ban_chat_member(msg.chat.id, data.user_id)
bot.ban_chat_member(msg.chat.id, user.id)
.await
.expect("Failed to ban the member after timeout");

bot.delete_message(msg.chat.id, msg_id)
.await
.expect("Failed to delete the message after timeout");
if let Some(msg_id) = data.msg_id {
bot.delete_message(msg.chat.id, msg_id)
.await
.expect("Failed to delete the message after timeout");
}
}
}
}
Expand All @@ -86,11 +88,11 @@ pub async fn join_handler(
pub async fn on_verified(
bot: Bot,
chat_id: ChatId,
msg_id: MessageId,
user_id: UserId,
join_requests: JoinRequests,
) -> HandlerResult {
let mut join_req = join_requests
.get_mut(&(chat_id, msg_id))
.get_mut(&(chat_id, user_id))
.ok_or("Can't find the message id in group dialogue")?;

let Some(permissions) = bot.get_chat(chat_id).await?.permissions() else {
Expand All @@ -99,10 +101,12 @@ pub async fn on_verified(

join_req.is_verified = true;

bot.restrict_chat_member(chat_id, join_req.user_id, permissions)
bot.restrict_chat_member(chat_id, user_id, permissions)
.await?;

bot.delete_message(chat_id, msg_id).await?;
if let Some(msg_id) = join_req.msg_id.take() {
bot.delete_message(chat_id, msg_id).await?;
}

Ok(())
}
8 changes: 4 additions & 4 deletions src/bot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ mod commands;
mod join_check;

type HandlerResult = Result<(), HandlerError>;
pub type JoinRequests = Arc<DashMap<(ChatId, MessageId), JoinRequest>>;
pub type JoinRequests = Arc<DashMap<(ChatId, UserId), JoinRequest>>;
type HandlerError = Box<dyn std::error::Error + Send + Sync>;

#[derive(Clone)]
pub struct JoinRequest {
pub user_id: UserId,
pub is_verified: bool,
pub msg_id: Option<MessageId>,
}

impl JoinRequest {
fn new(user_id: UserId) -> Self {
pub fn new(msg_id: MessageId) -> Self {
Self {
user_id,
is_verified: false,
msg_id: Some(msg_id),
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ use dotenvy::dotenv;
use std::sync::Arc;
use teloxide::{
requests::Requester,
types::{ChatId, MessageId},
types::{ChatId, UserId},
Bot,
};

use crate::{bot::JoinRequest, config::AppConfig};
use crate::{
bot::{JoinRequest, JoinRequests},
config::AppConfig,
};

mod bot;
mod config;
Expand All @@ -19,7 +22,7 @@ async fn main() {
pretty_env_logger::init();

let config = AppConfig::try_read().expect("Failed to read config");
let join_requests = Arc::new(DashMap::<(ChatId, MessageId), JoinRequest>::new());
let join_requests: JoinRequests = Arc::new(DashMap::<(ChatId, UserId), JoinRequest>::new());

let bot = Bot::new(&config.bot_token);
let bot_data = bot.get_me().await.expect("Failed to get bot account");
Expand Down
20 changes: 10 additions & 10 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use indoc::formatdoc;
use serde_json::json;
use std::net::SocketAddr;
use teloxide::{
types::{ChatId, MessageId, User},
types::{ChatId, User, UserId},
Bot,
};
use tokio::signal;
Expand Down Expand Up @@ -47,12 +47,13 @@ pub async fn start(bot: Bot, config: AppConfig, bot_data: User, join_requests: J

async fn verify_page(
Extension(config): Extension<AppConfig>,
Path((chat_id, msg_id)): Path<(ChatId, i32)>,
Path((chat_id, user_id)): Path<(ChatId, UserId)>,
Extension(join_reqs): Extension<JoinRequests>,
) -> Result<Html<String>, StatusCode> {
if !join_reqs.contains_key(&(chat_id, MessageId(msg_id))) {
return Err(StatusCode::NOT_FOUND);
}
let join_req = join_reqs
.get(&(chat_id, user_id))
.ok_or(StatusCode::NOT_FOUND)?;
let msg_id = join_req.msg_id.ok_or(StatusCode::CONFLICT)?;

let page = formatdoc! {"<!DOCTYPE html>
<html lang=\"en\">
Expand Down Expand Up @@ -102,15 +103,14 @@ struct VerifyRequest {
async fn verify_api(
Extension(bot): Extension<Bot>,
Extension(config): Extension<AppConfig>,
Path((chat_id, msg_id)): Path<(ChatId, i32)>,
Path((chat_id, user_id)): Path<(ChatId, UserId)>,
Extension(join_reqs): Extension<JoinRequests>,
Json(req): Json<VerifyRequest>,
) -> Result<&'static str, StatusCode> {
let msg_id = MessageId(msg_id);

let join_req = join_reqs
.get(&(chat_id, msg_id))
.get(&(chat_id, user_id))
.ok_or(StatusCode::NOT_FOUND)?;
let msg_id = join_req.msg_id.ok_or(StatusCode::CONFLICT)?;

reqwest::Client::new()
.post(format!(
Expand All @@ -133,7 +133,7 @@ async fn verify_api(

drop(join_req);

on_verified(bot, chat_id, msg_id, join_reqs)
on_verified(bot, chat_id, user_id, join_reqs)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

Expand Down

0 comments on commit fdd3a34

Please sign in to comment.