greetings.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 8 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. temp_keyboard_3 = []
  59. for i in range(2):
  60. temp_keyboard_1.append(
  61. InlineKeyboardButton(
  62. f"{wrong_answers[i]}",
  63. callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
  64. )
  65. )
  66. for i in range(2, 5):
  67. temp_keyboard_2.append(
  68. InlineKeyboardButton(
  69. f"{wrong_answers[i]}",
  70. callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
  71. )
  72. )
  73. for i in range(5, 8):
  74. temp_keyboard_3.append(
  75. InlineKeyboardButton(
  76. f"{wrong_answers[i]}",
  77. callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
  78. )
  79. )
  80. shuffle(temp_keyboard_1)
  81. keyboard = [temp_keyboard_1, temp_keyboard_2, temp_keyboard_3]
  82. shuffle(keyboard)
  83. verification_data = {
  84. "user_id": member.id,
  85. "answer": captcha_answer,
  86. "keyboard": keyboard
  87. }
  88. keyboard = InlineKeyboardMarkup(keyboard)
  89. # Append user info, correct answer and
  90. answers_dicc.append(verification_data)
  91. # keyboard for later use with callback query
  92. button_message = await message.reply_photo(
  93. photo=captcha_image,
  94. caption=text,
  95. reply_markup=keyboard,
  96. quote=True
  97. )
  98. os.remove(captcha_image)
  99. asyncio.create_task(kick_restricted_after_delay(
  100. WELCOME_DELAY_KICK_SEC, button_message, member))
  101. await asyncio.sleep(0.5)
  102. @app.on_callback_query(filters.regex("pressed_button"))
  103. async def callback_query_welcome_button(_, callback_query):
  104. """After the new member presses the correct button,
  105. set his permissions to chat permissions,
  106. delete button message and join message.
  107. """
  108. global answers_dicc
  109. data = callback_query.data
  110. pending_user = await app.get_users(int(data.split(None, 2)[2]))
  111. pressed_user_id = callback_query.from_user.id
  112. pending_user_id = pending_user.id
  113. button_message = callback_query.message
  114. answer = data.split(None, 2)[1]
  115. if len(answers_dicc) != 0:
  116. for i in answers_dicc:
  117. if i['user_id'] == pending_user_id:
  118. correct_answer = i['answer']
  119. keyboard = i['keyboard']
  120. if pending_user_id == pressed_user_id:
  121. if answer != correct_answer:
  122. await callback_query.answer("Yeah, It's Wrong.")
  123. shuffle(keyboard[0])
  124. shuffle(keyboard[1])
  125. shuffle(keyboard[2])
  126. shuffle(keyboard)
  127. keyboard = InlineKeyboardMarkup(keyboard)
  128. await button_message.edit(
  129. text=button_message.caption.markdown,
  130. reply_markup=keyboard
  131. )
  132. return
  133. await callback_query.answer("Captcha passed successfully!")
  134. await button_message.chat.unban_member(pending_user_id)
  135. await button_message.delete()
  136. if len(answers_dicc) != 0:
  137. for ii in answers_dicc:
  138. if ii['user_id'] == pending_user_id:
  139. answers_dicc.remove(ii)
  140. return
  141. else:
  142. await callback_query.answer("This is not for you")
  143. return
  144. async def kick_restricted_after_delay(delay, button_message: Message, user: User):
  145. """If the new member is still restricted after the delay, delete
  146. button message and join message and then kick him
  147. """
  148. global answers_dicc
  149. await asyncio.sleep(delay)
  150. join_message = button_message.reply_to_message
  151. group_chat = button_message.chat
  152. user_id = user.id
  153. await join_message.delete()
  154. await button_message.delete()
  155. if len(answers_dicc) != 0:
  156. for i in answers_dicc:
  157. if i['user_id'] == user_id:
  158. answers_dicc.remove(i)
  159. await _ban_restricted_user_until_date(group_chat, user_id, duration=delay)
  160. async def _ban_restricted_user_until_date(group_chat,
  161. user_id: int,
  162. duration: int):
  163. try:
  164. member = await group_chat.get_member(user_id)
  165. if member.status == "restricted":
  166. until_date = int(datetime.utcnow().timestamp() + duration)
  167. await group_chat.kick_member(user_id, until_date=until_date)
  168. except UserNotParticipant:
  169. pass
  170. @app.on_message(filters.command("captcha") & ~filters.private)
  171. @capture_err
  172. async def captcha_state(_, message):
  173. usage = "**Usage:**\n/captcha [ON|OFF]"
  174. if len(message.command) != 2:
  175. await message.reply_text(usage)
  176. return
  177. user_id = message.from_user.id
  178. chat_id = message.chat.id
  179. permissions = await member_permissions(chat_id, user_id)
  180. if "can_restrict_members" not in permissions:
  181. await message.reply_text("You don't have enough permissions.")
  182. return
  183. state = message.text.split(None, 1)[1].strip()
  184. state = state.lower()
  185. if state == "on":
  186. await captcha_on(chat_id)
  187. await message.reply_text("Enabled Captcha For New Users.")
  188. elif state == "off":
  189. await captcha_off(chat_id)
  190. await message.reply_text("Disabled Captcha For New Users.")
  191. else:
  192. await message.reply_text(usage)