From 282cec92dfd29ad50d262a13c3e787ea32b2d2d4 Mon Sep 17 00:00:00 2001 From: Gilang Date: Wed, 24 Dec 2025 12:01:15 +1100 Subject: [PATCH 1/4] Fix Pixeldrain upload support and rclone integration - Update Dockerfile to install latest rclone with Pixeldrain backend support - Fix asyncio event loop initialization for uvloop compatibility - Fix is_gdrive_remote() missing await in rclone_mirror.py - Fix cmd_exec() return value unpacking in tasks_listener.py (3 values not 2) - Add sudo() helper method to CustomFilters - Update .gitignore to exclude rclone configs, IDE files, and temp files --- .gitignore | 5 +++++ Dockerfile | 3 +++ bot/__init__.py | 2 ++ bot/helper/mirror_leech_utils/upload_utils/rclone_mirror.py | 2 +- bot/helper/telegram_helper/filters.py | 5 +++++ bot/modules/tasks_listener.py | 2 +- 6 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 194f318b..2b39d89e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,13 +4,18 @@ users botlog.txt cookies.txt rclone.conf +rclone/ config.env *.json *.pickle *.pyc .netrc .vscode +.idea/ +.DS_Store pyrogram.session pyrogram_session.session Thumbnails/* +*.tar +bot/Gilang* diff --git a/Dockerfile b/Dockerfile index 20a61c83..e9268a8a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,9 @@ FROM sammax23/rcmltb WORKDIR /usr/src/app RUN chmod 777 /usr/src/app +# Install latest rclone with pixeldrain support +RUN curl -fsSL https://rclone.org/install.sh | bash + COPY requirements.txt . RUN pip3 install --no-cache-dir -r requirements.txt diff --git a/bot/__init__.py b/bot/__init__.py index d2a2cc19..e06529a4 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -2,6 +2,7 @@ __author__ = "Sam-Max" from uvloop import install +import asyncio from asyncio import Lock from socket import setdefaulttimeout from logging import getLogger, FileHandler, StreamHandler, INFO, basicConfig @@ -23,6 +24,7 @@ faulthandler_enable() install() +asyncio.set_event_loop(asyncio.new_event_loop()) setdefaulttimeout(600) diff --git a/bot/helper/mirror_leech_utils/upload_utils/rclone_mirror.py b/bot/helper/mirror_leech_utils/upload_utils/rclone_mirror.py index 32eb29b1..a3002c5d 100644 --- a/bot/helper/mirror_leech_utils/upload_utils/rclone_mirror.py +++ b/bot/helper/mirror_leech_utils/upload_utils/rclone_mirror.py @@ -100,7 +100,7 @@ async def upload( "-P", ] - is_gdrive = is_gdrive_remote(remote, conf_path) + is_gdrive = await is_gdrive_remote(remote, conf_path) await setRcloneFlags(cmd, "upload") if ospath.isdir(path): diff --git a/bot/helper/telegram_helper/filters.py b/bot/helper/telegram_helper/filters.py index 8aa6275f..6dfc64c0 100644 --- a/bot/helper/telegram_helper/filters.py +++ b/bot/helper/telegram_helper/filters.py @@ -34,3 +34,8 @@ async def custom_sudo_filter(self, client, update): sudo_filter = create(custom_sudo_filter) + @staticmethod + def sudo(user_id): + """Check if user_id is owner or sudo user""" + return user_id == OWNER_ID or (user_id in user_data and user_data[user_id].get("is_sudo", False)) + diff --git a/bot/modules/tasks_listener.py b/bot/modules/tasks_listener.py index 46da49bf..cbabe0f7 100644 --- a/bot/modules/tasks_listener.py +++ b/bot/modules/tasks_listener.py @@ -522,7 +522,7 @@ async def onUploadComplete( ) else: cmd = ["rclone", "link", f"--config={rclone_config}", rclone_path] - res, code = await cmd_exec(cmd) + res, err, code = await cmd_exec(cmd) if code == 0: buttons.url_buildbutton("Cloud Link 🔗", res) else: From 844688f8a27f71e9db7db04dd310a6b333acbb77 Mon Sep 17 00:00:00 2001 From: Gilang Date: Wed, 24 Dec 2025 12:39:34 +1100 Subject: [PATCH 2/4] Fix: Resolve 'Peer id invalid' error for private channel batch operations - Fixed batch.py to iterate through user dialogs to populate Pyrogram's peer cache before fetching messages from private/restricted channels - Added better error handling with descriptive error messages for batch command failures - Updated README to document fork improvements over the original repository --- README.md | 12 +++++++++++- bot/modules/batch.py | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6eba463b..3036b0df 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,19 @@ An Rclone Mirror-Leech Telegram Bot to transfer to and from many clouds. Based on [mirror-leech-telegram-bot](https://github.com/anasty17/mirror-leech-telegram-bot) with rclone support added, and other features and changes from base code. +This is a fork of [Sam-Max/rcmltb](https://github.com/Sam-Max/rcmltb) with additional improvements and bug fixes. -**NOTE**: Base repository added recently its own rclone implementation. +**NOTE**: Base repository added recently its own rclone implementation. +## Fork Improvements + +This fork includes the following enhancements over the original repository: + +### Bug Fixes +- **Fixed "Peer id invalid" error for private channel batch operations**: The original bot would fail with "Peer id invalid" error when using `/mb` (mirror batch) or `/lb` (leech batch) commands with private/restricted channel links. This was caused by Pyrogram's peer cache not being populated for private channels. The fix iterates through user dialogs to find and cache the channel peer before attempting to fetch messages. + +### Enhanced Error Handling +- **Improved error messages for batch commands**: When batch operations fail on private channels, the bot now provides more descriptive error messages including the actual exception, making it easier to diagnose issues. ## Features: diff --git a/bot/modules/batch.py b/bot/modules/batch.py index 4cec0f1d..986e6385 100644 --- a/bot/modules/batch.py +++ b/bot/modules/batch.py @@ -153,9 +153,20 @@ async def download(message, link, multi, isLeech, value=0): try: client = app chat = int("-100" + link.split("/")[-2]) + # Search for the channel in dialogs to populate peer cache + found = False + async for dialog in app.get_dialogs(): + if dialog.chat.id == chat: + found = True + break + if not found: + await sendMessage("Could not find the channel in your chats. Make sure you joined it!", message) + return msg = await app.get_messages(chat, msg_id) - except Exception: - await sendMessage("Make sure you joined the channel!!", message) + except Exception as e: + from bot import LOGGER + LOGGER.error(f"Error accessing private channel: {e}") + await sendMessage(f"Make sure you joined the channel!! Error: {e}", message) return else: client = bot From 9c37ba4a4ee4daa947ee67e3f5af5bc22bae53b1 Mon Sep 17 00:00:00 2001 From: Gilang Date: Wed, 24 Dec 2025 12:44:05 +1100 Subject: [PATCH 3/4] docs: Add comprehensive changelog and private channel batch guide - Added Fork Improvements & Changelog section with version history - Added step-by-step guide for generating User Session String - Added detailed instructions for using private channel batch operations - Documented the root cause and solution for the Peer id invalid fix --- README.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3036b0df..62f780dc 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,79 @@ This is a fork of [Sam-Max/rcmltb](https://github.com/Sam-Max/rcmltb) with addit **NOTE**: Base repository added recently its own rclone implementation. -## Fork Improvements +--- + +## 🆕 Fork Improvements & Changelog This fork includes the following enhancements over the original repository: -### Bug Fixes -- **Fixed "Peer id invalid" error for private channel batch operations**: The original bot would fail with "Peer id invalid" error when using `/mb` (mirror batch) or `/lb` (leech batch) commands with private/restricted channel links. This was caused by Pyrogram's peer cache not being populated for private channels. The fix iterates through user dialogs to find and cache the channel peer before attempting to fetch messages. +### v1.1.0 - Private Channel Batch Fix (2024-12-24) + +#### 🐛 Bug Fixes +- **Fixed "Peer id invalid" error for private channel batch operations**: The original bot would fail with `BAD_REQUEST: Peer id invalid` error when using `/mb` (mirror batch) or `/lb` (leech batch) commands with private/restricted channel links. + - **Root Cause**: Pyrogram requires the peer (channel) to be in its internal cache before it can fetch messages. For private channels, this cache wasn't being populated. + - **Solution**: The fix now iterates through user dialogs to find and cache the channel peer before attempting to fetch messages from private channels. -### Enhanced Error Handling +#### 🔧 Enhanced Error Handling - **Improved error messages for batch commands**: When batch operations fail on private channels, the bot now provides more descriptive error messages including the actual exception, making it easier to diagnose issues. +- **Added channel validation**: The bot now checks if the channel exists in user's dialogs and provides a clear message if the channel is not found. + +#### 📝 Documentation +- Added comprehensive guide for generating User Session String +- Added step-by-step instructions for private channel batch operations +- Updated README with fork improvements and changelog + +--- + +## 📱 How to Use Private Channel Batch Operations + +To download/mirror files from **private or restricted Telegram channels**, you need to set up a User Session String. This allows the bot to access channels that your Telegram account has joined. + +### Step 1: Generate User Session String + +1. **Install requirements** (if not already installed): + ```bash + pip3 install pyrogram + ``` + +2. **Run the session generator script**: + ```bash + python3 session_generator.py + ``` + +3. **Enter your credentials when prompted**: + - `API_ID`: Get from https://my.telegram.org + - `API_HASH`: Get from https://my.telegram.org + - You will receive a verification code on your Telegram app - enter it when prompted + +4. **Copy the generated session string**: The script will output a long string starting with `BQ...` - this is your session string. + +### Step 2: Configure the Bot + +Add your session string to `config.env`: +```env +USER_SESSION_STRING = "your_session_string_here" +``` + +### Step 3: Join the Private Channel + +Make sure the Telegram account (whose session string you generated) has **joined the private channel** you want to download from. + +### Step 4: Use Batch Commands + +Now you can use batch commands with private channel links: + +``` +/mb https://t.me/c/1234567890/100 https://t.me/c/1234567890/150 +``` + +This will mirror all files from message 100 to 150 from the private channel. + +**Commands:** +- `/mb` or `/mirror_batch` - Mirror files from private channel to cloud +- `/lb` or `/leech_batch` - Leech files from private channel to Telegram + +--- ## Features: From 34d75db18aa2150706308400ec29d7476edbb81c Mon Sep 17 00:00:00 2001 From: Gilang Date: Fri, 26 Dec 2025 21:57:57 +1100 Subject: [PATCH 4/4] Add ARM64 branch reference and fix sudo_filter bug Changes: - README: Added ARM64 branch documentation and quick start guide - Fixed bug in rclone_utils.py: Use sync CustomFilters.sudo() instead of async sudo_filter which was causing 'coroutine never awaited' warning and preventing DEFAULT_OWNER_REMOTE from being auto-selected --- README.md | 15 +++++++++++++++ bot/helper/ext_utils/rclone_utils.py | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 62f780dc..007b2027 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,21 @@ This is a fork of [Sam-Max/rcmltb](https://github.com/Sam-Max/rcmltb) with addit --- +## 🍎 ARM64 Support (Apple Silicon / Raspberry Pi / ARM Servers) + +**Running on ARM64?** Use the [`arm64` branch](https://github.com/cybercyberz/rcmltb/tree/arm64) for native support: + +```bash +git clone -b arm64 https://github.com/cybercyberz/rcmltb.git +``` + +The ARM64 branch includes: +- Native ARM64 Dockerfile (Apple M1/M2/M3, Raspberry Pi 4/5, ARM cloud servers) +- All features work except MEGA downloads (SDK not available for ARM64) +- Bug fixes backported from master + +--- + ## 🆕 Fork Improvements & Changelog This fork includes the following enhancements over the original repository: diff --git a/bot/helper/ext_utils/rclone_utils.py b/bot/helper/ext_utils/rclone_utils.py index 064f3344..ea8b483d 100644 --- a/bot/helper/ext_utils/rclone_utils.py +++ b/bot/helper/ext_utils/rclone_utils.py @@ -23,7 +23,8 @@ async def is_remote_selected(user_id, message): - if CustomFilters.sudo_filter("", message): + # Use sync CustomFilters.sudo() instead of async sudo_filter to avoid coroutine warning + if CustomFilters.sudo(user_id): if DEFAULT_OWNER_REMOTE := config_dict["DEFAULT_OWNER_REMOTE"]: update_rclone_data("MIRROR_SELECT_REMOTE", DEFAULT_OWNER_REMOTE, user_id) return True