Walrus is a Telegram bot that downloads files from Telegram or direct links and uploads them to Rubika. It is built for personal file transfer workflows where you want Telegram as the control panel and Rubika as the destination.
This project is shared for research, learning, and personal experimentation. Do not use it for abuse, spam, unauthorized access, privacy violations, or any harmful or unlawful purpose. You are responsible for using it in a way that respects platform rules, local laws, and other people's rights.
- Accepts videos, documents, audio, photos, and other Telegram file messages in private chat
- Accepts direct file links such as
https://...pdf,https://...zip, andfile:///...mp4 - Accepts multiple direct file links in one message and queues each one
- Sends a final summary message after a multi-link batch finishes intake
- Keeps a local upload queue to avoid overlapping jobs
- Shows live download and upload progress
- Supports upload retries for temporary Rubika errors
- Supports canceling active or queued transfers
- Supports retrying failed transfers when the downloaded file still exists
- Provides quick action buttons for status, transfers, cleanup, cancel, and retry
- Sends a completion notification when a transfer finishes successfully
- Shows total elapsed transfer time on successful uploads
- Lets you switch the active Rubika number/session from Telegram
- Lets you choose the upload destination from Telegram
- Supports
Rubika Saved Messagesand recentRubika channelsas destinations - Uploads files with a sanitized, readable version of their original filename
- Python 3.9+
- Telegram
API_ID - Telegram
API_HASH - Telegram bot token
git clone https://github.com/rezaaa/walrus.git
cd walrus
cp .env.example .envEdit .env in the project root:
API_ID=your_telegram_api_id
API_HASH=your_telegram_api_hash
BOT_TOKEN=your_telegram_bot_token
TELEGRAM_SESSION=walrus
RUBIKA_SESSION=rubsession
OWNER_TELEGRAM_ID=123456789Variables:
API_ID- from https://my.telegram.orgAPI_HASH- from https://my.telegram.orgBOT_TOKEN- from BotFatherTELEGRAM_SESSION- optional Pyrogram session name; defaults towalrusRUBIKA_SESSION- session name or path used byrubpyOWNER_TELEGRAM_ID- optional; if set, only this Telegram user ID can use the bot
TELEGRAM_SESSION controls the Telegram/Pyrogram session file name, such as walrus.session.
RUBIKA_SESSION controls the session file name that rubpy uses on disk, such as rubsession.rp.
Changing the Rubika account from Telegram replaces the authenticated session file for that configured session name. It does not require editing .env or restarting the bot.
How to get your Telegram user ID:
- forward one of your messages to @userinfobot
- or message @RawDataBot and use the value in
from.id
Then put that number into .env as OWNER_TELEGRAM_ID.
If you leave it unset, the bot stays open for everyone.
Walrus uses Telegram for Rubika account setup.
After the app is running, open the Telegram bot and send:
/start
If no saved Rubika session exists yet, the bot will guide you through setup and create the session file automatically.
Account setup and account changes work like this:
- Send
/startfor first setup, or open⚙️ Settings - Tap
📱 Change Accountor run/set_rubika - Send the Rubika phone number
- If Rubika asks for an account password, send it in the bot
- Wait for the OTP prompt
- Send the OTP code
After a successful login, the current Rubika session is replaced and reused by the worker for future uploads.
rubpy stores the authenticated session on disk using the configured RUBIKA_SESSION name. With current versions of rubpy, that is typically a .rp file such as rubsession.rp.
Install the system packages once:
apt update && apt install -y git python3 python3-venv screenClone Walrus and configure .env:
cd /opt
git clone https://github.com/rezaaa/walrus.git
cd /opt/walrus
cp .env.example .env
nano .envRun the setup script:
bash update.shupdate.sh creates venv/ if needed, installs dependencies, stops any old walrus screen session, and starts the app in a new screen session.
Verify or attach to the running app:
screen -ls
screen -r walrusThen open the Telegram bot and finish Rubika setup with /start. Detach from screen without stopping the app with Ctrl + A, then D.
Use the same script for later updates:
cd /opt/walrus
bash update.shThe script updates the code, refreshes dependencies, restarts the screen session, and keeps the same .env.
Rubika setup and destination setup are handled from the Telegram bot UI. After updating, open the bot and run /start or /settings to confirm the Rubika account and upload destination.
If an older install behaves strangely after updating, run the setup again with bash update.sh. If the app still does not recover, clone the repository again, copy your .env, and complete Rubika setup from the bot UI.
If you do not want to use screen or update.sh:
cd walrus
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.pyThis starts:
telegram_bot.py- Telegram receiver and downloaderrubika_worker.py- Rubika upload worker
Main menu buttons:
📊 Status📋 Transfers🧹 Cleanup🛑 Cancel⚙️ Settings
Available commands:
/start- open the main menu/settings- show the current Rubika session and upload destination/set_rubika- start Rubika number setup in Telegram/set_rubika <phone_number>- start Rubika number setup directly with a phone number/status- show active downloads, active upload, queue, failed count, and local storage usage/transfers- show current downloads, current upload, queued items, and retryable failed transfers/cleanup- preview removable files indownloads//cleanup confirm- delete safe cleanup candidates/cancel- show clickable cancel buttons for active jobs/cancel <task_id>- cancel a specific task/retry <task_id>- requeue a failed task if its local file still exists/retry_all- requeue every retryable failed task
Transfer message buttons:
🛑 Cancelon active and queued transfers🔁 Retryon failed transfers🔁 Retry All Failedin Transfers when retryable failed items exist
Successful transfers:
- the original status message is updated with the total transfer time
- the bot sends a separate completion message when the upload finishes
Upload destinations:
- default destination is Rubika Saved Messages
- open
⚙️ Settingsand tap📬 Destinationto change where future uploads go - choose
☁️ Saved Messagesor📣 Choose Channel - channel uploads require the active Rubika account to have permission to post in that channel
- already queued transfers keep the destination they had when they were queued
Direct link uploads:
- send a message containing a direct file URL
- you can include multiple direct file URLs in one message
- when a multi-link batch finishes, the bot sends one summary with queued, failed, and cancelled counts
- supported schemes:
https://,http://, andfile:// - the link should point to the actual file, not a webpage
- supported direct-link extensions include common video, image, audio, document, PDF, and archive formats such as
.pdfand.zip
Rubika uploads retry automatically on temporary errors.
- Max attempts:
5 - Base retry delay:
3seconds - Backoff:
3s,6s,9s,12s,15s
If all retries fail, the task is written to queue/failed.jsonl and the local downloaded file is kept for inspection or retry.
You can cancel a transfer in three ways:
- tap a
🛑 Cancelbutton on the transfer message - run
/canceland choose a task from the buttons - run
/cancel <task_id>
Behavior:
- Telegram download: stops as soon as possible
- Upload queue: removed immediately
- Rubika upload: stops at the next safe checkpoint
Runtime files:
downloads/- temporary downloaded filesqueue/tasks.jsonl- pending jobsqueue/processing.json- the job currently being uploadedqueue/failed.jsonl- failed jobs logqueue/cancelled/- cancellation markersqueue/settings.json- active Rubika session setting
Cleanup behavior:
- successful upload: local file is deleted
- canceled task: local file is deleted
- failed upload: local file is kept
If the bot does not start:
- verify
.env - install dependencies
- confirm Telegram credentials are valid
If uploads fail:
- check the Rubika session
- if uploading to a channel, confirm the Rubika account can post there
- review
queue/failed.jsonl - confirm the file still exists in
downloads/ - check server memory and swap if the process was killed
This project started after a few storage/upload experiments:
- I first tried Arvan OSS as the target, but it was too slow.
- Then I tried Google Drive, but it got filtered.
- After that, I found caffeinexz/Tele2Rub and used it as the inspiration for trying Rubika instead.
- The name Walrus is inspired by the Black Sails series: Captain Flint's ship, Walrus.
Walrus uses a simple queue-based flow:
- The Telegram bot receives a file in a private chat, or a direct file URL in a text message.
- The file is downloaded into
downloads/. - A task is added to
queue/tasks.jsonl. - The Rubika worker uploads the file.
- The Telegram status message is updated during the whole transfer.