123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- import asyncio
- import datetime
- from random import randint
- from typing import Iterable, Callable
- from aiogram import Router, F, exceptions, types
- from aiogram.fsm.context import FSMContext
- from aiogram.filters import IS_ADMIN, ChatMemberUpdatedFilter, JOIN_TRANSITION, LEAVE_TRANSITION, IS_NOT_MEMBER, \
- IS_MEMBER
- from aiogram.types import Message, CallbackQuery
- from aiogram.utils.markdown import hunderline, hlink, hbold
- from apscheduler.job import Job
- from apscheduler.triggers.date import DateTrigger
- from keyboards import menu_keys
- from keyboards.callbacks_data import MenuCategory
- from loader import scheduler, bot, logger
- from async_db import Database
- db = Database()
- router = Router()
- router.message.filter(~F.chat.type.in_({'private', 'channel'}))
- router.message.filter(F.from_user)
- async def delete_mess(m: Message):
- try:
- await bot.delete_message(m.chat.id, m.message_id)
- except Exception as e:
- if "message to delete not found" in e.message:
- logger.error(f'{e.message}\t\t{m}')
- async def answer_mess(m: Message, text: str, reply_markup=None, delete_timer: int = 0):
- to_del = await m.answer(text, reply_markup=reply_markup)
- if delete_timer != 0:
- await scheduled_function(delete_mess, (to_del,), delete_timer)
- async def check_subs(require_channels_id: Iterable[int], user_id):
- subs = []
- for chat in require_channels_id:
- # try:
- sub = await bot.get_chat_member(chat, user_id)
- # except exceptions.TelegramBadRequest:
- # continue
- if sub.status == 'left':
- return False
- if sub.status in ['member', "creator"]:
- subs.append(sub)
- if len(subs) == len(require_channels_id):
- return True
- # else:
- # return False
- async def check_bot_admin(m: Message):
- adm = None
- admins = [i.user.id for i in await bot.get_chat_administrators(m.chat.id)]
- me = await bot.get_me()
- if me.id in admins:
- adm = me
- return adm
- @router.message(
- F.new_chat_participant,
- F.left_chat_member,
- )
- # @router.message(
- # ChatMemberUpdatedFilter(member_status_changed=JOIN_TRANSITION),
- # ChatMemberUpdatedFilter(member_status_changed=LEAVE_TRANSITION),
- # ChatMemberUpdatedFilter(member_status_changed=IS_NOT_MEMBER >> IS_MEMBER),
- # )
- async def join_user(m: Message):
- if hasattr(m, 'new_chat_member') or hasattr(m, 'left_chat_participant'):
- try:
- await m.delete()
- logger.success(f"{m.chat.title}: {m}")
- return True
- except exceptions.TelegramBadRequest as e:
- logger.error(f"{m.chat.title}({m.chat.id}): {e.message}")
- return True
- else:
- return False
- async def scheduled_function(func, args: tuple = (), start_time: int = randint(2, 10)):
- time = datetime.datetime.now() + datetime.timedelta(seconds=start_time)
- task = scheduler.add_job(func, args=args, trigger='date', next_run_time=time)
- logger.debug(f"{task} / {args}")
- return task.func
- async def any_mess(m: Message):
- await scheduled_function(answer_mess, (m, m.text, None, 3), 2)
- await scheduled_function(delete_mess, (m,), 5)
- @router.message()
- async def any_mess2(m: Message, context: dict):
- if await join_user(m):
- return
- logger.debug(m)
- # TODO Drop to modules: require_channels, default_words, stop_words
- admins = [i.user.id for i in await bot.get_chat_administrators(m.chat.id)]
- if m.from_user.id in admins:
- logger.info('admin')
- return
- words_in_chat = []
- users = context["users"]
- user = None
- require_channel_id = []
- no_admin_text = f'В чате {hbold(m.chat.title)} бот не может нормально работать ' \
- f'из-за того что не назначен там администратором или не имеет прав удалять сообщения'
- for c in users:
- if m.chat.id in c.chats_id:
- user = c
- break
- if user:
- words_in_chat = user.stop_words
- if m.chat.id in user.require_channel_id.keys():
- require_channel_id = user.require_channel_id[m.chat.id]
- if require_channel_id:
- if hasattr(m, 'new_chat_member'):
- text = f'Привет, {hlink(m.from_user.full_name, f"tg://user?id={m.from_user.id}")}\n' \
- f'Чтобы начать общение в этом чате подпишись по ссылкам ниже и нажми кнопку чтобы проверить подписку\n'
- await scheduled_function(answer_mess,
- (m, text, await menu_keys.list_subs_keys(require_channel_id, m.from_user.id), 240))
- no_subscribe_text = f'{hlink(m.from_user.full_name, f"tg://user?id={m.from_user.id}")},\n' \
- f'❗️ Вы не подписались на каналы, поэтому Ваше сообщение удаляется.\n' \
- f'✅ Подпишитесь на каналы, указанные ниже и сможете писать в чат.\n'
- subscribe = await check_subs(require_channel_id, m.from_user.id)
- if not subscribe:
- # await db.jobs_add(2, m.chat.id, no_subscribe_text)
- await scheduled_function(answer_mess, (
- m, no_subscribe_text, await menu_keys.list_subs_keys(require_channel_id, m.from_user.id), 30))
- try:
- await m.delete()
- logger.success(f'[req_channel] {m.chat.title} | {m.from_user.full_name}: Писал не подписавшись')
- except exceptions.TelegramBadRequest as e:
- adm = await check_bot_admin(m)
- if not adm:
- await bot.send_message(user.client_id, no_admin_text)
- logger.error(f'[req_channel] {e} | {m.chat.title}({m.chat.id}): {m.from_user.full_name}')
- return
- # TODO add support edit this answer
- wrong_word = f"Добрый день, {hlink(m.from_user.full_name, f'tg://user?id={m.from_user.id}')}\n\n" \
- f"⚠️ Если Ваше объявление удаляется в чате, то Вы можете разместить его " \
- f"только на {hunderline('ПЛАТНОЙ ОСНОВЕ.')}\n" \
- f"С тарифами на размещение можно ознакомиться в боте: @Vacansy_resume_bot\n\n" \
- f"Администрация чата не несёт ответственности за размещаемую пользователями информацию и не исправляет её."
- text = m.text
- if m.caption:
- text = m.caption
- for w in context['stop_words']:
- # TODO replace to search in regexp
- if w.lower() in text.lower():
- # await scheduled_function(answer_mess, (m, wrong_word, None, 30))
- await db.jobs_add(message_id=2, chat_id=m.chat.id, text=wrong_word)
- try:
- await m.delete()
- logger.success(f'[delete] {m.chat.title} | {m.from_user.full_name}: {w[:10]}')
- except Exception as e:
- if "message can't be deleted" in e:
- return
- adm = await check_bot_admin(m)
- if not adm:
- await bot.send_message(user.client_id, no_admin_text)
- logger.error(f'[delete] {e} | {m.chat.title}({m.chat.id}): {w[:10]}')
- break
- for w in words_in_chat:
- if w.lower() in text.lower():
- # await scheduled_function(answer_mess, (m, wrong_word, None, 30))
- await db.jobs_add(message_id=2, chat_id=m.chat.id, text=wrong_word)
- try:
- await m.delete()
- logger.success(f'[delete] {m.chat.title} | {m.from_user.full_name}: {w[:10]}')
- except Exception as e:
- adm = await check_bot_admin(m)
- if not adm:
- await bot.send_message(user.client_id, no_admin_text)
- logger.error(f'[delete] {e} | {m.chat.title}({m.chat.id}): {w[:10]}')
- break
- @router.callback_query(
- MenuCategory.filter(F.category == 'require_channels'),
- MenuCategory.filter(F.action == 'check'),
- MenuCategory.filter(F.level == 10),
- )
- async def check_subscription_in_require_channels(call: CallbackQuery, callback_data: MenuCategory, context: dict,
- state: FSMContext):
- users = context["users"]
- require_channel_id = []
- for c in users:
- if call.message.chat.id in c.chats_id:
- if call.message.chat.id in c.require_channel_id.keys():
- require_channel_id = c.require_channel_id[call.message.chat.id]
- break
- subscribe = await check_subs(require_channel_id, callback_data.chat_id)
- if subscribe:
- await call.answer(text='Умничка, теперь твои сообщения не будут удаляться. Пиши на здоровье', show_alert=True)
- await call.message.delete()
- return
- elif not subscribe:
- await call.answer(text='Ты не на всё подписался', show_alert=True)
- # @router.callback_query()
- # async def nobody_handler(call: types.CallbackQuery, context: dict):
- # logger.debug(call)
|