PlayDL یک ربات تلگرام برای دانلود برنامه از Google Play است. کاربر لینک برنامه را میفرستد، ربات برنامه را دانلود میکند، اگر فایلها split باشند آنها را به یک APK قابل نصب تبدیل میکند و فایل نهایی را در تلگرام برای کاربر میفرستد.
این پروژه با Python 3.13 و aiogram 3.28.x ساخته شده
English guide: README.md
.apks یا split APKها به یک .apk معمولیpanel.nixfile.com با Selenium و گرفتن لینک.@username از حساب روبیکای ربات با آپلودر چند-تکه موازی و wrap داخل zip (روبیکا پسوند .apk را قبول نمیکند).alltechdev/gplay-apk-downloadergplaydlapkeepAPKEditor.jar برای merge کردن split APKهااگر AUTO_INSTALL_TOOLS=true باشد، PlayDL ابزارهای کمکی را موقع شروع نصب میکند: repo مربوط به alltechdev/gplay-apk-downloader را clone میکند، gplaydl را با pip نصب میکند، اگر Rust/Cargo نصب باشد apkeep را نصب میکند و آخرین APKEditor jar را دانلود میکند. سرویسها و پکیجهای سیستمی مثل Java، MongoDB، Telegram Bot API server، git و Rust را خودش نصب نمیکند.
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
cp .env.example .env
python App.main
در Windows PowerShell:
py -3.13 -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Copy-Item .env.example .env
Ubuntu/Debian:
sudo apt update
sudo apt install -y openjdk-17-jre-headless
java -version
اگر JDK کامل خواستی:
sudo apt install -y openjdk-17-jdk
CentOS/RHEL/Rocky:
sudo dnf install -y java-17-openjdk
java -version
آخرین فایل APKEditor-*.jar را از این صفحه بگیر:
https://github.com/REAndroid/APKEditor/releases
بعد داخل این مسیر بگذار:
tools/APKEditor.jar
یا مسیرش را در .env تنظیم کن:
APKEDITOR_JAR=/opt/apkeditor/APKEditor.jar
فایل .env را ویرایش کن:
BOT_TOKEN=123456:CHANGE_ME
TELEGRAM_API_BASE_URL=http://127.0.0.1:8081
TELEGRAM_API_IS_LOCAL=true
MONGODB_URI=mongodb://localhost:27017
MONGODB_DB_NAME=playdl
AUTO_INSTALL_TOOLS=true
TOOLS_DIR=tools
DOWNLOAD_DIR=storage/downloads
MAX_PARALLEL_JOBS=2
این گزینه برای کار ما مناسبتر است، چون دانلود Google Play، merge، patch و signing را خودش انجام میدهد.
PLAY_DOWNLOADER_BACKEND=alltech-gplay
ALLTECH_GPLAY_PATH=tools/gplay-apk-downloader/gplay
ALLTECH_AUTO_AUTH=true
ALLTECH_AUTH_FILE=~/.gplay-auth.json
PLAY_ARCH=arm64
MERGE_SPLITS=true
اگر AUTO_INSTALL_TOOLS=true باشد، ربات این repo را داخل tools/gplay-apk-downloader clone میکند. اگر ALLTECH_AUTO_AUTH=true باشد، وقتی ~/.gplay-auth.json وجود نداشته باشد یک بار gplay auth را اجرا میکند.
gplaydl با requirements.txt نصب میشود. فایلهای base و split را دانلود میکند و PlayDL آنها را با APKEditor تبدیل میکند.
PLAY_DOWNLOADER_BACKEND=gplaydl
PLAY_ARCH=arm64
APKEDITOR_JAR=tools/APKEditor.jar
اگر نصب خودکار فعال باشد و دستور gplaydl پیدا نشود، ربات آن را با pip نصب میکند.
اگر از apkeep استفاده میکنی و اکانت/توکن Google Play داری:
PLAY_DOWNLOADER_BACKEND=apkeep
APKEEP_SOURCE=google-play
APKEEP_EMAIL=you@example.com
APKEEP_TOKEN=your_aas_token
اگر نصب خودکار فعال باشد و apkeep پیدا نشود، ربات با cargo install apkeep نصبش میکند. برای این حالت Rust/Cargo باید از قبل نصب باشد.
اگر دانلودر اختصاصی خودت را داری:
PLAY_DOWNLOADER_BACKEND=custom
PLAY_DOWNLOADER_CMD=apkeep -a "{package}" "{output_dir}"
APKS_TO_APK_CMD=java -jar tools/APKEditor.jar m -i "{input}" -o "{output}"
متغیرهای قابل استفاده:
{url}: لینک کامل Google Play{package}: نام پکیج، مثل org.telegram.messenger{output_dir}: پوشه دانلود همان job{arch}: معماری انتخاب شده، مثل arm64در nixfile.com اکانت بساز و NIXFILE_USERNAME و NIXFILE_PASS را در .env بگذار. ربات بار اول لاگین میکند و session را برای دفعات بعد ذخیره میکند.
کانال روبیکا فایل APK را از حساب روبیکای ربات برای هر @username میفرستد. احراز با فایل session از قبل ساختهشده با rubpy انجام میشود.
python session_rubika.py
شماره موبایل و کد OTP را وارد کن. فایل storage/playdl_rubika.rp ساخته میشود. اگر این فایل نباشد دکمه روبیکا فعال است ولی هنگام آپلود پیام «Rubika غیرفعال است» میگیری.
روبیکا روی اکانت کاربری اجازه آپلود .apk نمیدهد، پس ربات قبل از ارسال فایل را داخل NitoNumber-1.zip بستهبندی میکند. برای جلوگیری از timeout روی APKهای بزرگ، آپلودر sequential ۱ مگابایتی rubpy موقع startup با یک پچ جایگزین میشود که ۸ chunk را موازی بالا میفرستد — تابع _parallel_upload_file در Services/rubika.py. اگر DC روبیکا rate-limit کرد، مقدار RUBIKA_UPLOAD_CONCURRENCY همان فایل را پایین بیار.
تنظیمات .env:
RUBIKA_SESSION_NAME=playdl_rubika
RUBIKA_SESSION_DIR=storage
RUBIKA_MAX_FILE_MB=500
RUBIKA_UPLOAD_TIMEOUT=900
python Main.py
اگر دانلودر خروجی زیر را بدهد:
.apk: همان فایل ارسال میشود.apks: با APKEditor به .apk تبدیل میشودmerged.apk تبدیل میشوداگر alltech-gplay با MERGE_SPLITS=true فعال باشد، اول خودش merge را انجام میدهد. اگر باز هم خروجی split بود، PlayDL مرحله merge با APKEditor را اجرا میکند.
App/ شروع bot و تنظیمات
Handlers/ هندلرهای class-based aiogram
DataBase/ لایه MongoDB
Services/ دانلود، تبدیل و مدیریت job
Utils/ متنهای فارسی و کیبوردهای inline
tools/ jarها و اسکریپتهای اختیاری
storage/ فایلهای دانلود و runtime
$ claude mcp add PlayDL \
-- python -m otcore.mcp_server <graph>