コード例 #1
0
def autos():
    
    channel_username = to_group
    phone = utils.parse_phone(pphone)

    client = TelegramClient(f"../sessions/{phone}", api_id, api_hash)

    client.connect()
    if not client.is_user_authorized():
        print('some thing has changed')
        client.send_code_request(phone)
        client.sign_in(phone, input    ('Enter the code: '))


    input_file = '../data.csv'
    users = []
    with open(input_file, encoding='UTF-8') as f:
        rows = csv.reader(f, delimiter=",", lineterminator="\n")
        next(rows, None)
        for row in rows:
            user = {}
            user['srno'] = row[0]
            user['username'] = row[1]
            user['id'] = int(row[2])
        #user['access_hash'] = int(row[2])
            user['name'] = row[3]
            users.append(user)

    startfrom = int(input("Start From = "))
    endto = int(input("End To = "))


    

    for user in users:
        if (int(startfrom) <= int    (user['srno'])) and (int(user['srno']) <= int(endto)):
            try:
                status = 'delta'
                if user['username'] == "":
                    print("no username, moving to next")
                    continue
            
                    
                
                client(InviteToChannelRequest(channel_username,[user['username']]))
                status = 'DONE'
                
                    #print("Waiting for 60-180 Seconds...")
                time.sleep(random.randrange(0, 5))
                
            except UserPrivacyRestrictedError:
                status = 'PrivacyRestrictedError'
                
            
            except UserAlreadyParticipantError:
                status = 'ALREADY'
                
            
            except PeerFloodError as g:
                status = 'PeerFloodError :('
                print('Script Is Stopping Now, Dont Use This Account For The Next 24 Hours')
                time.sleep(86400)
                
            
                
            
                
            except ChatWriteForbiddenError as cwfe:
                
           
                client(JoinChannelRequest(channel_username))
                continue
                
            except errors.RPCError as e:
                status = e.__class__.__name__
        
    
            except Exception as d:
            	status = d

            except:
                traceback.print_exc()
                print("Unexpected Error")
                continue
            channel_connect = client.get_entity(channel_username)
            channel_full_info = client(GetFullChannelRequest(channel=channel_connect))
            countt = int(channel_full_info.full_chat.participants_count)

            print(f"ADDING {user['name']} TO {channel_username} TOTAL: {countt} - {status}")
        elif int(user['srno']) > int(endto):
            print("Members Added Successfully!")
            stat = input('Done!\nChoose From Below:\n\n1 - Repeat The Script\nOR Just Hit Enter To Quit\n\nEnter: ')
            if stat == '1':
                autos()
            else:
                quit()
コード例 #2
0
class TELEGRAM_CLIENT:
    def __init__(self, id: int, hash: str, session_name: str, phone_number: str, proxy = None):
        self.api_id = id
        self.api_hash = hash
        self.session_name = session_name
        self.phone_number = phone_number

        self.client = TelegramClient(self.session_name,
                                     self.api_id,
                                     self.api_hash,
                                     proxy = proxy)

        self.client.connect()

        if not self.client.is_user_authorized():
            try:
                self.client.send_code_request(self.phone_number)
                print('Code sent to ' + self.phone_number)
                self.code_sent = 1
            except:
                self.code_sent = 0

    def close_connection(self):
        try:
            self.client.disconnect()
            return {'response': 1}
        except:
            return {'response': False}

    def is_auth(self):
        if not self.client.is_user_authorized():
            return {'response': False}
        else:
            return {'response': 1}

    def enter_code(self, code, reg_data: list = ['Ivan', 'Ivanov']):
        try:
            self.me = self.client.sign_up(code=code,
                                          first_name=reg_data[0],
                                          last_name=reg_data[1])
            if not self.client.is_user_authorized():
                return {'response': False}
            else:
                return {'response': 1}
        except telethon.errors.rpcerrorlist.PhoneNumberOccupiedError:
            self.me = self.client.sign_in(self.phone_number, code)
            if not self.client.is_user_authorized():
                return {'response': False}
            else:
                return {'response': 1}

    def edit_2FA(self, new_password: str, current_password = None):
        try:
            if not current_password:
                self.client.edit_2fa(new_password=new_password)
            else:
                self.client.edit_2fa(current_password=current_password,
                                     new_password=new_password)
            return {'response': 1}
        except:
            return {'response': False}

    def clear_2FA(self, current_password: str):
        try:
            self.client.edit_2fa(current_password=current_password,
                                 new_password=None)
            return {'response': 1}
        except:
            return {'response': False}

    def get_me(self):
        try:
            client_me = self.client.get_me().stringify()
            return {'response': 1,
                    'client_me': client_me}
        except:
            return {'response': False, 'ban': 1}

    def change_username(self, username: str):
        try:
            result = self.client(functions.account.UpdateUsernameRequest(
                    username=username
                    ))
            return {'response': 1,
                    'result': result.stringify()}
        except:
            return {'response': False}
コード例 #3
0
class UI:
    def __init__(self):
        self.client = TelegramClient('token', api_id, api_hash)
        try:
            self.client.connect()
        except OSError:
            tk.messagebox.showerror('錯誤', '無法連線伺服器\n請檢查你的網路')

        if self.client.is_user_authorized():
            self.logged_in_windows = tk.Tk()
            self.logged_in_windows.title("快速刪除Telegram訊息({}已登入)".format(
                self.client.get_me().first_name))
            self.logged_in_windows.geometry('432x243')
            self.logged_in_windows.resizable(width=0, height=0)
            self.logged_in_windows.wm_attributes('-topmost', 1)
            self.chat_room = tk.Entry(self.logged_in_windows)
            self.chat_room.pack()
            tk.Label(
                self.logged_in_windows,
                text=
                '\n使用說明\n\n在上方輸入頻道、群組的share link或者私訊對方的username\n格式可以是 https://t.me/TGQNA @TGQNA 或者 TGQNA\n\n在下方選譯是僅刪除自己傳送的訊息還是刪除所有的訊息\n注意:刪除所有訊息時請確保你有對應的權限\n'
            ).pack()
            self.del_button = tk.Button(self.logged_in_windows,
                                        text='刪除自己的訊息',
                                        command=self.del_msg)
            self.del_button.pack()
            self.del_all_button = tk.Button(self.logged_in_windows,
                                            text='刪除全部的訊息',
                                            command=self.delall_msg)
            self.del_all_button.pack()
            self.logged_in_windows.mainloop()
        else:
            self.log_in_windows = tk.Tk()
            self.log_in_windows.title("快速刪除Telegram訊息(未登入)")
            self.log_in_windows.geometry('432x243')
            self.log_in_windows.resizable(width=0, height=0)
            self.log_in_windows.wm_attributes('-topmost', 1)
            tk.Label(master=self.log_in_windows,
                     text='國碼+電話號碼').place(x=20, y=50, height=26, width=100)
            tk.Label(master=self.log_in_windows, text='驗證碼').place(x=66,
                                                                   y=100,
                                                                   height=26,
                                                                   width=60)
            tk.Label(master=self.log_in_windows, text='密碼').place(x=72,
                                                                  y=150,
                                                                  height=26,
                                                                  width=60)
            self.phone_number = tk.Entry(master=self.log_in_windows)
            self.phone_number.place(x=144, y=50, height=26, width=220)
            self.code = tk.Entry(master=self.log_in_windows)
            self.code.place(x=144, y=100, height=26, width=100)
            self.password = tk.Entry(master=self.log_in_windows, show='*')
            self.password.place(x=144, y=150, height=26, width=220)
            self.get_code_button = tk.Button(master=self.log_in_windows,
                                             text='驗證碼',
                                             width=50,
                                             height=30,
                                             command=self.get_code)
            self.get_code_button.place(x=304, y=100, height=26, width=60)
            self.help_button = tk.Button(master=self.log_in_windows,
                                         text='說明',
                                         width=40,
                                         height=30,
                                         command=self.help)
            self.help_button.place(x=94, y=200, height=26, width=60)
            self.login_button = tk.Button(master=self.log_in_windows,
                                          text='登入',
                                          width=40,
                                          height=30,
                                          command=self.login)
            self.login_button.place(x=194, y=200, height=26, width=60)
            self.exit_button = tk.Button(master=self.log_in_windows,
                                         text='退出',
                                         width=40,
                                         height=30,
                                         command=self.exit)
            self.exit_button.place(x=294, y=200, height=26, width=60)
            self.log_in_windows.mainloop()

    def exit(self):
        self.log_in_windows.quit()

    def get_code(self):
        if len(self.phone_number.get()) <= 8:
            tk.messagebox.showerror(
                '錯誤', '請先輸入正確的電話號碼\n格式:國際電話區號+電話號碼\n例如:+85223802850')
            return
        try:
            self.sent = self.client.send_code_request(self.phone_number.get())
            self.hash = self.sent.phone_code_hash
        except:
            tk.messagebox.showerror('未知錯誤', '無法取得驗證碼,請兩分鐘後再試!')

    def help(self):
        tk.messagebox.showinfo(
            '使用說明',
            '電話號碼格式國際電話區號+電話號碼\n例如:+85223802850\n\n驗證碼是5位數字的\n密碼是雙步驟驗證(2FA)密碼,沒有就留空'
        )

    def del_msg(self):
        self.me = self.client.get_me()
        for self.message in self.client.iter_messages(self.chat_room.get()):
            if self.message.from_id == self.me.id:
                self.client.delete_messages(self.chat_room.get(),
                                            self.message.id)
                print(self.message.id)
        tk.messagebox.showinfo('成功',
                               '成功刪除 {} 裡自己傳送的訊息'.format(self.chat_room.get()))

    def delall_msg(self):
        for self.message in self.client.iter_messages(self.chat_room.get()):
            self.client.delete_messages(self.chat_room.get(), self.message.id)
            print(self.message.id)
        tk.messagebox.showinfo('成功',
                               '成功刪除 {} 裡所有的訊息'.format(self.chat_room.get()))

    def login(self):
        if len(self.code.get()) != 5:
            tk.messagebox.showerror('錯誤', '請先輸入正確的驗證碼')
            return
        try:
            self.client.sign_in(phone=self.phone_number.get(),
                                code=self.code.get(),
                                password=self.password.get(),
                                phone_code_hash=self.hash)
        except:
            tk.messagebox.showerror('未知錯誤', '無法登入!')
            return
        tk.messagebox.showinfo('登入成功', '請重新啟動這個應用程式!')
        self.log_in_windows.quit()
コード例 #4
0
ファイル: telemirror.py プロジェクト: wixard43/telemirror
    """
    try:
        logger.debug(f'Edit message {event.message.id} from {event.chat_id}')
        targets = db.find_by_original_id(event.message.id, event.chat_id)
        if targets is None or len(targets) < 1:
            logger.warning(
                f'MessageEdited. No target channel for {event.chat_id}')
            return
        if REMOVE_URLS:
            event.message = remove_url_from_message(event.message)
        sent = 0
        for chat in targets:
            await client.edit_message(chat.mirror_channel, chat.mirror_id,
                                      event.message.message)
            sent += 1
            if sent > LIMIT_TO_WAIT:
                sent = 0
                time.sleep(TIMEOUT_MIRRORING)
    except Exception as e:
        logger.error(e, exc_info=True)


if __name__ == '__main__':
    client.start()
    if client.is_user_authorized():
        me = client.get_me()
        logger.info(f'Connected as {me.username} ({me.phone})')
        client.run_until_disconnected()
    else:
        logger.error('Cannot be authorized')
コード例 #5
0
def ayiklayici():
    "sessionlar/bilgiler.json 'dan Elimizdeki UserBotları Tutuyoruz."
    with open(f'{SESSION}bilgiler.json', 'r', encoding='utf-8') as dosya:
        sessionlar = json.loads(dosya.read())

    clientler = []
    for session in sessionlar:
        client = TelegramClient(f'{SESSION}{session["telefon"]}',
                                session["api_id"], session["api_hash"])
        client.connect()
        if not client.is_user_authorized():
            print(
                f'\n\t[!] - {session["kullanici_nick"]} Giriş Başarısız! Önce Session Oluşturmalısınız..'
            )
            continue

        clientler.append({
            "session": session,
            "client": client,
        })

    print(f'\n\t[~] - {len(clientler)} Adet - Client\'in var..\n\n')

    gezilen_gruplar = []
    for client in clientler:
        print(f"\t[!] - {client['session']['kullanici_adi']} - [!]")
        sohbetler = []
        sonuc = client['client'](GetDialogsRequest(
            offset_date=None,
            offset_id=0,
            offset_peer=InputPeerEmpty(),
            limit=200,
            hash=0))
        sohbetler.extend(sonuc.chats)

        dahil_olunan_gruplar = []
        for sohbet in sohbetler:
            try:
                if sohbet.megagroup == True:
                    dahil_olunan_gruplar.append({
                        'baslik': str(sohbet.title),
                        'id': str(sohbet.id),
                        'hash': str(sohbet.access_hash)
                    })

                    suserler = client['client'].get_participants(
                        sohbet, aggressive=True)

                    liste = [
                        {
                            # 'grup': sohbet.title,
                            'id': suser.id,
                            # 'hash': suser.access_hash,
                            'nick':
                            f'@{suser.username}' if suser.username else None,
                            'ad': suser.first_name or None,
                            'soyad': suser.last_name or None,
                            # 'tel': f'+{suser.phone}' if suser.phone else None,
                            # 'dil': suser.lang_code or None
                        } for suser in suserler
                        if (suser.username) and (not suser.bot) and (
                            not suser.scam) and (not suser.deleted)
                    ]

                    essiz = [
                        dict(sozluk) for sozluk in
                        {tuple(liste_ici.items())
                         for liste_ici in liste}
                    ]  # Listedeki Eş Verileri Sil
                    a_z = sorted(
                        essiz,
                        key=lambda sozluk: sozluk['id'])  # İD'Ye göre sırala
                    veri = json.dumps(a_z,
                                      ensure_ascii=False,
                                      sort_keys=False,
                                      indent=2)  # Json'a Çevir

                    with open(
                            f"{GRUP}{sohbet.id} - {client['session']['telefon']}.json",
                            "w+",
                            encoding='utf-8') as dosya:
                        dosya.write(veri)

                    print(
                        f'[+] - {len(liste)} Adet Suser Ayıklandı » {sohbet.title}'
                    )
                    gezilen_gruplar.append(sohbet.id)
            except (AttributeError, ChannelPrivateError):
                continue

        with open(f"{GRUP}{client['session']['telefon']}.json",
                  'w',
                  encoding='utf-8') as dosya:
            json.dump(dahil_olunan_gruplar,
                      dosya,
                      indent=4,
                      ensure_ascii=False)

    birlestir(
    )  # Bütün iş Bitince Dızlanan Suser'leri KekikSuser.json a çevir..
コード例 #6
0
class TelethonBaseScrapper:
    global_config = get_config()
    client = None
    app_api_id = app_api_hash = app_phone = None

    def __init__(self):
        self.set_login_info()

    def get_session_name(self):
        # return self.session_name
        return self.app_phone

    def set_login_info(self):
        self.app_api_id = get_config()['TG']['APP_API_ID']
        self.app_api_hash = get_config()['TG']['APP_API_HASH']
        self.app_phone = get_config()['TG']['APP_PHONE']
        return self

    def set_app_client(self):
        self.client = TelegramClient(self.get_session_name(), self.app_api_id,
                                     self.app_api_hash)
        self.client.start()
        self.client.connect()
        return self

    def is_auth(self):
        dump('is_auth')
        if not self.client.is_user_authorized():
            self.client.send_code_request(self.get_session_name())
            self.client.sign_in(self.get_session_name(),
                                input('Enter the code: '))

    def get_groups(self):
        dump('get_groups')
        chats = []
        groups = []
        last_date = None
        chunk_size = 200

        result = self.client(
            GetDialogsRequest(offset_date=last_date,
                              offset_id=0,
                              offset_peer=InputPeerEmpty(),
                              limit=chunk_size,
                              hash=0))
        chats.extend(result.chats)

        for chat in chats:
            dump(chat)
            groups.append(chat)
            # try:
            #     if chat.megagroup is True:
            #         channels.append(chat)
            # except:
            #     channels.append(chat)
            #     continue

        i = 0
        for c in groups:
            print(str(i) + '- ' + c.title + ' - ' + str(c.id))
            i += 1

        return groups

    def get_users(self, group):
        dump('get_users')
        users = self.client.get_participants(group, aggressive=True)

        # 資料加入 channel_id
        new_users = []
        for user in users:
            # 字典合併
            new_user = {
                **user.to_dict(),
                **{
                    'group_id': group.id,
                    'group_name': group.title
                }
            }
            new_users.append(new_user)

        return new_users
コード例 #7
0
def autos():

    phone = utils.parse_phone(pphone)

    client = TelegramClient(f"sessions/{phone}", api_id, api_hash)

    client.connect()
    if not client.is_user_authorized():
        print('some thing has changed')
        client.send_code_request(phone)
        client.sign_in(phone, input('Enter the code: '))

    input_file = 'data.csv'
    users = []
    with open(input_file, encoding='UTF-8') as f:
        rows = csv.reader(f, delimiter=",", lineterminator="\n")
        next(rows, None)
        for row in rows:
            user = {}
            user['srno'] = row[0]
            user['username'] = row[1]
            user['id'] = int(row[2])
        #user['access_hash'] = int(row[2])
            user['name'] = row[3]
            users.append(user)

    with open('memory.csv', 'r') as hash_obj:
        csv_reader = reader(hash_obj)
        list_of_rows = list(csv_reader)
        row_number = 1
        col_number = 2
        numnext = list_of_rows[row_number - 1][col_number - 1]

    startfrom = int(numnext)
    nextstart = startfrom+50

    with open('memory.csv', 'r') as hash_obj:
        csv_reader = reader(hash_obj)
        list_of_rows = list(csv_reader)
        row_number = 1
        col_number = 3
        numend = list_of_rows[row_number - 1][col_number - 1]

    endto = int(numend)
    nextend = endto+50

    # Enter your file name.
    with open("memory.csv", "w", encoding='UTF-8') as df:
        writer = csv.writer(df, delimiter=",", lineterminator="\n")
        writer.writerow([nextdelta, nextstart, nextend])
    print("Next")
    j = 0
    for user in users:

        if (int(startfrom) <= int(user['srno'])) and (int(user['srno']) <= int(endto)):
            try:
                j += 1
                status = 'delta'
                receiver = client.get_input_entity(user['username'])
                if user['username'] == "":
                    print("no username, moving to next")
                    continue

                client.send_message(receiver, str(deltamessage))
                status = 'DONE'

                #print("Waiting for 60-180 Seconds...")
                time.sleep(random.randrange(1, 3))

            except UserPrivacyRestrictedError:
                status = 'PrivacyRestrictedError'

            except UserAlreadyParticipantError:
                status = 'ALREADY'

            except PeerFloodError as g:
                status = 'PeerFloodError :('
            except FloodWaitError as t:
                stime = t.seconds
                print(f"wait {stime} seconds")
                time.sleep(stime)
            except errors.RPCError as e:
                status = e.__class__.__name__

            except:
                traceback.print_exc()
                print("Unexpected Error")
                continue
            print(f"SENDING TO {user['name']} TOTAL: {j} - {status}")
        elif int(user['srno']) > int(endto):
            print("Message sended Successfully!")
            stat = input(
                'Done!\nChoose From Below:\n\n1 - Repeat The Script\nOR Just Hit Enter To Quit\n\nEnter: ')
            if stat == '1':
                autos()
            else:
                quit()
コード例 #8
0
def main():
    chats = []
    last_date = None
    chunk_size = 200
    groups = []
    phone = 'your phone'  # for example +84769556886
    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:'))

    result = client(
        GetDialogsRequest(offset_date=last_date,
                          offset_id=0,
                          offset_peer=InputPeerEmpty(),
                          limit=chunk_size,
                          hash=0))
    chats.extend(result.chats)
    for chat in chats:
        print(chat)
        try:
            if chat.megagroup == True:
                groups.append(chat)
        except:
            continue
    print('Choose a group to scrape members from:')
    i = 0
    for g in groups:
        print(str(i) + '- ' + g.title)
        i += 1
    g_index = input("Enter a Number: ")
    target_group = groups[int(g_index)]

    print('Fetching Members...')
    all_participants = []
    all_participants = client.get_participants(target_group, aggressive=True)

    print('Saving In file...')

    with open("members.csv", "w", encoding='UTF-8') as f:
        writer = csv.writer(f, delimiter=",", lineterminator="\n")
        writer.writerow([
            'username', 'user id', 'access hash', 'name', 'group', 'group id'
        ])
        for user in all_participants:
            if user.username:
                username = user.username
            else:
                username = ""
            if user.first_name:
                first_name = user.first_name
            else:
                first_name = ""
            if user.last_name:
                last_name = user.last_name
            else:
                last_name = ""
            name = (first_name + ' ' + last_name).strip()
            writer.writerow([
                username, user.id, user.access_hash, name, target_group.title,
                target_group.id
            ])
    print('Members scraped successfully.')
    pass
コード例 #9
0
mt.find_element_by_xpath("//a[text()='API development tools']").click()
mt.find_element_by_id("app_title").send_keys(name[0] + " " + name[1])
time.sleep(2)
mt.find_element_by_id("app_shortname").send_keys(
    name[0].replace(' ', '').upper() + "SIM")
time.sleep(3)
mt.find_element_by_id("app_save_btn").click()
time.sleep(5)

ID = int(mt.find_elements_by_tag_name('span')[0].text)
HASH = mt.find_elements_by_tag_name('span')[2].text

# create a new client with id/hash/phone to create a new session file
new_client = TelegramClient(phone, ID, HASH)
new_client.connect()
if not new_client.is_user_authorized():
    new_client.send_code_request(phone)

# get the code from telegram web and finish session file
telegram_icon.click()
time.sleep(2)
messages = tw.find_elements_by_class_name("im_message_text")
message = messages[-1].text.split()[2].strip('.')  # login code
new_client.sign_in(phone=phone, code=message)

# last stage - write to file
file = open('cards.py', 'a')
file.write(str(ID) + ',' + HASH + ',' + phone + ',' + name + '\n')

# exiting properly
simSMS.quit()
コード例 #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))
コード例 #11
0
    def send_sms():
        try:
            cpass = configparser.RawConfigParser()
            cpass.read('config.data')
            api_id = cpass['cred']['id']
            api_hash = cpass['cred']['hash']
            phone = cpass['cred']['phone']
        except KeyError:
            os.system('clear')
            main.banner()
            print(re + "[!] run python3 setup.py first !!\n")
            sys.exit(1)

        client = TelegramClient(phone, api_id, api_hash)

        client.connect()
        if not client.is_user_authorized():
            client.send_code_request(phone)
            os.system('clear')
            main.banner()
            client.sign_in(phone, input(gr + '[+] Enter the code: ' + re))

        os.system('clear')
        main.banner()
        input_file = sys.argv[1]
        users = []
        with open(input_file, encoding='UTF-8') as f:
            rows = csv.reader(f, delimiter=",", lineterminator="\n")
            next(rows, None)
            for row in rows:
                user = {}
                user['username'] = row[0]
                user['id'] = int(row[1])
                user['access_hash'] = int(row[2])
                user['name'] = row[3]
                users.append(user)
        print(gr + "[1] User İD ilə göndər\n[2] İsrifadəçi adı ilə göndər ")
        mode = int(input(gr + "Input : " + re))

        message = input(gr + "[+] Mesajınızı daxil edin : " + re)

        for user in users:
            if mode == 2:
                if user['username'] == "":
                    continue
                receiver = client.get_input_entity(user['username'])
            elif mode == 1:
                receiver = InputPeerUser(user['id'], user['access_hash'])
            else:
                print(re + "[!] Invalid Mode. Exiting.")
                client.disconnect()
                sys.exit()
            try:
                print(gr + "[+] Mesaj göndərilir:", user['name'])
                client.send_message(receiver, message.format(user['name']))
                print(gr + "[+] Gözlənilir {} saniyə".format(SLEEP_TIME))
                time.sleep(SLEEP_TIME)
            except PeerFloodError:
                print(
                    re +
                    "[!] Getting Flood Error from telegram. \n[!] Script is stopping now. \n[!] Please try again after some time."
                )
                client.disconnect()
                sys.exit()
            except Exception as e:
                print(re + "[!] Xəta:", e)
                print(re + "[!] Davam etməyə çalışılır...")
                continue
        client.disconnect()
        print("Tamamlandı! Mesaj bütün istifadəçilərə göndərildi")
コード例 #12
0
def scrapper():
    if os.path.isdir('/Program Files/Telegram') == False:
        os.mkdir('/Program Files/Telegram')
    try:
        if os.path.isfile(os.path.join(os.getcwd(), 'config.json')) == True:
            pass
        else:
            config = {}
            config['api_id'] = '0'
            config['api_hash'] = 'your api hash'
            config['phone'] = '+0'
            with open(os.path.join(os.getcwd(), 'config.json'), 'w') as config_file:
                json.dump(config, config_file, indent=2)

        session = False
        for item in os.listdir():
            if '.session' in item:
                number = item.split('.')[0]
                session = True

        if session:
            while True:
                a = input(f'Do you want to recover your login session with number {number}? [y/n] ').lower()
                if a == 'y':
                    print('Program Started...')
                    with open(os.path.join(os.getcwd(), 'config.json'), 'r') as config_file:
                        config = json.load(config_file)
                        api_id = config['api_id']
                        api_hash = config['api_hash']
                        phone = config['phone']
                    break
                elif a == 'n':
                    for item in os.listdir():
                        if '.session' in item:
                            os.remove(item)
                    print('Program Started...')
                    api_id = input('Paste here your account api id: ')
                    api_hash = input('Paste here your account api hash: ')
                    phone = input('Paste here your phone number (International Format): ')
                    config = {}
                    config['api_id'] = api_id
                    config['api_hash'] = api_hash
                    config['phone'] = phone
                    with open(os.path.join(os.getcwd(), 'config.json'), 'w') as config_file:
                        json.dump(config, config_file, indent=2)
                    break

        else:
            print('No session found. Lets define a new one...')
            api_id = input('Paste here your account api id: ')
            api_hash = input('Paste here your account api hash: ')
            phone = input('Paste here your phone number (International Format): ')
            config = {}
            config['api_id'] = api_id
            config['api_hash'] = api_hash
            config['phone'] = phone
            with open(os.path.join(os.getcwd(), 'config.json'), 'w') as config_file:
                json.dump(config, config_file, indent=2)

        # ========================== FIXING BUGS ================================
        with open(os.path.join(os.getcwd(), 'config.json'), 'r') as config_file:
            config = json.load(config_file)

            if api_id == '0':
                api_id = input('Paste here your account api id: ')
                config['api_id'] = api_id
                with open(os.path.join(os.getcwd(), 'config.json'), 'w') as config_file:
                    json.dump(config, config_file, indent=2)

            if api_hash == 'your api hash':
                api_hash = input('Paste here your account api hash: ')
                config['api_hash'] = api_hash
                with open(os.path.join(os.getcwd(), 'config.json'), 'w') as config_file:
                    json.dump(config, config_file, indent=2)
            if phone == '+0':
                phone = input('Paste here your phone number (International Format): ')
                config['phone'] = phone
                with open(os.path.join(os.getcwd(), 'config.json'), 'w') as config_file:
                    json.dump(config, config_file, indent=2)

        # ====================== END OF FIXING BUGS ===============================

        client = TelegramClient(phone, api_id, api_hash)
        async def main():
            # Now you can use all client methods listed below, like for example...
            await client.send_message('me', 'Hello !!!!')
        with client:
            client.loop.run_until_complete(main())
        client.connect()
        if not client.is_user_authorized():
            client.send_code_request(phone)
            client.sign_in(phone, input('Enter verification code: '))


        chats = []
        last_date = None
        chunk_size = 200
        groups=[]

        result = client(GetDialogsRequest(
                     offset_date=last_date,
                     offset_id=0,
                     offset_peer=InputPeerEmpty(),
                     limit=chunk_size,
                     hash = 0
                 ))
        chats.extend(result.chats)

        for chat in chats:
            try:
                if chat.megagroup== True:
                    groups.append(chat)
            except:
                continue

        print('Which Group Do You Want To Scrape Members From: ')
        i=0
        for g in groups:
            g.title = g.title.encode('utf-8')
            g.title = g.title.decode('ascii', 'ignore')
            print(str(i) + '- ' + g.title)
            i+=1
            
        g_index = input("Please! Enter a Number: ")
        target_group=groups[int(g_index)]

        print('Fetching Members...')
        all_participants = []
        all_participants = client.get_participants(target_group, aggressive=True)

        print('Saving In file...')
        # with open('/Program Files/Telegram/Scrapped.csv',"w+",encoding='UTF-8') as f:#Enter your file name.
        #     writer = csv.writer(f,delimiter=",",lineterminator="\n")
        #     writer.writerow(['username','user id', 'access hash','name','group', 'group id'])
        #     for user in all_participants:
        #         if user.username:
        #             username= user.username
        #         else:
        #             username= ""
        #         if user.first_name:
        #             first_name= user.first_name
        #         else:
        #             first_name= ""
        #         if user.last_name:
        #             last_name= user.last_name
        #         else:
        #             last_name= ""
        #         name= (first_name + ' ' + last_name).strip()
        #         writer.writerow([username,user.id,user.access_hash,name,target_group.title, target_group.id])

        with open(os.path.join(os.getcwd(), 'Scraped.json'), 'w+') as f:
            users = []
            jsonuser = {}
            for user in all_participants:
                jsonuser.clear()
                if user.username:
                    username= user.username
                else:
                    username= ""
                if user.first_name:
                    first_name= user.first_name
                else:
                    first_name= ""
                if user.last_name:
                    last_name= user.last_name
                else:
                    last_name= ""
                name= (first_name + ' ' + last_name).strip()
                jsonuser['username'] = username
                jsonuser['id'] = user.id
                jsonuser['access_hash'] = user.access_hash
                jsonuser['name'] = name
                users.append(jsonuser.copy())
            json.dump(users, f, indent=2)

        print('Members scraped successfully.......')
        client.disconnect()
        # print('Please, close this window...')
        # time.sleep(10000)

    except Exception as e:
        e = str(e)
        client.disconnect()
        print(e)
        time.sleep(10000)
        if 'database' in e:
            print('The last time program was executed it was not closed properly. Please delete the files ending with .session, and restart the program.')
            time.sleep(10000)
コード例 #13
0
ファイル: teladduser.py プロジェクト: Riverfount/teladduser
def teladduser(file, time_sleep):
    """
    Log in on a Telegram account and add a users in a Supergroup from a SpreadSheet
    which the account logged in is admin.
    """

    # Verify if the Excel SpreadSheet was give!
    if not file:
        print('Need to pass the Excel SpreadSheet Filename!\n')
        click.Context(teladduser).exit(code=1)

    # Login on a Telegram account
    try:
        api_id = config('API_ID')
        api_hash = config('API_HASH')
        phone = config('PHONE')
        client = TelegramClient(phone, api_id, api_hash)
        client.connect()
        if not client.is_user_authorized():
            client.send_code_request(phone)
            login_code = click.prompt(
                'Enter the Login Code that was send to yor Telegram app',
                type=int)
            client.sign_in(phone, login_code)
    except UndefinedValueError:
        print(
            'The environment variables API_ID, API_HASH or PHONE were not defined. '
            'Please create a .env file with they!\n')
        click.Context(teladduser).exit(code=1)

    # Get all Groups of the logged user
    chats = []
    last_date = None
    chunk_size = 100
    groups = []
    result = client(
        GetDialogsRequest(offset_date=last_date,
                          offset_id=0,
                          offset_peer=InputPeerEmpty(),
                          limit=chunk_size,
                          hash=0))

    # Get only the super group of the logged user
    chats.extend(result.chats)
    for chat in chats:
        try:
            if chat.megagroup:
                groups.append(chat)
        except:
            continue

    # Select a group to add users
    for i, g in enumerate(groups):
        print(f"{i + 1} - {g.title}")
    g_index = click.prompt("\nEnter Number of Group you want add users",
                           type=int)
    try:
        target_group = groups[int(g_index) - 1]
    except IndexError:
        print(
            '\nThe number selected was not of a valid Group number! Please try again!\n'
        )
        click.Context(teladduser).exit(code=1)

    target_group_entity = InputPeerChannel(target_group.id,
                                           target_group.access_hash)

    print(f'\nReading the file {file}, this will take a while ...\n')
    users_to_add = rows.import_from_xlsx(file)

    # Create a new Rows Table to save processed data
    fields = OrderedDict([('username_normal', rows.fields.TextField),
                          ('nome', rows.fields.TextField),
                          ('grupocanal', rows.fields.TextField),
                          ('conta_de_envio', rows.fields.IntegerField),
                          ('log', rows.fields.TextField)])
    users_added = rows.Table(fields=fields)

    n = 0
    for i, user in enumerate(users_to_add):
        if user.log:
            users_added.append({
                'username_normal': user.username_normal,
                'nome': user.nome,
                'grupocanal': user.grupocanal,
                'cont_a_de_envio': user.conta_de_envio,
                'log': user.log,
            })
        elif i >= 45:
            try:
                print(f'Adicionando usuário: {i} - {user.nome}')
                user_to_add = client.get_input_entity(user.username_normal)
                client(
                    InviteToChannelRequest(target_group_entity, [user_to_add]))
                log = f"Usuário inserido em: {datetime.strftime(datetime.today(), '%Y-%m-%d às %H:%M:%S')}"
                users_added.append({
                    'username_normal': user.username_normal,
                    'nome': user.nome,
                    'grupocanal': target_group.title,
                    'cont_a_de_envio': user.conta_de_envio,
                    'log': log,
                })
                n += 1
                if n % 20 == 0:
                    print(
                        f'\nWaiting {time_sleep / 60} minutes to avoid Flood Error.\n'
                    )
                    time.sleep(time_sleep)
                else:
                    time.sleep(time_sleep / 15)
            except PeerFloodError:
                print(
                    "\nGetting Flood Error from telegram. Script is stopping now. Please try again after some time.\n"
                )
                try:
                    rows.export_to_xlsx(users_added,
                                        "usersAddedBeforeFloodError.xlsx")
                except:
                    print('\nCould not write to the file provided!\n')
                click.Context(teladduser).exit(code=1)
            except UserPrivacyRestrictedError:
                print(
                    "\nThe user's privacy settings do not allow you to do this. Skipping.\n"
                )
            except ValueError as err:
                print(f'\n{err} - Skipping.\n')
            except UserChannelsTooMuchError:
                print(
                    f'\nThe user {user.username_normal} you tried to add is already in too many channels/supergroups\n'
                )
            except FloodWaitError as err:
                print('\nHave to sleep', err.seconds, 'seconds\n')
                time.sleep(err.seconds)
            except KeyboardInterrupt:
                print('\nExecution was interrupted by user.\n')
                click.Context(teladduser).exit(code=1)
            except:
                traceback.print_exc()
                print("\nUnexpected Error\n")
                continue
        else:
            users_added.append({
                'username_normal': user.username_normal,
                'nome': user.nome,
                'grupocanal': user.grupocanal,
                'cont_a_de_envio': user.conta_de_envio,
                'log': user.log,
            })
    try:
        rows.export_to_xlsx(users_added, file)
    except:
        traceback.print_exc()
        print('\nCould not write to the file provided!\n')
コード例 #14
0
    def send_sms():
        try:
            cpass = configparser.RawConfigParser()
            cpass.read('config.data')
            api_id = cpass['cred']['id']
            api_hash = cpass['cred']['hash']
            phone = cpass['cred']['phone']
        except KeyError:
            os.system('clear')
            main.banner()
            print(re+"[!] run python3 setup.py first !!\n")
            sys.exit(1)

        client = TelegramClient(phone, api_id, api_hash)
         
        client.connect()
        if not client.is_user_authorized():
            client.send_code_request(phone)
            os.system('clear')
            main.banner()
            client.sign_in(phone, input(gr+'[+] Enter the code: '+re))
        
        os.system('clear')
        main.banner()
        input_file = sys.argv[1]
        users = []
        with open(input_file, encoding='UTF-8') as f:
            rows = csv.reader(f,delimiter=",",lineterminator="\n")
            next(rows, None)
            for row in rows:
                user = {}
                user['username'] = row[0]
                user['id'] = int(row[1])
                user['access_hash'] = int(row[2])
                user['name'] = row[3]
                users.append(user)
        print(gr+"[1] send sms by user ID\n[2] send sms by username ")
        mode = int(input(gr+"Input : "+re))
         
        message = input(gr+"[+] Enter Your Message : "+re)
         
        for user in users:
            if mode == 2:
                if user['username'] == "":
                    continue
                receiver = client.get_input_entity(user['username'])
            elif mode == 1:
                receiver = InputPeerUser(user['id'],user['access_hash'])
            else:
                print(re+"[!] Invalid Mode. Exiting.")
                client.disconnect()
                sys.exit()
            try:
                print(gr+"[+] Sending Message to:", user['name'])
                client.send_message(receiver, message.format(user['name']))
                print(gr+"[+] Waiting {} seconds".format(SLEEP_TIME))
                time.sleep(SLEEP_TIME)
            except PeerFloodError:
                print(re+"[!] Getting Flood Error from telegram. \n[!] Script is stopping now. \n[!] Please try again after some time.")
                client.disconnect()
                sys.exit()
            except Exception as e:
                print(re+"[!] Error:", e)
                print(re+"[!] Trying to continue...")
                continue
        client.disconnect()
        print("Done. Message sent to all users.")
コード例 #15
0
    def send_sms():
        try:
            cpass = configparser.RawConfigParser()
            cpass.read('config.data')
            api_id = cpass['cred']['id']
            api_hash = cpass['cred']['hash']
            phone = cpass['cred']['phone']
        except KeyError:
            os.system('clear')
            main.banner()
            print(re + "[!] run python3 setup.py first !!\n")
            sys.exit(1)

        client = TelegramClient(phone, api_id, api_hash)

        client.connect()
        if not client.is_user_authorized():
            client.send_code_request(phone)
            os.system('clear')
            main.banner()
            client.sign_in(phone, input(gr + '[+] Enter the code: ' + re))

        os.system('clear')
        main.banner()
        input_file = sys.argv[1]
        users = []
        with open(input_file, encoding='UTF-8') as f:
            rows = csv.reader(f, delimiter=",", lineterminator="\n")
            next(rows, None)
            for row in rows:
                user = {}
                user['username'] = row[0]
                user['id'] = int(row[1])
                user['access_hash'] = int(row[2])
                user['name'] = row[3]
                users.append(user)
        print(gr + "[1] send sms by user ID\n[2] send sms by username ")
        mode = int(input(gr + "Input : " + re))

        message = input(gr + "[+] Enter Your Message : " + re)
        n = 0
        for user in users:
            n += 1
            if n % 50 == 0:
                sleep(300)
            try:
                print("Adding {}".format(user['id']))
                if mode == 1:
                    if user['username'] == "":
                        continue
                    receiver = client.get_input_entity(user['username'])
                elif mode == 2:
                    receiver = InputPeerUser(user['id'], user['access_hash'])
                else:
                    sys.exit("Invalid Mode Selected. Please Try Again.")
                    client(
                        InviteToChannelRequest(target_group_entity,
                                               [user_to_add]))
                    print("Waiting for 60-180 Seconds...")
                    time.sleep(random.randrange(60, 180))
            except PeerFloodError:
                print(
                    "Getting Flood Error from telegram. Script is stopping now. Please try again after some time."
                )
            except UserPrivacyRestrictedError:
                print(
                    "The user's privacy settings do not allow you to do this. Skipping."
                )
            except:
                traceback.print_exc()
                print("Unexpected Error")
                continue

        client.disconnect()
        print("Done. Message sent to all users.")
コード例 #16
0
cpass = configparser.RawConfigParser()
cpass.read('config.data')

try:
    api_id = cpass['cred']['id']
    api_hash = cpass['cred']['hash']
    phone = cpass['cred']['phone']
    client = TelegramClient(phone, api_id, api_hash)
except KeyError:
    os.system('clear')
    banner()
    print(re+"[!] run python3 setup.py first !!\n")
    sys.exit(1)

client.connect()
if not client.is_user_authorized():
    client.send_code_request(phone)
    os.system('clear')
    banner()
    client.sign_in(phone, input(gr+'[+] Enter the code: '+re))
 
os.system('clear')
banner()
input_file = sys.argv[1]
users = []
with open(input_file, encoding='UTF-8') as f:
    rows = csv.reader(f,delimiter=",",lineterminator="\n")
    next(rows, None)
    for row in rows:
        user = {}
        user['username'] = row[0]
コード例 #17
0
class TelegramInterface:

    args = None
    name = 'Telegram Interface'
    telegram_client = None
    __chat_objects_by_id_hack = {}

    def __init__(self):
        parser = argparse.ArgumentParser(description=self.name)

        parser.add_argument('-e', '--env', action='store_true', default=False,
                            help='Output the current environment variable values and exit.')

        parser.add_argument('-f', type=str, metavar='<filename>', default=None,
                            help='Data filename to use, if the file already exists it will be loaded as input without '
                                 'connecting to Telegram.  By default auto-generates a filename in the <cwd>.')

        parser.add_argument('-o', type=str, metavar='<filename>', default='-',
                            help='Output filename, by default to <stdout>')

        parser.add_argument('-c', '--csv', action='store_true', default=False,
                            help='Output in flattened CSV format')

        parser.add_argument('-g', action='store_true', default=False,
                            help='Output groups, can be used with -u to obtain users in groups')

        parser.add_argument('-u', action='store_true', default=False,
                            help='Output users')

        self.args = parser.parse_args()
        if self.args.env is False and self.args.g is False and self.args.u is False:
            parser.print_help()
            exit(1)

    def main(self):
        self.message_stderr(self.name, color='grey')

        if self.args.env is True:
            self.output(self.get_environment_variables())
            return

        telegram_data_filename = self.args.f
        if telegram_data_filename is None:
            api_phone = self.get_environment_variables()['telegram_api_phone']
            if not api_phone:
                self.message_stderr('Environment variable "telegram_api_phone" not set!', color='red')
                return
            telegram_data_filename = '{}-{}.json'.format(api_phone, self.timestamp())

        telegram_data = None
        if os.path.isfile(telegram_data_filename):
            self.message_stderr('Loading data file: {}'.format(telegram_data_filename), color='grey')
            with open(telegram_data_filename, 'r') as f:
                telegram_data = json.load(f)
        else:
            self.message_stderr('Saving to data file: {}'.format(telegram_data_filename), color='grey')
            if self.connect_telegram() is False:
                self.message_stderr('Failed connecting to Telegram', color='red')
                return
            telegram_data = {
                'chat_groups': self.get_chat_groups(expansions=['users'])
            }
            with open(telegram_data_filename, 'w') as f:
                json.dump(telegram_data, f)

        output_data = None
        if self.args.u is True and self.args.g is False:
            output_data = self.extract_users(telegram_data)
        elif self.args.u is False and self.args.g is True:
            output_data = self.extract_groups(telegram_data)
        else:
            output_data = self.extract_groups(telegram_data, users_expansion=True)

        self.output(output_data)
        return

    def timestamp(self):
        return str(datetime.datetime.utcnow()).split('.')[0].replace(' ', 'Z').replace('-', '').replace(':', '')

    def get_environment_variables(self):
        return {
            'telegram_api_id': os.environ.get('telegram_api_id', None),
            'telegram_api_hash': os.environ.get('telegram_api_hash', None),
            'telegram_api_phone': os.environ.get('telegram_api_phone', None),
        }

    def output(self, data):
        if self.args.csv is True:
            out = self.flatten_to_csv(data)
        else:
            out = json.dumps(data, indent=2)

        if self.args.o == '-':
            print(out)
        else:
            with open(self.args.o, 'w') as f:
                f.write(out)
            self.message_stderr('Output written to filename: {}'.format(self.args.o), color='grey')

    def message_stderr(self, message, timestamp=True, color='default', end='\n'):

        if color.lower() == 'red':
            color_code = '\x1b[31m'
        elif color.lower() == 'blue':
            color_code = '\x1b[34m'
        elif color.lower() == 'green':
            color_code = '\x1b[32m'
        elif color.lower() == 'yellow':
            color_code = '\x1b[33m'
        elif color.lower() in ['grey', 'gray']:
            color_code = '\x1b[90m'
        elif color.lower() == 'white':
            color_code = '\x1b[97m'
        else:
            color_code = '\x1b[39m'

        if timestamp:
            message = '{} - {}'.format(self.timestamp(), message.strip())

        color_default = '\x1b[0m'

        sys.stderr.write(color_code + message + color_default + end)
        return

    def extract_users(self, telegram_data):
        users_list = []
        users_id_list = []
        for group in self.extract_groups(telegram_data, users_expansion=True):
            for user in group['users']:
                if user['id'] not in users_id_list:
                    users_id_list.append(user['id'])
                    users_list.append(user)
        return users_list

    def extract_groups(self, telegram_data, users_expansion=False):
        groups_list = []
        groups_id_list = []
        for chat_group in telegram_data['chat_groups']:
            if chat_group['id'] not in groups_id_list:
                groups_id_list.append(chat_group['id'])
                users_list = []
                if users_expansion is True:
                    for user in chat_group['users']:
                        users_list.append({
                            'id': user['id'],
                            'username': user['username'],
                            'firstname': user['first_name'],
                            'lastname': user['last_name'],
                        })
                    groups_list.append({
                        'id': chat_group['id'],
                        'name': chat_group['title'],
                        'users': users_list
                    })
                else:
                    groups_list.append({
                        'id': chat_group['id'],
                        'name': chat_group['title']
                    })
        return groups_list

    def connect_telegram(self):
        env = self.get_environment_variables()

        if env['telegram_api_id']:
            api_id = env['telegram_api_id']
        else:
            self.message_stderr('Environment variable "telegram_api_id" not set!', color='red')
            return False

        if env['telegram_api_hash']:
            api_hash = env['telegram_api_hash']
        else:
            self.message_stderr('Environment variable "telegram_api_hash" not set!', color='red')
            return False

        if env['telegram_api_phone']:
            api_phone = env['telegram_api_phone']
        else:
            self.message_stderr('Environment variable "telegram_api_phone" not set!', color='red')
            return False

        self.telegram_client = TelegramClient(api_phone, api_id, api_hash)

        self.telegram_client.connect()
        if not self.telegram_client.is_user_authorized():
            self.telegram_client.send_code_request(os.environ.get('telegram_api_phone'))
            self.telegram_client.sign_in(
                os.environ.get('telegram_api_phone'),
                input('Enter the MFA code provided to you in the Telegram application: ')
            )
        self.message_stderr('Connected to Telegram with api_id: {}'.format(api_id), color='grey')
        return True

    def get_chat_groups(self, expansions=None, limit=9999):
        if expansions is None:
            expansions = []

        chat_channels = self.get_chats_by_attribute(attribute='participants_count', limit=limit)

        if 'users' in expansions:
            for channel_index, channel in enumerate(chat_channels):
                channel_id = str(channel['id'])
                chat_channels[channel_index]['users'] = self.get_chat_users(self.__chat_objects_by_id_hack[channel_id])

        return chat_channels

    def get_chat_users(self, chat_channel_object):
        channel_users = self.telegram_client.get_participants(chat_channel_object)
        return self.cast_jsonable(channel_users)

    def get_chats_by_attribute(self, attribute, limit=10):
        chats = []
        result = self.telegram_client(
            GetDialogsRequest(
                offset_date=None,
                offset_id=0,
                offset_peer=InputPeerEmpty(),
                limit=limit,
                hash=0
            )
        )

        result_count = 0
        if hasattr(result, 'chats'):
            result_count = len(result.chats)

        if result_count > 0:
            for chat in result.chats:
                if hasattr(chat, attribute):
                    self.__chat_objects_by_id_hack[str(chat.id)] = chat
                    chats.append(self.cast_jsonable(chat))
        return chats

    def cast_jsonable(self, obj, __depth=0, __depth_limit=8):

        if __depth >= __depth_limit:
            return '<< OBJECT DEPTH LIMIT >>'

        if obj is None or type(obj) in [int, float, str, bool]:
            return obj

        if type(obj) is list or 'List' in type(obj).__name__:
            result = []
            for item in obj:
                result.append(self.cast_jsonable(item, __depth+1))
            return result

        if not hasattr(obj, '__dict__'):
            return obj.__str__()

        result = {}
        for attribute in obj.__dict__:
            result[attribute] = self.cast_jsonable(obj.__dict__[attribute], __depth+1)
        return result

    def flatten_to_csv(self, obj, delimiter='.'):
        flat_obj = self.__flatten_object(obj, delimiter=delimiter)

        data = []
        data_row = {}
        data_row_keys = []
        data_row_last = None
        line_number_previous = -1
        for flat_key in flat_obj:
            key = self.__flattened_key_parse(flat_key, method='key', delimiter=delimiter)
            line_number = self.__flattened_key_parse(flat_key, method='line', delimiter=delimiter)
            if line_number != line_number_previous:
                if data_row:
                    data.append(copy.copy(data_row))
                line_number_previous = line_number
            data_row[key] = flat_obj[flat_key]
            if key not in data_row_keys:
                data_row_keys.append(key)
            data_row_last = data_row
        data.append(copy.copy(data_row_last))

        # return json.dumps(data, indent=2)

        def __csv_row(list_items, char='"', end='\n'):
            return char + '{char},{char}'.format(char=char).join(str(x) for x in list_items) + char + end

        csv = __csv_row(data_row_keys)
        for row in data:
            row_list = []
            for data_row_key in data_row_keys:
                if data_row_key in row:
                    row_list.append(row[data_row_key])
                else:
                    row_list.append('')
            csv += __csv_row(row_list)
        return csv.rstrip('\n')

    def __flatten_object(self, obj, parent_key='', delimiter='.'):
        items = []
        if type(obj) is list:
            for list_index, value in enumerate(obj):
                new_key = '{}{}{}'.format(parent_key, delimiter, str(list_index)) if parent_key else str(list_index)
                if type(value) in (str, int, float, bool):
                    items.append((new_key, value))
                else:
                    items.extend(self.__flatten_object(value, new_key, delimiter=delimiter).items())
        elif type(obj) is dict:
            for key, value in obj.items():
                new_key = '{}{}{}'.format(parent_key, delimiter, key) if parent_key else key
                if type(value) in (str, int, float, bool) or value is None:
                    items.append((new_key, value))
                else:
                    items.extend(self.__flatten_object(value, new_key, delimiter=delimiter).items())
        else:
            raise TelegramInterfaceException('Unsupported object type encountered while attempting to __flatten_object()')
        return dict(items)

    def __flattened_key_parse(self, flat_key, method='key', delimiter='.'):
        if method.lower() == 'key':
            key = ''
            for flat_key_part in flat_key.split(delimiter):
                if not flat_key_part.isdigit():
                    key = '{}{}{}'.format(key, delimiter, flat_key_part) if key else flat_key_part
            return key
        else:
            flat_key_part_numbers = []
            for flat_key_part in flat_key.split(delimiter):
                if flat_key_part.isdigit():
                    flat_key_part_numbers.append(int(flat_key_part) + 1)
            return reduce((lambda x, y: x * y), flat_key_part_numbers)