async def new_chat_member(message: types.Message):
    """
    Обрабатываем вход нового пользователя
    """
    # Пропускаем старые запросы
    if message.date < datetime.datetime.now() - datetime.timedelta(minutes=1):
        return False

    # сразу выдаём ему права, неподтверждённого пользователя
    await bot.restrict_chat_member(
        chat_id=message.chat.id,
        user_id=message.new_chat_members[0].id,
        permissions=new_user_added,
    )

    # TODO вместо кучи сообщений, отправлять одно с несколькими айдишниками
    
    # Каждому пользователю отсылаем кнопку
    for new_member in message.new_chat_members:
        await message.reply(
            (
                f"{new_member.get_mention(as_html=True)}, добро пожаловать в чат!\n"
                "Подтверди, что ты не бот, нажатием на кнопку ниже"
            ),
            reply_markup=generate_confirm_markup(new_member.id)
        )
示例#2
0
async def new_chat_member(message: types.Message):
    """
    Обрабатываем вход нового пользователя
    """

    logger.debug(
        f"New chat member: @{message.from_user.username}:{message.from_user.id} -> "
        f"{', '.join([f'@{user.username}:{user.id}' for user in message.new_chat_members])} "
        f'in chat "{message.chat.title}@{message.chat.username}" chat_id:{message.chat.id}'
    )
    # Пропускаем старые запросы
    if message.date < datetime.datetime.now() - datetime.timedelta(minutes=1):
        return logger.debug('Old updates was skipped')

    for new_member in message.new_chat_members:
        try:
            # сразу выдаём ему права, неподтверждённого пользователя
            await bot.restrict_chat_member(
                chat_id=message.chat.id,
                user_id=new_member.id,
                permissions=new_user_added,
            )
            logger.debug(f'User @{new_member.username}:{new_member.id} cannot send messages now')
        except CantRestrictSelf:
            return logger.debug('Can\'t restrict self')

    service_messages = list()

    # Каждому пользователю отсылаем кнопку
    for new_member in message.new_chat_members:
        generated_tuple = generate_confirm_markup(new_member.id)
        markup = generated_tuple[0]
        subject = generated_tuple[1]
        answer = users_entrance_generator(mention=new_member.get_mention(as_html=True), subject=subject)
        service_message: types.Message = await message.reply(
            text=answer,
            reply_markup=markup
        )
        logger.debug(f'User @{new_member.username}:{new_member.id} '
                     f'got message {service_message.message_id} with keyboard')
        await storage.set_state(chat=message.chat.id, user=new_member.id, state=ConfirmUserState.IncomerUser)
        logger.debug(f'User @{new_member.username}:{new_member.id} in state "IncomerUser"')
        state = dp.current_state(user=new_member.id, chat=message.chat.id)
        await state.update_data(user_id=new_member.id)
        logger.debug(f'@{new_member.username}:{new_member.id} user data has been updated')
        service_messages.append(service_message)

    logger.debug(f'The bot waits {ENTRY_TIME} seconds '
                 f'for {", ".join([str(user.username) for user in message.new_chat_members])}')
    await asyncio.sleep(ENTRY_TIME)
    for new_member in message.new_chat_members:
        state = dp.current_state(user=new_member.id, chat=message.chat.id)
        data = await state.get_data()
        if data.get('user_id', None):
            logger.debug(f'User @{new_member.username}:{new_member.id} data: {data}')
            until_date = datetime.datetime.now() + datetime.timedelta(seconds=BAN_TIME)
            # Получаем информацию о пользователе и провереям не заблокировал ли его кто-то, 
            # пока бот ожидал ответа на капчу.
            # asyncio так как требуются свежие данные, а не на время входа в цикл.
            asyncio.user = await bot.get_chat_member(chat_id=message.chat.id, user_id=new_member.id)
            if asyncio.user['status'] == 'kicked':
            # Если пользователь заблокирован в чате то ничего не делаем и просто выдаём сообщение в консоль
                logger.debug(f'User @{new_member.username}:{new_member.id} already kicked from the chat \
                ("{message.chat.title}@{message.chat.username}" chat_id:{message.chat.id}) by other bot or admin')
            else:
            # Если пользователь не был заблокирован то назначается его блокировка на указанное в конфигурации время
                await bot.kick_chat_member(chat_id=message.chat.id, user_id=new_member.id, until_date=until_date)
                logger.debug(f'User was kicked from chat @{new_member.username}:{new_member.id} on {BAN_TIME} seconds')
            # Завершаем состояние "новый пользователь", если пользователь просто проигнорировал капчу
            state = dp.current_state(user=new_member.id, chat=message.chat.id)
            await state.finish()
            logger.debug(f'User @{new_member.username}:{new_member.id} is out of the state')

    for service_message in service_messages:
        logger.debug(f'Message {service_message.message_id} was deleted')
        await service_message.delete()
        await message.delete()
async def updated_chat_member(chat_member_updated: types.ChatMemberUpdated):
    """Хендлер для вышедших либо кикнутых пользователей"""

    performer_mention = chat_member_updated.from_user.get_mention(as_html=True)
    member_mention = chat_member_updated.old_chat_member.user.get_mention(as_html=True)

    bot_user = await dp.bot.me
    if chat_member_updated.from_user.id == bot_user.id:
        return False

    if chat_member_updated.new_chat_member.status == types.ChatMemberStatus.MEMBER:
        state = dp.current_state(chat=chat_member_updated.chat.id,
                                 user=chat_member_updated.new_chat_member.user.id)
        await state.update_data(is_active=False)
        await chat_member_updated.bot.restrict_chat_member(
            chat_id=chat_member_updated.chat.id,
            user_id=chat_member_updated.new_chat_member.user.id,
            permissions=set_new_user_permissions(),
        )
        message_bot = await chat_member_updated.bot.send_message(
            chat_member_updated.chat.id,
            text=(
                f"{member_mention}, добро пожаловать в чат!\n"
                "Подтверди, что ты не бот, нажатием на кнопку ниже. Внимание! У тебя есть всего одна минута, или я тебя удаляю."
            ),
            reply_markup=generate_confirm_markup(chat_member_updated.new_chat_member.user.id),
        )
        await asyncio.sleep(60)
        data = await state.get_data()
        is_active = data.get('is_active')
        if not is_active:
            service_message = data.get('service_message')
            await chat_member_updated.bot.kick_chat_member(chat_member_updated.chat.id,
                                                           chat_member_updated.new_chat_member.user.id)
            await chat_member_updated.bot.unban_chat_member(chat_member_updated.chat.id,
                                                            chat_member_updated.new_chat_member.user.id)
            await message_bot.delete()
            await service_message.delete()

        await state.finish()
        return

    if chat_member_updated.new_chat_member.status == types.ChatMemberStatus.BANNED:
        text = f"{member_mention} был удален из чата пользователем {performer_mention}."

    elif chat_member_updated.new_chat_member.status == types.ChatMemberStatus.RESTRICTED and chat_member_updated.old_chat_member.status == types.ChatMemberStatus.ADMINISTRATOR:
        text = f"Для пользователя {member_mention} были изменены права пользователем {performer_mention}."

    # Проверяем вышел ли пользователь сам
    # elif chat_member_updated.new_chat_member.status == types.ChatMemberStatus.LEFT:
    #     text = f"{member_mention} вышел из чата."
    #
    #     until_date = datetime.datetime.now() + datetime.timedelta(days=1)
    #     await chat_member_updated.chat.kick(user_id=chat_member_updated.old_chat_member.user.id,
    #                                         until_date=until_date)

    elif chat_member_updated.new_chat_member.status == types.ChatMemberStatus.ADMINISTRATOR:
        if chat_member_updated.old_chat_member.status != types.ChatMemberStatus.ADMINISTRATOR:
            db.add_chat_admin(chat_member_updated.chat.id, chat_member_updated.from_user.id)
            text = f'Пользователь {member_mention} был повышен до статуса Администратора чата с титулом: {chat_member_updated.new_chat_member.custom_title}'
        else:
            text = f'Для администратора {member_mention} были изменены права'

    elif chat_member_updated.old_chat_member.status == types.ChatMemberStatus.ADMINISTRATOR and chat_member_updated.new_chat_member.status != types.ChatMemberStatus.ADMINISTRATOR:
        db.del_chat_admin(chat_member_updated.chat.id, chat_member_updated.from_user.id)
        text = f'Администратора {member_mention} понизили до статуса Пользователь'
    else:
        return

    await chat_member_updated.bot.send_message(
        chat_member_updated.chat.id,
        text
    )
async def new_chat_member(message: types.Message):
    """
    Обрабатываем вход нового пользователя
    """

    logger.debug(
        f"New chat member: @{message.from_user.username}:{message.from_user.id} -> "
        f"{', '.join([f'@{user.username}:{user.id}' for user in message.new_chat_members])} "
        f'in chat "{message.chat.title}@{message.chat.username}" chat_id:{message.chat.id}'
    )
    # Пропускаем старые запросы
    if message.date < datetime.datetime.now() - datetime.timedelta(minutes=1):
        return logger.debug('Old updates was skipped')

    for new_member in message.new_chat_members:
        try:
            # сразу выдаём ему права, неподтверждённого пользователя
            await bot.restrict_chat_member(
                chat_id=message.chat.id,
                user_id=new_member.id,
                permissions=new_user_added,
            )
            logger.debug(
                f'User @{new_member.username}:{new_member.id} cannot send messages now'
            )
        except CantRestrictSelf:
            return logger.debug('Can\'t restrict self')

    service_messages = list()

    # Каждому пользователю отсылаем кнопку
    for new_member in message.new_chat_members:
        generated_tuple = generate_confirm_markup(new_member.id)
        markup = generated_tuple[0]
        subject = generated_tuple[1]
        answer = users_entrance_generator(
            mention=new_member.get_mention(as_html=True), subject=subject)
        service_message: types.Message = await message.reply(
            text=answer, reply_markup=markup)
        logger.debug(f'User @{new_member.username}:{new_member.id} '
                     f'got message {service_message.message_id} with keyboard')
        await storage.set_state(chat=message.chat.id,
                                user=new_member.id,
                                state=ConfirmUserState.IncomerUser)
        logger.debug(
            f'User @{new_member.username}:{new_member.id} in state "IncomerUser"'
        )
        state = dp.current_state(user=new_member.id, chat=message.chat.id)
        await state.update_data(user_id=new_member.id)
        logger.debug(
            f'@{new_member.username}:{new_member.id} user data has been updated'
        )
        service_messages.append(service_message)

    logger.debug(
        f'The bot waits {ENTRY_TIME} seconds '
        f'for {", ".join([str(user.username) for user in message.new_chat_members])}'
    )
    await asyncio.sleep(ENTRY_TIME)
    for new_member in message.new_chat_members:
        state = dp.current_state(user=new_member.id, chat=message.chat.id)
        data = await state.get_data()
        if data.get('user_id', None):
            logger.debug(
                f'User @{new_member.username}:{new_member.id} data: {data}')
            until_date = datetime.datetime.now() + datetime.timedelta(
                seconds=BAN_TIME)
            await bot.kick_chat_member(chat_id=message.chat.id,
                                       user_id=new_member.id,
                                       until_date=until_date)
            logger.debug(
                f'User was kicked from chat @{new_member.username}:{new_member.id} on {BAN_TIME} seconds'
            )

    for service_message in service_messages:
        logger.debug(f'Message {service_message.message_id} was deleted')
        await service_message.delete()
        await message.delete()