DEV Community

Cover image for Bildirimleri Otomatikleştirmek: GitHub ve Sunucu İzleme için Discord Botu
Taha Yağız Güler
Taha Yağız Güler

Posted on

Bildirimleri Otomatikleştirmek: GitHub ve Sunucu İzleme için Discord Botu

Bildirimleri Otomatikleştirmek: GitHub ve Sunucu İzleme için Discord Botu

Çoğu şirket, "pipeline'da bir şey olduğunda ilgili ekip anında haberdar olsun" ya da "sunucuda bir sorun varsa DevOps ekibi hemen bilsin" gibi basit ama kritik bir ihtiyaca sahip. Bu yazıda, bu ihtiyacı karşılayan küçük ama üretime hazır bir Discord bot/otomasyon setini nasıl kurduğumu anlatıyorum.

Problem

Ekipler genelde bildirimleri iki şekilde takip ediyor: ya sürekli GitHub/GitLab sekmesini açık tutup manuel kontrol ederek, ya da e-posta bildirimlerinin arasında kaybolarak. İkisi de verimsiz. Asıl istenen şey, ekibin zaten kullandığı iletişim aracına (bu örnekte Discord) doğrudan ve gürültüsüz bildirim düşmesi.

Mimari

Sistem üç bağımsız parçadan oluşuyor:

  1. Discord Bot (discord.py) — komutlara cevap verebilen, ileride interaktif özellikler eklenebilecek temel bir bot.
  2. GitHub Webhook Dinleyici (Flask) — GitHub'dan gelen push, pull_request, issues event'lerini yakalayıp Discord'a anlamlı mesajlar olarak ileten bir servis.
  3. Sunucu İzleme Scripti (psutil + cron) — CPU, RAM ve disk kullanımını periyodik kontrol edip yalnızca eşik değer aşıldığında uyarı gönderen bir script.

Bot ile webhook arasındaki fark önemli bir tasarım kararıydı: bot, karşılıklı etkileşim (komut-cevap) gerektiren senaryolar için; webhook ise tek yönlü "haber verme" senaryoları için kullanılıyor. Sürekli açık bir process'e ihtiyaç duymadan, sadece bir HTTP isteğiyle mesaj göndermek yeterliyse webhook her zaman daha basit ve daha az bakım gerektiren çözüm.

GitHub Webhook Dinleyici

Flask üzerinde küçük bir endpoint, GitHub'ın gönderdiği X-GitHub-Event header'ına bakarak event tipini ayırt ediyor:

@app.route("/webhook/github", methods=["POST"])
def github_webhook():
    event_type = request.headers.get("X-GitHub-Event", "unknown")
    payload = request.json

    if event_type == "push":
        pusher = payload["pusher"]["name"]
        repo = payload["repository"]["full_name"]
        message = f"**{pusher}**, `{repo}` reposuna commit gönderdi."
        send_to_discord(message)

    return "OK", 200
Enter fullscreen mode Exit fullscreen mode

Local geliştirme sırasında GitHub'ın localhost'a erişemediğini unutmamak gerekiyor — bunun için ngrok ile geçici bir public tünel açtım. Production'da bu servis bir VPS ya da AWS instance'ında sabit bir domain arkasında çalışacak.

Bir noktada, repo'da GitHub Actions pipeline'ı olduğu için workflow_run, workflow_job, check_run gibi event'ler de webhook'a düşmeye başladı ve gereksiz "gürültü" oluşturdu. Çözüm basitti: GitHub'ın webhook ayarlarında yalnızca ihtiyaç duyulan event tiplerini (push, pull_request, issues) seçili bırakmak.

Sunucu İzleme

def check_system():
    cpu = psutil.cpu_percent(interval=1)
    ram = psutil.virtual_memory().percent
    disk = psutil.disk_usage("/").percent

    warnings = []
    if cpu >= CPU_THRESHOLD:
        warnings.append(f"CPU kullanımı yüksek: %{cpu}")
    # ...

    if warnings:
        send_to_discord("**Sunucu uyarısı**\n" + "\n".join(warnings))
Enter fullscreen mode Exit fullscreen mode

Burada bilinçli bir tasarım tercihi var: eşik aşılmadığında hiçbir mesaj gönderilmiyor. Bir izleme sisteminin en büyük tuzağı, "her şey yolunda" mesajlarıyla kanalı doldurup asıl önemli uyarıların gözden kaçmasına sebep olmak. Script, cron ile 5 dakikada bir tetikleniyor ve sessizce çalışıyor; yalnızca gerçekten bir sorun olduğunda konuşuyor.

Öğrendiklerim

  • Bot ve webhook farklı problemler için var: Karşılıklı etkileşim mi istiyorsun, yoksa tek yönlü bildirim mi? Bu soru mimariyi baştan belirliyor.
  • Varsayılan ayarlara güvenme: GitHub webhook kurulumunda "her şeyi gönder" seçeneği pipeline'ı olan bir repoda ciddi gürültüye yol açabiliyor; hangi event'lere gerçekten ihtiyacın olduğunu düşünüp seçmek gerekiyor.
  • Sessizlik de bir özellik: Bildirim sistemlerinde "konuşmaması gereken an" kadar "konuşması gereken an" da tasarımın bir parçası.

Sırada ne var?

Bu yapı, Mattermost gibi başka bir platforma da kolayca taşınabilir bir soyutlama üzerine kurulu (notify_all() fonksiyonu hem Discord hem farklı hedeflere mesaj gönderebiliyor). Bir sonraki yazıda, aynı prensiplerin Mattermost + CI/CD pipeline bildirimlerinde nasıl uygulandığını anlatacağım.


Kod: github.com/tahayagizguler/discord-notif-bot
Sonraki Yazı;Mattermost Kurulumu, Zoom Entegrasyonu ve CI/CD Pipeline Bildirimleri

Top comments (1)

Collapse
 
robin_harman_f7fecdd7f379 profile image
Robin Harman

I am very interested