users_message.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import asyncio
  2. import datetime
  3. from random import randint
  4. from typing import Iterable, Callable
  5. from aiogram import Router, F, exceptions, types
  6. from aiogram.fsm.context import FSMContext
  7. from aiogram.filters import IS_ADMIN, ChatMemberUpdatedFilter, JOIN_TRANSITION, LEAVE_TRANSITION, IS_NOT_MEMBER, \
  8. IS_MEMBER
  9. from aiogram.types import Message, CallbackQuery
  10. from aiogram.utils.markdown import hunderline, hlink, hbold
  11. from apscheduler.job import Job
  12. from apscheduler.triggers.date import DateTrigger
  13. from keyboards import menu_keys
  14. from keyboards.callbacks_data import MenuCategory
  15. from loader import scheduler, bot, logger
  16. from async_db import Database
  17. db = Database()
  18. router = Router()
  19. router.message.filter(~F.chat.type.in_({'private', 'channel'}))
  20. router.message.filter(F.from_user)
  21. async def delete_mess(m: Message):
  22. try:
  23. await bot.delete_message(m.chat.id, m.message_id)
  24. except Exception as e:
  25. if "message to delete not found" in e.message:
  26. logger.error(f'{e.message}\t\t{m}')
  27. async def answer_mess(m: Message, text: str, reply_markup=None, delete_timer: int = 0):
  28. to_del = await m.answer(text, reply_markup=reply_markup)
  29. if delete_timer != 0:
  30. await scheduled_function(delete_mess, (to_del,), delete_timer)
  31. async def check_subs(require_channels_id: Iterable[int], user_id):
  32. subs = []
  33. for chat in require_channels_id:
  34. # try:
  35. sub = await bot.get_chat_member(chat, user_id)
  36. # except exceptions.TelegramBadRequest:
  37. # continue
  38. if sub.status == 'left':
  39. return False
  40. if sub.status in ['member', "creator"]:
  41. subs.append(sub)
  42. if len(subs) == len(require_channels_id):
  43. return True
  44. # else:
  45. # return False
  46. async def check_bot_admin(m: Message):
  47. adm = None
  48. admins = [i.user.id for i in await bot.get_chat_administrators(m.chat.id)]
  49. me = await bot.get_me()
  50. if me.id in admins:
  51. adm = me
  52. return adm
  53. @router.message(
  54. F.new_chat_participant,
  55. F.left_chat_member,
  56. )
  57. # @router.message(
  58. # ChatMemberUpdatedFilter(member_status_changed=JOIN_TRANSITION),
  59. # ChatMemberUpdatedFilter(member_status_changed=LEAVE_TRANSITION),
  60. # ChatMemberUpdatedFilter(member_status_changed=IS_NOT_MEMBER >> IS_MEMBER),
  61. # )
  62. async def join_user(m: Message):
  63. if hasattr(m, 'new_chat_member') or hasattr(m, 'left_chat_participant'):
  64. try:
  65. await m.delete()
  66. logger.success(f"{m.chat.title}: {m}")
  67. return True
  68. except exceptions.TelegramBadRequest as e:
  69. logger.error(f"{m.chat.title}({m.chat.id}): {e.message}")
  70. return True
  71. else:
  72. return False
  73. async def scheduled_function(func, args: tuple = (), start_time: int = randint(2, 10)):
  74. time = datetime.datetime.now() + datetime.timedelta(seconds=start_time)
  75. task = scheduler.add_job(func, args=args, trigger='date', next_run_time=time)
  76. logger.debug(f"{task} / {args}")
  77. return task.func
  78. async def any_mess(m: Message):
  79. await scheduled_function(answer_mess, (m, m.text, None, 3), 2)
  80. await scheduled_function(delete_mess, (m,), 5)
  81. @router.message()
  82. async def any_mess2(m: Message, context: dict):
  83. if await join_user(m):
  84. return
  85. logger.debug(m)
  86. # TODO Drop to modules: require_channels, default_words, stop_words
  87. admins = [i.user.id for i in await bot.get_chat_administrators(m.chat.id)]
  88. if m.from_user.id in admins:
  89. logger.info('admin')
  90. return
  91. words_in_chat = []
  92. users = context["users"]
  93. user = None
  94. require_channel_id = []
  95. no_admin_text = f'В чате {hbold(m.chat.title)} бот не может нормально работать ' \
  96. f'из-за того что не назначен там администратором или не имеет прав удалять сообщения'
  97. for c in users:
  98. if m.chat.id in c.chats_id:
  99. user = c
  100. break
  101. if user:
  102. words_in_chat = user.stop_words
  103. if m.chat.id in user.require_channel_id.keys():
  104. require_channel_id = user.require_channel_id[m.chat.id]
  105. if require_channel_id:
  106. if hasattr(m, 'new_chat_member'):
  107. text = f'Привет, {hlink(m.from_user.full_name, f"tg://user?id={m.from_user.id}")}\n' \
  108. f'Чтобы начать общение в этом чате подпишись по ссылкам ниже и нажми кнопку чтобы проверить подписку\n'
  109. await scheduled_function(answer_mess,
  110. (m, text, await menu_keys.list_subs_keys(require_channel_id, m.from_user.id), 240))
  111. no_subscribe_text = f'{hlink(m.from_user.full_name, f"tg://user?id={m.from_user.id}")},\n' \
  112. f'❗️ Вы не подписались на каналы, поэтому Ваше сообщение удаляется.\n' \
  113. f'✅ Подпишитесь на каналы, указанные ниже и сможете писать в чат.\n'
  114. subscribe = await check_subs(require_channel_id, m.from_user.id)
  115. if not subscribe:
  116. # await db.jobs_add(2, m.chat.id, no_subscribe_text)
  117. await scheduled_function(answer_mess, (
  118. m, no_subscribe_text, await menu_keys.list_subs_keys(require_channel_id, m.from_user.id), 30))
  119. try:
  120. await m.delete()
  121. logger.success(f'[req_channel] {m.chat.title} | {m.from_user.full_name}: Писал не подписавшись')
  122. except exceptions.TelegramBadRequest as e:
  123. adm = await check_bot_admin(m)
  124. if not adm:
  125. await bot.send_message(user.client_id, no_admin_text)
  126. logger.error(f'[req_channel] {e} | {m.chat.title}({m.chat.id}): {m.from_user.full_name}')
  127. return
  128. # TODO add support edit this answer
  129. wrong_word = f"Добрый день, {hlink(m.from_user.full_name, f'tg://user?id={m.from_user.id}')}\n\n" \
  130. f"⚠️ Если Ваше объявление удаляется в чате, то Вы можете разместить его " \
  131. f"только на {hunderline('ПЛАТНОЙ ОСНОВЕ.')}\n" \
  132. f"С тарифами на размещение можно ознакомиться в боте: @Vacansy_resume_bot\n\n" \
  133. f"Администрация чата не несёт ответственности за размещаемую пользователями информацию и не исправляет её."
  134. text = m.text
  135. if m.caption:
  136. text = m.caption
  137. for w in context['stop_words']:
  138. # TODO replace to search in regexp
  139. if w.lower() in text.lower():
  140. # await scheduled_function(answer_mess, (m, wrong_word, None, 30))
  141. await db.jobs_add(message_id=2, chat_id=m.chat.id, text=wrong_word)
  142. try:
  143. await m.delete()
  144. logger.success(f'[delete] {m.chat.title} | {m.from_user.full_name}: {w[:10]}')
  145. except Exception as e:
  146. if "message can't be deleted" in e:
  147. return
  148. adm = await check_bot_admin(m)
  149. if not adm:
  150. await bot.send_message(user.client_id, no_admin_text)
  151. logger.error(f'[delete] {e} | {m.chat.title}({m.chat.id}): {w[:10]}')
  152. break
  153. for w in words_in_chat:
  154. if w.lower() in text.lower():
  155. # await scheduled_function(answer_mess, (m, wrong_word, None, 30))
  156. await db.jobs_add(message_id=2, chat_id=m.chat.id, text=wrong_word)
  157. try:
  158. await m.delete()
  159. logger.success(f'[delete] {m.chat.title} | {m.from_user.full_name}: {w[:10]}')
  160. except Exception as e:
  161. adm = await check_bot_admin(m)
  162. if not adm:
  163. await bot.send_message(user.client_id, no_admin_text)
  164. logger.error(f'[delete] {e} | {m.chat.title}({m.chat.id}): {w[:10]}')
  165. break
  166. @router.callback_query(
  167. MenuCategory.filter(F.category == 'require_channels'),
  168. MenuCategory.filter(F.action == 'check'),
  169. MenuCategory.filter(F.level == 10),
  170. )
  171. async def check_subscription_in_require_channels(call: CallbackQuery, callback_data: MenuCategory, context: dict,
  172. state: FSMContext):
  173. users = context["users"]
  174. require_channel_id = []
  175. for c in users:
  176. if call.message.chat.id in c.chats_id:
  177. if call.message.chat.id in c.require_channel_id.keys():
  178. require_channel_id = c.require_channel_id[call.message.chat.id]
  179. break
  180. subscribe = await check_subs(require_channel_id, callback_data.chat_id)
  181. if subscribe:
  182. await call.answer(text='Умничка, теперь твои сообщения не будут удаляться. Пиши на здоровье', show_alert=True)
  183. await call.message.delete()
  184. return
  185. elif not subscribe:
  186. await call.answer(text='Ты не на всё подписался', show_alert=True)
  187. # @router.callback_query()
  188. # async def nobody_handler(call: types.CallbackQuery, context: dict):
  189. # logger.debug(call)