Membangun Downloader Telegram Otomatis: Tinggal Forward, Server yang Kerja
Ada satu masalah klasik kalau sudah punya server media sendiri.
Media berseliweran di Telegram.
IYKWIM. π
Kadang ada video, kadang ada foto, kadang ada file yang rasanya:
βHmm... ini kayaknya harus masuk koleksi Jellyfin.β
Sebenarnya cara manualnya gampang.
Download di HP β pindahkan ke komputer β upload ke server β rapikan folder β tunggu Jellyfin scan.
Secara teknis tidak sulit.
Masalahnya cuma satu:
You know how lazy I am laaa.
Kalau cuma satu file, masih oke.
Tapi kalau harus dilakukan berkali-kali, mulai muncul kalimat:
βNanti aja.β
Dan biasanya βnantiβ itu tidak pernah datang.
Akhirnya kepikiran:
Kenapa nggak Telegram saja yang mengantarkan medianya ke server?
Jadi daripada download di HP lalu upload manual ke Jellyfin, saya cukup forward media dari nomor A ke nomor B.
Sisanya biar homelab yang kerja.
1. Memanfaatkan Git
Daripada membuat downloader Telegram sendiri dari nol, saya mencari project yang sudah mengerjakan bagian yang merepotkan tersebut.
Pilihan yang digunakan adalah:
Dineshkarthik/telegram_media_downloader di GitHub
Repository tersebut kemudian di-clone ke homelab:
cd /home/serverkamu/PYTHON
git clone https://github.com/Dineshkarthik/telegram_media_downloader.git
cd telegram_media_downloader
Kenapa pakai Git?
Ya karena kalau nanti project-nya mau di-update, dicek perubahannya, atau sekadar ingin tahu source code yang sedang digunakan, semuanya sudah rapi.
Tidak perlu:
βIni file Python bikinan siapa ya?β
2. Python Virtual Environment
Karena ini Python project, dependency-nya dipisahkan dari Python sistem.
python3 -m venv .venv
source .venv/bin/activate
Kemudian:
make install
Sekarang downloader punya lingkungan Python sendiri.
telegram_media_downloader/
βββ .venv/
βββ media_downloader.py
βββ config.yaml
βββ media_downloader.session
βββ DOWNLOADS/
Virtual environment ini nantinya juga penting ketika program dijalankan oleh systemd.
3. Nomor B Menjadi Downloader
Saya tidak menggunakan Telegram Bot API.
Tidak ada bot token.
Tidak ada:
A β Bot β Server
Yang digunakan adalah akun Telegram biasa.
Misalnya:
Nomor A = sumber media
Nomor B = akun downloader
Jadi workflow-nya:
Nomor A
β
β forward media
βΌ
Nomor B
Nomor B login menggunakan Telegram API dan Telethon.
API ID dan API Hash dibuat melalui:
Setelah login pertama kali, Telethon membuat session:
media_downloader.session
Session inilah yang menyimpan autentikasi akun B.
Jadi setelah login pertama:
Nomor B
β
Telethon
β
media_downloader.session
program tidak perlu meminta OTP setiap kali dijalankan.
4. Menentukan Chat yang Dipantau
Downloader perlu tahu percakapan mana yang harus dipantau.
Dari akun B, chat dengan nomor A mempunyai ID:
169172416
Kemudian dimasukkan ke config.yaml:
chats:
- chat_id: 169172416
last_read_message_id: 0
ids_to_retry: []
download_directory: ./DOWNLOADS
Sekarang server tahu:
Chat yang perlu diperiksa adalah 169172416.5. Checkpoint Supaya Tidak Download Ulang
Bagian yang sangat penting adalah:
last_read_message_id
Anggap saja downloader sudah memproses:
message ID = 500
Maka config menyimpan:
last_read_message_id: 500
Saat program dijalankan lagi, dia tidak mengulang semuanya dari awal.
Dia tahu:
βSaya sudah sampai message 500.β
Ini juga terbukti ketika downloader dijalankan kembali: media yang sudah diproses tidak di-download ulang.
Dengan kata lain, restart server bukan berarti download ulang semua isi chat.
6. Downloader Ternyata Bukan Daemon
Pada awalnya saya kira tinggal menjalankan:
python3 media_downloader.py
dan membiarkannya hidup.
Ternyata tidak.
Downloader bekerja seperti ini:
connect
β
check messages
β
download
β
update checkpoint
β
disconnect
β
exit
Jadi dia bukan proses yang terus menunggu pesan baru.
Kalau ada pesan baru lima menit kemudian, downloader yang sudah exit tentu tidak tahu.
Maka dibutuhkan watcher.
7. Watcher: Cek Setiap 30 Detik
Watcher dibuat sangat sederhana.
Setiap 30 detik, dia:
- membaca
config.yaml, - mengambil
last_read_message_id, - mengambil message terbaru dari chat A β B,
- membandingkan ID,
- kalau sama β tidak melakukan apa-apa,
- kalau berbeda β menjalankan downloader.
Konsepnya:
setiap 30 detik
β
βΌ
message terbaru
β
βΌ
current ID == last ID?
β β
YES NO
β β
βΌ βΌ
skip downloader
Watcher tidak mengubah checkpoint.
Yang mengubah:
last_read_message_id
tetap downloader.
Dengan begitu hanya downloader yang bertanggung jawab terhadap status message yang sudah diproses.
8. Kenapa Pakai systemd?
Kalau watcher harus dijalankan manual setiap kali server boot:
python3 telegram_watcher.py
berarti kita belum benar-benar otomatis.
Maka watcher dijadikan systemd service.
File:
/etc/systemd/system/telegram-watcher.service
Konfigurasinya:
[Unit]
Description=Telegram Media Watcher
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=serverkamu
WorkingDirectory=/home/serverkamu/PYTHON/telegram_media_downloader
ExecStart=/home/serverkamu/PYTHON/telegram_media_downloader/.venv/bin/python telegram_watcher.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Kemudian:
sudo systemctl daemon-reload
sudo systemctl enable --now telegram-watcher
Sekarang setiap server boot:
server boot
β
systemd
β
telegram-watcher
β
check Telegram
β
setiap 30 detik
Tidak perlu menjalankan apa-apa secara manual.
Kalau watcher crash, systemd juga bisa menjalankannya kembali.
Untuk melihat status:
systemctl status telegram-watcher
Untuk melihat aktivitas secara live:
journalctl -u telegram-watcher -f
9. Ada Sedikit Drama dengan Python 3.14
Tentu saja tidak mungkin proyek homelab berjalan mulus tanpa sedikit drama.
Server menggunakan:
CPython 3.14.4
Sementara downloader masih menggunakan pola asyncio lama.
Saat pertama dijalankan muncul:
RuntimeError:
There is no current event loop in thread 'MainThread'.
Untungnya masalahnya cukup lokal.
Event loop dibuat terlebih dahulu sebelum main() dijalankan.
Setelah patch kecil tersebut:
Telegram connection β OK
chat β OK
download β OK
checkpoint β OK
disconnect β OK
Lanjut.
10. Watcher Juga Sempat Salah Python
Setelah watcher berjalan, muncul error:
ModuleNotFoundError: No module named 'telethon'
Padahal Telethon sudah terinstall.
Ternyata watcher menggunakan Python dari .venv, tetapi ketika menjalankan downloader dia memanggil:
python3 media_downloader.py
yang mengarah ke Python sistem.
Solusinya adalah menggunakan interpreter yang sedang menjalankan watcher:
subprocess.run(
[sys.executable, "media_downloader.py"],
check=True,
)
Sekarang watcher dan downloader sama-sama menggunakan Python dari .venv.
11. Dan Akhirnya: Tinggal Forward
Setelah semua bagian selesai, workflow sehari-hari menjadi sangat sederhana.
Misalnya ada sebuah film yang mau ditangkap.
Tidak perlu:
download ke HP
β
upload ke komputer
β
copy ke server
β
rapikan folder
β
tunggu Jellyfin
Cukup:
Telegram
β
β forward film
βΌ
Nomor B
Kemudian server akan melakukan sisanya.
Nomor B
β
watcher cek setiap 30 detik
β
ada message baru
β
media_downloader.py
β
download
β
update last_read_message_id
β
storage
β
Jellyfin
Jadi dari sisi saya:
Film yang mau ditangkap? Forward ke nomor B.
Sudah.
Server akan mengecek maksimal sekitar 30 detik kemudian, menjalankan downloader, dan mengambil medianya sendiri.
12. Berikutnya: Caption Sebagai Routing
Setelah mekanisme download stabil, sistem masih bisa dibuat lebih malas lagi.
Misalnya nomor A forward film dengan caption:
indonesia
Watcher bisa membaca caption tersebut dan menjadikannya routing key.
Misalnya:
indonesia β /home/serverkamu//MEDIA/indonesia/
jepang β /home/serverkamu/DATA/CLOUD/MEDIA/jepang/
korea β /home/serverkamu/DATA/CLOUD/MEDIA/korea/
Maka caption tidak lagi hanya menjadi keterangan.
Dia menjadi instruksi:
caption
β
routing
β
folder tujuan
Untuk tahap awal, semuanya bahkan bisa diarahkan statis ke:
/home/serverkamu//MEDIA/indonesia/
Baru nanti kalau sudah terbukti stabil, caption bisa digunakan untuk memilih folder secara otomatis.
Penutup
Pada akhirnya, tujuan sistem ini sebenarnya bukan membuat sesuatu yang canggih.
Tujuannya justru sebaliknya:
mengurangi sebanyak mungkin pekerjaan manual.
Awalnya:
Telegram
β
download HP
β
upload
β
copy
β
rapikan
β
Jellyfin
Sekarang:
Telegram
β
forward ke B
β
selesai.
Sementara di belakang layar:
Nomor B
β
Telethon session
β
Watcher
β
cek setiap 30 detik
β
Downloader
β
Checkpoint
β
Storage
β
Jellyfin
Dan itulah inti homelab ini.
Bukan supaya saya bisa melakukan lebih banyak pekerjaan.
Tapi supaya server melakukan pekerjaan yang sebenarnya tidak ingin saya lakukan.
Kalau ada film yang mau ditangkap:
forward ke nomor B.
Sisanya?
Biar server yang capek. π