greetings.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. """ Kang with proper credits or /gbun """
  2. import asyncio
  3. import os
  4. from wbb import app, WELCOME_DELAY_KICK_SEC, SUDOERS
  5. from wbb.modules.admin import member_permissions
  6. from wbb.core.decorators.errors import capture_err
  7. from wbb.utils.filter_groups import welcome_captcha_group
  8. from wbb.utils.functions import generate_captcha
  9. from wbb.utils.dbfunctions import (
  10. is_gbanned_user, is_captcha_on, captcha_on, captcha_off
  11. )
  12. from pyrogram.types import (
  13. Message, InlineKeyboardMarkup,
  14. InlineKeyboardButton, ChatPermissions, User
  15. )
  16. from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant, ChatAdminRequired
  17. from pyrogram import filters
  18. from random import shuffle
  19. from datetime import datetime
  20. __MODULE__ = "Captcha"
  21. __HELP__ = "/captcha [ON|OFF] - Enable/Disable Captcha."
  22. answers_dicc = []
  23. @app.on_message(filters.new_chat_members, group=welcome_captcha_group)
  24. @capture_err
  25. async def welcome(_, message: Message):
  26. global answers_dicc
  27. """Mute new member and send message with button"""
  28. if not await is_captcha_on(message.chat.id):
  29. return
  30. for member in message.new_chat_members:
  31. try:
  32. if member.id in SUDOERS:
  33. continue # ignore sudos
  34. if await is_gbanned_user(member.id):
  35. await message.chat.kick_member(member.id)
  36. await message.reply_text(f"{member.mention} was globally banned, and got removed,"
  37. + " if you think this is a false gban, you can appeal"
  38. + " for this ban in support chat.")
  39. continue
  40. if member.is_bot:
  41. continue # ignore bots
  42. await message.chat.restrict_member(member.id, ChatPermissions())
  43. text = (f"Welcome, {(member.mention())} Are you human?\n"
  44. f"Solve this captcha in {WELCOME_DELAY_KICK_SEC} seconds or you'll be kicked.")
  45. except ChatAdminRequired:
  46. break
  47. # Generate a captcha image, answers and some wrong answers
  48. captcha = generate_captcha()
  49. captcha_image = captcha[0]
  50. captcha_answer = captcha[1]
  51. wrong_answers = captcha[2] # This consists of 7 wrong answers
  52. correct_button = InlineKeyboardButton(
  53. f"{captcha_answer}",
  54. callback_data=f"pressed_button {captcha_answer} {member.id}"
  55. )
  56. temp_keyboard_1 = [correct_button] # Button row 1
  57. temp_keyboard_2 = [] # Botton row 2
  58. for i in range(3):
  59. temp_keyboard_1.append(
  60. InlineKeyboardButton(
  61. f"{wrong_answers[i]}",
  62. callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
  63. )
  64. )
  65. for i in range(3, 7):
  66. temp_keyboard_2.append(
  67. InlineKeyboardButton(
  68. f"{wrong_answers[i]}",
  69. callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
  70. )
  71. )
  72. shuffle(temp_keyboard_1)
  73. keyboard = [temp_keyboard_1, temp_keyboard_2]
  74. shuffle(keyboard)
  75. verification_data = {
  76. "user_id": member.id,
  77. "answer": captcha_answer,
  78. "keyboard": keyboard
  79. }
  80. keyboard = InlineKeyboardMarkup(keyboard)
  81. # Append user info, correct answer and
  82. answers_dicc.append(verification_data)
  83. # keyboard for later use with callback query
  84. button_message = await message.reply_photo(
  85. photo=captcha_image,
  86. caption=text,
  87. reply_markup=keyboard,
  88. quote=True
  89. )
  90. os.remove(captcha_image)
  91. asyncio.create_task(kick_restricted_after_delay(
  92. WELCOME_DELAY_KICK_SEC, button_message, member))
  93. await asyncio.sleep(0.5)
  94. @app.on_callback_query(filters.regex("pressed_button"))
  95. async def callback_query_welcome_button(_, callback_query):
  96. """After the new member presses the correct button,
  97. set his permissions to chat permissions,
  98. delete button message and join message.
  99. """
  100. global answers_dicc
  101. data = callback_query.data
  102. pending_user = await app.get_users(int(data.split(None, 2)[2]))
  103. pressed_user_id = callback_query.from_user.id
  104. pending_user_id = pending_user.id
  105. button_message = callback_query.message
  106. answer = data.split(None, 2)[1]
  107. if len(answers_dicc) != 0:
  108. for i in answers_dicc:
  109. if i['user_id'] == pending_user_id:
  110. correct_answer = i['answer']
  111. keyboard = i['keyboard']
  112. if pending_user_id == pressed_user_id:
  113. if answer != correct_answer:
  114. await callback_query.answer("Yeah, It's Wrong.")
  115. shuffle(keyboard[0])
  116. shuffle(keyboard[1])
  117. shuffle(keyboard)
  118. keyboard = InlineKeyboardMarkup(keyboard)
  119. await button_message.edit(
  120. text=button_message.caption.markdown,
  121. reply_markup=keyboard
  122. )
  123. return
  124. await callback_query.answer("Captcha passed successfully!")
  125. await button_message.chat.unban_member(pending_user_id)
  126. await button_message.delete()
  127. if len(answers_dicc) != 0:
  128. for ii in answers_dicc:
  129. if ii['user_id'] == pending_user_id:
  130. answers_dicc.remove(ii)
  131. return
  132. else:
  133. await callback_query.answer("This is not for you")
  134. return
  135. async def kick_restricted_after_delay(delay, button_message: Message, user: User):
  136. """If the new member is still restricted after the delay, delete
  137. button message and join message and then kick him
  138. """
  139. global answers_dicc
  140. await asyncio.sleep(delay)
  141. join_message = button_message.reply_to_message
  142. group_chat = button_message.chat
  143. user_id = user.id
  144. await join_message.delete()
  145. await button_message.delete()
  146. if len(answers_dicc) != 0:
  147. for i in answers_dicc:
  148. if i['user_id'] == user_id:
  149. answers_dicc.remove(i)
  150. await _ban_restricted_user_until_date(group_chat, user_id, duration=delay)
  151. async def _ban_restricted_user_until_date(group_chat,
  152. user_id: int,
  153. duration: int):
  154. try:
  155. member = await group_chat.get_member(user_id)
  156. if member.status == "restricted":
  157. until_date = int(datetime.utcnow().timestamp() + duration)
  158. await group_chat.kick_member(user_id, until_date=until_date)
  159. except UserNotParticipant:
  160. pass
  161. @app.on_message(filters.command("captcha") & ~filters.private)
  162. @capture_err
  163. async def captcha_state(_, message):
  164. usage = "**Usage:**\n/captcha [ON|OFF]"
  165. if len(message.command) != 2:
  166. await message.reply_text(usage)
  167. return
  168. user_id = message.from_user.id
  169. chat_id = message.chat.id
  170. permissions = await member_permissions(chat_id, user_id)
  171. if "can_restrict_members" not in permissions:
  172. await message.reply_text("You don't have enough permissions.")
  173. return
  174. state = message.text.split(None, 1)[1].strip()
  175. state = state.lower()
  176. if state == "on":
  177. await captcha_on(chat_id)
  178. await message.reply_text("Enabled Captcha For New Users.")
  179. elif state == "off":
  180. await captcha_off(chat_id)
  181. await message.reply_text("Disabled Captcha For New Users.")
  182. else:
  183. await message.reply_text(usage)