Bladeren bron

Auto accept chat join requests (tested) (#220)

* Update requirements.txt

* Create autoapprove.py

* #Added welcome message

* Using adminsOnly decorator to detect admins

* Update autoapprove.py

* #Added welcome message when captcha is disabled for chat

* #Added captcha verification for newly accepted members

* Redundant returns

* Format

---------

Co-authored-by: Akshay Rajput <thehamkercat@gmail.com>
SI_NN_ER_LS 3 jaren geleden
bovenliggende
commit
d2cceb54a9
3 gewijzigde bestanden met toevoegingen van 202 en 90 verwijderingen
  1. 2 2
      requirements.txt
  2. 105 0
      wbb/modules/autoapprove.py
  3. 95 88
      wbb/modules/greetings.py

+ 2 - 2
requirements.txt

@@ -2,7 +2,7 @@ aiohttp
 aiofiles
 ffmpeg-python
 gTTS
-dnspython
+dnspython==2.1.0
 future
 googletrans==4.0.0-rc1
 motor
@@ -25,4 +25,4 @@ fuzzysearch
 img2pdf
 telegraph
 pytube
-pytz
+pytz

+ 105 - 0
wbb/modules/autoapprove.py

@@ -0,0 +1,105 @@
+from pyrogram import filters
+from pyrogram.types import (
+    CallbackQuery,
+    Chat,
+    ChatJoinRequest,
+    InlineKeyboardButton,
+    InlineKeyboardMarkup,
+    Message,
+)
+from wbb import SUDOERS, app, db
+from wbb.core.decorators.permissions import adminsOnly
+from wbb.modules.admin import member_permissions
+from wbb.modules.greetings import handle_new_member
+
+approvaldb = db.autoapprove
+
+# For /help menu
+__MODULE__ = "Autoapprove"
+__HELP__ = """
+command: /autoapprove
+
+This module helps to automatically accept chat join request send by a user through invitation link of your group"""
+
+
+@app.on_message(filters.command("autoapprove") & filters.group)
+@adminsOnly("can_change_info")
+async def approval_command(client, message):
+    chat_id = message.chat.id
+    if (await approvaldb.count_documents({"chat_id": chat_id})) > 0:
+        keyboard_OFF = InlineKeyboardMarkup(
+            [[InlineKeyboardButton("Turn OFF", callback_data="approval_off")]]
+        )
+        await message.reply(
+            "**Autoapproval for this chat: Enabled.**",
+            reply_markup=keyboard_OFF,
+        )
+    else:
+        keyboard_ON = InlineKeyboardMarkup(
+            [[InlineKeyboardButton("Turn ON", callback_data="approval_on")]]
+        )
+        await message.reply(
+            "**Autoapproval for this chat: Disabled.**",
+            reply_markup=keyboard_ON,
+        )
+
+
+@app.on_callback_query(filters.regex("approval(.*)"))
+async def approval_cb(client, cb):
+    chat_id = cb.message.chat.id
+    from_user = cb.from_user
+
+    permissions = await member_permissions(chat_id, from_user.id)
+    permission = "can_restrict_members"
+    if permission not in permissions:
+        if from_user.id not in SUDOERS:
+            return await cb.answer(
+                f"You don't have the required permission.\n Permission: {permission}",
+                show_alert=True,
+            )
+
+    command_parts = cb.data.split("_", 1)
+    option = command_parts[1]
+
+    if option == "on":
+        if await approvaldb.count_documents({"chat_id": chat_id}) == 0:
+            approvaldb.insert_one({"chat_id": chat_id})
+            keyboard_off = InlineKeyboardMarkup(
+                [
+                    [
+                        InlineKeyboardButton(
+                            "Turn OFF", callback_data="approval_off"
+                        )
+                    ]
+                ]
+            )
+            await cb.edit_message_text(
+                "**Autoapproval for this chat: Enabled.**",
+                reply_markup=keyboard_off,
+            )
+    elif option == "off":
+        if await approvaldb.count_documents({"chat_id": chat_id}) > 0:
+            approvaldb.delete_one({"chat_id": chat_id})
+            keyboard_on = InlineKeyboardMarkup(
+                [
+                    [
+                        InlineKeyboardButton(
+                            "Turn ON", callback_data="approval_on"
+                        )
+                    ]
+                ]
+            )
+            await cb.edit_message_text(
+                "**Autoapproval for this chat: Disabled.**",
+                reply_markup=keyboard_on,
+            )
+    return await cb.answer()
+
+
+@app.on_chat_join_request(filters.group)
+async def accept(client, message: ChatJoinRequest):
+    chat = message.chat
+    user = message.from_user
+    if (await approvaldb.count_documents({"chat_id": chat.id})) > 0:
+        await app.approve_chat_join_request(chat_id=chat.id, user_id=user.id)
+        await handle_new_member(message, user, chat)

+ 95 - 88
wbb/modules/greetings.py

@@ -107,9 +107,7 @@ async def get_initial_captcha_cache():
 loop.create_task(get_initial_captcha_cache())
 
 
-@app.on_message(filters.new_chat_members, group=welcome_captcha_group)
-@capture_err
-async def welcome(_, message: Message):
+async def handle_new_member(message: Message, member, chat):
     global answers_dicc
 
     # Get cached answers from mongodb in case of bot's been restarted or crashed.
@@ -117,102 +115,111 @@ async def welcome(_, message: Message):
 
     # Mute new member and send message with button
     if not await is_captcha_on(message.chat.id):
+        await send_welcome_message(message.chat, member.id)
         return
 
-    for member in message.new_chat_members:
-        try:
-            if member.id in SUDOERS:
-                continue  # ignore sudo users
-
-            if await is_gbanned_user(member.id):
-                await message.chat.ban_member(member.id)
-                await message.reply_text(
-                    f"{member.mention} was globally banned, and got removed,"
-                    + " if you think this is a false gban, you can appeal"
-                    + " for this ban in support chat."
-                )
-                continue
-
-            if member.is_bot:
-                continue  # ignore bots
-
-            # Ignore user if he has already solved captcha in this group
-            # someday
-            if await has_solved_captcha_once(message.chat.id, member.id):
-                continue
-
-            await message.chat.restrict_member(member.id, ChatPermissions())
-            text = (
-                f"{(member.mention())} Are you human?\n"
-                f"Solve this captcha in {WELCOME_DELAY_KICK_SEC} "
-                "seconds and 4 attempts or you'll be kicked."
+    try:
+        if member.id in SUDOERS:
+            return  # Ignore sudo users
+
+        if await is_gbanned_user(member.id):
+            await message.chat.ban_member(member.id)
+            await app.send_message(
+                chat.id,
+                f"{member.mention} was globally banned, and got removed,"
+                + " if you think this is a false gban, you can appeal"
+                + " for this ban in support chat."
             )
-        except ChatAdminRequired:
             return
-        # Generate a captcha image, answers and some wrong answers
-        captcha = generate_captcha()
-        captcha_image = captcha[0]
-        captcha_answer = captcha[1]
-        wrong_answers = captcha[2]  # This consists of 8 wrong answers
-        correct_button = InlineKeyboardButton(
-            f"{captcha_answer}",
-            callback_data=f"pressed_button {captcha_answer} {member.id}",
+
+        if member.is_bot:
+            return  # Ignore bots
+
+        # Ignore user if he has already solved captcha in this group
+        # someday
+        if await has_solved_captcha_once(message.chat.id, member.id):
+            return
+
+        await message.chat.restrict_member(member.id, ChatPermissions())
+        text = (
+            f"{(member.mention())} Are you human?\n"
+            f"Solve this captcha in {WELCOME_DELAY_KICK_SEC} "
+            "seconds and 4 attempts or you'll be kicked."
         )
-        temp_keyboard_1 = [correct_button]  # Button row 1
-        temp_keyboard_2 = []  # Botton row 2
-        temp_keyboard_3 = []
-        for i in range(2):
-            temp_keyboard_1.append(
-                InlineKeyboardButton(
-                    f"{wrong_answers[i]}",
-                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
-                )
+    except ChatAdminRequired:
+        return
+
+    # Generate a captcha image, answers, and some wrong answers
+    captcha = generate_captcha()
+    captcha_image = captcha[0]
+    captcha_answer = captcha[1]
+    wrong_answers = captcha[2]  # This consists of 8 wrong answers
+    correct_button = InlineKeyboardButton(
+        f"{captcha_answer}",
+        callback_data=f"pressed_button {captcha_answer} {member.id}",
+    )
+    temp_keyboard_1 = [correct_button]  # Button row 1
+    temp_keyboard_2 = []  # Botton row 2
+    temp_keyboard_3 = []
+    for i in range(2):
+        temp_keyboard_1.append(
+            InlineKeyboardButton(
+                f"{wrong_answers[i]}",
+                callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
             )
-        for i in range(2, 5):
-            temp_keyboard_2.append(
-                InlineKeyboardButton(
-                    f"{wrong_answers[i]}",
-                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
-                )
+        )
+    for i in range(2, 5):
+        temp_keyboard_2.append(
+            InlineKeyboardButton(
+                f"{wrong_answers[i]}",
+                callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
             )
-        for i in range(5, 8):
-            temp_keyboard_3.append(
-                InlineKeyboardButton(
-                    f"{wrong_answers[i]}",
-                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
-                )
+        )
+    for i in range(5, 8):
+        temp_keyboard_3.append(
+            InlineKeyboardButton(
+                f"{wrong_answers[i]}",
+                callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
             )
-
-        shuffle(temp_keyboard_1)
-        keyboard = [temp_keyboard_1, temp_keyboard_2, temp_keyboard_3]
-        shuffle(keyboard)
-        verification_data = {
-            "chat_id": message.chat.id,
-            "user_id": member.id,
-            "answer": captcha_answer,
-            "keyboard": keyboard,
-            "attempts": 0,
-        }
-        keyboard = InlineKeyboardMarkup(keyboard)
-        # Append user info, correct answer and
-        answers_dicc.append(verification_data)
-        # keyboard for later use with callback query
-        button_message = await message.reply_photo(
-            photo=captcha_image,
-            caption=text,
-            reply_markup=keyboard,
-            quote=True,
         )
-        os.remove(captcha_image)
 
-        # Save captcha answers etc in mongodb in case bot gets crashed or restarted.
-        await update_captcha_cache(answers_dicc)
-
-        asyncio.create_task(
-            kick_restricted_after_delay(WELCOME_DELAY_KICK_SEC, button_message, member)
-        )
-        await asyncio.sleep(0.5)
+    shuffle(temp_keyboard_1)
+    keyboard = [temp_keyboard_1, temp_keyboard_2, temp_keyboard_3]
+    shuffle(keyboard)
+    verification_data = {
+        "chat_id": message.chat.id,
+        "user_id": member.id,
+        "answer": captcha_answer,
+        "keyboard": keyboard,
+        "attempts": 0,
+    }
+    keyboard = InlineKeyboardMarkup(keyboard)
+    # Append user info, correct answer, and
+    answers_dicc.append(verification_data)
+    # keyboard for later use with callback query
+    button_message = await app.send_photo(
+        chat_id=chat.id,
+        photo=captcha_image,
+        caption=text,
+        reply_markup=keyboard,
+    )
+    os.remove(captcha_image)
+
+    # Save captcha answers etc in mongodb in case the bot gets crashed or restarted.
+    await update_captcha_cache(answers_dicc)
+
+    asyncio.create_task(
+        kick_restricted_after_delay(WELCOME_DELAY_KICK_SEC, button_message, member)
+    )
+    await asyncio.sleep(0.5)
 
+@app.on_message(filters.new_chat_members, group=welcome_captcha_group)
+@capture_err
+async def welcome(_, message: Message):
+    chat = message.chat
+    members = message.new_chat_members
+    for member in members:
+        return await handle_new_member(message, member, chat)
 
 async def send_welcome_message(chat: Chat, user_id: int, delete: bool = False):
     raw_text = await get_welcome(chat.id)