def _on_cw_msg(self, message): print(str(datetime.now()) + ': ' + 'Получили сообщение от ChatWars') if self._character.status == CharacterStatus.PAUSED: return if re.search(regexp.main_hero, message.message): self._tgClient.invoke( ForwardMessageRequest(get_input_peer(self._dataBot), message.id, utils.generate_random_long())) if '/fight_' in message.message: self._tgClient.invoke( ForwardMessageRequest(get_input_peer(self._dataBot), message.id, utils.generate_random_long())) if 'Ты вернулся со стройки:' in message.message or 'Здание отремонтировано:' in message.message: self._tgClient.invoke( ForwardMessageRequest(get_input_peer(self._dataBot), message.id, utils.generate_random_long())) print(str(datetime.now()) + ': ' + 'Вернулись из стройки') self._next_build_try = datetime.now() + timedelta( minutes=random.randint(0, 2), seconds=random.randint(0, 59)) self._character.status = CharacterStatus.REST if 'В казне недостаточно ресурсов' in message.message: print(str(datetime.now()) + ': ' + 'Стройка не удалась') self._character.status = CharacterStatus.REST self._next_build_try = datetime.now() + timedelta( minutes=random.randint(1, 4), seconds=random.randint(0, 59)) if 'Твои результаты в бою:' in message.message: self._tgClient.invoke( ForwardMessageRequest(get_input_peer(self._dataBot), message.id, utils.generate_random_long())) self.parse_message(message.message)
def addUserFromFileToChannel(input_file_content, client, channeltoinvite): channeltoinvite = client.get_entity(channeltoinvite) print("get channel to invite success") print(input_file_content) for x in input_file_content: print(x) client.get_entity(x) print("get username to invite success") client.invoke( InviteToChannelRequest(get_input_peer(channeltoinvite), [get_input_peer(client.get_entity(x))])) time.sleep(5)
def send_media_file(self, input_media, entity): """Sends any input_media (contact, document, photo...) to the given entiy""" self.invoke( SendMediaRequest( peer=get_input_peer(entity), media=input_media, random_id=utils.generate_random_long()))
def _entity_to_row(self, e): if not isinstance(e, types.TLObject): return try: p = utils.get_input_peer(e, allow_self=False) marked_id = utils.get_peer_id(p) except TypeError: # Note: `get_input_peer` already checks for non-zero `access_hash`. # See issues #354 and #392. It also checks that the entity # is not `min`, because its `access_hash` cannot be used # anywhere (since layer 102, there are two access hashes). return if isinstance(p, (types.InputPeerUser, types.InputPeerChannel)): p_hash = p.access_hash elif isinstance(p, types.InputPeerChat): p_hash = 0 else: return username = getattr(e, 'username', None) or None if username is not None: username = username.lower() phone = getattr(e, 'phone', None) name = utils.get_display_name(e) or None return self._entity_values_to_row(marked_id, p_hash, username, phone, name)
async def save_resume_entities(self, context_id, entities): """ Saves the given entities for resuming at a later point. """ rows = [] for ent in entities: ent = get_input_peer(ent) if isinstance(ent, types.InputPeerUser): rows.append({ 'context_id': context_id, 'id': ent.user_id, 'access_hash': ent.access_hash }) elif isinstance(ent, types.InputPeerChat): rows.append({ 'context_id': context_id, 'id': ent.chat_id, 'access_hash': None }) elif isinstance(ent, types.InputPeerChannel): rows.append({ 'context_id': context_id, 'id': ent.channel_id, 'access_hash': ent.access_hash }) if rows: await db_resume_entity.insert_many(rows)
def __init__(self, subrredits, min_score, pages, send_message, entity): self._api_base = "https://old.reddit.com" self.subrredits = subrredits self.min_score = min_score self.pages = pages self.data = [] self.send_message = send_message self.api_id = 393731 self.api_hash = 'c9063f355bcb76b0267dfddde0bc5744' self.username = '******' # Verificando se devo enviar menssagem if self.send_message: # Vertificando se eu tenho o numero do usuario pois isto eh obrigatorio para mandar a menssagem if not entity: # Caso o usuario nao tenha passado eu gero um execao raise AttributeError( "O numero do usuario é obrigatorio ser informado para a enviar a menssagem" ) # Inicio a Conexao como a api do Telegram self.client = TelegramClient(self.username, self.api_id, self.api_hash) self.client.start() # Recupero o usuario conforme os meus contatos self.entity = self.client.get_entity(entity) self.peer = utils.get_input_peer(self.entity)
async def test_get_input_users_no_action_message(): user = get_user_456() event = events.ChatAction.build( types.UpdateChatParticipantDelete(chat_id=123, user_id=456, version=1)) event._set_client(get_client()) event._entities[user.id] = user assert await event.get_input_users() == [utils.get_input_peer(user)]
def _on_login(self, user): """ Callback called whenever the login or sign up process completes. Returns the input user parameter. """ self._bot = bool(user.bot) self._self_input_peer = utils.get_input_peer(user, allow_self=False) self._authorized = True return user
def get_updates(self, client: TelegramClient): updates = client.invoke( GetChannelDifferenceRequest(get_input_peer(self.channel), ChannelMessagesFilterEmpty(), self.pts, -1)) if type(updates) is ChannelDifference: self.pts = updates.pts return updates elif type(updates) is ChannelDifferenceTooLong: self.pts = updates.pts return updates else: return None
def update_total_messages(self): """Updates the total messages with the current peer""" result = self.client.invoke(GetHistoryRequest( peer=get_input_peer(self.entity), # No offset, we simply want the total messages count offset_id=0, limit=0, offset_date=None, add_offset=0, max_id=0, min_id=0 )) self.metadata['total_msgs'] = getattr(result, 'count', len(result.messages)) self.metadata['etl'] = str(self.calculate_etl( self.metadata['saved_msgs'], self.metadata['total_msgs'])) self.save_metadata()
def send_message(self, entity, message, markdown=False, no_web_page=False): """Sends a message to the given entity (or input peer) and returns the sent message ID""" if markdown: msg, entities = parse_message_entities(message) else: msg, entities = message, [] msg_id = utils.generate_random_long() self.invoke( SendMessageRequest(peer=get_input_peer(entity), message=msg, random_id=msg_id, entities=entities, no_webpage=no_web_page)) return msg_id
def edit(self, msg, force=False): while True: try: self.client.invoke( EditMessageRequest(get_input_peer(self.channel), self.msg.id, message=msg)) break except ValueError: self.client.disconnect() self.client.connect() except FloodWaitError as e: if not force: break print('flood error occurred, waiting...') sleep(e.seconds + 2)
async def get_input_entity(self, key): try: if key.SUBCLASS_OF_ID in (0xc91c90b6, 0xe669bf46, 0x40f202fd): # hex(crc32(b'InputPeer', b'InputUser' and b'InputChannel')) # We already have an Input version, so nothing else required return key # Try to early return if this key can be casted as input peer return utils.get_input_peer(key) except (AttributeError, TypeError): # Not a TLObject or can't be cast into InputPeer if isinstance(key, types.TLObject): key = utils.get_peer_id(key) exact = True else: exact = not isinstance(key, int) or key < 0 result = None if isinstance(key, str): phone = utils.parse_phone(key) if phone: result = await self.get_entity_rows_by_phone(phone) else: username, invite = utils.parse_username(key) if username and not invite: result = await self.get_entity_rows_by_username(username) else: tup = utils.resolve_invite_link(key)[1] if tup: result = await self.get_entity_rows_by_id(tup, exact=False) elif isinstance(key, int): result = await self.get_entity_rows_by_id(key, exact) if not result and isinstance(key, str): result = await self.get_entity_rows_by_name(key) if result: entity_id, entity_hash = result # unpack resulting tuple entity_id, kind = utils.resolve_id(entity_id) # removes the mark and returns type of entity if kind == types.PeerUser: return types.InputPeerUser(entity_id, entity_hash) elif kind == types.PeerChat: return types.InputPeerChat(entity_id) elif kind == types.PeerChannel: return types.InputPeerChannel(entity_id, entity_hash) else: raise ValueError('Could not find input entity with key ', key)
def flush_delete(self, with_update=True): while True: try: print('try processing delete queue...') self.client.invoke( DeleteMessagesRequest(get_input_peer(self.channel), self.del_list)) break except ValueError: self.client.disconnect() self.client.connect() except FloodWaitError as e: print('flood error occurred, waiting...') sleep(e.seconds + 2) self.del_list.clear() if with_update: self.update('작동중')
def save_resume_entities(self, context_id, entities): """ Saves the given entities for resuming at a later point. """ rows = [] for ent in entities: ent = get_input_peer(ent) if isinstance(ent, types.InputPeerUser): rows.append((context_id, ent.user_id, ent.access_hash)) elif isinstance(ent, types.InputPeerChat): rows.append((context_id, ent.chat_id, None)) elif isinstance(ent, types.InputPeerChannel): rows.append((context_id, ent.channel_id, ent.access_hash)) c = self.conn.cursor() c.executemany("INSERT OR REPLACE INTO ResumeEntity " "VALUES (?,?,?)", rows)
def get_message_history(self, entity, limit=20, offset_date=None, offset_id=0, max_id=0, min_id=0, add_offset=0): """ Gets the message history for the specified entity :param entity: The entity (or input peer) from whom to retrieve the message history :param limit: Number of messages to be retrieved :param offset_date: Offset date (messages *previous* to this date will be retrieved) :param offset_id: Offset message ID (only messages *previous* to the given ID will be retrieved) :param max_id: All the messages with a higher (newer) ID or equal to this will be excluded :param min_id: All the messages with a lower (older) ID or equal to this will be excluded :param add_offset: Additional message offset (all of the specified offsets + this offset = older messages) :return: A tuple containing total message count and two more lists ([messages], [senders]). Note that the sender can be null if it was not found! """ result = self.invoke( GetHistoryRequest( get_input_peer(entity), limit=limit, offset_date=offset_date, offset_id=offset_id, max_id=max_id, min_id=min_id, add_offset=add_offset)) # The result may be a messages slice (not all messages were retrieved) or # simply a messages TLObject. In the later case, no "count" attribute is specified: # the total messages count is retrieved by counting all the retrieved messages total_messages = getattr(result, 'count', len(result.messages)) # Iterate over all the messages and find the sender User users = [] for msg in result.messages: for usr in result.users: if msg.from_id == usr.id: users.append(usr) break return total_messages, result.messages, users
def ping_bot(self, entity, timeout=30): input_entity = utils.get_input_peer(entity) time.sleep(1) bot_user_id = input_entity.user_id self._pinged_bots.append(bot_user_id) log.debug('Pinging @{username}...'.format(username=entity.username)) self.client.send_message(input_entity, '/start') start = datetime.datetime.now() help_attempted = False while not self._response_received(bot_user_id): if datetime.datetime.now() - start > datetime.timedelta(seconds=5) and \ not help_attempted: # Try sending /help if /start didn't work self.client.send_message(input_entity, '/help') help_attempted = True if datetime.datetime.now() - start > datetime.timedelta( seconds=timeout): # No response self._pinged_bots.remove(bot_user_id) log.debug('@{} did not respond after {} seconds.'.format( entity.username, timeout)) return False time.sleep(0.3) response_text = self._responses[bot_user_id] self._delete_response(bot_user_id) self._pinged_bots.remove(bot_user_id) if isinstance(response_text, str): if 'Use /off to pause your subscription.' in response_text \ or 'Use /stop to unsubscribe.' in response_text: self.botbuilders.append(entity) # Evaluate WJClub's ParkMeBot flags reserved_username = ZERO_CHAR1 + ZERO_CHAR1 + ZERO_CHAR1 + ZERO_CHAR1 parked = ZERO_CHAR1 + ZERO_CHAR1 + ZERO_CHAR1 + ZERO_CHAR2 maintenance = ZERO_CHAR1 + ZERO_CHAR1 + ZERO_CHAR2 + ZERO_CHAR1 if zero_width_encoding(response_text) in (reserved_username, parked, maintenance): return False return True
def setUpClass(cls): # set bot cls.bot = LottoBot(telegram_settings['test_token']) cls.bot.run() # set up client cls.client = InteractiveTelegramClient( 'session_id', telegram_settings['user_id'], api_id=telegram_settings['api_id'], api_hash=telegram_settings['api_hash']) # set bot entity dialogs, entities = cls.client.get_dialogs(10) for i, entity in enumerate(entities): i += 1 # 1-based index for normies if get_display_name(entity) == cls.bot.updater.bot.first_name: cls.bot_entity = get_input_peer(entity)
def send_read_acknowledge(self, entity, messages=None, max_id=None): """Sends a "read acknowledge" (i.e., notifying the given peer that we've read their messages, also known as the "double check ✅✅"). Either a list of messages (or a single message) can be given, or the maximum message ID (until which message we want to send the read acknowledge). Returns an AffectedMessages TLObject""" if max_id is None: if not messages: raise InvalidParameterError( 'Either a message list or a max_id must be provided.') if isinstance(messages, list): max_id = max(msg.id for msg in messages) else: max_id = messages.id return self.invoke(ReadHistoryRequest(peer=get_input_peer(entity), max_id=max_id))
def update_total_messages(self): """Updates the total messages with the current peer""" result = self.client.invoke( GetHistoryRequest( peer=get_input_peer(self.entity), # No offset, we simply want the total messages count offset_id=0, limit=0, offset_date=None, add_offset=0, max_id=0, min_id=0)) self.metadata['total_msgs'] = getattr(result, 'count', len(result.messages)) self.metadata['etl'] = str( self.calculate_etl(self.metadata['saved_msgs'], self.metadata['total_msgs'])) self.save_metadata()
async def get_me(self: 'TelegramClient', input_peer: bool = False) \ -> 'typing.Union[types.User, types.InputPeerUser]': """ Gets "me", the current :tl:`User` who is logged in. If the user has not logged in yet, this method returns `None`. Arguments input_peer (`bool`, optional): Whether to return the :tl:`InputPeerUser` version or the normal :tl:`User`. This can be useful if you just need to know the ID of yourself. Returns Your own :tl:`User`. Example .. code-block:: python me = await client.get_me() print(me.username) """ if input_peer and self._self_input_peer: return self._self_input_peer try: me = (await self(functions.users.GetUsersRequest([types.InputUserSelf()]) ))[0] self._bot = me.bot if not self._self_input_peer: self._self_input_peer = utils.get_input_peer(me, allow_self=False) return self._self_input_peer if input_peer else me except errors.UnauthorizedError: return None
async def test_get_input_users_no_action_message(): """ Test for users input. Args: """ user = get_user_456() event = events.ChatAction.build(types.UpdateChatParticipantDelete( chat_id=123, user_id=456, version=1 )) event._set_client(get_client()) event._entities[user.id] = user assert await event.get_input_users() == [utils.get_input_peer(user)] @pytest.mark.asyncio async def test_get_users_no_action_message_no_entities(): """ Builds the action. Args: """ event = events.ChatAction.build(types.UpdateChatParticipantDelete( chat_id=123, user_id=456, version=1 )) event._set_client(get_client())
def backup_messages_thread(self): """This method backups the messages and should be ran in a different thread""" self.backup_running = True # Create a connection to the database db = TLDatabase(self.backup_dir) # Determine whether we started making the backup from the very first message or not. # If this is the case: # We won't need to come back to the first message again after we've finished downloading # them all, since that first message will already be in backup. # # Otherwise, if we did not start from the first message: # More messages were in the backup already, and after we backup those "left" ones, # we must return to the first message and backup until where we started. started_at_0 = self.metadata['resume_msg_id'] == 0 # Keep an internal downloaded count for it to be faster # (instead of querying the database all the time) self.metadata['saved_msgs'] = db.count('messages') # We also need to keep track of how many messages we've downloaded now # in order to calculate the estimated time left properly saved_msgs_now = 0 # Make the backup try: # We need this to invoke GetHistoryRequest input_peer = get_input_peer(self.entity) # Keep track from when we started to determine the estimated time left start = datetime.now() # Enter the download-messages main loop while self.backup_running: # Invoke the GetHistoryRequest to get the next messages after those we have result = self.client.invoke(GetHistoryRequest( peer=input_peer, offset_id=self.metadata['resume_msg_id'], limit=self.download_chunk_size, offset_date=None, add_offset=0, max_id=0, min_id=0 )) self.metadata['total_msgs'] = getattr(result, 'count', len(result.messages)) # First add users and chats, replacing any previous value for user in result.users: db.add_object(user, replace=True) for chat in result.chats: db.add_object(chat, replace=True) # Then add the messages to the backup for msg in result.messages: if db.in_table(msg.id, 'messages'): # If the message we retrieved was already saved, this means that we're # done because we have the rest of the messages. # Clear the list so we enter the next if, and break to early terminate self.metadata['resume_msg_id'] = result.messages[-1].id del result.messages[:] break else: db.add_object(msg) saved_msgs_now += 1 self.metadata['saved_msgs'] += 1 self.metadata['resume_msg_id'] = msg.id self.metadata['etl'] = str(self.calculate_etl( saved_msgs_now, self.metadata['total_msgs'], start=start)) # Always commit at the end to save changes db.commit() self.save_metadata() # The list can be empty because we've either used a too big offset # (in which case we have all the previous messages), or we've reached # a point where we have the upcoming messages (so there's no need to # download them again and we stopped) if not result.messages: # We've downloaded all the messages since the last backup if started_at_0: # And since we started from the very first message, we have them all print('Downloaded all {}'.format(self.metadata['total_msgs'])) break else: # We need to start from the first message (latest sent message) # and backup again until we have them all self.metadata['resume_msg_id'] = 0 started_at_0 = True # Always sleep a bit, or Telegram will get angry and tell us to chill sleep(self.download_delay) pass # end while except KeyboardInterrupt: print('Operation cancelled, not downloading more messages!') # Also commit here, we don't want to lose any information! db.commit() self.save_metadata() finally: self.backup_running = False
def backup_messages_thread(self): """This method backups the messages and should be ran in a different thread""" self.backup_running = True # Create a connection to the database db = TLDatabase(self.backup_dir) # Determine whether we started making the backup from the very first message or not. # If this is the case: # We won't need to come back to the first message again after we've finished downloading # them all, since that first message will already be in backup. # # Otherwise, if we did not start from the first message: # More messages were in the backup already, and after we backup those "left" ones, # we must return to the first message and backup until where we started. started_at_0 = self.metadata['resume_msg_id'] == 0 # Keep an internal downloaded count for it to be faster # (instead of querying the database all the time) self.metadata['saved_msgs'] = db.count('messages') # We also need to keep track of how many messages we've downloaded now # in order to calculate the estimated time left properly saved_msgs_now = 0 # Make the backup try: # We need this to invoke GetHistoryRequest input_peer = get_input_peer(self.entity) # Keep track from when we started to determine the estimated time left start = datetime.now() # Enter the download-messages main loop while self.backup_running: # Invoke the GetHistoryRequest to get the next messages after those we have result = self.client.invoke( GetHistoryRequest(peer=input_peer, offset_id=self.metadata['resume_msg_id'], limit=self.download_chunk_size, offset_date=None, add_offset=0, max_id=0, min_id=0)) self.metadata['total_msgs'] = getattr(result, 'count', len(result.messages)) # First add users and chats, replacing any previous value for user in result.users: db.add_object(user, replace=True) for chat in result.chats: db.add_object(chat, replace=True) # Then add the messages to the backup for msg in result.messages: if db.in_table(msg.id, 'messages'): # If the message we retrieved was already saved, this means that we're # done because we have the rest of the messages. # Clear the list so we enter the next if, and break to early terminate self.metadata['resume_msg_id'] = result.messages[-1].id del result.messages[:] break else: db.add_object(msg) saved_msgs_now += 1 self.metadata['saved_msgs'] += 1 self.metadata['resume_msg_id'] = msg.id self.metadata['etl'] = str( self.calculate_etl(saved_msgs_now, self.metadata['total_msgs'], start=start)) # Always commit at the end to save changes db.commit() self.save_metadata() # The list can be empty because we've either used a too big offset # (in which case we have all the previous messages), or we've reached # a point where we have the upcoming messages (so there's no need to # download them again and we stopped) if not result.messages: # We've downloaded all the messages since the last backup if started_at_0: # And since we started from the very first message, we have them all print('Downloaded all {}'.format( self.metadata['total_msgs'])) break else: # We need to start from the first message (latest sent message) # and backup again until we have them all self.metadata['resume_msg_id'] = 0 started_at_0 = True # Always sleep a bit, or Telegram will get angry and tell us to chill sleep(self.download_delay) pass # end while except KeyboardInterrupt: print('Operation cancelled, not downloading more messages!') # Also commit here, we don't want to lose any information! db.commit() self.save_metadata() finally: self.backup_running = False
def StartCount(dialogs): global TotalDialogs, UserCount, ChannelCount, UserId, ConvertedGroupsIDs, NewGroupsIDs, NumChannel, NumUser, NumChat, \ NumSuper, SupCount, __version__ CachedSupergroups = [] FirstRun = None database = DBConnection(False, False) db1 = database.cursor() db1.execute('SELECT * FROM Version') for row in db1: if row[3] is None: FirstRun = True else: FirstRun = False if FirstRun is True: cursor = database.cursor() cursor.execute( '''CREATE TABLE GroupsInfo(SuperGroupID INTEGER PRIMARY KEY, OldGroupID INTEGER)''' ) date = str(datetime.today()) reg5 = (date, ) database.execute("UPDATE Version SET LastUpdated=?", reg5) database.commit() else: date = str(datetime.today()) reg5 = (date, __version__) database.execute("UPDATE Version SET LastUpdated=?, AppVersion=?", reg5) database.commit() db3 = database.cursor() db3.execute('SELECT * FROM GroupsInfo') for row in db3: CachedSupergroups.append(row[0]) print("\nChecking and processing each chat's data before counting...") UserId = client.get_me().id for dialog in dialogs: client.get_input_entity(dialog) if isinstance(dialog.entity, Chat): NumChat = NumChat + 1 if isinstance(dialog.entity, User): NumUser = NumUser + 1 if isinstance(dialog.entity, Channel): if dialog.entity.megagroup == True: NumSuper = NumSuper + 1 else: NumChannel = NumChannel + 1 completed = 0 bar = progressbar.ProgressBar(max_value=NumSuper, widget=None, poll_interval=1) bar.update(completed) for dialog in dialogs: if isinstance(dialog.entity, Channel): if dialog.entity.megagroup == True: ID1 = get_peer_id(get_input_peer(dialog, allow_self=False)) strid = str(ID1).replace("-100", "") ID = int(strid) if ID not in CachedSupergroups: gotChatFull = SendRequest( GetFullChannelRequest(client.get_input_entity(ID1))) reg = (gotChatFull.full_chat.id, gotChatFull.full_chat.migrated_from_chat_id) database.execute("INSERT INTO GroupsInfo VALUES(?,?)", reg) completed = completed + 1 bar.update(completed) try: database.commit() except: pass LookIds = [] for dialog in dialogs: ID = None try: ID = get_peer_id(get_input_peer(dialog, allow_self=False)) except: ID = UserId if isinstance(dialog.entity, Channel): strid = str(ID).replace("-100", "") ID = int(strid) elif isinstance(dialog.entity, Chat): strid = str(ID).replace("-", "") ID = int(strid) LookIds.append(ID) for dialog in dialogs: if isinstance(dialog.entity, Channel): if dialog.entity.megagroup == True: ID1 = get_peer_id(get_input_peer(dialog, allow_self=False)) strid = str(ID1).replace("-100", "") ID = int(strid) db3 = database.cursor() db3.execute('SELECT * FROM GroupsInfo WHERE SuperGroupID={id}'.\ format(id=ID)) for row in db3: if row[1] is not None: NewGroupsIDs.append(row[0]) ConvertedGroupsIDs.append(row[1]) bar.finish() DBConnection(False, True) print("\nAll is ready. Counting your chats: ") print() for dialog in dialogs: ID = None try: ID = get_peer_id(get_input_peer(dialog, allow_self=False)) except: ID = UserId if isinstance(dialog.entity, Channel): strid = str(ID).replace("-100", "") ID = int(strid) elif isinstance(dialog.entity, Chat): strid = str(ID).replace("-", "") ID = int(strid) if get_display_name(dialog.entity) == "": name = "Deleted Account" elif ID == UserId: name = "***--Chat with yourself (Saved Messages)--***" else: name = get_display_name(dialog.entity) if ID not in ConvertedGroupsIDs: count = GatherHistory(client.get_input_entity(dialog)) if isinstance(dialog.entity, Channel): sprint(' {}: {}'.format(name, count) + " *") if dialog.entity.megagroup == True: SupCount = SupCount + count else: ChannelCount = ChannelCount + count elif isinstance(dialog.entity, (Chat, User)): sprint(' {}: {}'.format(name, count)) UserCount = UserCount + count if ID in NewGroupsIDs: if (ID not in LookIds) and (ID in ConvertedGroupsIDs): continue else: index = NewGroupsIDs.index(ID) OldChatCount = GatherHistory( client.get_input_entity( int("-" + str(ConvertedGroupsIDs[index])))) print( "· !--> You also have ", OldChatCount, " messages before '" + name + "' was converted into a supergroup.") UserCount = UserCount + OldChatCount
async def GetStats(): global FirstRun TotalDialogs = 0 UserCount = 0 ChannelCount = 0 SupCount = 0 ConvertedGroupsIDs = [] NewGroupsIDs = [] NumChannel = 0 NumUser = 0 NumBot = 0 NumDeleted = 0 NumChat = 0 NumSuper = 0 FirstTimeRunning = None UpdateTime = time.strftime("%c") connection = engine.connect() if not engine.dialect.has_table(engine, stats_tbl): metadata.create_all(bind=engine, tables=[stats_tbl, GroupsInfo_tbl]) connection.close() connection = engine.connect() query = db.select([stats_tbl]) if not connection.execute(query).fetchall(): FirstTimeRunning = True if FirstRun: LOGGER.info( "Gathering Stats. You'll be able to use this app during this process without problems" ) LOGGER.info( "The companion may not respond to your command for 5 second. Don't panic and try again if your command didn't worked" ) LOGGER.info("You can disable this in the config.env file") if FirstTimeRunning: LOGGER.info( "Because this is your first time running this, the .stats command won't work until this process isn't over" ) else: LOGGER.info("Updating Stats...") LOGGER.info( "The companion may not respond to your command for 5 second. Don't panic and try again if your command didn't worked" ) CachedSupergroups = [] if not FirstTimeRunning: connection = engine.connect() query = db.select([GroupsInfo_tbl.columns.supergroupid]) result = connection.execute(query).fetchall() for row in result: CachedSupergroups.append(row[0]) connection.close() UserId = await client.get_me() UserId = UserId.id dialogs = await client.get_dialogs(limit=None) for dialog in dialogs: if dialog.is_group: NumChat = NumChat + 1 if dialog.is_user: if dialog.entity.bot: NumBot = NumBot + 1 else: NumUser = NumUser + 1 if dialog.is_channel: if dialog.is_group: NumSuper = NumSuper + 1 else: NumChannel = NumChannel + 1 completed = 0 bar = progressbar.ProgressBar(max_value=NumSuper, widget=None, poll_interval=1) bar.update(completed) for dialog in dialogs: if dialog.is_channel: if dialog.is_group: ID1 = utils.get_peer_id( utils.get_input_peer(dialog, allow_self=False)) strid = str(ID1).replace("-100", "") ID = int(strid) if ID not in CachedSupergroups: ent = await client.get_input_entity(ID1) gotChatFull = await client(GetFullChannelRequest(ent)) connection = engine.connect() query = db.insert(GroupsInfo_tbl).values( supergroupid=gotChatFull.full_chat.id, oldgroupid=gotChatFull.full_chat.migrated_from_chat_id) connection.execute(query) connection.close() LookIds = [] for dialog in dialogs: ID = None try: ID = utils.get_peer_id( utils.get_input_peer(dialog, allow_self=False)) except Exception: ID = UserId if dialog.is_channel: strid = str(ID).replace("-100", "") ID = int(strid) elif dialog.is_group: strid = str(ID).replace("-", "") ID = int(strid) LookIds.append(ID) for dialog in dialogs: if dialog.is_group: ID = utils.get_peer_id( utils.get_input_peer(dialog, allow_self=False)) strid = str(ID).replace("-100", "") ID = int(strid) connection = engine.connect() query = db.select([ GroupsInfo_tbl ]).where(GroupsInfo_tbl.columns.supergroupid == ID) exec = connection.execute(query) result = exec.fetchall() connection.close() for row in result: if row[1] is not None: NewGroupsIDs.append(row[0]) ConvertedGroupsIDs.append(row[1]) bar.finish() print("Counting your chats...") for dialog in dialogs: try: ID = utils.get_peer_id( utils.get_input_peer(dialog, allow_self=False)) except Exception: ID = UserId if dialog.is_channel: strid = str(ID).replace("-100", "") ID = int(strid) elif dialog.is_group: strid = str(ID).replace("-", "") ID = int(strid) if utils.get_display_name(dialog.entity) == "": NumDeleted = NumDeleted + 1 elif ID == UserId: pass if ID not in ConvertedGroupsIDs: ent = await client.get_input_entity(dialog) msgs = await client.get_messages(ent, limit=0) count = msgs.total if dialog.is_channel: if dialog.entity.megagroup: SupCount = SupCount + count else: ChannelCount = ChannelCount + count elif dialog.is_group and dialog.is_user: UserCount = UserCount + count if ID in NewGroupsIDs: if ID in LookIds and ID not in ConvertedGroupsIDs: index = NewGroupsIDs.index(ID) ent = await client.get_input_entity( int("-" + str(ConvertedGroupsIDs[index]))) msgs = await client.get_messages(ent) OldChatCount = msgs.total UserCount = UserCount + OldChatCount ConvertedCount = len(NewGroupsIDs) NumChat = NumChat - ConvertedCount TotalDialogs = UserCount + ChannelCount + SupCount connection = engine.connect() query = db.select([stats_tbl.columns.updatetime]) if not connection.execute(query).fetchall(): query = db.insert(stats_tbl).values( updatetime=UpdateTime, totaldialogs=TotalDialogs, usercount=UserCount, channelcount=ChannelCount, supcount=SupCount, convertedgroups=ConvertedCount, numchannel=NumChannel, numuser=NumUser, numdeleted=NumDeleted, numbot=NumBot, numchat=NumChat, numsuper=NumSuper, ) else: query = db.update(stats_tbl).values( updatetime=UpdateTime, totaldialogs=TotalDialogs, usercount=UserCount, channelcount=ChannelCount, supcount=SupCount, convertedgroups=ConvertedCount, numchannel=NumChannel, numuser=NumUser, numdeleted=NumDeleted, numbot=NumBot, numchat=NumChat, numsuper=NumSuper, ) connection.execute(query) connection.close() LOGGER.info("DONE!! You can see your stats by sending .stats in any chat")
def send_oldnine(client, usernameORphone, content=''): peer = client.get_input_entity(usernameORphone) # 可更换用户名@username或者手机号 if content != '': client(SendMessageRequest(usernameORphone, content)) peer = utils.get_input_peer(peer) print(peer)
elif '#업데이트확인' in msg.message: try: url = urlopen( 'http://comic.naver.com/webtoon/list.nhn?titleId=119874&weekday=' ) html = url.read().decode('utf-8') url.close() spt = html.split( '<a href="/webtoon/detail.nhn?titleId=119874&no=' ) toon_id = spt[1].split('&')[0] update_date = spt[2].split( '<td class="num">')[1].split('</')[0] sleep(0.5) client.invoke( EditMessageRequest( get_input_peer(dest_channel.channel), msg.id, message= '< 업데이트 정보 >\n%s\nhttp://comic.naver.com/webtoon/detail.nhn?titleId=119874&no=%s&weekday=tue' % (update_date, toon_id))) except: client.invoke( EditMessageRequest( get_input_peer(dest_channel.channel), msg.id, message= '< 업데이트 정보 >\n일시적인 오류로 업데이트를 확인할 수 없습니다.')) client.disconnect()
def run(self): # Listen for updates self.add_update_handler(self.update_handler) # Enter a while loop to chat as long as the user wants while True: # Retrieve the top dialogs dialog_count = 10 # Entities represent the user, chat or channel # corresponding to the dialog on the same index dialogs, entities = self.get_dialogs(dialog_count) i = None while i is None: try: print_title('Dialogs window') # Display them so the user can choose for i, entity in enumerate(entities): i += 1 # 1-based index for normies print('{}. {}'.format(i, get_display_name(entity))) # Let the user decide who they want to talk to print() print('> Who do you want to send messages to?') print('> Available commands:') print(' !q: Quits the dialogs window and exits.') print(' !l: Logs out, terminating this session.') print() i = input('Enter dialog ID or a command: ') if i == '!q': return if i == '!l': self.log_out() return i = int(i if i else 0) - 1 # Ensure it is inside the bounds, otherwise set to None and retry if not 0 <= i < dialog_count: i = None except ValueError: pass # Retrieve the selected user (or chat, or channel) entity = entities[i] input_peer = get_input_peer(entity) # Show some information print_title('Chat with "{}"'.format(get_display_name(entity))) print('Available commands:') print(' !q: Quits the current chat.') print(' !Q: Quits the current chat and exits.') print( ' !h: prints the latest messages (message History) of the chat.' ) print( ' !up <path>: Uploads and sends a Photo located at the given path.' ) print( ' !uf <path>: Uploads and sends a File document located at the given path.' ) print( ' !dm <msg-id>: Downloads the given message Media (if any).') print(' !dp: Downloads the current dialog Profile picture.') print() # And start a while loop to chat while True: msg = input('Enter a message: ') # Quit if msg == '!q': break elif msg == '!Q': return # History elif msg == '!h': # First retrieve the messages and some information total_count, messages, senders = self.get_message_history( input_peer, limit=10) # Iterate over all (in reverse order so the latest appears the last in the console) # and print them in "[hh:mm] Sender: Message" text format for msg, sender in zip(reversed(messages), reversed(senders)): # Get the name of the sender if any name = sender.first_name if sender else '???' # Format the message content if msg.media: self.found_media.add(msg) content = '<{}> {}'.format( # The media may or may not have a caption msg.media.__class__.__name__, getattr(msg.media, 'caption', '')) else: content = msg.message # And print it to the user print('[{}:{}] (ID={}) {}: {}'.format( msg.date.hour, msg.date.minute, msg.id, name, content)) # Send photo elif msg.startswith('!up '): # Slice the message to get the path self.send_photo(path=msg[len('!p '):], peer=input_peer) # Send file (document) elif msg.startswith('!uf '): # Slice the message to get the path self.send_document(path=msg[len('!f '):], peer=input_peer) # Download media elif msg.startswith('!dm '): # Slice the message to get message ID self.download_media(msg[len('!d '):]) # Download profile photo elif msg == '!dp': output = str('usermedia/propic_{}'.format(entity.id)) print('Downloading profile picture...') success = self.download_profile_photo(entity.photo, output) if success: print( 'Profile picture downloaded to {}'.format(output)) else: print('"{}" does not seem to have a profile picture.'. format(get_display_name(entity))) # Send chat message (if any) elif msg: self.send_message(input_peer, msg, markdown=True, no_web_page=True)
api_hash = '0b614532fe73ef4fe3f28705808d6e60' client = TelegramClient('social_computing', api_id, api_hash).start() # client.send_message('me', 'Hello! Talking to you from Telethon') # messages = client.get_messages('me')#可更改用户名 # print(messages[0].text) # peer = client.get_input_entity('@teng0927') # 可更换用户名 # peer = utils.get_input_peer(peer) # print(peer) # print(client.get_entity("@hello")) str_all = 'Top Game:' + dict['name'] + ' ; ' + 'Viewers:' + str( dict['viewers']) client.send_message('@MaDolphin', str_all) def print_all_message(): api_id = 759517 api_hash = '0b614532fe73ef4fe3f28705808d6e60' client = TelegramClient('social_computing', api_id, api_hash).start() # print all message for message in client.iter_messages("@MaDolphin"): print(message) if __name__ == '__main__': api_id = 759517 api_hash = '0b614532fe73ef4fe3f28705808d6e60' client = TelegramClient('social_computing', api_id, api_hash).start() peer = client.get_input_entity('@teng0927') # 可更换用户名 peer = utils.get_input_peer(peer) print(peer)
async def get_input_entity( self: 'TelegramClient', peer: 'hints.EntityLike') -> 'types.TypeInputPeer': """ Turns the given entity into its input entity version. Most requests use this kind of :tl:`InputPeer`, so this is the most suitable call to make for those cases. **Generally you should let the library do its job** and don't worry about getting the input entity first, but if you're going to use an entity often, consider making the call: Arguments entity (`str` | `int` | :tl:`Peer` | :tl:`InputPeer`): If a username or invite link is given, **the library will use the cache**. This means that it's possible to be using a username that *changed* or an old invite link (this only happens if an invite link for a small group chat is used after it was upgraded to a mega-group). If the username or ID from the invite link is not found in the cache, it will be fetched. The same rules apply to phone numbers (``'+34 123456789'``) from people in your contact list. If an exact name is given, it must be in the cache too. This is not reliable as different people can share the same name and which entity is returned is arbitrary, and should be used only for quick tests. If a positive integer ID is given, the entity will be searched in cached users, chats or channels, without making any call. If a negative integer ID is given, the entity will be searched exactly as either a chat (prefixed with ``-``) or as a channel (prefixed with ``-100``). If a :tl:`Peer` is given, it will be searched exactly in the cache as either a user, chat or channel. If the given object can be turned into an input entity directly, said operation will be done. Unsupported types will raise ``TypeError``. If the entity can't be found, ``ValueError`` will be raised. Returns :tl:`InputPeerUser`, :tl:`InputPeerChat` or :tl:`InputPeerChannel` or :tl:`InputPeerSelf` if the parameter is ``'me'`` or ``'self'``. If you need to get the ID of yourself, you should use `get_me` with ``input_peer=True``) instead. Example .. code-block:: python # If you're going to use "username" often in your code # (make a lot of calls), consider getting its input entity # once, and then using the "user" everywhere instead. user = await client.get_input_entity('username') # The same applies to IDs, chats or channels. chat = await client.get_input_entity(-123456789) """ # Short-circuit if the input parameter directly maps to an InputPeer try: return utils.get_input_peer(peer) except TypeError: pass # Next in priority is having a peer (or its ID) cached in-memory try: # 0x2d45687 == crc32(b'Peer') if isinstance(peer, int) or peer.SUBCLASS_OF_ID == 0x2d45687: return self._entity_cache[peer] except (AttributeError, KeyError): pass # Then come known strings that take precedence if peer in ('me', 'self'): return types.InputPeerSelf() # No InputPeer, cached peer, or known string. Fetch from disk cache try: return await self.session.get_input_entity(peer) except ValueError: pass # Only network left to try if isinstance(peer, str): return utils.get_input_peer(await self._get_entity_from_string(peer)) # If we're a bot and the user has messaged us privately users.getUsers # will work with access_hash = 0. Similar for channels.getChannels. # If we're not a bot but the user is in our contacts, it seems to work # regardless. These are the only two special-cased requests. peer = utils.get_peer(peer) if isinstance(peer, types.PeerUser): users = await self( functions.users.GetUsersRequest( [types.InputUser(peer.user_id, access_hash=0)])) if users and not isinstance(users[0], types.UserEmpty): # If the user passed a valid ID they expect to work for # channels but would be valid for users, we get UserEmpty. # Avoid returning the invalid empty input peer for that. # # We *could* try to guess if it's a channel first, and if # it's not, work as a chat and try to validate it through # another request, but that becomes too much work. return utils.get_input_peer(users[0]) elif isinstance(peer, types.PeerChat): return types.InputPeerChat(peer.chat_id) elif isinstance(peer, types.PeerChannel): try: channels = await self( functions.channels.GetChannelsRequest( [types.InputChannel(peer.channel_id, access_hash=0)])) return utils.get_input_peer(channels.chats[0]) except errors.ChannelInvalidError: pass raise ValueError( 'Could not find the input entity for {!r}. Please read https://' 'docs.telethon.dev/en/latest/concepts/entities.html to' ' find out more details.'.format(peer))
print("connected") print("authorizing") if not client.is_user_authorized(): client.send_code_request(phone_number) client.sign_in(phone_number, input('Enter the code: ')) print("authorized") print("getting dialogs") dialogs, entities = client.get_dialogs(10) entity = entities[0] print("invoking GetHistoryRequest") result = client.invoke( GetHistoryRequest(get_input_peer(entity), limit=20, offset_date=None, offset_id=0, max_id=0, min_id=0, add_offset=0)) messages = result.messages print(str(messages[0]))