Tujuan kita kali ini adalah automation agar saat Sonarr selesai download dan melakukan import episode baru, kita otomatis mendapatkan notifikasi melalui Telegram. Dengan ini kita tidak perlu membuka dashboard Sonarr ataupun cek secara manual.
Kita akan membuat server webhook sederhana dengan FastAPI, menjalankannya di Docker, kemudian menghubungkannya ke Sonarr.
Kenapa Tidak Menggunakan Fitur Bawaan Sonarr?
Sonarr punya notifikasi Telegram bawaan. Tapi jika menggunakan fitur itu, format pesannya sudah ditentukan oleh Sonarr dan kita tidak bisa membuat notifikasi yang customized. Kalau kita mau menggunakan notifikasi yang customized, atau yang lebih canggih seperti melampirkan poster, link yang jika di klik membuka Jellyfin, dsb, kita butuh server sendiri.
Alur Secara Umum
| |
Stack yang Digunakan
- FastAPI + Uvicorn – web framework dan server-nya
- httpx – untuk mengirim HTTP request ke API Telegram
- python-dotenv – untuk membaca credentials dari file
.env - Docker – supaya semuanya berjalan rapi
Struktur Folder
| |
Buat Struktur Folder
| |
Flag -p langsung membuat semua folder, termasuk folder parent.
requirements.txt
Buat file di /home/stevelaurensius/dockerconfig/webhook-bot/requirements.txt:
| |
File ini hanya teks biasa yang isinya nama package yang kita perlukan. Tidak ada yang terinstall di host dan file ini akan dibaca oleh Docker saat membangun image-nya.
Dockerfile
Buat file di /home/stevelaurensius/dockerconfig/webhook-bot/Dockerfile:
| |
(Jangan lupa cek dulu apakah port 8000 masih bisa digunakan atau tidak)
Mari kita pelajari baris per baris dari Dockerfile tersebut.
FROM python:3.12-slim
Kita menggunakan Python versi slim karena ukurannya lebih kecil dan tidak berisi banyak tool yang tidak kita perlukan.
WORKDIR /app
Semua command selanjutnya akan dijalankan di dalam folder /app di dalam container.
COPY requirements.txt . dan RUN pip install
Dua command ini akan copy file requirements.txt ke dalam image, lalu menginstall semua package-nya. Proses instalasi terjadi di dalam image, bukan di host.
COPY app/ .
Copy semua kode Python kita ke dalam image.
CMD […]
Perintah yang dijalankan saat container dijalankan. Kita meminta uvicorn untuk menjalankan aplikasi main:app (objek app di dalam main.py) pada port 8000.
docker-compose.yml
Buat file di /home/stevelaurensius/dockerconfig/webhook-bot/docker-compose.yml:
| |
.env
Buat file di /home/stevelaurensius/dockerconfig/webhook-bot/.env:
| |
WEBHOOK_SECRET adalah kode yang akan kita gunakan untuk melakukan verifikasi bahwa request yang masuk benar-benar berasal dari Sonarr, bukan dari sumber lain.
app/notify_telegram.py
File ini berisi satu function saja: mengirim pesan ke Telegram. Kita buat independen supaya bisa dipanggil dari mana saja. Jika nanti kita menambah notifikasi dari aplikasi lain, fungsi ini tetap bisa dipakai ulang.
| |
app/sonarr.py
Di file ini kita menulis logic khusus Sonarr. Kita memakai APIRouter supaya route tidak menumpuk di main.py. Nanti kalau menambah Radarr, cukup buat file baru dan daftarkan router-nya di main.py.
| |
Beberapa hal yang perlu diperhatikan di sini:
Cek secret: Setiap request yang masuk ke webhook ini harus memiliki header X-Webhook-Secret dengan value yang sudah kita set sebelumnya di .env kita. Kalau value-nya salah, server langsung menolak dengan 403 Forbidden.
Cek eventType: Sonarr mengirimkan banyak jenis event, tidak hanya saat episode selesai download. Di bot kita kali ini, kita hanya akan memproses event Download. Event Test juga diproses secara terpisah agar tombol Test di Sonarr bisa digunakan tanpa error.
Cek isUpgrade: Kalau semua trigger notifikasi di Sonarr aktif, event Download bisa datang dari beberapa sumber:
On File ImportmengirimisUpgrade: false(episode baru per file).On File UpgrademengirimisUpgrade: true.On Import Completetidak punya fieldisUpgradesama sekali.
Tanpa filter isUpgrade, File Import dan Import Complete keduanya akan mengirimkan pesan ke Telegram untuk rilis yang sama. Kode if payload.get("isUpgrade") is not False memastikan kita hanya memproses import file baru.
app/main.py
Entry point dari aplikasi kita seperti yang sudah dijelaskan di atas. Di file ini kita hanya membuat objek FastAPI, mendaftarkan router dari sonarr.py, dan menyediakan endpoint health check.
| |
Kalau lain kali kita mau menambahkan fungsi baru dari aplikasi lain, kita hanya perlu menambahkan dua baris kode di sini (import dan include).
Build dan Jalankan
Buka /home/stevelaurensius/dockerconfig/webhook-bot/
| |
Flag --build memberitahu Docker untuk membangun ulang image-nya. Ini diperlukan karena kita baru pertama kali menjalankannya, atau setiap kali kode kita berubah.
Verifikasi container sudah berjalan:
| |
Kalau berhasil, log-nya akan menampilkan:
| |
Test health check:
| |
Konfigurasi di Sonarr
- Buka Settings > Connect
- Klik + dan pilih Webhook
- Isi field-nya:
- Name:
Notifikasi Telegram(boleh diisi apa saja) - URL:
http://[ip-address]:8000/webhook/sonarr - Method:
POST
- Name:
- Tambahkan custom header:
- Name:
X-Webhook-Secret - Value: nilai
WEBHOOK_SECRETdari file.env
- Name:
- Centang semua Notification Triggers
- Klik Test dulu, kalau muncul centang hijau, klik Save
Kita centang semua Notification Triggers agar Sonarr mengirim semua jenis event ke webhook yang kita siapkan. Filter-nya ada di webhook dan kali ini hanya event Download dengan isUpgrade: false yang dikirim ke Telegram. Kalau nantinya kita mau handle event lainnya, kita cukup ubah kode tanpa perlu kembali ke Sonarr.
Saat kita klik Test, Sonarr mengirim POST dengan eventType: Test. Server kita mengenalinya dan membalas {"status": "test received"}. Tidak ada pesan Telegram yang terkirim saat tes.
