Example #1
0
def dump_chat(left_chat, full_info, client: TelegramClient):
    if full_info is None:
        print(
            ' > You cannot access full information about this chat. It may be private, or you were removed by an admin.\n'
            ' > Dumping only information you can access.')
        print(
            textwrap.indent(json.dumps(left_chat.to_dict(),
                                       indent=4,
                                       default=lambda x: x.__repr__()),
                            prefix=' >  '))
    else:
        print(
            textwrap.indent(json.dumps(full_info.to_dict(),
                                       indent=4,
                                       default=lambda x: x.__repr__()),
                            prefix=' >  '))

        if isinstance(full_info.full_chat.chat_photo, Photo):
            if sys.platform == 'linux':
                resp = input(' > View the current chat photo? [y/N]: ')
                if resp == 'y':
                    path = client.download_profile_photo(
                        entity=full_info.full_chat, file='/tmp/chat-photo.png')
                    if isinstance(path, str):
                        subprocess.check_output(['xdg-open', path],
                                                stderr=subprocess.DEVNULL)
            else:
                print(
                    ' > Viewing chat photos is currently only supported on Linux desktop.'
                )
        else:
            print(' > This chat has no profile picture.')
Example #2
0
class Telegram:
    USER_TYPE_ADMIN = 'admin'
    USER_TYPE_CREATOR = 'creator'
    USER_TYPE_PARTICIPANT = 'participant'
    USER_TYPE_SELF = 'myself'
    USER_TYPE_UNKNOWN = 'unknown'

    USER_STATUS_EMPTY = ''
    USER_STATUS_RECENTLY = 'recently'
    USER_STATUS_ONLINE = 'online'
    USER_STATUS_OFFLINE = 'offline'
    USER_STATUS_LAST_WEEK = 'last week'
    USER_STATUS_LAST_MONTH = 'last month'
    USER_STATUS_UNKNOWN = 'unknown'

    _client: TelegramClient = None
    phone_number: str = None
    _api_id: int = None
    _api_hash: str = None
    _me: User = None

    def connect(self, phone_number, api_id, api_hash):
        self.phone_number = phone_number
        self._api_id = api_id
        self._api_hash = api_hash

        self._client = TelegramClient(phone_number, api_id, api_hash)
        self._client.connect()
        self._me = self._client.get_me()

    def list_channels(self,
                      only_admin=False,
                      list_from_date=None,
                      limit_size=200):
        channels = []
        result = []

        dialogs_result = self._client(
            GetDialogsRequest(offset_date=list_from_date,
                              offset_id=0,
                              offset_peer=InputPeerEmpty(),
                              limit=limit_size,
                              hash=0))
        channels.extend(dialogs_result.chats)

        for channel in channels:
            if not isinstance(channel, Chat) \
                    and not isinstance(channel, ChannelForbidden) \
                    and not isinstance(channel, ChatForbidden):
                # List all channels or only channels for which we have admin privileges
                if not only_admin or channel.admin_rights or channel.creator:
                    result.append(channel)

        return result

    def list_groups(self, list_from=None, limit_size=200):
        groups = []
        chats_result = []

        result = self._client(
            GetDialogsRequest(offset_date=list_from,
                              offset_id=0,
                              offset_peer=InputPeerEmpty(),
                              limit=limit_size,
                              hash=0))
        groups.extend(result.chats)

        for group in groups:
            if not isinstance(group, ChatForbidden) and not isinstance(
                    group, ChannelForbidden):
                if hasattr(group, 'megagroup') and group.megagroup:
                    chats_result.append(group)

        return chats_result

    @staticmethod
    def channel_participant_type(channel_participant):
        if isinstance(channel_participant, ChannelParticipant):
            return Telegram.USER_TYPE_PARTICIPANT
        elif isinstance(channel_participant, ChannelParticipantCreator):
            return Telegram.USER_TYPE_CREATOR
        elif isinstance(channel_participant, ChannelParticipantAdmin):
            return Telegram.USER_TYPE_ADMIN
        elif isinstance(channel_participant, ChannelParticipantSelf):
            return Telegram.USER_TYPE_SELF
        else:
            return Telegram.USER_TYPE_UNKNOWN

    @staticmethod
    def identify_user_status(channel_participant):
        user_status = channel_participant.status

        if isinstance(user_status, UserStatusEmpty) or user_status is None:
            return Telegram.USER_STATUS_EMPTY
        elif isinstance(user_status, UserStatusRecently):
            return Telegram.USER_STATUS_RECENTLY
        elif isinstance(user_status, UserStatusOnline):
            return Telegram.USER_STATUS_ONLINE
        elif isinstance(user_status, UserStatusOffline):
            return Telegram.USER_STATUS_OFFLINE
        elif isinstance(user_status, UserStatusLastWeek):
            return Telegram.USER_STATUS_LAST_WEEK
        elif isinstance(user_status, UserStatusLastMonth):
            return Telegram.USER_STATUS_LAST_MONTH
        else:
            return Telegram.USER_STATUS_UNKNOWN

    def full_user_info(self, user_id):
        return self._client(GetFullUserRequest(user_id))

    def is_user_authorized(self):
        return self._client.is_user_authorized()

    def request_authorization_code(self):
        self._client.send_code_request(self.phone_number)

    def verify_authorization_code(self, authorization_code):
        self._client.sign_in(self.phone_number, authorization_code)

    def get_channel_participants(self, target_group):
        return self._client.get_participants(target_group, aggressive=True)

    def download_profile_photo(self, user, to_file):
        return self._client.download_profile_photo(user, to_file)
Example #3
0
class Sync:
    """
    Sync iterates and receives messages from the Telegram group to the
    local SQLite DB.
    """
    config = {}
    db = None

    def __init__(self, config, session_file, db):
        self.config = config
        self.db = db

        self.client = TelegramClient(session_file, self.config["api_id"],
                                     self.config["api_hash"])
        self.client.start()

        if not os.path.exists(self.config["media_dir"]):
            os.mkdir(self.config["media_dir"])

    def sync(self):
        """
        Sync syncs messages from Telegram from the last synced message
        into the local SQLite DB.
        """
        last_id, last_date = self.db.get_last_message_id()

        if last_id:
            logging.info("fetching from last message id={} ({})".format(
                last_id, last_date))

        n = 0
        while True:
            has = False
            for m in self._get_messages(self.config["group"],
                                        offset_id=last_id if last_id else 0):
                if not m:
                    continue

                has = True

                # Inser the records into DB.
                self.db.insert_user(m.user)

                if m.media:
                    self.db.insert_media(m.media)

                self.db.insert_message(m)

                last_date = m.date
                n += 1
                if n % 300 == 0:
                    logging.info("fetched {} messages".format(n))
                    self.db.commit()

                if self.config["fetch_limit"] > 0 and n >= self.config[
                        "fetch_limit"]:
                    has = False
                    break

            self.db.commit()
            if has:
                last_id = m.id
                logging.info(
                    "fetched {} messages. sleeping for {} seconds".format(
                        n, self.config["fetch_wait"]))
                time.sleep(self.config["fetch_wait"])
            else:
                break

        self.db.commit()
        logging.info("finished. fetched {} messages. last message = {}".format(
            n, last_date))

    def _get_messages(self, group, offset_id) -> Message:
        # https://docs.telethon.dev/en/latest/quick-references/objects-reference.html#message
        for m in self.client.get_messages(
                group,
                offset_id=offset_id,
                limit=self.config["fetch_batch_size"],
                reverse=True):

            if not m or not m.sender:
                continue

            # Media.
            sticker = None
            med = None
            if m.media:
                # If it's a sticker, get the alt value (unicode emoji).
                if isinstance(m.media, telethon.tl.types.MessageMediaDocument) and \
                        m.media.document.mime_type == "application/x-tgsticker":
                    alt = [
                        a.alt for a in m.media.document.attributes
                        if isinstance(
                            a, telethon.tl.types.DocumentAttributeSticker)
                    ]
                    if len(alt) > 0:
                        sticker = alt[0]
                else:
                    med = self._get_media(m)

            # Message.
            typ = "message"
            if m.action:
                if isinstance(m.action,
                              telethon.tl.types.MessageActionChatAddUser):
                    typ = "user_joined"
                elif isinstance(m.action,
                                telethon.tl.types.MessageActionChatDeleteUser):
                    typ = "user_left"

            yield Message(type=typ,
                          id=m.id,
                          date=m.date,
                          edit_date=m.edit_date,
                          content=sticker if sticker else m.raw_text,
                          reply_to=m.reply_to_msg_id if m.reply_to
                          and m.reply_to.reply_to_msg_id else None,
                          user=self._get_user(m.sender),
                          media=med)

    def _get_user(self, u) -> User:
        tags = []
        if u.bot:
            tags.append("bot")

        if u.scam:
            tags.append("scam")

        if u.fake:
            tags.append("fake")

        # Download sender's profile photo if it's not already cached.
        avatar = None
        if self.config["download_avatars"]:
            try:
                fname = self._download_avatar(u)
                avatar = fname
            except Exception as e:
                logging.error("error downloading avatar: #{}: {}".format(
                    u.id, e))

        return User(id=u.id,
                    username=u.username if u.username else str(u.id),
                    first_name=u.first_name,
                    last_name=u.last_name,
                    tags=tags,
                    avatar=avatar)

    def _get_media(self, msg):
        if isinstance(msg.media, telethon.tl.types.MessageMediaWebPage) and \
                not isinstance(msg.media.webpage, telethon.tl.types.WebPageEmpty):
            return Media(id=msg.id,
                         type="webpage",
                         url=msg.media.webpage.url,
                         title=msg.media.webpage.title,
                         description=msg.media.webpage.description
                         if msg.media.webpage.description else None,
                         thumb=None)
        elif isinstance(msg.media, telethon.tl.types.MessageMediaPhoto) or \
                isinstance(msg.media, telethon.tl.types.MessageMediaDocument) or \
                isinstance(msg.media, telethon.tl.types.MessageMediaContact):
            if self.config["download_media"]:
                logging.info("downloading media #{}".format(msg.id))
                try:
                    basename, fname, thumb = self._download_media(msg)
                    return Media(id=msg.id,
                                 type="photo",
                                 url=fname,
                                 title=basename,
                                 description=None,
                                 thumb=thumb)
                except Exception as e:
                    logging.error("error downloading media: #{}: {}".format(
                        msg.id, e))

    def _download_media(self, msg) -> [str, str, str]:
        """
        Download a media / file attached to a message and return its original
        filename, sanitized name on disk, and the thumbnail (if any). 
        """
        # Download the media to the temp dir and copy it back as
        # there does not seem to be a way to get the canonical
        # filename before the download.
        fpath = self.client.download_media(msg, file=tempfile.gettempdir())
        basename = os.path.basename(fpath)

        newname = "{}.{}".format(msg.id, self._get_file_ext(basename))
        shutil.move(fpath, os.path.join(self.config["media_dir"], newname))

        # If it's a photo, download the thumbnail.
        tname = None
        if isinstance(msg.media, telethon.tl.types.MessageMediaPhoto):
            tpath = self.client.download_media(msg,
                                               file=tempfile.gettempdir(),
                                               thumb=1)
            tname = "thumb_{}.{}".format(
                msg.id, self._get_file_ext(os.path.basename(tpath)))
            shutil.move(tpath, os.path.join(self.config["media_dir"], tname))

        return basename, newname, tname

    def _get_file_ext(self, f) -> str:
        if "." in f:
            e = f.split(".")[-1]
            if len(e) < 6:
                return e

        return ".file"

    def _download_avatar(self, user):
        fname = "avatar_{}.jpg".format(user.id)
        fpath = os.path.join(self.config["media_dir"], fname)

        if os.path.exists(fpath):
            return fname

        logging.info("downloading avatar #{}".format(user.id))

        # Download the file into a container, resize it, and then write to disk.
        b = BytesIO()
        self.client.download_profile_photo(user, file=b)

        im = Image.open(b)
        im.thumbnail(self.config["avatar_size"], Image.ANTIALIAS)
        im.save(fpath, "JPEG")

        return fname
Example #4
0
with bot:
   # bot.send_message('me', 'Hello, myself!')
    me = bot.get_me()

    # "me" is an User object. You can pretty-print
    # any Telegram object with the "stringify" method:
    print(me.stringify())

    # When you print something, you see a representation of it.
    # You can access all attributes of Telegram objects with
    # the dot operator. For example, to get the username:
    username = me.username
    print(username)
    print(me.phone)

    print(bot.download_profile_photo('me'))

    @bot.on(events.NewMessage(pattern='(?i).*Hello'))
    async def handler(event):
        await event.reply('Hey!')
        raise events.StopPropagation

    @bot.on(events.NewMessage(pattern='^https:\/\/(www\.)?you.*'))
    async def handler_link(event):
        chat = await event.get_chat()
        sender = await event.get_sender()
        chat_id = event.chat_id
        sender_id = event.sender_id
        
        downloader = YDownLoader(event.text)
        downloader.start()
Example #5
0
class Sync:
    """
    Sync iterates and receives messages from the Telegram group to the
    local SQLite DB.
    """
    config = {}
    db = None

    def __init__(self, config, session_file, db):
        self.config = config
        self.db = db

        self.client = TelegramClient(session_file, self.config["api_id"],
                                     self.config["api_hash"])
        self.client.start()

        if not os.path.exists(self.config["media_dir"]):
            os.mkdir(self.config["media_dir"])

    def sync(self, ids=None):
        """
        Sync syncs messages from Telegram from the last synced message
        into the local SQLite DB.
        """

        if ids:
            last_id, last_date = (ids, None)
        else:
            last_id, last_date = self.db.get_last_message_id()

        if ids:
            logging.info("fetching message id={}".format(ids))
        elif last_id:
            logging.info("fetching from last message id={} ({})".format(
                last_id, last_date))

        group_id = self._get_group_id(self.config["group"])

        n = 0
        while True:
            has = False
            for m in self._get_messages(group_id,
                                        offset_id=last_id if last_id else 0,
                                        ids=ids):
                if not m:
                    continue

                has = True

                # Inser the records into DB.
                self.db.insert_user(m.user)

                if m.media:
                    self.db.insert_media(m.media)

                self.db.insert_message(m)

                last_date = m.date
                n += 1
                if n % 300 == 0:
                    logging.info("fetched {} messages".format(n))
                    self.db.commit()

                if self.config["fetch_limit"] > 0 and n >= self.config[
                        "fetch_limit"] or ids:
                    has = False
                    break

            self.db.commit()
            if has:
                last_id = m.id
                logging.info(
                    "fetched {} messages. sleeping for {} seconds".format(
                        n, self.config["fetch_wait"]))
                time.sleep(self.config["fetch_wait"])
            else:
                break

        self.db.commit()
        logging.info("finished. fetched {} messages. last message = {}".format(
            n, last_date))

    def _get_messages(self, group, offset_id, ids=None) -> Message:
        # https://docs.telethon.dev/en/latest/quick-references/objects-reference.html#message
        for m in self.client.get_messages(
                group,
                offset_id=offset_id,
                limit=self.config["fetch_batch_size"],
                ids=ids,
                reverse=True):

            if not m or not m.sender:
                continue

            # Media.
            sticker = None
            med = None
            if m.media:
                # If it's a sticker, get the alt value (unicode emoji).
                if isinstance(m.media, telethon.tl.types.MessageMediaDocument) and \
                        hasattr(m.media, "document") and \
                        m.media.document.mime_type == "application/x-tgsticker":
                    alt = [
                        a.alt for a in m.media.document.attributes
                        if isinstance(
                            a, telethon.tl.types.DocumentAttributeSticker)
                    ]
                    if len(alt) > 0:
                        sticker = alt[0]
                elif isinstance(m.media, telethon.tl.types.MessageMediaPoll):
                    med = self._make_poll(m)
                else:
                    med = self._get_media(m)

            # Message.
            typ = "message"
            if m.action:
                if isinstance(m.action,
                              telethon.tl.types.MessageActionChatAddUser):
                    typ = "user_joined"
                elif isinstance(m.action,
                                telethon.tl.types.MessageActionChatDeleteUser):
                    typ = "user_left"

            yield Message(type=typ,
                          id=m.id,
                          date=m.date,
                          edit_date=m.edit_date,
                          content=sticker if sticker else m.raw_text,
                          reply_to=m.reply_to_msg_id if m.reply_to
                          and m.reply_to.reply_to_msg_id else None,
                          user=self._get_user(m.sender),
                          media=med)

    def _get_user(self, u) -> User:
        tags = []
        is_normal_user = isinstance(u, telethon.tl.types.User)

        if is_normal_user:
            if u.bot:
                tags.append("bot")

        if u.scam:
            tags.append("scam")

        if u.fake:
            tags.append("fake")

        # Download sender's profile photo if it's not already cached.
        avatar = None
        if self.config["download_avatars"]:
            try:
                fname = self._download_avatar(u)
                avatar = fname
            except Exception as e:
                logging.error("error downloading avatar: #{}: {}".format(
                    u.id, e))

        return User(id=u.id,
                    username=u.username if u.username else str(u.id),
                    first_name=u.first_name if is_normal_user else None,
                    last_name=u.last_name if is_normal_user else None,
                    tags=tags,
                    avatar=avatar)

    def _make_poll(self, msg):
        options = [{
            "label": a.text,
            "count": 0,
            "correct": False
        } for a in msg.media.poll.answers]

        total = msg.media.results.total_voters
        if msg.media.results.results:
            for i, r in enumerate(msg.media.results.results):
                options[i]["count"] = r.voters
                options[i][
                    "percent"] = r.voters / total * 100 if total > 0 else 0
                options[i]["correct"] = r.correct

        return Media(id=msg.id,
                     type="poll",
                     url=None,
                     title=msg.media.poll.question,
                     description=json.dumps(options),
                     thumb=None)

    def _get_media(self, msg):
        if isinstance(msg.media, telethon.tl.types.MessageMediaWebPage) and \
                not isinstance(msg.media.webpage, telethon.tl.types.WebPageEmpty):
            return Media(id=msg.id,
                         type="webpage",
                         url=msg.media.webpage.url,
                         title=msg.media.webpage.title,
                         description=msg.media.webpage.description
                         if msg.media.webpage.description else None,
                         thumb=None)
        elif isinstance(msg.media, telethon.tl.types.MessageMediaPhoto) or \
                isinstance(msg.media, telethon.tl.types.MessageMediaDocument) or \
                isinstance(msg.media, telethon.tl.types.MessageMediaContact):
            if self.config["download_media"]:
                logging.info("downloading media #{}".format(msg.id))
                try:
                    basename, fname, thumb = self._download_media(msg)
                    return Media(id=msg.id,
                                 type="photo",
                                 url=fname,
                                 title=basename,
                                 description=None,
                                 thumb=thumb)
                except Exception as e:
                    logging.error("error downloading media: #{}: {}".format(
                        msg.id, e))

    def _download_media(self, msg) -> [str, str, str]:
        """
        Download a media / file attached to a message and return its original
        filename, sanitized name on disk, and the thumbnail (if any). 
        """
        # Download the media to the temp dir and copy it back as
        # there does not seem to be a way to get the canonical
        # filename before the download.
        fpath = self.client.download_media(msg, file=tempfile.gettempdir())
        basename = os.path.basename(fpath)

        newname = "{}.{}".format(msg.id, self._get_file_ext(basename))
        shutil.move(fpath, os.path.join(self.config["media_dir"], newname))

        # If it's a photo, download the thumbnail.
        tname = None
        if isinstance(msg.media, telethon.tl.types.MessageMediaPhoto):
            tpath = self.client.download_media(msg,
                                               file=tempfile.gettempdir(),
                                               thumb=1)
            tname = "thumb_{}.{}".format(
                msg.id, self._get_file_ext(os.path.basename(tpath)))
            shutil.move(tpath, os.path.join(self.config["media_dir"], tname))

        return basename, newname, tname

    def _get_file_ext(self, f) -> str:
        if "." in f:
            e = f.split(".")[-1]
            if len(e) < 6:
                return e

        return ".file"

    def _download_avatar(self, user):
        fname = "avatar_{}.jpg".format(user.id)
        fpath = os.path.join(self.config["media_dir"], fname)

        if os.path.exists(fpath):
            return fname

        logging.info("downloading avatar #{}".format(user.id))

        # Download the file into a container, resize it, and then write to disk.
        b = BytesIO()
        self.client.download_profile_photo(user, file=b)

        im = Image.open(b)
        im.thumbnail(self.config["avatar_size"], Image.ANTIALIAS)
        im.save(fpath, "JPEG")

        return fname

    def _get_group_id(self, group):
        """
        Syncs the Entity cache and returns the Entity ID for the specified group,
        which can be a str/int for group ID, group name, or a group username.

        The authorized user must be a part of the group.
        """
        # Get all dialogs for the authorized user, which also
        # syncs the entity cache to get latest entities
        # ref: https://docs.telethon.dev/en/latest/concepts/entities.html#getting-entities
        _ = self.client.get_dialogs()

        try:
            # If the passed group is a group ID, extract it.
            group = int(group)
        except ValueError:
            # Not a group ID, we have either a group name or
            # a group username: @group-username
            pass

        try:
            entity = self.client.get_entity(group)
        except ValueError:
            logging.critical(
                "the group: {} does not exist,"
                " or the authorized user is not a participant!".format(group))
            # This is a critical error, so exit with code: 1
            exit(1)

        return entity.id
Example #6
0
        id=[contact_info.id]
    ))
    contact_info = result.users[0]
    res.append(contact_info.id)
    if contact_info.username is not None: res.append( "@" + contact_info.username)
    else: res.append(contact_info.username)
    res.append(contact_info.first_name)
    res.append(contact_info.last_name)
    res.append(contact_info.lang_code)
    if hasattr(contact_info.status, "was_online"):
        res.append(contact_info.status.was_online.astimezone(pytz.timezone('Europe/Kiev')))
    elif str(contact_info.status) == "UserStatusRecently()":
        res.append("Статус скрыт")
    else:
        res.append("Online")
    res.append(client.download_profile_photo(contact_info.id))
except Exception as err:
    print(err)
    bot.send_message(chatId, "Nomer nezaregan ili scrut")
    exit()

masName = ["*Number: *+", "*Telegram ID: *", "*Username: *", "*First_name: *", "*Last_name: *", "*language_code: *", "*Last_Online: *"]
resultString = ""
for i in range(len(masName)):
    if str(res[i]) == "None":
        continue
    resultString += str(masName[i]) + str(res[i]) + "\n"

keyboard = telebot.types.InlineKeyboardMarkup(row_width=1)
button = telebot.types.InlineKeyboardButton(text='Проверить WhatsApp', url='https://wa.me/%s'%res[0])
button1 = telebot.types.InlineKeyboardButton(text='Загуглить телефон', url='https://www.google.ru/search?q=+%s'%res[0])