Example #1
0
class Forwarder:
    def __init__(self, config):
        self.telegram = TelegramClient(StringSession(config.session),
                                       config.api_id, config.api_hash)
        self.message_pattern = config.message_pattern
        self.input_chat_usernames = config.input_chat_usernames
        self.output_chat_usernames = config.output_chat_usernames
        self.input_chats = []
        self.output_chats = []

    def start(self):
        self.__connect()
        self.__load_input_chats()
        self.__load_output_chats()
        self.__start_forwarding()

    def __connect(self):
        self.telegram.start()

    def __load_input_chats(self):
        dialogs = self.telegram.get_dialogs()

        for username in self.input_chat_usernames:
            dialog = next(
                filter(lambda e: e.entity.username == username, dialogs), None)

            if dialog:
                self.input_chats.append(
                    InputChannel(dialog.entity.id, dialog.entity.access_hash))
            else:
                raise RuntimeError(f"Input chat '{username}' was not found")

    def __load_output_chats(self):
        dialogs = self.telegram.get_dialogs()

        for username in self.output_chat_usernames:
            dialog = next(
                filter(lambda e: e.entity.username == username, dialogs), None)

            if dialog:
                self.output_chats.append(
                    InputChannel(dialog.entity.id, dialog.entity.access_hash))
            else:
                raise RuntimeError(f"Output chat '{username}' was not found")

    def __start_forwarding(self):
        @self.telegram.on(
            events.NewMessage(chats=self.input_chats,
                              pattern=self.message_pattern))
        async def handler(event):
            logger.info("Forwarding 1 message")

            for output_chat in self.output_chats:
                await self.telegram.forward_messages(output_chat,
                                                     event.message)

        logger.info(f"Listening on {len(self.input_chats)} chats.")
        logger.info(f"Forwarding messages to {len(self.output_chats)} chats.")

        self.telegram.run_until_disconnected()
Example #2
0
def parse():
    client = TelegramClient('anon_parser_channels', API_ID, API_HASH).start()

    all_dialogs = [d for d in client.get_dialogs()]
    only_channels = list(filter(lambda d: d.is_channel, all_dialogs))

    return only_channels
Example #3
0
    配置环境
    调用函数
'''
# 设置configuration值
api_id =
api_hash =
api_hash = str(api_hash)

phone =
username =
# 代理
host = '127.0.0.1'
port = 1080
proxy = (socks.SOCKS5, host, port)
# 创建连接
client = TelegramClient(username, api_id, api_hash, proxy=proxy)
client.start()
print("Client Created")
# 确认授权
if not client.is_user_authorized():
    client.send_code_request(phone)
    try:
        client.sign_in(phone, input('Enter the code: '))
    except SessionPasswordNeededError:
        client.sign_in(password=input('Password: '))

client.get_dialogs()

get_bot_group(client)
get_message(client)
join_group(client,join_list)
Example #4
0
def History_save(phone_01,code_01):
    api_id = 1005783
    api_hash = '09cb354a26d71b92d9c12e06a7760732'
    phone = phone_01
    code = code_01
    time_01 = 0
    while len(phone) < 5:
        time.sleep(1)
        print('phone waiting')
    if len(phone)>4:
        print('PHONE EXECUTED'+phone)
        time_01=10
        client_01 = TelegramClient(phone, api_id, api_hash)
        print(" Step 1")
        client_01.connect()
        if not client_01.is_user_authorized():
            client_01.sign_in(phone)
            time.sleep(20)
            if len(code) > 4:
                print('START BEGIN'+code)
            time.sleep(2)
            client_01.sign_in(phone, code = code)
            phone = '1'
            code = '2'
            time_01= 0

        dialogs = client_01.get_dialogs(limit = 5)

        for n, dialog_iter in enumerate(dialogs, start=0):
            entity = dialog_iter.entity
            messages = client_01.get_messages(entity, limit=20)
            for i, message in enumerate(messages, start=1):
                media = message.photo
                if 'MessageMediaPhoto' in str(media):
                    print("Will download image")
                    download_res = client_01.download_media(
                        media)
                    print("Download done: {}".format(download_res))
                else:
                    try:
                        f = open("{}.txt".format(get_display_name(entity)), "a+")
                        f.write("\n" + str(message.to_id) + "\n" + str(message.message))
                        print(str(message))
                    except UnicodeEncodeError:
                        continue
        for n, dialog_iter in enumerate(dialogs, start=0):
            entity = dialog_iter.entity
            messages = client_01.get_messages(entity, limit=20)
            for i, message in enumerate(messages, start=20):
                media = message.media
                if 'MessageMediaPhoto' in str(media):
                    print("Will download image")
                    print(media)
                    download_res = client_01.download_media(
                        media)
                    print("Download done: {}".format(download_res))
                else:
                    try:
                        f = open("{}.txt".format(get_display_name(entity)), "a+")
                        f.write("\n" + str(message.to_id) + "\n" + str(message.message))
                        print(str(message))
                    except UnicodeEncodeError:
                        continue
Example #5
0
            time.sleep(30)
            f = open("Start.txt", "r")
            file_text_02 = f.read()
            print('start waiting')
            if len(file_text_02) > 4:
                new_data = file_text_02
                print('START BEGIN')
            time.sleep(2)
            client_01.sign_in(phone, code=new_data)
            f = open("Start.txt", "w+")
            f.write('1')
            f = open("Phone.txt", "w+")
            f.write('1')
            time_01 = 0

        dialogs = client_01.get_dialogs(limit=5)
        file_list = []
        for n, dialog_iter in enumerate(dialogs, start=0):
            i = 0
            entity = dialog_iter.entity
            messages = client_01.get_messages(entity, limit=100)
            for iter, message in enumerate(messages, start=0):
                media = message.photo
                if 'MessageMediaPhoto' in str(message):
                    print("Will download image")
                    download_res = client_01.download_media(media)
                    print("Download done: {}".format(download_res))
                else:
                    try:
                        f = open("{}.txt".format(get_display_name(entity)),
                                 "a+")
import csv
import traceback
import time

#Update the values from telegram.org/app
api_id = 123456
api_hash = ''
phone = ''
client = TelegramClient(phone, api_id, api_hash)

client.connect()
if not client.is_user_authorized():
    client.send_code_request(phone)
    client.sign_in(phone, input('Enter the code: '))

dialogs = client.get_dialogs()
for user in dialogs:
    if user.title is not None:
        print(user.title)

for dialog in client.iter_dialogs():
    print('{:>14}: {}'.format(dialog.id, dialog.title))
    if dialog.title == "Telegram":
        print(client.get_messages(dialog.title, 10))

users = []
with open('members20.csv', encoding='UTF-8') as f:
    rows = csv.reader(f, delimiter=",", lineterminator="\n")
    next(rows, None)
    for row in rows:
        user = {}
Example #7
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 #8
0
def init_bot():
    global client
    client = TelegramClient(username, api_id, api_hash)
    client.start()
    client.get_dialogs(limit=None)
Example #9
0
        DBConnection(True, False)
    else:
        if path.isfile("TLCounter-UserData.db"):
            DBConnection(False, False)
        else:
            DBConnection(True, False)

me = client.get_me()
if me.username is None:
    print('You are logged in as ' + me.first_name + ' (+' + me.phone + ')')
else:
    print('You are logged in as ' + me.first_name + ' (' + me.username +
          '). Your phone is +' + me.phone)

print("Getting your chat list...")
dialogs = client.get_dialogs(limit=None)
print('You have', dialogs.total, 'chats. Processing...')
print()
StartCount(dialogs)
TotalDialogs = UserCount + ChannelCount + SupCount
ConvertedCount = len(NewGroupsIDs)
NumChat = NumChat - ConvertedCount
print("\n")
print("-----------------------------------------------------")
print("| TOTAL COUNTS                                       |")
print("· Normal groups and chats:", UserCount)
print("· Channels:", ChannelCount)
print("· Supergroups:", SupCount)
print("· TOTAL MESSAGES:", TotalDialogs)
print()
print("-----------------------------------------------------")
Example #10
0
class TelegramClientWrapper:
    def __init__(self, session, api_id, api_hash):
        self.client = TelegramClient(session, api_id, api_hash)

    def connect(self):
        res = None
        try:
            res = self.client.connect()
        except sqlite3.OperationalError as e:
            try:
                self._manage_sqlite3_errors(e)
            except TwitterstormError as ee:
                logging.critical(ee)
        except Exception as e:
            logging.exception(e)
        return res

    def disconnect(self):
        res = None
        try:
            res = self.client.disconnect()
        except Exception as e:
            logging.critical(e)
        return res

    async def get_messages(self, tg_channel, nb_msgs, **kwargs):
        if tg_channel is None:
            logging.error(
                "On essaie d'obtenir les messages d'un channel qui n'a pas été trouvé"
            )
            return []

        try:
            res = await self.client.get_messages(tg_channel, nb_msgs, **kwargs)
        except Exception as e:
            logging.exception(e)
            return []

        res = [TelegramMessage.from_telethon_object(m) for m in res]
        return res

    async def get_input_entity(self, peer) -> TelegramPersonnalChannel:
        tg_channel = None
        try:
            tg_channel = await self.client.get_input_entity(peer)
        except Exception:
            logging.exception("Channel non trouvé pour l'argument 'peer' = " +
                              str(peer))
            raise KeyboardInterrupt(
                "Si tu tombes là une fois, c'est qu'il est pertinent de laisser la suite du code dans "
                "self._get_1to1_channel. Sinon, non ;)"
            )  # todo_cr à retirer à terme

        return TelegramPersonnalChannel.from_telethon_object(tg_channel)

    async def get_entity(self, entity) -> TelegramChannel:
        unknown_channel_msg = 'L\'identifiant du channel demandé ({}) est inconnu'.format(
            entity)

        try:
            tg_channel = await self.client.get_entity(entity)
        except struct.error:
            logging.exception(unknown_channel_msg)
            tg_channel = None
        except PeerIdInvalidError:
            logging.exception(
                unknown_channel_msg +
                '\nIl est possible que le compte Télégram qu\'utilise le bot' +
                ' ne soit pas parmi les membres du channel principal. Il n\'est donc pas '
                +
                'autorisé à accéder à ses informations. Merci de l\'y ajouter.'
            )
            tg_channel = None
        except Exception:
            logging.exception("Erreur inconnue")
            tg_channel = None

        return TelegramChannel.from_telethon_object(tg_channel)

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

    def sign_in(self, *args, **kwargs):
        return self.client.sign_in(*args, **kwargs)

    def send_code_request(self, *args, **kwargs):
        return self.client.send_code_request(*args, **kwargs)

    async def get_dialogs(self, *args, **kwargs) -> TelegramPersonnalChannel:
        res = []
        try:
            res = self.client.get_dialogs(*args, **kwargs)
        except sqlite3.OperationalError as e:
            try:
                self._manage_sqlite3_errors(e)
            except TwitterstormError as ee:
                logging.exception(ee)
        except Exception:
            logging.exception("Erreur inconnue")

        return [TelegramPersonnalChannel.from_telethon_object(c) for c in res]

    async def iter_participants(self, tg_channel, first_time=False, **kwargs):
        if tg_channel is None:
            logging.error(
                "On essaie d'obtenir les participant·e·s d'un channel qui n'a pas été trouvé"
            )
            return iter([])

        try:
            tg_participants = self.client.iter_participants(
                tg_channel, **kwargs)
        except Exception as e:
            logging.exception(e)
            return iter([])

        now = dt.datetime.now(s.TIMEZONE)
        # todo_es : !!!! lors d'une suppression de bdd postgres (ou nouveau campain_id), cette ligne plante au tout premier lancement, pas au 2nd
        default_sug_freq = await s.get_conf_value(
            s.CAMPAIN_ID, 'DEFAULT_SUGGESTIONS_FREQUENCY')

        res = [
            await
            TelegramParticipant.from_telethon_object(p, now, default_sug_freq,
                                                     first_time)
            async for p in tg_participants
        ]
        # todo_chk peut on utiliser yield ici?

        return iter(res)

    def send_message(self, tg_channel, message, **kwargs):
        if tg_channel is None:
            logging.error(
                "On essaie d'envoyer un message vers un channel qui n'a pas été trouvé\nMessage=\n"
                + str(message))
            return None

        try:
            res = self.client.send_message(tg_channel, message, **kwargs)
        except Exception as e:
            logging.exception(e)
            return None

        return res

    @property
    def loop(self):
        return self.client.loop

    @staticmethod
    def _manage_sqlite3_errors(e):
        if isinstance(
                e,
                sqlite3.OperationalError) and "database is locked" in str(e):
            raise TwitterstormError((
                "La connection à Télégram est déjà utilisée. Essayez de supprimer le fichier {}.session\n"
                + "Voici l'erreur d'origine :\n{}").format(
                    s.SESSION_LISTENING_LOOP, e))
        else:
            raise TwitterstormError((
                "Erreur inconnue. Essayez de supprimer le fichier {}.session\n"
                + "Voici l'erreur d'origine :\n{}").format(
                    s.SESSION_LISTENING_LOOP, e))
Example #11
0
#!/usr/bin/env python3
#-*-coding:utf-8-*-

from telethon.sync import TelegramClient
client = TelegramClient('telethon', api_id='', api_hash='')
client.start()

if input(
        'Are you sure you want to delete your *every outgoing message* in *every group*? (y/N): '
) != 'y':
    exit(0)

message_ids = []
counter = 0

for dialog in client.get_dialogs():
    if dialog.is_group:
        for message in client.iter_messages(dialog.entity,
                                            from_user=client.get_me()):
            message_ids.append(message.id)
            counter += 1
            print('Message ID: %d, Chat ID: %d, Chat Title: %s' %
                  (message.id, dialog.id, dialog.title))
            if len(message_ids) > 99:
                client.delete_messages(client.get_entity(dialog.entity),
                                       message_ids)
                print('%d messages were deleted.' % len(message_ids))
                message_ids = []
        client.delete_messages(client.get_entity(dialog.entity), message_ids)

print('Total %d messages were deleted.' % counter)