n8n ile "Falcı BACI" Tarot Falı Uygulaması (Form Tetikleyici ile)
- Alper AKBAS
- 5 Oca
- 7 dakikada okunur
Güncelleme tarihi: 6 Oca

Bu derste (videoda) neler öğreneceksiniz?
Workflow mantığını gerçekten kavramak (export / import kültürü)
Bir workflow’u JSON olarak dışa aktarıp başka ortama (cloud / local / başka hesap) içe aktarmak ve kaldığınız yerden devam etmek.
Başkalarının paylaştığı public workflow şablonlarını inceleyip kendi projene uyarlama mantığı (paylaşma–çoğaltma ekosistemi).
Debug sırasında node’ları deactivate ederek akışı parça parça test etmek (geliştirme alışkanlığı).
⠀
2) Workflow JSON paylaşırken güvenlik: “Pin data” detayı
Export ettiğin JSON dosyasına pinlediğin/sabitlediğin test verilerinin de girebildiğini; bu yüzden paylaşımdan önce kontrol etmen gerektiğini.
⠀
3) Message a Model node’u doğru kullanmak (System vs User)
Bu senaryoda chatbot değil, “tek mesaj → tek cevap” mantığıyla model çağırmak (use-case’e uygun kurgu).
Prompt yapısını doğru kurgulamak: System mesajı = davranış/kurallar, User mesajı = kullanıcı verisi + istek (tarot falı örneğiyle).
⠀
4) Mapping (eşleştirme) ve bağlam yönetimi
Formdan gelen alanları modele ve sonraki adımlara dinamik şekilde map etmek; test sürecinde veriyi tekrar tekrar doldurmamak için pinleme gibi pratikler.
“Bu işin özü mapping” farkındalığı: akışların çalışma biçimini ve veri eşleştirmeyi sindirme.
⠀
5) Form test/production ayrımı + yayınlama mantığı
Form Trigger’ın “testte dinleme / production URL” mantığını doğru anlamak; publish akışını yönetmek.
⠀
6) Form arayüzünü güzelleştirmek (Custom CSS)
n8n Form’da Custom form styling ile CSS basarak form tasarımını değiştirme (buton, genişlik, renkler vs.).
CSS’i dışarıda üretip (LLM’ye yazdırıp) forma basma ve publish ederek aktif etme.
7) Üretime yakın çıktı: HTML üretmek ve Form Ending’de göstermek
LLM çıktısını “kullanıcıya güzel sunum”a çevirmek için HTML akışına hazırlanmak (tasarım + sunum katmanı).
8) Airtable entegrasyonu: veriyi veri tabanına yazmak
Form verisini + üretilen çıktıları Airtable’a taşımak için akış kurgusunu tamamlamak (üretim pipeline’ı gibi düşünmek).
Bu ders, önceki dersi “bir üst seviyeye” taşıyor.
Bir önceki videoda n8n’in form yapısını kullanıp son kullanıcıdan veri toplamayı ve bunu bir veritabanına (Airtable) hızlıca kaydetmeyi gösterdik. Bu ders ise aynı altyapının üstüne LLM (Message a Model) ekleyerek otomasyonu “AI destekli” hale getiriyor: Formdan gelen bilgileri modele gönderiyoruz, modelden gelen cevabı yapılandırıp hem kullanıcıya şık bir sonuç ekranı olarak gösteriyoruz hem de Airtable’a kaydediyoruz.
Önceki video hakkında:
Önceki video'da çok iş yapmıştık. Form trigger (tetikleyici) detaylı incelemiş, mapping (yani veri eşleştirme) yapmış, devamında da AirTable'da bir workspace, base ve altında da bir tablo oluşturup alanlarımızı belirlemiştik. Untmayın biz bu işler detaylı yaparken n8n içerisinde çalışmaya alışıyoruz ve pratik yapıyoruz. Eğer o videoyu izlemediyseniz, izlemeniz şiddetle tavsiye olunur.
İlgili videoya bu linkten ulaşabilirsiniz:
Ayrıca tüm seriye aşağıdaki linkten ulaşabilirsiniz:
Bölüm I — Workflow export/import neden kritik?
Bu seride en büyük hızlandırıcı alışkanlıklardan biri şu: Çalışan bir akışı her seferinde sıfırdan kurmak yerine workflow’u JSON olarak export edip import etmek. Böylece:
bir önceki derste kaldığın yerden devam edebilirsin,
izleyici aynı akışı indirip birebir uygulayabilir,
“kopyala–yapıştır” ile farklı versiyonlar (prova/canlı) üretebilirsin.
Makale ekinde paylaştığım JSON dosyası bu dersin başlangıç noktasını veriyor. (Aşağıya link koy.)
Bölüm II — Message a Model: System vs User farkı neden önemli?
“Message a Model” düğümünde üç rol görürsün (system / user / assistant). Bu derste özellikle system mesajına “davranış kuralları” (tarz, format, sınır) koyup; user mesajında ise formdan gelen dinamik veriyi modele aktarıyoruz. Böyle ayırınca hem anlatım daha temiz oluyor hem de prompt’u yönetmek kolaylaşıyor. Örnek yapı bu şekilde:
Ayrıca, prompt’u “dinamik hale getirme” kısmı (mapping) aslında n8n’deki en kritik refleks: Form alan isimleri JSON’da nasıl geliyorsa, model mesajına da aynı isimlerle taşımayı öğreniyorsun. Formdaki fieldName’in JSON karşılığı olduğunu derste özellikle vurguluyorsun.
Bölüm III — LLM çıktısını “işlenebilir” hale getirme: Edit Fields + HTML
Edit Fields Node: Çok çok önemli, hemen hemen her workflow'da karşılaşacağınız bir node.
LLM’den gelen çıktı “düz metin” olunca bir yerde tıkanırsın:
Airtable’a düzenli kaydetmek zorlaşır
Form Ending’de şık bir sonuç UI üretmek zorlaşır
Bu yüzden bu derste çıktıyı JSON formatına zorlayıp Edit Fields (Set) node ile alanlara ayırıyoruz; ardından HTML node ile tasarımlı bir ekran üretiyoruz. Bu yaklaşım hem eğitim hem gerçek kullanım için çok temiz bir pattern.
Bölüm IV — Airtable’a kayıt: mapping disiplin ister
Airtable tarafında en önemli konu “alan eşleştirme”: Formdan gelen alanlar + modelden gelen alanlar + ürettiğin HTML’i doğru kolonlara yazmak. Senin workflow’unda bu mapping açık şekilde kurulmuş durumda (isim, doğumTarihi, cinsiyet, soru, htmlSonuc, sonuc…).
Bölüm V — Formu yayınlama ve Conflicting Path hatası
n8n Form’larda “path” canlıya çıkarken çok kritik. Aynı path daha önce kullanıldıysa Conflicting Path hatasıyla karşılaşırsın. Derste bunu yakalayıp çözme mantığını gösteriyorsun; ayrıca formu daha “markalı” hale getirmek için custom CSS tarafına da giriyorsun (renkler, buton, arka plan, vb.).
Dersimizin Videosu
Çok yakında yayında
Kullandığımız kodlar (Copy/Paste Candır)
Önce hatırlayalım çünkü önemli:

Kodlar
Hata varsa lütfen makale yorumlarında da paylaşın ki müdahale etme şansım olsun. Community candır! 😍
System Prompt örneği
Sen eğlence amaçlı tarot yorumcususun.
KURALLAR
- Sadece 2 kart çek.
- 3 maddelik öğüt ver.
- Samimi Türkçe, net ve kısa paragraflar.
- Kesin hüküm verme.
- Sağlık/hukuk/finans yönlendirmesi yapma.
- En sonda mutlaka uyarı notu olsun.
- Ders kaydı yaptığım için eğer sana "Youtube kanalım büyüyecek mi?" sorusu gelirse, mutlaka sempatik bir şekilde, bu videoyu izleyen sana videoyu beğenip abone olursa ile başlayan espirili bir cümle ekle mutlaka yoruma! ve mutlaka desteklenmenin önemini dile getir.
KULLANICIdan gelecek bilgiler (isim, doğum tarihi, cinsiyet, soru) ışığında yorum yapacaksın.
ÇIKTI
SADECE aşağıdaki JSON'u döndür (başka metin yok, markdown bloğu kullanma):
{
"kart1": "",
"kart2": "",
"karrlarin_kisa_aciklamasi": "",
"aciklama": "",
"yorum": "",
"ogutler": ["", "", ""],
"not": "Not: Bu yorum tamamen eğlence amaçlıdır; kesin doğrular içermez."
}User Prompt (formdan gelen veriyi gönderme)
Lütfen aşağıdaki bilgiler ışığında tarot falıma bakar mısın?
İsim:
Doğum Tarihi:
Cinsiyet:
Soru: HTML Kodumuz
Ben gemini'ya yazdırmıştım, bence sizde denemeler yapın ki eliniz biraz kirlensin
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tarot Fal Sonucu</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&family=Lato:wght@300;400;700&display=swap');
:root {
--primary: #6d28d9;
--secondary: #d8b4fe;
--accent: #fbbf24;
--bg-dark: #1e1b4b;
--card-bg: rgba(255, 255, 255, 0.08);
}
body {
margin: 0;
padding: 0;
font-family: 'Lato', sans-serif;
background: linear-gradient(135deg, #1e1b4b 0%, #312e81 100%);
color: #fff;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
max-width: 800px;
width: 90%;
margin: 40px auto;
background: rgba(15, 23, 42, 0.6);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 24px;
padding: 40px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}
h1, h2, h3 {
font-family: 'Cinzel', serif;
text-align: center;
}
h1 {
color: var(--secondary);
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 0 0 10px rgba(216, 180, 254, 0.3);
}
/* User Info Box */
.user-info {
background: rgba(255, 255, 255, 0.05);
border-radius: 12px;
padding: 20px;
margin-bottom: 40px;
border-left: 4px solid var(--accent);
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: space-between;
}
.info-item {
flex: 1;
min-width: 150px;
}
.info-label {
font-size: 0.85rem;
color: #94a3b8;
text-transform: uppercase;
letter-spacing: 1px;
display: block;
margin-bottom: 5px;
}
.info-value {
font-size: 1.1rem;
font-weight: 700;
color: #fff;
}
/* Cards Section */
.cards-container {
display: flex;
justify-content: center;
gap: 30px;
margin: 40px 0;
flex-wrap: wrap;
}
.tarot-card {
background: linear-gradient(145deg, #2e1065, #4c1d95);
border: 1px solid var(--secondary);
border-radius: 16px;
padding: 30px 20px;
width: 220px;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
position: relative;
overflow: hidden;
}
.tarot-card:hover {
transform: translateY(-10px);
box-shadow: 0 20px 25px -5px rgba(109, 40, 217, 0.5);
}
.tarot-card::before {
content: '🔮';
font-size: 3rem;
display: block;
margin-bottom: 15px;
}
.card-name {
font-family: 'Cinzel', serif;
font-size: 1.2rem;
color: var(--accent);
font-weight: bold;
}
/* Interpretation Text */
.interpretation {
background: var(--card-bg);
padding: 30px;
border-radius: 16px;
line-height: 1.8;
margin-bottom: 30px;
font-size: 1.05rem;
border: 1px solid rgba(255,255,255,0.05);
}
.short-desc {
text-align: center;
font-style: italic;
color: var(--secondary);
margin-bottom: 20px;
font-weight: 300;
}
/* Advice List */
.advice-box {
margin-top: 30px;
}
.advice-list {
list-style: none;
padding: 0;
display: grid;
gap: 15px;
}
.advice-list li {
background: rgba(109, 40, 217, 0.2);
padding: 15px 20px;
border-radius: 8px;
display: flex;
align-items: center;
}
.advice-list li::before {
content: '✨';
margin-right: 15px;
}
.footer {
margin-top: 40px;
text-align: center;
font-size: 0.8rem;
color: #64748b;
border-top: 1px solid rgba(255,255,255,0.1);
padding-top: 20px;
}
@media (max-width: 600px) {
.container { width: 95%; padding: 20px; margin: 20px auto; }
.cards-container { gap: 15px; }
.tarot-card { width: 100%; }
h1 { font-size: 2rem; }
}
</style>
</head>
<body>
<div class="container">
<h1>🔮 Kozmik Rehberin</h1>
<p style="text-align: center; color: #a5b4fc; margin-top: -10px;">Yapay Zeka Destekli Tarot Yorumu</p>
<!-- Kullanıcı Bilgileri -->
<div class="user-info">
<div class="info-item">
<span class="info-label">Danışan</span>
<span class="info-value">{{ $json.kullanici.isim }}</span>
</div>
<div class="info-item">
<span class="info-label">Doğum Tarihi</span>
<span class="info-value">{{ $json.kullanici.dogumTarihi }}</span>
</div>
<div class="info-item" style="flex-basis: 100%; margin-top: 10px;">
<span class="info-label">Soru / Niyet</span>
<span class="info-value">"{{ $json.kullanici.soru }}"</span>
</div>
</div>
<!-- Kartlar -->
<div class="cards-container">
<div class="tarot-card">
<div class="card-name">{{ $json.cevap.kart1 }}</div>
</div>
<div class="tarot-card">
<div class="card-name">{{ $json.cevap.kart2 }}</div>
</div>
</div>
<!-- Yorumlar -->
<div class="interpretation">
<div class="short-desc">
{{ $json.cevap.kartlarin_kisa_aciklamasi }}
</div>
<p>{{ $json.cevap.aciklama }}</p>
<p>{{ $json.cevap.yorum }}</p>
</div>
<!-- Öğütler -->
<div class="advice-box">
<h3 style="color: var(--accent);">Yıldızların Tavsiyesi</h3>
<ul class="advice-list">
<li>{{ $json.cevap.ogutler[0] }}</li>
<li>{{ $json.cevap.ogutler[1] }}</li>
<li>{{ $json.cevap.ogutler[2] }}</li>
</ul>
</div>
<div class="footer">
{{ $json.cevap.not }}
</div>
</div>
</body>
</html>
Ana formumuzun css'i
:root {
/* Fontlar - Google Font import destekliyorsa ekleyebilirsin, yoksa varsayılan kalır */
--font-family: 'Open Sans', sans-serif;
/* --- RENKLER (Tarot Teması) --- */
/* Arka Plan: Koyu Lacivert/Mor */
--color-background: #1e1b4b;
/* Kart (Form Kutusu) Arka Planı: Hafif transparan koyu mor /
--color-card-bg: #2e1065;
--color-card-border: #6d28d9; / Parlak Mor Çerçeve */
--color-card-shadow: rgba(0, 0, 0, 0.5);
/* Başlıklar ve Metinler /
--color-header: #fbbf24; / Altın Sarısı Başlık /
--color-header-subtext: #d8b4fe; / Açık Mor Alt Metin /
--color-label: #e9d5ff; / Çok Açık Mor Etiketler */
--color-paragraph: #d8b4fe;
/* Input Alanları /
--color-input-bg: #1e1b4b; / Koyu zemin /
--color-input-border: #4c1d95; / Koyu Mor Çerçeve /
--color-input-text: #ffffff; / Beyaz Yazı /
--color-focus-border: #fbbf24; / Tıklayınca Altın Sarısı Olsun */
--opacity-placeholder: 0.4;
/* Butonlar /
--color-submit-btn-bg: #6d28d9; / Canlı Mor /
--color-submit-btn-text: #ffffff; / Beyaz Yazı */
/* Hata Mesajları /
--color-error: #ef4444;
--color-required: #fbbf24; / Zorunlu işaretleri Altın olsun */
/* Diğer /
--color-link: #fbbf24;
--border-radius-card: 16px; / Daha yuvarlak köşeler */
--border-radius-input: 8px;
--submit-btn-height: 52px;
}
/* Ekstra Dokunuşlar (n8n CSS izin veriyorsa çalışır) */
body {
background-image: linear-gradient(135deg, #1e1b4b 0%, #312e81 100%);
}
/* Buton Hover Efekti /
button[type="submit"]:hover {
background-color: #5b21b6 !important; / Daha koyu mor */
box-shadow: 0 0 15px rgba(109, 40, 217, 0.5);
}
Edit Fields Node içerisine eklediğimiz kod (kısa ama etkili)
{{ JSON.parse($json.output[0].content[0].text) }}Önmeli: "Object" seçmeyi unutmayın 👍🏼

Yarattığımız Workflow (İş Akışı) JSON dosyası

Makaleye de yorum ve beğeni atarsanız ben mutlu oluyorum yani. Ciddiyim. 👽
Yukarıda da dediğim gibi hata bulursanız lütfen yorumlara yazın. Ya da aşağıdaki sohbet kutusundan iletişime geçin. Zor bir iş yapıyoruz, beraber büyüyeceğiz 🤝 😇
Önümüzdeki ders aynı yapıyı bir rest api hizmetine çevimeyi planlıyorum. Takipte kalın 👌🏼
İçeriği Nasıl buldunuz?
Bomba çok acayip. Çok işime yaradı.
İyiydi.
Fena değildi.
Daha da anlaşılabilir olabilir mi acaba?


Yorumlar