randydev commited on
Commit
2242e9d
β€’
1 Parent(s): 711e3ec

Upload join_request.py

Browse files
Files changed (1) hide show
  1. chatbot/plugins/join_request.py +180 -0
chatbot/plugins/join_request.py ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import json
4
+ import asyncio
5
+ import io
6
+ import os
7
+ import re
8
+ import logging
9
+ import string
10
+ import random
11
+ from pyrogram import *
12
+ from pyrogram.types import *
13
+ from pyrogram.errors import *
14
+ from database import db
15
+ from logger import LOGS
16
+
17
+ from pyrogram import Client, filters
18
+ from pyrogram.enums import ChatMemberStatus, ChatMembersFilter, ChatType
19
+ from pyrogram.types import (
20
+ CallbackQuery,
21
+ InlineKeyboardMarkup,
22
+ InlineKeyboardButton,
23
+ Message
24
+ )
25
+
26
+ from PIL import Image, ImageDraw, ImageFont
27
+
28
+ logging.basicConfig(level=logging.INFO)
29
+ logger = logging.getLogger(__name__)
30
+
31
+ user_list = []
32
+ captcha_texts = {}
33
+
34
+ async def remove_captcha_after_timeout(client, user_id, delay=300):
35
+ await asyncio.sleep(delay)
36
+ if user_id in captcha_texts:
37
+ del captcha_texts[user_id]
38
+ await client.send_message(user_id, "⏰ Your CAPTCHA verification has expired. Please try again by sending /getapikey.")
39
+ logger.info(f"CAPTCHA for user {user_id} has expired and been removed.")
40
+
41
+ def generate_captcha_multiple_choice():
42
+ letters = string.ascii_uppercase + string.digits
43
+ captcha_text = ''.join(random.choice(letters) for _ in range(5))
44
+ choices = [captcha_text]
45
+ for _ in range(2):
46
+ wrong_choice = ''.join(random.choice(letters) for _ in range(5))
47
+ while wrong_choice in choices:
48
+ wrong_choice = ''.join(random.choice(letters) for _ in range(5))
49
+ choices.append(wrong_choice)
50
+ random.shuffle(choices)
51
+ img = Image.new('RGB', (300, 60), color=(255, 255, 255))
52
+ d = ImageDraw.Draw(img)
53
+ try:
54
+ font = ImageFont.truetype("arial.ttf", 40)
55
+ except IOError:
56
+ font = ImageFont.load_default()
57
+ d.text((10, 10), captcha_text, font=font, fill=(0, 0, 0))
58
+ img_path = f"captcha_{captcha_text}.png"
59
+ img.save(img_path)
60
+ return captcha_text, img_path, choices
61
+
62
+ @Client.on_chat_join_request(filters.chat("KillerXSupport"))
63
+ async def join_request(client: Client, event: ChatJoinRequest):
64
+ member = await client.get_chat_member(event.chat.id, "me")
65
+ if member.status != ChatMemberStatus.ADMINISTRATOR:
66
+ return await client.send_message(event.chat.id, text="I am not an administrator in this group.")
67
+ async for m in client.get_chat_members(event.chat.id, filter=ChatMembersFilter.ADMINISTRATORS):
68
+ if not m.user.is_bot:
69
+ user_list.append(m.user.id)
70
+ captcha_text, img_path, choices = generate_captcha_multiple_choice()
71
+ captcha_texts[user_id] = captcha_text
72
+ captcha_texts["chat_id"] = event.chat.id
73
+ keyboard = InlineKeyboardMarkup(
74
+ [
75
+ [InlineKeyboardButton(choice, callback_data=f"verify_{user_id}_{choice}")]
76
+ for choice in choices
77
+ ] + [
78
+ [InlineKeyboardButton("πŸ”„ Refresh CAPTCHA", callback_data="refresh_captcha")],
79
+ [InlineKeyboardButton("❌ Cancel", callback_data="cancel_captcha")]
80
+ ]
81
+ )
82
+ if event.chat.type == ChatType.SUPERGROUP:
83
+ try:
84
+ await client.send_photo(
85
+ event.from_user.id,
86
+ photo=img_path,
87
+ caption=f"❗️ **Verify that you are human!**\n\n❔ Please enter the CAPTCHA text below the image.",
88
+ reply_markup=keyboard
89
+ )
90
+ os.remove(img_path)
91
+ asyncio.create_task(remove_captcha_after_timeout(client, user_id))
92
+ except Exception as e:
93
+ await client.send_message(
94
+ event.chat.id,
95
+ text=str(e)
96
+ )
97
+ logger.error(str(e))
98
+
99
+ @Client.on_callback_query(filters.regex("^cancel_captcha$"))
100
+ async def cancel_captcha_callback(client: Client, cb: CallbackQuery):
101
+ user_id = cb.from_user.id
102
+ if user_id in captcha_texts:
103
+ del captcha_texts[user_id]
104
+ logger.info(f"User {user_id} has canceled CAPTCHA verification.")
105
+ await cb.edit_message_text(
106
+ "❌ CAPTCHA verification has been canceled. If you wish to try again,",
107
+ disable_web_page_preview=True
108
+ )
109
+ await cb.answer("CAPTCHA verification canceled.", show_alert=False)
110
+ else:
111
+ await cb.answer("No active CAPTCHA verification found.", show_alert=True)
112
+
113
+ @Client.on_callback_query(filters.regex("^refresh_captcha$"))
114
+ async def refresh_captcha_callback(client: Client, cb: CallbackQuery):
115
+ user_id = cb.from_user.id
116
+ if user_id in captcha_texts:
117
+ del captcha_texts[user_id]
118
+ captcha_text, img_path, choices = generate_captcha_multiple_choice()
119
+ captcha_texts[user_id] = captcha_text
120
+ keyboard = InlineKeyboardMarkup(
121
+ [
122
+ [InlineKeyboardButton("πŸ”„ Refresh CAPTCHA", callback_data="refresh_captcha")],
123
+ [InlineKeyboardButton("βœ… Verify", callback_data="verify_captcha")],
124
+ [InlineKeyboardButton("❌ Cancel", callback_data="cancel_captcha")]
125
+ ]
126
+ )
127
+ await cb.edit_message_media(
128
+ media=InputMediaPhoto(img_path),
129
+ reply_markup=keyboard
130
+ )
131
+ os.remove(img_path)
132
+ await cb.answer("CAPTCHA refreshed!", show_alert=False)
133
+
134
+ @Client.on_callback_query(filters.regex("^verify_"))
135
+ async def verify_captcha_multiple_choice_callback(client: Client, cb: CallbackQuery):
136
+ data = cb.data.split("_")
137
+ if len(data) != 3:
138
+ await cb.answer("Invalid data format.", show_alert=True)
139
+ return
140
+ _, user_id_str, user_choice = data
141
+ try:
142
+ user_id = int(user_id_str)
143
+ except ValueError:
144
+ await cb.answer("Invalid user ID.", show_alert=True)
145
+ return
146
+ if user_id not in captcha_texts:
147
+ await cb.answer("❗️ Please start the CAPTCHA verification first.", show_alert=True)
148
+ logger.warning(f"User {user_id} attempted to verify CAPTCHA without starting verification.")
149
+ return
150
+ correct_captcha = captcha_texts.get(user_id)
151
+ logger.info(f"User {user_id} selected CAPTCHA: {user_choice} (Expected: {correct_captcha})")
152
+ if user_choice == correct_captcha:
153
+ await cb.edit_message_text("βœ… CAPTCHA verification successful!)
154
+ logger.info(f"User {user_id} successfully verified CAPTCHA.")
155
+ await client.approve_chat_join_request(
156
+ chat_id=captcha_texts.get("chat_id"),
157
+ user_id=user_id
158
+ )
159
+ del captcha_texts[user_id]
160
+ del captcha_texts["chat_id"]
161
+ else:
162
+ await cb.edit_message_text("❌ Incorrect CAPTCHA. Please try again")
163
+ logger.info(f"User {user_id} failed CAPTCHA verification.")
164
+ await client.decline_chat_join_request(
165
+ chat_id=captcha_texts.get("chat_id"),
166
+ user_id=user_id
167
+ )
168
+ del captcha_texts[user_id]
169
+ del captcha_texts["chat_id"]
170
+
171
+ @Client.on_callback_query(filters.regex("^verify_captcha$"))
172
+ async def verify_captcha_callback(client: Client, cb: CallbackQuery):
173
+ user_id = cb.from_user.id
174
+ if user_id not in captcha_texts:
175
+ await cb.answer("❗️ Please start the CAPTCHA verification first", show_alert=True)
176
+ logger.warning(f"User {user_id} attempted to verify CAPTCHA without starting verification.")
177
+ return
178
+ await cb.message.reply_text("πŸ” **Please enter the CAPTCHA text exactly as shown in the image:**")
179
+ await cb.answer()
180
+ logger.info(f"User {user_id} is attempting to verify CAPTCHA.")