From 43bf90ebcc4f93b5a70e8b0dc76013850ae9fac9 Mon Sep 17 00:00:00 2001 From: Dmitry Anderson <4nd3r5z0n@gmail.com> Date: Thu, 24 Oct 2024 15:19:25 +0200 Subject: [PATCH] User leaving/joining proper handling --- bot/normal_mode/init.ts | 76 +++++++++++++++++++++---------- bot/normal_mode/user_managment.ts | 11 +++++ 2 files changed, 63 insertions(+), 24 deletions(-) diff --git a/bot/normal_mode/init.ts b/bot/normal_mode/init.ts index 7eeb0e7..99d370b 100644 --- a/bot/normal_mode/init.ts +++ b/bot/normal_mode/init.ts @@ -3,48 +3,53 @@ import { Kysely } from 'npm:kysely'; import { Ctx } from "../ctx.ts"; import { CompiledConfig } from "../../cfg/config.ts"; import { Database } from "../../repo/exports.ts"; -import { checkUser, checkUserOnNewChatMember } from "./user_managment.ts"; +import { checkUser, checkUserOnNewChatMember, onMemberLeftChat } from "./user_managment.ts"; import { checkCaptchaSolution, initUserCaptcha } from "./captcha.ts"; import { checkUserOnStart } from "./user_managment.ts"; +import { ChatMember } from "https://deno.land/x/grammy_types@v3.14.0/manage.ts"; + +interface ChatMemberUpdateStatus { + joined: boolean, + left: boolean, + kicked: boolean, + restricted: boolean, + roleChanged: boolean +} + +function getChatMemberUpdateStatus(oldMember: ChatMember, newMember: ChatMember): ChatMemberUpdateStatus { + return { + joined: oldMember.status === "left" && + newMember.status !== "left" && newMember.status !== "kicked", + left: oldMember.status !== "left" && newMember.status === "left", + kicked: newMember.status === "kicked", + restricted: oldMember.status !== "restricted" && newMember.status === "restricted", + roleChanged: oldMember.status !== newMember.status && + (newMember.status !== "left" && newMember.status !== "kicked") + }; +} export const init = (bot: Bot, db: Kysely, cfg: CompiledConfig) => { console.log(`initializing normal mode`) const { botCfg } = cfg - bot.on('message', ctx => { - if (ctx.from.is_bot) return - checkUser(ctx, db, botCfg) + bot.on('message', async (ctx, next) => { + if (ctx.from?.is_bot) return + console.log(`Chat ID: ${ctx.msg.chat.id} From: ${ctx.from.id} Message: ${ctx.msg.text}`) + await next() }) - - bot.on('chat_member', async ctx => { - if (ctx.chatMember.from.is_bot || ctx.chat.id !== botCfg.chat_id) return - await checkUserOnNewChatMember(ctx, db, botCfg) - // TODO: - // const userInfo = await checkUserOnNewChatMember(ctx, db, botCfg) - //if (userInfo.isNewUser) { /* Some hello message? */ } - }) - - - bot.on('message:text', async ctx => { - console.log(`From: ${ctx.from.id} Message: ${ctx.msg.text}`) - if (ctx.from.is_bot || ctx.hasCommand('start')) return - + bot.on('message:text', async (ctx, next) => { if (ctx.chat.id === botCfg.chat_id) { await checkUser(ctx, db, botCfg, true) } else if (ctx.message.chat.type == "private" && ctx.session.captcha_data) { await checkCaptchaSolution(ctx, db, botCfg) + } else { + await next() } }) - bot.command('start', async ctx => { - if (!ctx.from || ctx.from.is_bot) return - if (ctx.chat.type !== 'private') return - - console.log(`Start called by ${ctx.from.id}`) - const userInfo = await checkUserOnStart(ctx, db) if (userInfo.isBlocked || userInfo.isTimeout) return @@ -53,4 +58,27 @@ export const init = (bot: Bot, db: Kysely, cfg: CompiledConfig) = await initUserCaptcha(ctx, db, userInfo, botCfg) } }) + + bot.on('chat_member', async (ctx, next) => { + if (ctx.from.is_bot) return + if (ctx.chat.id !== botCfg.chat_id) return + const chatMemberUpdateStatus = getChatMemberUpdateStatus( + ctx.chatMember.old_chat_member, ctx.chatMember.new_chat_member + ) + + if (chatMemberUpdateStatus.joined) { + console.log(`New Chat member ${ctx.chatMember.from.id}:'+ + '${ctx.from.first_name} ${ctx.from.last_name}`) + await checkUserOnNewChatMember(ctx, db, botCfg) + // TODO: + // const userInfo = await checkUserOnNewChatMember(ctx, db, botCfg) + //if (userInfo.isNewUser) { /* Some hello message? */ } + } else if (chatMemberUpdateStatus.left) { + console.log(`Chat member left ${ctx.chatMember.from.id}:'+ + '${ctx.from.first_name} ${ctx.from.last_name}`) + await onMemberLeftChat(ctx, db) + // TODO: /* POBEG S DURKI! */ + } + await next() + }) } \ No newline at end of file diff --git a/bot/normal_mode/user_managment.ts b/bot/normal_mode/user_managment.ts index 18ecdbe..d545887 100644 --- a/bot/normal_mode/user_managment.ts +++ b/bot/normal_mode/user_managment.ts @@ -182,3 +182,14 @@ export const checkUserOnStart = async ( isCaptchaSolved } } + + +export const onMemberLeftChat = async ( + ctx: Filter, + db: Kysely, +) => { + await db.updateTable('users') + .where('tg_id', '=', ctx.chatMember.from.id).set({ + is_chat_participant: false + }).execute() +} \ No newline at end of file