From 4bcf93f0985d79fffa9944191f5edc4145c843eb Mon Sep 17 00:00:00 2001 From: lifegpc Date: Wed, 15 Dec 2021 15:01:38 +0800 Subject: [PATCH] add deleteallmymessages to tg user bot --- tdlib.py | 18 ++++++++---- tg_delete_all_my_msgs.py | 19 ++---------- tg_user_bot.py | 63 +++++++++++++++++++++++++++++++++++++++- util.py | 16 ++++++++++ 4 files changed, 93 insertions(+), 23 deletions(-) diff --git a/tdlib.py b/tdlib.py index 0ea2390..2ccc75f 100644 --- a/tdlib.py +++ b/tdlib.py @@ -484,16 +484,22 @@ class TdLib: async def deleteAllMyMessageInChat(self, chat_id: int, start_time: int = None, - end_time: int = None): + end_time: int = None, + verbose: bool = True, + excludes: List[int] = None): uid = await self.getUid() messages = await self.searchChatMessages(chat_id, sender_user_id=uid, limit=100) + c = 0 if messages is None: - return False + return None while len(messages['messages']) != 0: last_mid = messages['messages'][-1]['id'] mids = [] for m in messages['messages']: + if excludes is not None: + if m['id'] in excludes: + continue need_deleted = False if start_time is None and end_time is None: need_deleted = True @@ -507,16 +513,18 @@ class TdLib: if m['date'] >= start_time and m['date'] <= end_time: need_deleted = True if need_deleted and m['can_be_deleted_for_all_users']: - print(f"Add {m['id']} to delete list. ({m['date']})") + if verbose: + print(f"Add {m['id']} to delete list. ({m['date']})") mids.append(m['id']) if not await self.deleteMessages(chat_id, mids): raise ValueError('Can not delete messages.') + c += len(mids) messages = await self.searchChatMessages( chat_id, sender_user_id=uid, from_message_id=last_mid, limit=100) if messages is None: - return False - return True + return None + return c async def deleteChatHistory(self, chat_id: int, remove_from_chat_list: bool = False, diff --git a/tg_delete_all_my_msgs.py b/tg_delete_all_my_msgs.py index 14b3a70..406ac47 100644 --- a/tg_delete_all_my_msgs.py +++ b/tg_delete_all_my_msgs.py @@ -3,23 +3,8 @@ import asyncio from json import load import sys from traceback import print_exc -try: - from dateutil.parser import parse - have_dateutil = True -except ImportError: - print('Warning: python-dateutil not found. -s and -e only accept integer now.') # noqa: E501 - have_dateutil = False from tdlib import TdLib - - -def tparse(s: str) -> int: - try: - return int(s) - except Exception: - if have_dateutil: - return round(parse(s).timestamp()) - else: - raise ValueError() +from util import tparse async def get_chat_id_from_name(lib: TdLib, name: str) -> int: @@ -82,7 +67,7 @@ async def main(lib: TdLib, arg): return 0 re = await lib.deleteAllMyMessageInChat(chat_id, arg.start_time, arg.end_time) # noqa: E501 print(re) - return 0 if re else -1 + return 0 if re is not None else -1 p = ArgumentParser(description='Delete all my messages in a chat.', add_help=True) # noqa: E501 diff --git a/tg_user_bot.py b/tg_user_bot.py index b79d95c..6ca77f5 100644 --- a/tg_user_bot.py +++ b/tg_user_bot.py @@ -13,7 +13,7 @@ from tdlib import ( TdLib, TextParseMode, ) -from util import commandLineToArgv, timeToStr +from util import commandLineToArgv, timeToStr, tparse USERNAME_REG = compile(r'^[0-9a-z_]+$', I) @@ -56,6 +56,11 @@ asts.add_argument('--id', help='Sticker set ID. Needed if name not specified.', asts.add_argument('-e', '--emoji', help='Emojis corresponding to the sticker', metavar='EMOJI', dest='emoji') # noqa: E501 asts.add_argument('-a', '--add-suffix', help='Add _by_ automatically', action='store_true', dest='add_suffix') # noqa: E501 asts.add_argument('-d', '--delete', help='Delete command message if executed successfully.', action='store_true', dest='delete') # noqa: E501 +damm = MyArgParser('-deleteallmymessages', add_help=False, description='Delete messages in one chat.') # noqa: E501 +damm.add_argument('chat_id', type=int, nargs='?', help="Specify chat's ID.") +damm.add_argument('-n', '--chat-name', help="Specify chat's name. Will used if chat_id is not sepcified.", metavar='NAME', dest='chat_name') # noqa: E501 +damm.add_argument('-s', '--start-time', type=tparse, metavar='TIME', help="The messages which are sended before this time will not be deleted.", dest='start_time') # noqa: E501 +damm.add_argument('-e', '--end-time', type=tparse, metavar='TIME', help="The messages which are sended after this time will not be deleted.", dest="end_time") # noqa: E501 def generateFileInfo(f: dict) -> str: @@ -289,6 +294,59 @@ async def handle_add_sticker_to_set(lib: TdLib, robot: TdLib, mes: dict, print('Can not edit/delete message.') +async def get_chat_id_from_name(lib: TdLib, name: str) -> int: + re = await lib.searchChatsOnServer(name) + if re is None: + raise ValueError('Can not search chats.') + le = len(re['chat_ids']) + if le == 0: + re = await lib.searchPublicChats(name) + if re is None: + raise ValueError('Can not search public chats.') + le = len(re['chat_ids']) + if le == 0: + raise ValueError('No chat found.') + if le == 1: + return re['chat_ids'][0] + else: + raise ValueError('Multipled chats returned, please speicfy a better name.') # noqa: E501 + + +async def handle_delete_all_my_messages(lib: TdLib, mes: dict, + argv: List[str]): + if len(argv) == 1: + re = await lib.editMessageText( + mes['chat_id'], mes['id'], f"```\n{damm.format_help()}\n```", + TextParseMode.MarkDown) + else: + try: + r = damm.parse_intermixed_args(argv[1:]) + if r.chat_id is None and r.chat_name is None: + r.chat_id = mes['chat_id'] + cid = await get_chat_id_from_name(lib, r.chat_name) if r.chat_id is None else r.chat_id # noqa: E501 + text = 'all the time' + if r.start_time is not None and r.end_time is not None: + text = f"between `{timeToStr(r.start_time)}` and `{timeToStr(r.end_time)}`" # noqa: E501 + elif r.start_time is not None: + text = f"after `{timeToStr(r.start_time)}`" + elif r.end_time is not None: + text = f"before `{timeToStr(r.end_time)}`" + re = await lib.editMessageText(mes['chat_id'], mes['id'], f"Started delete messages {text}.", TextParseMode.MarkDown) # noqa: E501 + re = await lib.deleteAllMyMessageInChat(cid, r.start_time, r.end_time, False, [mes['id']]) # noqa: E501 + if re is None: + raise ValueError('Failed to delete.') + re = await lib.editMessageText(mes['chat_id'], mes['id'], f"Deleted `{re}` messages {text}.", TextParseMode.MarkDown) # noqa: E501 + except ValueError as e: + if len(e.args) == 0: + re = await lib.editMessageText(mes['chat_id'], mes['id'], "Unknown error.") # noqa: E501 + else: + re = await lib.editMessageText(mes['chat_id'], mes['id'], f"```\n{damm.format_usage()}{damm.prog}: error: {e.args[0] if len(e.args) == 1 else e.args}\n```", TextParseMode.MarkDown) # noqa: E501 + except Exception: + re = await lib.editMessageText(mes['chat_id'], mes['id'], f"```\n{format_exc()}\n```", TextParseMode.MarkDown) # noqa: E501 + if re is None: + print('Can not edit message.') + + async def main(lib: TdLib, robot: TdLib): with open('tdlib.json', 'r', encoding='UTF-8') as f: se = load(f) @@ -333,6 +391,9 @@ async def main(lib: TdLib, robot: TdLib): elif argv[0] in ['-addstickertoset', '-asts']: re = handle_add_sticker_to_set(lib, robot, mes, argv) asyncio.create_task(re) + elif argv[0] in ['-deleteallmymessages', '-damm']: + re = handle_delete_all_my_messages(lib, mes, argv) + asyncio.create_task(re) with TdLib() as lib: diff --git a/util.py b/util.py index 47936e6..1301820 100644 --- a/util.py +++ b/util.py @@ -1,5 +1,11 @@ from time import strftime, localtime, timezone from typing import List +try: + from dateutil.parser import parse + have_dateutil = True +except ImportError: + print('Warning: python-dateutil not found. -s and -e only accept integer now.') # noqa: E501 + have_dateutil = False def timeToStr(t: int) -> str: @@ -10,6 +16,16 @@ def timeToStr(t: int) -> str: return te +def tparse(s: str) -> int: + try: + return int(s) + except Exception: + if have_dateutil: + return round(parse(s).timestamp()) + else: + raise ValueError() + + def commandLineToArgv(c: str) -> List[str]: s = c.split(' ') r = []