AI-Driven Instagram Workflow: n8n ile Sosyal Medya Otomasyonu
Instagram otomasyonu için n8n ve Python ile kuyruk tabanlı içerik tamponu, zamanlanmış paylaşım, hata yönetimi ve hukuki sınırlar üzerine pratik rehber.
Instagram otomasyonu lafını duyan çoğu kişinin aklına takipçi botları, otomatik beğeni orduları ve şişirilmiş etkileşim rakamları geliyor. Benim bu yazıda anlatacağım şey bunun tam tersi: kendi hesabım için içerik üretimini, zamanlanmış paylaşımı ve durum takibini tek bir düzende toplayan, insan gözetiminde çalışan bir sistem. Danışmanlık işinde asıl emek içeriğin kendisine gidiyor — metni yazmak, görseli hazırlamak, mesajı oturtmak. Paylaşma anı ise saati gelince yapılması gereken mekanik bir iştir ve mekanik işi makineye devretmek, içeriğe ayırdığım zamanı korumanın en doğrudan yolu.
Bu yazıda n8n ve Python ile kendi hesabım için kurduğum düzeni adım adım anlatacağım: kuyruk tabanlı bir içerik tamponu, zamanlanmış paylaşım, oturum yeniden kullanımı ve hata durumunda geri alma. Yaklaşım, blogda daha önce anlattığım Google Maps ile potansiyel müşteri keşfi çalışmasıyla aynı ilkeye dayanıyor: tekrarlayan işi makineye, kararı insana bırakmak. Yazının sonunda da çoğu rehberin atladığı tarafı, hukuki ve etik sınırları açıkça konuşacağız; çünkü Instagram tarafında otomasyonun kuralları sandığınızdan daha nettir ve görmezden gelmenin bedeli hesabınızdır.
Mimari: n8n Orkestra Şefi, Python İşçi
İlk denemede her şeyi n8n içinde çözmeye çalışmıştım; kısa sürede vazgeçtim. n8n, HTTP tabanlı servisleri birbirine bağlamakta, zamanlamada ve dallanmada çok iyidir; ama Instagram'ın resmi olmayan istemcisi instagrapi bir Python kütüphanesidir ve oturum yönetimi, medya yükleme gibi ince işleri n8n düğümleriyle taklit etmek kırılgan bir yapı üretir. Bu yüzden iş bölümü net: n8n orkestra şefi, Python işçi.
n8n tarafının sorumlulukları şunlar:
- Zamanlama: Cron düğümü, paylaşım saatlerinde Python işçisini tetikler. Saatler sabit değil; hafta içi ve hafta sonu için ayrı pencereler tanımlı.
- Durum toplama: Bir Webhook düğümü, işçiden gelen "yayınlandı" ya da "başarısız" bildirimlerini karşılar ve kaydeder.
- Dallanma ve uyarı: Başarısızlıkta bana Telegram üzerinden uyarı düşer; başarıda kayıt sessizce arşive gider.
- Tampon nöbeti: Kuyruktaki hazır içerik sayısı eşiğin altına inince "içerik üret" hatırlatması gelir.
Python işçisi ise tek bir iş yapar: kuyruğun başındaki içeriği alır, Instagram'a yükler, sonucu webhook'a bildirir. n8n hiçbir noktada Instagram'a doğrudan dokunmaz. Bu ayrımın en büyük getirisi test edilebilirlik: işçiyi kuru çalıştırma (dry-run) kipinde tek başına deneyebiliyorum, n8n akışını da sahte bildirimlerle ayrı ayrı sınayabiliyorum.
Kuyruk Tabanlı İçerik Tamponu
Sistemin kalbi, üretim ile yayını birbirinden ayıran tampondur. İçerik ürettiğim gün yayınlamak zorunda değilim; hazır içerikler kuyrukta bekler, yayın saati gelince sıradaki çıkar. Böylece bir hafta yoğun geçse bile paylaşım ritmi bozulmaz. Görseller şablondan üretildiği için tutarlılık kendiliğinden gelir; şablonların dayandığı renk, tipografi ve kompozisyon kurallarını marka görsel kılavuzu yazısında anlattığım yaklaşımla belirliyorum. Kuyruğun kendisi ise bilinçli olarak sıkıcı bir teknoloji: sürümlenebilen, elle düzeltilebilen bir JSON dosyası.
import json
import os
from datetime import datetime, timezone
KUYRUK_DOSYASI = "kuyruk/icerik-tamponu.json"
MIN_TAMPON = 3
def kuyruk_oku() -> list:
# Tampon dosyasini oku; yoksa bos liste don
if not os.path.exists(KUYRUK_DOSYASI):
return []
with open(KUYRUK_DOSYASI, "r", encoding="utf-8") as f:
return json.load(f)
def kuyruk_yaz(kayitlar: list) -> None:
# Atomik yazim: once gecici dosyaya yaz, sonra yer degistir
gecici = KUYRUK_DOSYASI + ".tmp"
with open(gecici, "w", encoding="utf-8") as f:
json.dump(kayitlar, f, ensure_ascii=False, indent=2)
os.replace(gecici, KUYRUK_DOSYASI)
def siradaki_icerik() -> dict | None:
# Durumu 'hazir' olan en eski kaydi getir
bekleyen = [k for k in kuyruk_oku() if k["durum"] == "hazir"]
if len(bekleyen) < MIN_TAMPON:
print(f"UYARI: tamponda yalnizca {len(bekleyen)} icerik kaldi")
return bekleyen[0] if bekleyen else None
def durum_guncelle(icerik_id: str, yeni_durum: str) -> None:
kayitlar = kuyruk_oku()
for k in kayitlar:
if k["id"] == icerik_id:
k["durum"] = yeni_durum
k["guncelleme"] = datetime.now(timezone.utc).isoformat()
kuyruk_yaz(kayitlar)
Buradaki en önemli ayrıntı atomik yazımdır: dosya önce geçici bir ada yazılır, sonra os.replace ile tek hamlede yerine geçer. Zamanlanmış görev tam yazma sırasında kesilirse bile kuyruk asla yarım kalmış, bozuk bir dosya olarak kalmaz. Tampon eşiği uyarısı da işçinin değil n8n'in işi olarak devam eder; işçi sadece sayıyı bildirir, hatırlatmanın nereye gideceğine akış karar verir.
Zamanlanmış Paylaşım, Oturum ve Geri Alma
instagrapi kullanırken en kritik ayrıntı oturumun yeniden kullanımıdır. Her çalıştırmada sıfırdan giriş yapmak, Instagram'ın gözünde şüpheli davranış sinyalidir ve doğrulama zorunluluğu ya da geçici kilit ile sonuçlanabilir. Doğru yöntem, ilk girişten sonra oturum ayarlarını diske kaydetmek ve sonraki çalıştırmalarda aynı oturumu yüklemektir. Buna oran sınırına saygı ve üstel geri çekilme eklenince işçi şu hale geliyor:
import time
import requests
from pathlib import Path
from instagrapi import Client
OTURUM_DOSYASI = Path("oturum.json")
N8N_WEBHOOK = "https://n8n.ornek.com/webhook/instagram-durum"
def istemci_getir(kullanici: str, parola: str) -> Client:
# Oturumu yeniden kullan; her calistirmada login riskli
cl = Client()
if OTURUM_DOSYASI.exists():
cl.load_settings(OTURUM_DOSYASI)
try:
cl.get_timeline_feed() # oturum hala gecerli mi?
return cl
except Exception:
pass # gecersiz: asagida yeniden gir
cl.login(kullanici, parola)
cl.dump_settings(OTURUM_DOSYASI)
return cl
def paylas_ve_bildir(cl: Client, icerik: dict, deneme: int = 4) -> bool:
for i in range(deneme):
try:
medya = cl.photo_upload(icerik["dosya"], icerik["aciklama"])
requests.post(N8N_WEBHOOK, json={
"id": icerik["id"], "durum": "yayinlandi",
"medya_pk": str(medya.pk)}, timeout=10)
return True
except Exception as hata:
bekleme = (2 ** i) * 60 # ustel geri cekilme: 1-2-4-8 dk
print(f"Deneme {i + 1} basarisiz: {hata}, {bekleme} sn bekleniyor")
time.sleep(bekleme)
requests.post(N8N_WEBHOOK, json={
"id": icerik["id"], "durum": "basarisiz"}, timeout=10)
return False
Geri alma mantığı bu iki parçanın birleşiminde yaşıyor. İşçi paylaşıma başlamadan önce kaydın durumunu "yayinlaniyor" yapar; tüm denemeler tükenirse durumu "hazir"e geri çevirir ve webhook'a "basarisiz" bildirir. Böylece içerik kaybolmaz, bir sonraki pencerede yeniden sıraya girer; ben de Telegram uyarısıyla durumdan haberdar olurum. Durum alanının bir yan görevi daha var: aynı içeriğin iki kez paylaşılmasını engellemek. İşçi yalnızca "hazir" durumundaki kayıtları aldığı için, çakışan iki tetikleme bile aynı gönderiyi tekrarlayamaz.
Hacim konusunda kuralım basit: günde bir, en fazla iki paylaşım ve paylaşımlar arasında insan ritmine uygun rastgele gecikmeler. Otomasyonun amacı makine hızına çıkmak değil, benim elimle yapacağım işi benim yokluğumda da aynı tempoda sürdürmektir.
Hukuki ve Etik Çerçeve: Neyi Otomatikleştirmemeli?
Burada dürüst olmak zorundayım. Instagram'da içerik yayınlamanın resmi yolu, Business ya da Creator hesapla kullanılan Graph API'dir; Meta'nın onayladığı bir uygulama üzerinden, belgelenmiş uçlarla çalışır. instagrapi gibi resmi olmayan istemciler ise mobil uygulamanın özel API'sini taklit eder ve bu kullanım Meta'nın Kullanım Koşulları'na ve otomasyon politikalarına aykırı olabilir. Sonuç olarak hesabın geçici kilitlenmesi ya da kalıcı askıya alınması gerçek ve her zaman masada olan bir risktir. Ben bu riski bilerek, yalnızca kendi hesabımda, düşük hacimde ve insan gözetiminde alıyorum; bir müşteri hesabı söz konusu olduğunda tek savunulabilir yol resmi Graph API'dir.
Kendi çizdiğim sınırlar şöyle:
- Yalnızca kendi hesabında: Riskin muhatabı da faydanın sahibi de sizsiniz. Başkasının hesabını resmi olmayan istemciyle yönetmek, başkasının adına risk almaktır.
- Etkileşim şişirme yok: Otomatik beğeni, otomatik takip, kalıp yorum — bunlar hem koşullara aykırıdır hem de etik olarak spamdır. Ben yalnızca kendi içeriğimin yayınını otomatikleştiriyorum; başkalarının içeriğiyle etkileşimi değil.
- KVKK sorumluluğu: Kullanıcı adları, yorumlar ve özellikle DM içerikleri kişisel veridir. Bunları toplayıp işleyen bir otomasyon kurduğunuz anda veri sorumlusu sıfatıyla yükümlülük altına girersiniz. Ben DM otomasyonundan ve kullanıcı verisi toplamaktan bilinçli olarak uzak duruyorum.
- Ölçek büyüyünce resmi yol: İş ticarileştiğinde ya da hacim arttığında resmi olmayan istemciyle devam etmek savunulamaz; Graph API'ye geçiş bir tercih değil zorunluluktur.
Kısacası otomasyonun meşru amacı kendi iş yükünüzü azaltmaktır; platformu ya da diğer kullanıcıları kandırmak değil. Bu çizgiyi geçen her kurgu, teknik olarak ne kadar zarif olursa olsun, bence kurulmamalıdır.
Sonuç
İçerik üretimini yayından ayıran bir tampon, işi tek noktadan yöneten bir n8n akışı ve Instagram'a dokunan tek parça olarak disiplinli bir Python işçisi: kurduğum düzenin tamamı bu. Oturum yeniden kullanımı ve üstel geri çekilme hesabı korur, durum alanı ve atomik yazım kuyruğu korur, hukuki çerçeve de sizi korur. Bana kazandırdığı şeyi sayıyla değil nitelikle anlatayım: paylaşım saatini düşünmeden geçen günler ve içeriğe ayrılan kesintisiz zaman. Benzer kuyruk ve otomasyon düzenlerini farklı alanlarda nasıl uyguladığımı ana sayfadaki çalışmalarımda görebilirsiniz; kendi süreçleriniz için birlikte düşünmek isterseniz ana sayfanın iletişim bölümünden (/#contact) bana ulaşabilirsiniz.