"""入群验证 handler""" import asyncio import logging from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup from telegram.ext import ContextTypes, CallbackQueryHandler, MessageHandler, filters import config from services.message_utils import record_bot_message from db.models import Action from services.verify_service import create_verify, check_answer, get_pending_verify logger = logging.getLogger("spam_guard") async def handle_verify_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): """处理验证按钮回调""" query = update.callback_query await query.answer() user = query.from_user data = query.data if data == "start_verify": result = await get_pending_verify(user.id) if not result: result = await create_verify(user.id, user.username) await query.edit_message_text( f"✅ 验证问题:\n\n{result['question']}\n\n" f"请直接回复你的答案(文字消息)" ) context.user_data["verifying"] = True context.user_data["verify_user_id"] = user.id if query.message: asyncio.create_task(auto_delete(query.message)) elif data == "verify_help": await query.edit_message_text( "💡 验证帮助\n\n" "请直接在群内发送你的答案文字消息。\n" f"你有 {config.VERIFY_MAX_ATTEMPTS} 次机会" ) if query.message: asyncio.create_task(auto_delete(query.message)) async def handle_verify_answer(update: Update, context: ContextTypes.DEFAULT_TYPE): """处理验证回答。用户答案不删,只焚毁 Bot 回复。""" if not context.user_data.get("verifying"): return user_id = context.user_data.get("verify_user_id", update.effective_user.id) answer = update.message.text.strip() result = await check_answer(user_id, answer) asyncio.create_task(auto_delete(update.message, seconds=60)) if result["ok"]: context.user_data["verifying"] = False try: from telegram import ChatPermissions await update.effective_chat.restrict_member( user_id=user_id, permissions=ChatPermissions( can_send_messages=True, can_send_audios=True, can_send_documents=True, can_send_photos=True, can_send_videos=True, can_send_video_notes=True, can_send_voice_notes=True, can_send_polls=True, can_send_other_messages=True, can_add_web_page_previews=True, can_invite_users=True, ), ) except Exception as e: logger.error(f"⚠️ 恢复权限失败: {e}") reply = await update.message.reply_text("🎉 验证通过!欢迎加入群组!") await record_bot_message(reply) asyncio.create_task(auto_delete(reply)) await Action.create(action="VERIFY_PASS", chat_id=update.effective_chat.id, user_id=user_id, username=update.effective_user.username) logger.info(f"✅ 验证通过: {user_id}") return if result["reason"] == "max_attempts": context.user_data["verifying"] = False reply = await update.message.reply_text("❌ 验证失败次数过多,你将被移出群组") await record_bot_message(reply) asyncio.create_task(auto_delete(reply)) try: await update.effective_chat.ban_member(user_id=user_id) await asyncio.sleep(5) await update.effective_chat.unban_member(user_id=user_id) except Exception: pass await Action.create(action="VERIFY_FAIL", chat_id=update.effective_chat.id, user_id=user_id, username=update.effective_user.username) else: reply = await update.message.reply_text(f"❌ 答案错误,剩余 {config.VERIFY_MAX_ATTEMPTS - result.get('attempts', 0)} 次机会") await record_bot_message(reply) asyncio.create_task(auto_delete(reply)) async def auto_delete(message, seconds=60): try: await asyncio.sleep(seconds) await message.delete() except Exception: pass def register_verify(app): app.add_handler(CallbackQueryHandler(handle_verify_callback, pattern=r"^(start_verify|verify_help)$")) app.add_handler(MessageHandler(filters.TEXT & filters.ChatType.GROUPS & ~filters.COMMAND, handle_verify_answer), group=1)