Exemple #1
0
def get_admins(client: Client, cid: int) -> Union[bool, List[ChatMember], None]:
    # Get a group's admins
    result = None

    try:
        chat = get_chat(client, cid)

        if isinstance(chat, Chat) and not chat.members_count:
            return False

        result = client.get_chat_members(chat_id=cid, filter="administrators")
    except FloodWait as e:
        logger.warning(f"Get admins in {cid} - Sleep for {e.x} second(s)")
        raise e
    except AttributeError as e:
        if "BadSeverSalt" in str(e):
            return None
        else:
            return False
    except (ChannelInvalid, ChannelPrivate, PeerIdInvalid):
        return False
    except Exception as e:
        logger.warning(f"Get admins in {cid} error: {e}", exc_info=True)

    return result
Exemple #2
0
 def privileges_control(self, client: Client, msg: Message):
     bot_name = re.match(
         r'^\/(setwelcome|clear|status|setflag)(@[a-zA-Z_]*bot)?\s?',
         msg.text).group(2)
     if bot_name is not None and bot_name[1:] != self.bot_name:
         return
     group_info = self.groups[msg.chat.id]
     if group_info.admins is None:
         admins = client.get_chat_members(msg.chat.id,
                                          filter='administrators')
         group_info.admins = [x.user.id for x in admins]
         self.groups.update_group(msg.chat.id, group_info)
         logger.info('Updated administrator list in %d, new list is => %s',
                     msg.chat.id, group_info.admins)
     if msg.from_user.id in group_info.admins:
         raise ContinuePropagation
     else:
         if not group_info.ignore_err and self.error_message != '':
             msg.reply(self.error_message)
             try:
                 client.restrict_chat_member(
                     msg.chat.id, msg.from_user.id,
                     ChatPermissions(can_send_messages=False),
                     msg.date + 60)
             except:
                 pass
Exemple #3
0
    def private(client: Client, message: Message):
        params = message.text.split()
        chat_id = message.chat.id

        if len(params) >= 2:
            name = params[1].lower()

            call = dao.get_call(chat_id, name)
            if call:

                cast_text = " ".join(
                    params[2:]) if len(params) > 2 else call.desc

                # to prevent calls to people outside of the group...
                members = client.get_chat_members(chat_id, offset=0, limit=200)
                users_in_group = [
                    member.user.id for member in members
                    if not member.user.is_bot
                ]

                # write to doppelganger
                mentions = all_mentions(client, chat_id)
                client.send_message(chat_id=user_name,
                                    text=mentions,
                                    parse_mode="html")

                text = f"Priv message's gonna be broadcasted.\n"
                text += f"To call: **{call.name}**\n"
                text += f"Text: __{cast_text}__"
                client.send_message(chat_id=chat_id,
                                    text=text,
                                    parse_mode="md")

                for user in call.users:
                    if user.uid in users_in_group:
                        # bot_peers = client.get_users([user.uid])
                        # user_peers = user_client.get_users([user.uid])
                        # client.resolve_peer(user.uid)
                        # bot_client.resolve_peer(user.uid)
                        # client.fetch_peers(peers)

                        try:
                            user_client.send_message(
                                chat_id=user.uid,
                                text=cast_text,
                                parse_mode="md",
                            )
                        except PeerIdInvalid as e:
                            print("FAILED!", e.NAME)

                return

        help_texts(client, chat_id, "cast")
Exemple #4
0
    def temporized(client: Client, message: Message):
        params = message.text.split()
        chat_id = message.chat.id

        if len(params) == 3:
            name = params[1].lower()
            minutes = params[2]
            if minutes.isdecimal() and int(minutes) <= 1000:
                minutes = int(minutes)
                call = dao.get_call(chat_id, name)
                if call:

                    # to prevent calls to people outside of the group...
                    members = client.get_chat_members(chat_id,
                                                      offset=0,
                                                      limit=200)
                    users_in_group = [
                        member.user.id for member in members
                        if not member.user.is_bot
                    ]

                    # write to doppelganger
                    mentions = all_mentions(client, chat_id)
                    client.send_message(chat_id=user_name,
                                        text=mentions,
                                        parse_mode="html")

                    text = f"Temporized message ⏰\n"
                    text += f"To call: **{call.name}**\n"
                    text += f"Text: __{call.desc}__\n"
                    text += f"When: in {minutes} minutes."

                    client.send_message(chat_id=chat_id,
                                        text=text,
                                        parse_mode="md")
                    ts = int(
                        datetime.timestamp(datetime.now() +
                                           timedelta(minutes=minutes)))
                    for user in call.users:
                        if user.uid in users_in_group:
                            try:
                                user_client.send_message(
                                    chat_id=user.uid,
                                    text=call.desc,
                                    parse_mode="md",
                                    schedule_date=ts,
                                )
                            except PeerIdInvalid as e:
                                print("FAILED!", e.NAME)
                    return

        help_texts(client, chat_id, "temp")
Exemple #5
0
def get_admins(client: Client, cid: int) -> Union[bool, List[ChatMember], None]:
    # Get a group's admins
    result = None
    try:
        flood_wait = True
        while flood_wait:
            flood_wait = False
            try:
                result = client.get_chat_members(chat_id=cid, filter="administrators")
            except FloodWait as e:
                flood_wait = True
                wait_flood(e)
            except (ChannelInvalid, ChannelPrivate, PeerIdInvalid):
                return False
    except Exception as e:
        logger.warning(f"Get admins in {cid} error: {e}", exc_info=True)

    return result
Exemple #6
0
    def get_admin_and_creator_ids(
        client: Client, chat_id: int, call_name: str
    ) -> List[int]:
        """
        Devuelve lista con los ids de los administradores del canal/grupo
        y el creador de la call.

        :param client:      Pyrogram Client
        :param chat_id:     Group ID
        :param call_name:   Call name
        :return:            List of user ids
        """
        admins = client.get_chat_members(chat_id=chat_id, filter="administrators")
        creator = dao.get_call_creator(chat_id, call_name)

        admin_ids = [admin.user.id for admin in admins]
        if creator:
            admin_ids.append(creator.uid)
        return admin_ids
Exemple #7
0
    def ring(client: Client, message: Message):
        params = message.text.split()
        chat_id = message.chat.id

        if len(params) == 2:
            name = params[1].lower()

            call = dao.get_call(chat_id, name)
            if call:

                # to prevent calls to people outside of the group...
                members = client.get_chat_members(chat_id, offset=0, limit=200)
                users_in_group = [
                    member.user.id for member in members
                    if not member.user.is_bot
                ]

                # write to doppelganger
                mentions = all_mentions(client, chat_id)
                client.send_message(chat_id=user_name,
                                    text=mentions,
                                    parse_mode="html")

                text = f"Ringin bastards ☎\n"
                text += f"To call: **{call.name}**"

                client.send_message(chat_id=chat_id,
                                    text=text,
                                    parse_mode="md")

                for user in call.users:
                    if user.uid in users_in_group:
                        try:
                            phone_call = voip.start_call(user.uid)
                            # print(type(phone_call), dir(phone_call))
                            phone_call.stop()
                        except PeerIdInvalid as e:
                            print("FAILED!", e.NAME)
                return

        help_texts(client, chat_id, "ring")
Exemple #8
0
def get_chat_admins(app: Client, message: Message) -> list:
    return [
        admin.user.id
        for admin in app.get_chat_members(message.chat.id,
                                          filter="administrators")
    ]
target = "pyrogramchat"  # Target channel/supergroup
members = {}  # List that will contain all the members of the target chat
limit = 200  # Amount of users to retrieve for each API call (max 200)

# "" + "0123456789" + "abcdefghijklmnopqrstuvwxyz" (as list)
queries = [""] + [str(i) for i in range(10)] + list(ascii_lowercase)

with app:
    for q in queries:
        print('Searching for "{}"'.format(q))
        offset = 0  # For each query, offset restarts from 0

        while True:
            try:
                chunk = app.get_chat_members(target, offset, query=q)
            except FloodWait as e:  # Very large chats could trigger FloodWait
                print("Flood wait: {} seconds".format(e.x))
                time.sleep(e.x)  # When it happens, wait X seconds and try again
                continue

            if not chunk.chat_members:
                print('Done searching for "{}"'.format(q))
                print()
                break  # No more members left

            members.update({i.user.id: i for i in chunk.chat_members})
            offset += len(chunk.chat_members)

            print("Total members: {}".format(len(members)))
Exemple #10
0
     for d in dialogs:
         chatListPrint(d['chat'])
         i += 1
         if i >= 10:
             cmd = input(Fore.CYAN + "[(c)/x]: " + Style.RESET_ALL)
             i = 0
             if cmd == 'x':
                 break
     chatID = input(Fore.CYAN + "[chat lookup]: " + Style.RESET_ALL)
     choice = input(
         Fore.CYAN +
         "[1] => Bulk search\n[2] => single user lookup\n[<]: " +
         Style.RESET_ALL)
     if choice == "1":
         limit = input(Fore.CYAN + "[# of users]: " + Style.RESET_ALL)
         members = app.get_chat_members(chat_id=int(chatID),
                                        limit=int(limit))
         chatMembersInfoPrint(members)
     elif choice == "2":
         userInput = input(
             Fore.CYAN +
             "[user-id (id)/username (u)/phone number (pn)]: " +
             Style.RESET_ALL)
         members = app.get_chat_member(chat_id=int(chatID),
                                       user_id=userID(userInput))
         chatMembersInfoPrint(members, total=False)
 elif choice == "2":
     userInput = input(
         Fore.CYAN + "[user-id (id)/username (u)/phone number (pn)]: " +
         Style.RESET_ALL)
     lookupResult = app.get_users([userID(userInput)])
     singleUserLookup({'user': lookupResult[0]})
def on_pair(client: Client, message: Message):
    logger.debug('entered handler')

    limit = config.bot.chat_max_members + 20 + 20 + 3  # 20 bots + 20 possible deleted accounts + 3 padding
    if limit > 200:
        limit = 200

    logger.info('draw id %d: limit %d', message.message_id, limit)

    all_members = client.get_chat_members(message.chat.id, limit=limit)

    valid_members = list()
    for member in all_members:
        if member.user.is_bot or member.user.is_deleted:
            logger.debug('%s (%d) is a bot or has been deleted',
                         member.user.first_name, member.user.id)
            continue

        logger.debug('%s (%d) is a valid user', member.user.first_name,
                     member.user.id)
        valid_members.append(member.user)

    logger.info(
        'number of members after removing bots and deleted accounts: %d',
        len(valid_members))

    if len(valid_members) > config.bot.chat_max_members:
        message.reply(
            'Sorry, this command works only in groups with {} members or less {}'
            .format(config.bot.chat_max_members, Emoji.PENSIVE_FACE))
        return

    chat_message = message.reply('{} <i>Matching users...</i>'.format(
        Emoji.HAMMER_AND_WRENCH))

    # store the names of the users we haven't been able to contact
    blocked_us = list()
    generic_errors = defaultdict(lambda: [])

    # store the users we are allowed to message
    users_to_message = list()
    users_to_pick = list()
    for user in valid_members:
        logger.debug('testing chat action to %s (%d)', user.first_name,
                     user.id)
        try:
            client.send_chat_action(user.id, 'typing')
            logger.debug('...success')

            users_to_message.append(user)
            users_to_pick.append(user)
        except (UserIsBlocked, PeerIdInvalid):
            logger.debug('...failed: not started yet/blocked us')
            blocked_us.append(user)
        except BadRequest as br:
            logger.error('bad request when testing chat action for user %d',
                         user.id,
                         exc_info=True)

            # save other errors
            error_message = re.search(r'(?:^\[.+\]: )?(.*)', str(br),
                                      re.I).group(1).strip()
            logger.debug('...failed: %s', error_message)
            generic_errors[error_message].append(user)

    number_of_users = len(users_to_message)
    logger.info('number of users involved: %d', number_of_users)
    assert (number_of_users == len(users_to_pick))

    if number_of_users < 2:
        chat_message.edit_text(NOT_ENOUGH_PEOPLE)
        return

    random.shuffle(users_to_pick)

    # we should make sure the last user of the users_to_message lists is not the
    # same of the first user of the users_to_pick list, otherwise when we loop
    # the last user of the list, the is no other user to pick (paired with self)
    while users_to_message[-1].id == users_to_pick[0].id:
        logger.info('shuffling again...')
        random.shuffle(users_to_pick)

    chat_message.edit_text('{} <i>Sending messages...</i>'.format(
        Emoji.HAMMER_AND_WRENCH))
    for user in users_to_message:
        pick = users_to_pick.pop(
        )  # this is already shuffled, so we just pop the last item

        if pick.id == user.id:
            logger.info('picked self, picking again...')
            # do not pick self, pick another user and insert the old one at the end
            old_pick = pick
            new_pick = users_to_pick.pop()
            users_to_pick.append(old_pick)
            pick = new_pick

        logger.debug('picked %s (%d) for %s (%d)', pick.first_name, pick.id,
                     user.first_name, user.id)

        text = SECRET_SANTA_MESSAGE.format(
            receiver_mention=utils.inline_mention(pick),
            chat_name=utils.html_escape(message.chat.title),
            wrapped_gift=Emoji.WRAPPED_GIFT,
            santa=Emoji.SANTA_CLAUS_MEDIUM_LIGHT_SKIN_TONE,
            christmas_tree=Emoji.CHRISTMAS_TREE,
            message_link=utils.message_link(chat_message),
            draw_id='<code>draw ID: {}</code>'.format(message.message_id)
            if config.public.draw_id else '')

        logger.debug('sending pairing to %s (%d): %s', user.first_name,
                     user.id, pick.first_name)
        client.send_message(user.id, text)

    text = PAIR_RESULT.format(
        father_christmas=Emoji.SANTA_CLAUS_MEDIUM_LIGHT_SKIN_TONE,
        number=len(users_to_message))

    if blocked_us:
        text += BLOCKED_US.format(blocked_us_list=list_to_text(blocked_us),
                                  pensive_face=Emoji.PENSIVE_FACE)

    chat_message.edit_text(text)

    if generic_errors:
        other_errors_texts = list()
        for error_desc, users in generic_errors.items():
            other_errors_texts.append(
                OTHER_ERRORS_LIST.format(users_list=list_to_text(users),
                                         error_description=error_desc))

        text = '{prefix}\n{errors_list}'.format(
            prefix=OTHER_ERRORS_PREFIX,
            errors_list='\n'.join(other_errors_texts))

        client.send_message(message.chat.id, text)