İndirme bittiğinde iki şey olması gerekiyordu: Plex kütüphaneye yeni dosyayı alsın ve ben haber alayım. İkisi de kendiliğinden olmuyordu. Film gece inmişse sabah kalktığımda qBittorrent’e bakıp dosyayı doğru kategoriye taşımam, sonra Plex’ten tarama başlatmam gerekiyordu. Günde bir kez yaptığım, beş dakika süren ve hep unuttuğum bir iş. Bu tür şeyleri kafamda tutmaya çalışmak yerine sunucuya anlatmayı tercih ediyorum; ev sunucusunda bunun adresi n8n.
Ev sunucusunda n8n ne işe yarıyor
n8n, düğümleri sürükleyip birbirine bağladığın açık kaynak bir otomasyon aracı. “İki program birbirini görsün” dediğim her yerde ilk baktığım yer orası. Sunucuda tek bir Docker konteyneri olarak çalışıyor, ~/n8n/docker-compose.yml dosyasında yaşıyor, 5678 portunu dinliyor ve yerel ağda 192.168.1.16:5678 diye açılıyor.
Bir ev sunucusunda bu tür araçların derdi dışarıdan erişilebilirlik. Webhook’la tetiklenen bir akışın dış servislerle konuşabilmesi için adresinin dünyadan görünür olması lazım, ama portu internete açmak istemiyorum. Çözüm Cloudflare Tunnel oldu: n8n.yigittenekeci.com tünele gidiyor, giriş tarafında Cloudflare Access duruyor, /webhook/* yolları ise dışarıdan gelen tetikleyiciler için serbest bırakıldı. Yani panele sadece ben giriyorum, ama akışların tetikleyici kapısı açık.
Bir ayar doğrudan akışları etkiliyor: compose dosyasındaki WEBHOOK_URL. Bu değişken, bir akışın üreteceği webhook adresinin ne olacağını belirliyor. Yerel adres kaldığı sürece n8n dışarıya http://localhost:5678/... diye bir adres veriyor ve Telegram gibi servislerin bundan haberi olmuyor. Adresi https://n8n.yigittenekeci.com/ yapmadan bu iş yürümüyor.
İndirme bitti: webhook → Telegram → Plex
İlk gerçek akış, indirme bitince çalışan zincir. qBittorrent’in “tamamlanınca komut çalıştır” özelliği bir HTTP isteği atıyor, n8n tarafında bunu karşılayan şey bir Webhook tetikleyicisi: POST /webhook/torrent-complete.
Webhook’un cevap modunu onReceived yaptım. Sebebi şu: istek sahibi qBittorrent, akışın bitmesini beklemek zorunda değil. Cevap bekleyen bir indirme istemcisi, arkasında çalışan iş yavaşlarsa zaman aşımına düşer. İsteği alır almaz “aldım” deyip kendi işine dönmesi daha sağlam.
Gelen veri ham: dosya adı, kategori, boyut. Araya bir Code düğümü koyup bunu okunur bir mesaja çeviriyorum — boyut byte’tan gigabayta, kategori kısaltması anlaşılır isme. Sonra iş iki kola ayrılıyor: Telegram’a “indirme bitti” mesajı ve Plex’e iki ayrı tarama isteği; filmler ve diziler ayrı kütüphane olduğu için iki ayrı çağrı.
Yeşil yanan ama hiçbir şey yapmayan düğüm
Akış bir süre sorunsuz çalıştı, sonra iki film indi ve tek bir Telegram mesajı gelmedi. n8n’in execution listesine baktığımda her şey yeşildi; başarısız görünen tek bir çalıştırma yoktu. Akış çalışıyordu, sadece Plex hiç tarama yapmıyordu.
Sebep basit ama görünmesi zor: Plex’in kütüphane yenileme ucu GET bekliyor, ben PUT gönderiyordum. İstek 404 dönüyordu. 404’ü görmemi engelleyen şey düğüm ayarıydı: hata durumunda akışı durdurmak yerine devam et seçeneği açıktı. Düğüm “başarılı” görünüyor, ama çıktısının içinde bir hata nesnesi taşıyor. Execution’ın rengi yeşil, gerçek ise başarısız.
Çıkardığım ders: bir düğümün yeşil olması, işini yaptığı anlamına gelmiyor. Hata yakalama davranışını “devam et” yaptıysan doğrulama için execution’ın durumuna değil, düğümün ürettiği veriye bakacaksın — içinde error alanı var mı, beklediğin alanlar gelmiş mi. Bir de HTTP metodu yanlışsa akış kırılmıyor; sadece içten içe çalışmaz hale geliyor. Sessiz başarısızlık, gürültülü başarısızlıktan çok daha pahalı.
Sağlık kontrolünü akışın içine taşımak
Akışların çalışması için n8n’in kendisinin ayakta olması gerekiyor, ama n8n ayakta mı diye dışarıdan bakmak göründüğü kadar kolay değil. Alan adına istek attığımda gelen 200 cevabı aslında Cloudflare’ın giriş katmanından geliyor; tünel ölü olsa bile o ekran açılıyor. Yani ölçtüğüm şey n8n değil, bir giriş sayfası. Bunu fark ettiğim gün iki düğümlü ayrı bir akış yazdım: GET /webhook/health → cevap {"status":"ok"}. İzleme tarafı artık bu adrese bakıyor, çünkü bu cevap ancak n8n gerçekten çalışıyorsa gelir. Yanlış şeyi ölçmek başlı başına bir konu; burada sadece akış tarafını not ediyorum.
Güncelleme, konfigürasyon ve API tuhaflıkları
Sunucudaki gece bakımı her gün imajı çekip konteyneri yeniden yaratıyor. Bu iyi bir şey ama bir sonucu var: dün çalışan akış, bugün yeni bir sürümün üstünde çalışıyor olabilir. Bu yüzden güncellemeden sonra /webhook/health’e bakan bir adım var. Çalıştığını varsaymak yerine soruyorum.
Konfigürasyonun kendisi de bir bakım kalemi. Saat dilimi Europe/Istanbul; varsayılan UTC kalsaydı zamanlanmış akışlar üç saat kayardı ve bunu fark etmek epey zaman alırdı. Yerel ağda HTTP üzerinden giriş yaptığım için güvenli çerez ayarı kapalı. Davet ve şifre sıfırlama mailleri domainin SMTP’si üzerinden gidiyor; o tarafta da şunu öğrendim: Cloudflare’ın e-posta yönlendirmesi maili alır ama göndermez, gönderim için ayrı bir servis gerekiyor.
n8n’i panelden değil API’den yönetmeye kalktığımda çıkan detaylar da var. Kullanıcı eklemek için CLI’de komut yok; API’de istek gövdesinin dizi olması gerekiyor. Varolan bir akışı güncellerken salt-okunur alanları göndermek 400 hatası veriyor; alanları ayıklayıp önce pasife almak, sonra güncellemek gerekiyor. Bunlar tek seferlik öğrenilen şeyler; ikinci kez aynı duvara tosladığımda notu açıp bakıyorum.
Neyi farklı yapardım
İlk akışı kurarken hata durumunda ne olacağını hiç düşünmedim. Bir düğüm patladığında bunu bana söyleyen bir mekanizma yoktu; bu yüzden indirmenin bittiğini ve taramanın olmadığını tesadüfen, kendi elimle Plex’i açtığımda fark ettim. Bugün olsa ilk iş genel hata akışını kurardım: herhangi bir akış hata verdiğinde Telegram’a tek satır mesaj. Otomasyonun bir sesi olmalı; yoksa çalışmadığını öğrenmenin tek yolu ona güvenip sonucuna bakmak oluyor.
İkinci düzeltme test adresiyle ilgili. n8n bir akış taslakken /webhook-test/ diye bir adres veriyor, aktif olduğunda adres /webhook/ oluyor. Başka bir programa test adresini verip akışı aktif bırakmazsan o istek sessizce düşer. Kapı numarasını iki kez kontrol etmek, saatlerce tetikleyici aramaktan kolay.
Genel ders ise küçük işleri küçümsememek. “İndirme bitince Plex’i tara” tek başına önemsiz görünüyor; ama bu işi her seferinde insan yaptığında sonuç ya unutulmuş bir tarama ya da geç fark edilmiş bir dosya oluyor. Otomasyonun değeri tek tek işlerin büyüklüğünde değil, o işlerin toplamda insanın dikkatinden çaldığı yerde ortaya çıkıyor.