Simple and reliable self-hosted YouTube Download Telegram Bot.
Version: 1.4.3. Release details.
- Buy me a coffee
- PayPal
- Bitcoin wallet
14kMRS8SvfD2ydMSMEyAmefHV3Yynf9kAd
- Download audio and videos from yt-dlp supported sites to your storage.
- Upload downloaded media to Telegram.
- Interact with the bot in private or group chats.
- Trigger video downloads via link to the API.
- Track download tasks using the API.
- Create Telegram bot using BotFather and get your
token
- Get your Telegram API Keys (
api_id
andapi_hash
) - Find your Telegram User ID
- Copy
app_bot/config-example.yml
toapp_bot/config.yml
- Write
token
,api_id
,api_hash
toapp_bot/config.yml
by changing respective placeholders - Write your Telegram user or group ID to the
allowed_users
->id
by replacing dummy value and changeforward_group_id
value if you want to forward the video to some group/channel when upload is enabled. Bot should be added to the group/channel to be able to send messages. - Change download media type for the user/group:
AUDIO
,VIDEO
orAUDIO_VIDEO
inapp_bot/config.yml
's variabledownload_media_type
. DefaultVIDEO
- If you want your downloaded audio/video to be uploaded back to the Telegram, set
upload_video_file
config variable for your user/group in theapp_bot/config.yml
toTrue
- Media
STORAGE_PATH
environment variable is located in theenvs/.env_worker
file. By default, it's/filestorage
path inside the container. What you want is to map the real path to this inside thedocker-compose.yml
file forworker
service, e.g. if you're on Windows, next strings mean container path/filestorage
is mapped to realD:/Videos
so your videos will be saved to yourVideos
folder.worker: volumes: - "D:/Videos:/filestorage"
- Change application's
LOG_LEVEL
inenvs/.env_common
toDEBUG
,INFO
,WARNING
,ERROR
,CRITICAL
if needed
# Build base image
docker compose build base-image
# Build and run all services in detached mode
docker compose up --build -d -t 0 && docker compose logs --tail 100 -f
# Stop all services
docker compose stop -t 0
Your telegram bot should send you a startup message:
β¨ <YOUR_BOT_NAME> started, paste a video URL(s) to start download
and that's it. After
pasting video URL(s) bot will send you appropriate message whether they were downloaded
or something went wrong.
- If you want to change
yt-dlp
download options, go to theapp_worker/ytdl_opts
directory, copy content fromdefault.py
touser.py
and modify as you wish by checking available options . - Default max simultaneous video downloads by worker service is 2. Change
the
MAX_SIMULTANEOUS_DOWNLOADS
variable inenvs/.env_worker
to desired value but keep in mind that default mounted volume size is 7168m (7GB) indocker-compose.yml
so it may be not enough if you download a lot of large videos at once. yt-dlp
will try to download video thumbnail if it exists. In other case Worker service (particularly the FFmpeg process) will make a JPEG thumbnail from the video. It's needed when you choose to upload the video to the Telegram chat. By default, it will try to make it on the 10th second of the video, but if the video is shorter, it will make it onvideo length / 2
time point because the FFmpeg process will error out. Change theTHUMBNAIL_FRAME_SECOND
variable if needed in theenvs/.env_worker
file.- Max upload file size for non-premium Telegram user is 2GB (2147483648 bytes) which is
reflected in the example config
app_bot/config-example.yml
. If the configured user is the premium user, you're allowed to upload files up to 4GB (4294967296 bytes) and can change the default value stored in theupload_video_max_file_size
config variable. - If the website you want to download from requires authentication you can use your cookies by putting them into
the
app_worker/cookies/cookies.txt
file in the Netscape format. - If your country has an Alpine Linux Mirror, you can speed up the image builds by:
- Creating
apk_mirrors
text file and putting there your mirror urls, for example for Ukraine they are:https://alpine.astra.in.ua/v3.17/main https://alpine.astra.in.ua/v3.17/community
- Adding
COPY apk_mirrors /etc/apk/repositories
to the third line inbase.Dockerfile
:FROM python:3.11-alpine COPY apk_mirrors /etc/apk/repositories ...
- Rebuild the images.
- Creating
If your URL can't be downloaded for some reason, you will see a message with error details
- API: default port is
1984
and no auth. Port can be changed indocker-compose.yml
- RabbitMQ: default credentials are located in
envs/.env_common
- PostgreSQL: default credentials are located in
envs/.env_common
.
By default, API service will run on your localhost
and 1984
port. API endpoint
documentations lives at http://127.0.0.1:1984/docs
.
Endpoint | Method | Description |
---|---|---|
/status |
GET |
Get API healthcheck status, usually response is {"status": "OK"} |
/v1/yt-dlp |
GET |
Get latest and currently installed yt-dlp version |
/v1/tasks/?include_meta=False&status=DONE |
GET |
Get all tasks with filtering options like to include large file metadata and by task status: PENDING , PROCESSING , FAILED and DONE . |
/v1/tasks/f828714a-5c50-45de-87c0-3b51b7e04039?include_meta=True |
GET |
Get info about task by ID |
/v1/tasks/latest?include_meta=True |
GET |
Get info about latest task |
/v1/tasks/f828714a-5c50-45de-87c0-3b51b7e04039 |
DELETE |
Delete task by ID |
/v1/tasks/latest?include_meta=True |
GET |
Get info about the latest task |
/v1/tasks |
POST |
Create a download task by sending json payload {"url": "<URL>"} |
/v1/tasks/stats |
GET |
Get overall tasks stats |
-
GET http://localhost:1984/v1/tasks/?include_meta=False&status=DONE&limit=2&offset=0
Response
[ { "id": "7ab91ef7-461c-4ef6-a35b-d3704fe28e6c", "url": "https://youtu.be/jMetnwUZBJQ", "status": "DONE", "source": "BOT", "added_at": "2022-02-14T02:29:55.981622", "created": "2022-02-14T02:29:57.211622", "updated": "2022-02-14T02:29:59.595551", "message_id": 621, "file": { "id": "4b1c63ed-3e32-43e6-a0b7-c7fc8713b268", "created": "2022-02-14T02:29:59.597839", "updated": "2022-02-14T02:29:59.597845", "name": "Ana Flora Vs. Dj Brizi - Conversa Fiada", "ext": "mp4" } }, { "id": "952bfb7f-1ab3-4db9-8114-eb9995d0cf8d", "url": "https://youtu.be/AWy1qiTF64M", "status": "DONE", "source": "API", "added_at": "2022-02-14T00:36:21.398624", "created": "2022-02-14T00:36:21.410999", "updated": "2022-02-14T00:36:23.535844", "message_id": null, "file": { "id": "ad1fef96-ce1c-4c5e-a426-58e2d5d3e907", "created": "2022-02-14T00:36:23.537706", "updated": "2022-02-14T00:36:23.537715", "name": "Rufford Ford | part 47", "ext": "mp4" } } ]
-
POST http://localhost:1984/v1/tasks
Request
{ "url": "https://www.youtube.com/watch?v=zGDzdps75ns", "download_media_type": "AUDIO_VIDEO", "save_to_storage": false }
Response
{ "id": "5ac05808-b29c-40d6-b250-07e3e769d8a6", "url": "https://youtu.be/AWy1qiTF64M", "source": "API", "added_at": "2022-02-14T00:35:25.419962+00:00" }
-
GET http://localhost:1984/v1/tasks/stats
Response
{ "total": 39, "unique_urls": 5, "pending": 0, "processing": 0, "failed": 26, "done": 13 }