diff --git a/README.md b/README.md index 4f58de53ba7..cdf8bf6f84c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ programming in Python. - Thumbnail (user and task option) - Leech filename prefix (user option) - Set upload as a document or as media (global and user option) -- Upload all files to a specific chat (superGroup/channel/private) (global, user, and task option) +- Upload all files to a specific chat (superGroup/channel/private/topic) (global, user, and task option) - Equal split size settings (global and user option) - Ability to leech split file parts in a media group (global and user option) - Download restricted messages (document or link) by tg private/public/super links (task option) @@ -234,7 +234,7 @@ quotes, even if it's `Int`, `Bool` or `List`. generate database. Data will be saved in Database: bot settings, users settings, rss data and incomplete tasks. **NOTE**: You can always edit all settings that saved in database from the official site -> (Browse collections). `Str` - `DOWNLOAD_DIR`: The path to the vps local folder where the downloads should be downloaded to. `Str` - `CMD_SUFFIX`: Commands index number. This number will added at the end all commands. `Str`|`Int` -- `AUTHORIZED_CHATS`: Fill user_id and chat_id of groups/users you want to authorize. Separate them by space. `Int` +- `AUTHORIZED_CHATS`: Fill user_id and chat_id of groups/users you want to authorize. To auth only specific topic write it in this format `chat_id|thread_id` Ex:-100XXXXXXXXXXX|10. Separate them by space. `Int` - `SUDO_USERS`: Fill user_id of users whom you want to give sudo permission. Separate them by space. `Int` - `DEFAULT_UPLOAD`: Whether `rc` to upload to `RCLONE_PATH` or `gd` to upload to `GDRIVE_ID`. Default is `gd`. Read More [HERE](https://github.com/anasty17/mirror-leech-telegram-bot/tree/master#upload).`Str` diff --git a/bot/__init__.py b/bot/__init__.py index 76057830030..23f038429b9 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -238,7 +238,14 @@ if len(AUTHORIZED_CHATS) != 0: aid = AUTHORIZED_CHATS.split() for id_ in aid: - user_data[int(id_.strip())] = {"is_auth": True} + if "|" in id_: + chat_id, thread_id = id_.split("|") + user_data[int(chat_id.strip())] = { + "is_auth": True, + "thread_ids": [int(thread_id.strip())], + } + else: + user_data[int(id_.strip())] = {"is_auth": True} SUDO_USERS = environ.get("SUDO_USERS", "") if len(SUDO_USERS) != 0: diff --git a/bot/helper/common.py b/bot/helper/common.py index f42c59fbb1b..de36f9b6ba1 100644 --- a/bot/helper/common.py +++ b/bot/helper/common.py @@ -22,7 +22,6 @@ cpu_eater_lock, subprocess_lock, intervals, - bot_loop, ) from .ext_utils.bot_utils import new_task, sync_to_async, get_size_bytes from .ext_utils.bulk_links import extract_bulk_links @@ -117,6 +116,7 @@ def __init__(self): self.force_download = False self.force_upload = False self.is_torrent = False + self.chat_thread_id = None self.suproc = None self.thumb = None self.extension_filter = [] @@ -288,7 +288,11 @@ async def before_start(self): elif self.up_dest.startswith("m:"): self.user_transmission = IS_PREMIUM_USER self.mixed_leech = self.user_transmission - if self.up_dest.isdigit() or self.up_dest.startswith("-"): + if "|" in self.up_dest: + self.up_dest, self.chat_thread_id = list( + map(int, self.up_dest.split("|", 1)) + ) + elif self.up_dest.isdigit() or self.up_dest.startswith("-"): self.up_dest = int(self.up_dest) elif self.up_dest.lower() == "pm": self.up_dest = self.user_id diff --git a/bot/helper/ext_utils/help_messages.py b/bot/helper/ext_utils/help_messages.py index f6f8511a9ea..38d2fa37595 100644 --- a/bot/helper/ext_utils/help_messages.py +++ b/bot/helper/ext_utils/help_messages.py @@ -46,15 +46,24 @@ upload = """Upload Destination: -up -/cmd link -up rcl/gdl (To select rclone config/token.pickle, remote & path/ gdrive id or Tg id/username) -You can directly add the upload path: -up remote:dir/subdir or -up (Gdrive_id) or -up id/username +/cmd link -up rcl/gdl (rcl: to select rclone config, remote & path | gdl: To select token.pickle, gdrive id) using buttons +You can directly add the upload path: -up remote:dir/subdir or -up Gdrive_id or -up id/username (telegram) or -up id/username|topic_id (telegram) If DEFAULT_UPLOAD is `rc` then you can pass up: `gd` to upload using gdrive tools to GDRIVE_ID. If DEFAULT_UPLOAD is `gd` then you can pass up: `rc` to upload to RCLONE_PATH. -If you want to add path or gdrive manually from your config/token (uploaded from usetting) add mrcc: for rclone and mtp: before the path/gdrive_id without space. -/cmd link -up mrcc:main:dump or -up mtp:gdrive_id or -up b:id/@username/pm(leech by bot) or -up u:id/@username(leech by user) or -up m:id/@username(mixed leech) +If you want to add path or gdrive manually from your config/token (UPLOADED FROM USETTING) add mrcc: for rclone and mtp: before the path/gdrive_id without space. +/cmd link -up mrcc:main:dump or -up mtp:gdrive_id -In case you want to specify whether using token.pickle or service accounts you can add tp:gdrive_id or sa:gdrive_id or mtp:gdrive_id. +To add leech destination: +-up id +-up @username +-up b:id/@username/pm (b: means leech by bot) (id or username of the chat or write pm means private message so bot will send the files in private to you) +when you should use b:(leech by bot)? When your default settings is leech by user and you want to leech by bot for specific task. +-up u:id/@username(u: means leech by user) This incase OWNER added USER_STRING_SESSION. +-up m:id/@username(mixed leech) m: to upload files by bot and user based on file size. +-up id/@username|topic_id(leech in specific chat and topic) add | without space and write topic id after chat id or username. + +In case you want to specify whether using token.pickle or service accounts you can add tp:gdrive_id (using token.pickle) or sa:gdrive_id (using service accounts) or mtp:gdrive_id (using token.pickle uploaded from usetting). DEFAULT_UPLOAD doesn't affect on leech cmds. """ diff --git a/bot/helper/mirror_leech_utils/telegram_uploader.py b/bot/helper/mirror_leech_utils/telegram_uploader.py index eed673a9754..659bcf0bfad 100644 --- a/bot/helper/mirror_leech_utils/telegram_uploader.py +++ b/bot/helper/mirror_leech_utils/telegram_uploader.py @@ -99,6 +99,7 @@ async def _msg_to_reply(self): chat_id=self._listener.up_dest, text=msg, link_preview_options=LinkPreviewOptions(is_disabled=True), + message_thread_id=self._listener.chat_thread_id, disable_notification=True, ) else: @@ -106,6 +107,7 @@ async def _msg_to_reply(self): chat_id=self._listener.up_dest, text=msg, link_preview_options=LinkPreviewOptions(is_disabled=True), + message_thread_id=self._listener.chat_thread_id, disable_notification=True, ) self._is_private = self._sent_msg.chat.type.name == "PRIVATE" diff --git a/bot/helper/telegram_helper/filters.py b/bot/helper/telegram_helper/filters.py index 84e9c526584..1fe03e4385a 100644 --- a/bot/helper/telegram_helper/filters.py +++ b/bot/helper/telegram_helper/filters.py @@ -4,17 +4,18 @@ class CustomFilters: - async def ownerFilter(self, _, update): + async def owner_filter(self, _, update): user = update.from_user or update.sender_chat uid = user.id return uid == OWNER_ID - owner = create(ownerFilter) + owner = create(owner_filter) - async def authorizedUser(self, _, update): + async def authorized_user(self, _, update): user = update.from_user or update.sender_chat uid = user.id chat_id = update.chat.id + thread_id = update.message_thread_id if update.is_topic_message else None return bool( uid == OWNER_ID or ( @@ -24,16 +25,23 @@ async def authorizedUser(self, _, update): or user_data[uid].get("is_sudo", False) ) ) - or (chat_id in user_data and user_data[chat_id].get("is_auth", False)) + or ( + chat_id in user_data + and user_data[chat_id].get("is_auth", False) + and ( + thread_id is None + or thread_id in user_data[chat_id].get("thread_ids", []) + ) + ) ) - authorized = create(authorizedUser) + authorized = create(authorized_user) - async def sudoUser(self, _, update): + async def sudo_user(self, _, update): user = update.from_user or update.sender_chat uid = user.id return bool( uid == OWNER_ID or uid in user_data and user_data[uid].get("is_sudo") ) - sudo = create(sudoUser) + sudo = create(sudo_user) diff --git a/bot/modules/authorize.py b/bot/modules/authorize.py index 1cad0ed0111..138d4198f28 100644 --- a/bot/modules/authorize.py +++ b/bot/modules/authorize.py @@ -12,18 +12,37 @@ @handler_new_task async def authorize(_, message): msg = message.text.split() + thread_id = None if len(msg) > 1: - id_ = int(msg[1].strip()) + if "|" in msg: + chat_id, thread_id = list(map(int, msg[1].split("|"))) + else: + chat_id = int(msg[1].strip()) elif reply_to := message.reply_to_message: - id_ = reply_to.from_user.id if reply_to.from_user else reply_to.sender_chat.id + chat_id = ( + reply_to.from_user.id if reply_to.from_user else reply_to.sender_chat.id + ) else: - id_ = message.chat.id - if id_ in user_data and user_data[id_].get("is_auth"): - msg = "Already Authorized!" + if message.is_topic_message: + thread_id = message.message_thread_id + chat_id = message.chat.id + if chat_id in user_data and user_data[chat_id].get("is_auth"): + if thread_id is not None and thread_id in user_data[chat_id].get( + "thread_ids", [] + ): + msg = "Already Authorized!" + else: + if "thread_ids" in user_data[chat_id]: + user_data[chat_id]["thread_ids"].append(thread_id) + else: + user_data[chat_id]["thread_ids"] = [thread_id] + msg = "Authorized" else: - update_user_ldata(id_, "is_auth", True) + update_user_ldata(chat_id, "is_auth", True) + if thread_id is not None: + update_user_ldata(chat_id, "thread_ids", [thread_id]) if config_dict["DATABASE_URL"]: - await database.update_user_data(id_) + await database.update_user_data(chat_id) msg = "Authorized" await send_message(message, msg) @@ -31,16 +50,27 @@ async def authorize(_, message): @handler_new_task async def unauthorize(_, message): msg = message.text.split() + thread_id = None if len(msg) > 1: - id_ = int(msg[1].strip()) + if "|" in msg: + chat_id, thread_id = list(map(int, msg[1].split("|"))) + else: + chat_id = int(msg[1].strip()) elif reply_to := message.reply_to_message: - id_ = reply_to.from_user.id if reply_to.from_user else reply_to.sender_chat.id + chat_id = ( + reply_to.from_user.id if reply_to.from_user else reply_to.sender_chat.id + ) else: - id_ = message.chat.id - if id_ not in user_data or user_data[id_].get("is_auth"): - update_user_ldata(id_, "is_auth", False) + if message.is_topic_message: + thread_id = message.message_thread_id + chat_id = message.chat.id + if chat_id in user_data and user_data[chat_id].get("is_auth"): + if thread_id is not None and thread_id in user_data[chat_id].get("thread_ids", []): + user_data[chat_id]["thread_ids"].remove(thread_id) + else: + update_user_ldata(chat_id, "is_auth", False) if config_dict["DATABASE_URL"]: - await database.update_user_data(id_) + await database.update_user_data(chat_id) msg = "Unauthorized" else: msg = "Already Unauthorized!" diff --git a/bot/modules/bot_settings.py b/bot/modules/bot_settings.py index 8baa9288074..b9545323b38 100644 --- a/bot/modules/bot_settings.py +++ b/bot/modules/bot_settings.py @@ -974,7 +974,14 @@ async def load_config(): if len(AUTHORIZED_CHATS) != 0: aid = AUTHORIZED_CHATS.split() for id_ in aid: - user_data[int(id_.strip())] = {"is_auth": True} + if "|" in id_: + chat_id, thread_id = id_.split("|") + user_data[int(chat_id.strip())] = { + "is_auth": True, + "thread_ids": [int(thread_id.strip())], + } + else: + user_data[int(id_.strip())] = {"is_auth": True} SUDO_USERS = environ.get("SUDO_USERS", "") if len(SUDO_USERS) != 0: