class SyncTelegramClient: """Class for getting messages from Telegram API""" def __init__(self): self._client = TelegramClient("session", config["api-id"], config["api-hash"]) def fetch_messages_since(self, channel, from_date, limit=1000): """Get messages since a particular date Arguments: channel {str} -- Name or ID of channel from_date {datetime} -- Messages after this date will be return """ logger.debug( "Fetching messages since %s from channel %s" % (str(from_date), channel) ) if not self._client.is_connected(): self._client.connect() itermsgs = self._client.iter_messages(channel, limit) messages = it.takewhile(lambda x: x.date > from_date, itermsgs) return list(messages) def fetch_messages( self, channel, size=100, max_id=None, min_id=None, search=None, filter=None ): """Method to fetch messages from a specific channel / group""" logger.debug("Fetching up to %d messages from channel %s" % (size, channel)) params = [channel, size] kwargs = {} # The telethon module has issues if a keyword passed is None, so we will add the keyword # only if it is not None for key in ["max_id", "min_id", "search", "filter"]: if locals()[key] is not None: kwargs[key] = locals()[key] with self._client as client: data = client.get_messages(*params, **kwargs) return data # This is cached with variable expiry to avoid overloading the API # @cachier(stale_after=timedelta(days=randint(10, 50)), hash_params=hash_params) def get_channel_info(self, channel): """Return metadata about Telegram channel Arguments: channel {str} -- Channel name or ID number """ with self._client as client: return client( functions.channels.GetFullChannelRequest(channel=channel) ).to_dict()
def main(id, hash, target, mime, limit, output): client = TelegramClient('telegram-files-downloader', id, hash) client.start() count = 0 print('[INFO] - Started downloading files to {}'.format(output)) for message in client.iter_messages(target): if count > limit: break if message.media is not None: client.download_media(message=message, file=output) count += 1 print('[INFO] - Ended downloading files')
async def main(): api_id = hash api_hash = 'hash' phone_number = 'domdude' channel_username = '******' client = TelegramClient(phone_number, api_id, api_hash) await client.start() cnt = 0 async for message in client.iter_messages(channel_username): print('Downloading' + message) try: await client.download_media(message=message) except errors.FloodWaitError as e: continue
class BaseTelegramCrawler(BaseCrawler): """ Базовый краулер для телеграмм-каналов """ def __init__(self, base_url='', base_account_folder='', limit=1000): super().__init__(base_url, base_account_folder) # Устанавливаем лимит получаемых с канала сообщений self.limit = limit # Получаем необходимые настройки _settings = get_settings() # Присваиваем значения настроек внутренним переменным _api_id = _settings['api_id'] _api_hash = _settings['api_hash'] _username = _settings['username'] # Создаем объект клиента Telegram API self.client = TelegramClient(_username, _api_id, _api_hash) # Запускаем клиент self.client.start() def set_base_url(self, url): """ Метод, устанавлявающий базовый урл, который парсится :param url: :return: """ self.base_url = url def get_messages(self): """ Возвращаем экземпляр класса Message при итерировании :return: Message """ for message in self.client.iter_messages(self.base_url, limit=self.limit): yield Message(self.base_url, message.text, datetime_=message.date) # Функция для отправки сообщения в определенный чат def send_message_to_chat(self, chat, message): self.client.send_message(chat, message.description)
from telethon.sync import TelegramClient # api_id and api_hash you must take from https://my.telegram.org/. Create your app (any) and get it. api_id = # Your api_id in int format (for example, 1234567) api_hash = # Your api_hash in str format (for example, 'deadbeef1337600613') username = # Session name in str format (for example, 'Anon') counter_deleted_message = 0 client = TelegramClient(username, api_id, api_hash) client.start() dialog_array = {} for dialog in client.iter_dialogs(): dialog_array[dialog.id] = dialog.name print("You are currently in the following chats:") for dialog in client.iter_dialogs(): print('"{}" with ID {}'.format(dialog.name, dialog.id)) while True: print() chat = int(input('Enter chat ID to remove your chat messages or "0" (without quotes) for exit: ')) print() if chat == 0: print('Bye bye!') break else: for message in client.iter_messages(chat, from_user='******'): if message.raw_text is not None: counter_deleted_message += 1 client.delete_messages(chat, message) print('Deleted {} post(s) from chat "{}"'.format(counter_deleted_message, dialog_array[chat]))
# if chat.megagroup== False: # groups.append(chat) # except: # continue #print('Choose a group to scrape members from:') #i=0 #for g in chats: # print(str(i) + '- ' + g.title) # i+=1 # #g_index = input("Enter a Number: ") for g in chats: if g.title=="Big Pump Signal": target_group=g #target_group=chats[int(g_index)] print("Hour of the pump (24h format) ex:22") pump_hour = input() print("amount BTC you want to invest") amount = input() coin = [] t = datetime.datetime.today() pmp_time = datetime.datetime(t.year,t.month,t.day,int(pump_hour)-1,59,59,5000) while pmp_time > datetime.datetime.now(): time.sleep(0.1) while not coin: time.sleep(0.1) for message in client.iter_messages(target_group, limit=2): coin = re.findall(r"[$]\w+", message.text) place_order(coin[0].replace('$', '').upper(), amount)
class UploadTelegramCrawler(BaseCrawler): """ Краулер, выгружающий данные из телеграмм-каналов """ def __init__(self, base_url, base_account_folder, limit=1000): super().__init__(base_url, base_account_folder) # Устанавливаем лимит получаемых с канала сообщений self.limit = limit # Получаем необходимые настройки _settings = get_settings() # Присваиваем значения внутренним переменным _api_id = _settings['api_id'] _api_hash = _settings['api_hash'] _username = _settings['username'] # Создадим объект клиента Telegram API self.client = TelegramClient(_username, _api_id, _api_hash) def __enter__(self): # Запускаем клиент self.client.start() return self def __exit__(self, type, value, traceback): """ Отключаем клиента :param type: :param value: :param traceback: :return: """ self.client.disconnect() def get_messages(self): """ Возвращаем экземпляр класса Message при итерировании :return: Message """ for message in self.client.iter_messages(self.base_url, limit=self.limit): yield Message(self.base_url, message.text, datetime_=message.date) def upload_to_csv(self): # Поля таблицы field_names = ['Text', 'Date'] # Путь к csv файлу csv_path = self.base_account_folder + self.base_url.split('/')[-1] + '.csv' # Открываем csv файл with open(csv_path, 'w', encoding='utf-8') as csv_file: # Инициализация экземляра DictWriter csv_writer = csv.DictWriter(csv_file, fieldnames=field_names) csv_writer.writeheader() # Итерируемся по сообщениям for message in self.get_messages(): if message.description: # Записываем один ряд таблицы csv_writer.writerow({'Text': message.description, 'Date': message.datetime_})
for path in [ config['gif_channel'], dir_video, dir_images, dir_buffer, dir_buffer_video, dir_buffer_images ]: if not os.path.exists(path): os.mkdir(path) # # # Download missing videos from gif channel print("Download missing videos from gif channel") client = TelegramClient('duplicate_checker', config['api_id'], config['api_hash']) client.start() channel_username = config['gif_channel'] channel_entity = client.get_entity(channel_username) for message in client.iter_messages(channel_entity): if message.file is None: # print(f"No file, skipping message: {message}") continue file_ext = message.file.mime_type.split("/")[-1] path = f"{dir_video}/{str(message.id).zfill(4)}.{file_ext}" if not os.path.exists(path): print("Downloading message: {}".format(message)) client.download_media(message=message, file=path) # # # Decompose missing videos print("Decompose missing videos") video_files = glob.glob(f"{dir_video}/*.mp4") for video_file in video_files: video_number = video_file.split(os.sep)[-1].split(".")[0] video_output_dir = f"{dir_images}/{video_number}/"
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()
class Telegram(object): def __init__(self, session='test', log_level='info'): api_id = os.environ.get("TELEGRAM_API_ID") api_hash = os.environ.get("TELEGRAM_API_HASH") if not api_id or not api_hash: raise ValueError( "Please set TELEGRAM_API_ID and TELEGRAM_API_HASH as environment variables!" ) self._client = TelegramClient(session, api_id, api_hash) self._logger = logging.getLogger(__name__) self._logger.setLevel(logging.INFO if log_level == 'info' else logging.DEBUG) # logFormatter = logging.Formatter("%(asctime)s [%(name)s] [%(levelname)s] %(message)s") self._logFormatter = logging.Formatter("%(message)s") console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter(self._logFormatter) self._logger.addHandler(console_handler) def _set_file_handler(self, method, channel=None, user=None, query=None): file_handler = logging.FileHandler("{}{}{}{}.log".format( method, '_[{}]'.format(channel.title) if channel else '', '_[{}]'.format(utils.get_display_name(user)) if user else '', '_[query={}]'.format(query) if query else '')) file_handler.setFormatter(self._logFormatter) self._logger.addHandler(file_handler) def _log_message(self, msg: Message, channel: Channel, user: User): self._logger.info("{} [{}] [{}]: {}".format( msg.date, get_url(channel, msg), utils.get_display_name(user), msg.text)) async def _send_to_ifttt_async(self, event, key, header, body, url): payload = {'value1': header, 'value2': body, 'value3': url} u = 'https://maker.ifttt.com/trigger/{}/with/key/{}'.format(event, key) async with aiohttp.ClientSession() as session: async with session.post(u, data=payload) as resp: self._logger.info("[{}] {}{}\nIFTTT status: {}".format( url, header, body, resp.status)) async def _iter_messages_async(self, chat, user, query, output, print_stat=False): if print_stat: counter = Counter() async for msg in self._client.iter_messages(chat, from_user=user): if not query or (msg.text and query in msg.text): if isinstance(output, Channel): url = get_url(chat, msg) await self._client.send_message( output, "{}:\n{}\n{}".format(msg.date, msg.text, url)) else: sender = user if sender is None: if msg.post: sender = chat elif msg.from_id == None: self._logger.debug(msg) continue else: sender = await self._client.get_entity(msg.from_id) self._log_message(msg, chat, sender) if print_stat: counter[msg.date.hour] += 1 if print_stat: total = sum(counter.values()) for hour in range(24): print("{}: {}".format(hour, floor(counter[hour] / total * 100) * '=')) async def _get_entity(self, entity_like): try: entity = await self._client.get_entity(entity_like) except Exception as e: entity = await self._client.get_entity(int(entity_like)) return entity def _parse_msg(self, msg, key, regex): m = re.search(r'{}=({})'.format(key, regex), msg) if m is not None: return m.groups()[0] return None async def _parse_entity(self, msg: str, entity_name: str): m = self._parse_msg(msg, entity_name, r'[0-9a-zA-Z_\-]+') if m is not None: return await self._get_entity(m) return None
class TelegramAnalytics: """ A that extracts information about messages times. """ def __init__(self, api_id, api_hash): self.__api_id = api_id self.__api_hash = api_hash self.__from_zone = tz.tzutc() self.__to_zone = tz.tzlocal() self.__client = TelegramClient('session_name', api_id, api_hash) self.__client.start() def __del__(self): self.__client.log_out() self.__client.disconnect() def get_all_message_date_times(self, username, limit=10): """ Get dates and times for all messages exchanged between you and an entity. :param str username: Username (or phone number) of entity to get chat history from. :param int limit: The number of messages to extract information from. :return: Array of dates and times that each messages was sent. :rtype: [datetime.datetime] >>> ca = TelegramAnalytics( api_id, api_hash ) >>> ca.get_all_message_date_times('+11234567891',limit=1) >>> ca.get_all_message_date_times('quartz_husky',limit=1) """ return list( map(lambda x: x.date.astimezone(self.__to_zone), self.__client.iter_messages(username, limit=limit))) def get_all_message_times(self, username, limit=10): """ Get time stamps (hours, minutes, seconds, microseconds) for all messages exchanged between you and an entity. :param str username: Username (or phone number) of entity to get chat history from. :param int limit: The number of messages to extract information from. :return: Array of times that each messages was sent. :rtype: [datetime.time] >>> ca = TelegramAnalytics( api_id, api_hash ) >>> ca.get_all_message_date_times('+11234567891',limit=1) >>> ca.get_all_message_date_times('quartz_husky',limit=1) """ return list( map(lambda x: x.date.astimezone(self.__to_zone).time(), self.__client.iter_messages(username, limit=limit))) def message_time_histogram(self, username, limit=10): """ Get a time histrogram for all messages exchanged between you and an entity. :param str username: Username (or phone number) of entity to get chat history from. :param int limit: The number of messages to extract information from. >>> from fnw_client import TelegramAnalytics >>> import matplotlib.pyplot as plt >>> >>> plt.figure() >>> >>> ca = TelegramAnalytics( api_id, api_hash ) >>> time_historgram = ca.message_time_histogram('quartz_husky',limit=100) >>> time_histogram.plot(kind='bar') >>> >>> plt.show() """ times = get_all_message_date_times(username, limit) df = pd.DataFrame({'hour': times}) return df.groupby(df['hour'].dt.hour).count() def __text_sentiment(self, text): def clean_text(self, text): return ' '.join( re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)", " ", text).split()) cln_text = clean_text(text) return None if not cln_text else TextBlob(cln_text).sentiment.polarity def get_sentiments(self, username, limit=10): message_iterator = self.__client.iter_messages(username, limit=limit) return [ self.__text_sentiment(x.text) for x in message_iterator if isinstance(x.text, str) ] def message_sentiment_histogram(self, username, limit=10): """ Get a sentiment histrogram for all messages exchanged between you and an entity. """ sentiments = get_sentiments(username, limit) df = pd.DataFrame({'sentiment': sentiments}) # Remove zero values and NAs df_nz = df[(df.T != 0).any()].dropna() return df_nz.hist(bins=20) def message_sentiment_rolling_avg(self, username, limit=10): """ Get rolling average data of all messages exchanged between you and an entity. """ sentiments = get_sentiments(username, limit) df = pd.DataFrame({'sentiment': sentiments}) # Remove zero values and NAs df_nz = df[(df.T != 0)].any().dropna() rolling_avg_factor = int(df_nz.shape[0] / 100) + 1 return df_nz.rolling(rolling_avg_factor).mean() def message_sentiment_vs_time(self, username, limit=10): """ Get a graph of sentiment as a function of hour of the day. :param str username: Username (or phone number) of entity to get chat history from. :param int limit: The number of messages to extract information from. :return: A tuple with the following format: (hour,sentiment,variance-in-sentiment) :rtype: (int,float,float) >>> from fnw_client import TelegramAnalytics >>> import matplotlib.pyplot as plt >>> >>> plt.figure() >>> >>> ca = TelegramAnalytics( api_id, api_hash ) >>> sentiment_and_time = ca.message_sentiment_and_time('quartz_husky',limit=100) >>> variances = [ x.variance() for x in sentiment_and_time ] >>> >>> plt.bar(range(len(sentiment_and_time)), [val.sentiment() for val in sentiment_and_time], align='center',yerr=variances) >>> plt.xticks(range(len(sentiment_and_time)), [val.time() for val in sentiment_and_time]) >>> plt.xticks(rotation=70) >>> plt.xlabel('Hour') >>> plt.ylabel('Average Sentiment') >>> >>> plt.show() """ class TimeAndSentiment: def __init__(self, time, sentiment): self.__time = time self.__sentiment = sentiment def time(self): return self.__time def sentiment(self): return self.__sentiment def get_sentiments_and_times(self, username, limit=10): message_iterator = self.__client.iter_messages(username, limit=limit) get_datetime = lambda x: x.date.astimezone(self.__to_zone).time() get_sentiment = lambda x: self.__text_sentiment(x.text) ts = [ TimeAndSentiment(get_datetime(x), get_sentiment(x)) for x in message_iterator if isinstance(x.text, str) ] # Sorted output by hours, which is necessary for groupby to work properly return sorted(ts, key=lambda x: x.time().hour) hour_group = groupby(get_sentiments_and_times(username, limit), lambda x: x.time().hour) average_sentiment = lambda group: mean( [x.sentiment() for x in group if x.sentiment() is not None]) def stdev_sentiment(group): clean_group = [x for x in group if x.sentiment() is not None] return stdev([x.sentiment() for x in clean_group ]) if (len(clean_group) >= 2) else 0 return [ TimeSentimentVariance(key, average_sentiment(group), stdev_sentiment(group)) for key, group in hour_group ]
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) print( 'Done! (Please run the script two to three times to clean every message. If you run once only, some messages may won\'t be deleted.)' )