Kembali ke Blog

Tutorial n8n #11: Membuat Workflow Content Approval dari Brief hingga Publikasi

Tutorial praktis membangun workflow content approval di n8n: menerima brief, membuat draft dengan AI, menyimpan status editorial, meminta review manusia, lalu mempublikasikan hanya setelah approval.

•
Frendi Triarista
Tutorial n8n #11: Membuat Workflow Content Approval dari Brief hingga Publikasi

Tutorial n8n #11: Membuat Workflow Content Approval dari Brief hingga Publikasi

Content automation yang baik bukan hanya menghasilkan teks lebih cepat. Menurut saya, bagian paling penting justru ada di sistem editorialnya: brief harus rapi, status jelas, reviewer punya ownership, perubahan tercatat, dan keputusan publikasi tidak dilepas begitu saja ke AI.

Di tutorial n8n #11 ini, kita akan membangun workflow content approval dari awal: menerima content brief melalui n8n Form Trigger, menghasilkan draft terstruktur dengan bantuan AI, menyimpan draft dan status review ke Notion atau Supabase, mengirim notifikasi ke editor, lalu memisahkan jalur approved dan revision. Workflow ini sengaja tidak mempublikasikan artikel secara otomatis dari output AI. Publikasi hanya berjalan setelah ada approval manusia.

Tutorial ini cocok untuk pemilik bisnis, tim marketing kecil, atau software engineer yang ingin membuat sistem content operations yang lebih rapi tanpa langsung membangun aplikasi internal dari nol.

Masalah content operations manual

Sebelum masuk ke workflow, kita perlu memahami masalah yang sering muncul ketika produksi konten mulai meningkat:

  1. Brief tercecer di chat, email, spreadsheet, atau dokumen yang berbeda.
  2. Draft tidak punya status yang konsisten, misalnya mana yang baru dibuat, sedang direview, butuh revisi, sudah approved, atau sudah published.
  3. Revisi sulit dilacak karena feedback ada di banyak tempat.
  4. Approval tidak terdokumentasi, sehingga tim sulit tahu siapa yang menyetujui artikel dan kapan keputusan dibuat.
  5. AI dipakai untuk mempercepat drafting, tetapi belum ada guardrail agar outputnya tetap diperiksa manusia.

Workflow yang akan kita buat menyelesaikan masalah tersebut dengan pendekatan sederhana: satu form untuk brief, satu tempat penyimpanan status, satu alur approval, dan satu jalur publish yang hanya aktif setelah approval.

Arsitektur workflow

Alur utama yang akan kita bangun:

n8n Form Trigger -> Set/Edit Fields -> OpenAI -> Notion atau Supabase Create -> Telegram/Email notification -> Wait/Webhook approval -> IF status -> HTTP Request publish atau update status revision

Fungsi setiap node:

Node Fungsi
n8n Form Trigger Menerima brief dari user melalui form yang dibuat oleh n8n.
Set/Edit Fields Membersihkan dan menormalkan input, misalnya trim judul, format keyword, dan status awal.
OpenAI Membantu menghasilkan draft terstruktur dari brief.
Notion atau Supabase Menyimpan draft, status editorial, reviewer, deadline, dan metadata.
Telegram atau Email Mengirim ringkasan draft dan link review ke reviewer.
Wait atau Webhook Menunggu keputusan manusia, misalnya approve atau request revision.
IF atau Switch Memisahkan jalur berdasarkan status approval.
HTTP Request Mengirim artikel ke CMS hanya jika status sudah approved.
Error Workflow atau dead-letter table Menangani kegagalan publish, timeout, atau data bermasalah.

Saat membangun dan mengetes workflow, gunakan Test URL dari Form Trigger agar data masuk terlihat di editor n8n. Setelah workflow siap, simpan, aktifkan, lalu gunakan Production URL. Untuk production, jangan berasumsi data submission akan selalu terlihat di editor seperti saat testing.

Prasyarat

Sebelum mengikuti tutorial ini, siapkan:

  1. Instance n8n yang sudah berjalan.
  2. Credential OpenAI di n8n Credentials.
  3. Salah satu penyimpanan editorial: Notion database atau Supabase table.
  4. Channel notifikasi, misalnya Telegram atau email.
  5. Endpoint CMS untuk publish, jika sudah tersedia. Di artikel ini kita gunakan placeholder [CMS_API_URL] dan [REDACTED].

Penting: jangan pernah menaruh API key, password, JWT, atau token nyata di Set node, form, workflow JSON, artikel, atau pesan notifikasi. Simpan credential di n8n Credentials.

1. Buat Form Brief di n8n Form Trigger

Tambahkan node n8n Form Trigger sebagai trigger utama. Buat form dengan field berikut:

Field Tipe Wajib Catatan
working_title Text Ya Judul kerja artikel.
audience Text Ya Target pembaca, misalnya pemilik bisnis kecil atau tim marketing.
business_goal Textarea Ya Tujuan bisnis dari artikel.
primary_keyword Text Ya Keyword utama.
supporting_keywords Textarea Tidak Satu keyword per baris atau dipisah koma.
content_angle Textarea Ya Sudut pandang konten.
reference_urls Textarea Tidak Daftar URL referensi, satu URL per baris.
CTA Text Tidak Ajakan tindakan di akhir artikel.
tone Dropdown Tidak Contoh: praktis, profesional, edukatif, santai.
deadline Date Ya Deadline review atau publikasi.
reviewer Text atau Email Ya Identitas reviewer.

Gunakan label yang jelas agar user tidak memasukkan informasi sensitif. Tambahkan helper text seperti: Jangan masukkan API key, password, token, credential, data pelanggan sensitif, atau informasi rahasia ke form ini.

2. Validasi input sebelum masuk ke AI

Jangan langsung mengirim semua submission ke AI. Minimal validasi berikut perlu diterapkan:

  1. working_title wajib ada dan tidak hanya berisi spasi.
  2. business_goal wajib ada karena AI butuh konteks tujuan.
  3. reference_urls harus valid jika diisi. Saya menyarankan hanya menerima URL https://.
  4. deadline harus masuk akal, misalnya tidak berada di masa lalu dan tidak terlalu dekat untuk proses review.
  5. Form tidak boleh menerima secret, API key, password, token, private key, atau credential lain.

Contoh expression aman di Set/Edit Fields:

  • clean_working_title: {{ $json.working_title.trim() }}
  • clean_primary_keyword: {{ $json.primary_keyword.toLowerCase().trim() }}
  • initial_status: draft
  • content_slug: {{ $json.working_title.toLowerCase().replace(/[^a-z0-9]+/g, '-') }}

Untuk validasi URL, Anda bisa menambahkan Code node atau IF node setelah Set/Edit Fields. Prinsipnya sederhana: pecah reference_urls per baris, buang baris kosong, lalu pastikan setiap URL diawali https:// dan dapat diparse sebagai URL. Jika gagal, hentikan workflow dengan status invalid_brief atau kirim notifikasi ke requester.

Untuk deadline, gunakan IF node. Jika deadline sudah lewat, arahkan ke jalur error ringan dan minta user mengirim ulang brief.

3. Generate draft dengan OpenAI node

Tambahkan OpenAI node setelah data bersih. Peran AI di sini adalah membantu membuat draft awal, bukan mengambil keputusan publikasi.

Output yang kita minta dari AI:

  1. Outline artikel.
  2. Search intent.
  3. Rekomendasi H1 dan H2.
  4. Pembuka artikel.
  5. Isi artikel terstruktur.
  6. Checklist praktis.
  7. Meta description.
  8. Internal-link suggestions.
  9. CTA.
  10. Daftar klaim yang perlu diverifikasi.

Contoh instruksi prompt yang aman:

Anda membantu membuat draft artikel berdasarkan content brief. Gunakan hanya informasi dari brief dan referensi yang diberikan. Jangan menyalin sumber. Jangan mengarang fakta. Jangan membuat klaim ranking SEO, angka performa, harga, SLA, kapasitas, atau fitur vendor yang tidak terverifikasi.

Jika ada informasi yang belum bisa diverifikasi, tandai di bagian claims_to_verify. Output harus terstruktur dengan bagian: search_intent, outline, h1, h2_sections, opening, body, practical_checklist, meta_description, internal_link_suggestions, CTA, claims_to_verify.

AI hanya membuat draft. Editor manusia tetap bertanggung jawab atas fakta, sumber, kualitas, dan keputusan publikasi.

Masukkan data brief ke prompt menggunakan expression, misalnya:

Working title: {{$json.clean_working_title}}
Audience: {{$json.audience}}
Business goal: {{$json.business_goal}}
Primary keyword: {{$json.clean_primary_keyword}}
Supporting keywords: {{$json.supporting_keywords}}
Content angle: {{$json.content_angle}}
Reference URLs: {{$json.reference_urls}}
CTA: {{$json.CTA}}
Tone: {{$json.tone}}
Deadline: {{$json.deadline}}
Reviewer: {{$json.reviewer}}

Saya biasanya meminta AI menghasilkan output JSON terstruktur agar mudah disimpan ke database. Namun, tetap siapkan fallback jika output tidak valid, misalnya arahkan ke status revision dengan catatan bahwa draft perlu diperiksa manual.

4. Simpan draft dan status editorial

Setelah draft dihasilkan, simpan ke Notion atau Supabase dengan status awal draft. Status yang digunakan dalam workflow ini:

Status Makna
draft Draft baru dibuat oleh AI dan belum dikirim untuk review.
review Draft sudah dikirim ke reviewer.
revision Reviewer meminta revisi.
approved Reviewer menyetujui draft untuk dipublikasikan.
published Artikel sudah berhasil dikirim ke CMS.

Opsi A: struktur tabel Supabase

Contoh struktur minimal content_pipeline:

create table content_pipeline (
  id uuid primary key default gen_random_uuid(),
  working_title text not null,
  audience text,
  business_goal text not null,
  primary_keyword text,
  draft_content text,
  status text not null check (status in ('draft', 'review', 'revision', 'approved', 'published')),
  reviewer text,
  feedback text,
  source_urls text[],
  deadline timestamptz,
  approved_at timestamptz,
  published_at timestamptz,
  created_at timestamptz default now(),
  updated_at timestamptz default now()
);

Tambahkan tabel audit jika memungkinkan:

create table content_pipeline_audit (
  id uuid primary key default gen_random_uuid(),
  content_id uuid not null,
  previous_status text,
  new_status text not null,
  actor text,
  action text,
  feedback text,
  created_at timestamptz default now()
);

Di Supabase node, gunakan operasi create row untuk menyimpan data awal. Jangan masukkan service role key ke node biasa. Simpan credential di n8n Credentials dan gunakan prinsip least privilege.

Opsi B: property database Notion

Jika menggunakan Notion, buat database editorial dengan property seperti berikut:

Property Tipe Catatan
id Text ID dari n8n atau database.
working_title Title Judul kerja.
audience Text Target pembaca.
business_goal Text Tujuan bisnis.
primary_keyword Text Keyword utama.
draft_content Page content atau Text Draft artikel.
status Select draft, review, revision, approved, published.
reviewer Person, Email, atau Text Penanggung jawab review.
feedback Text Catatan revisi.
source_urls URL atau Text Daftar sumber.
deadline Date Deadline review.
approved_at Date Waktu approval.
published_at Date Waktu publish.
created_at Date Waktu dibuat.
updated_at Date Waktu diperbarui.

Notion lebih nyaman untuk proses editorial karena reviewer bisa membaca dan memberi catatan di halaman yang familiar. Supabase lebih kuat untuk schema, query, audit trail, dan skala.

5. Kirim notifikasi review ke Telegram atau email

Setelah draft disimpan, update status menjadi review, lalu kirim notifikasi ke reviewer.

Isi notifikasi sebaiknya ringkas:

  1. Judul kerja.
  2. Primary keyword.
  3. Deadline.
  4. Link review ke Notion page, internal dashboard, atau approval form.
  5. Ringkasan pendek dari draft.
  6. Instruksi approve atau request revision.

Jangan mengirim credential, token, API key, full request header, atau data sensitif di notifikasi. Jika menggunakan approval link, gunakan approval request ID yang random, batasi masa berlaku, dan simpan hash token di database. Jangan menampilkan token mentah di log.

Contoh pesan:

Draft siap direview.
Judul: {{$json.working_title}}
Keyword: {{$json.primary_keyword}}
Deadline: {{$json.deadline}}
Reviewer: {{$json.reviewer}}
Link review: [REVIEW_LINK]

Pilih approve jika fakta, sumber, struktur, dan CTA sudah sesuai. Pilih revision jika masih perlu perbaikan.

6. Tambahkan approval human-in-the-loop

Bagian ini adalah guardrail utama. Workflow tidak boleh publish langsung dari output AI.

Ada beberapa opsi implementasi:

  1. Wait node, workflow berhenti sementara sampai menerima resume URL.
  2. Webhook approval, reviewer mengirim decision melalui form internal.
  3. Telegram command, misalnya approve atau revision, tetapi harus memverifikasi identitas reviewer.
  4. Email approval link, reviewer membuka halaman approval lalu mengisi keputusan.

Data approval minimal yang perlu disimpan:

Field Fungsi
content_id Menghubungkan approval ke draft.
reviewer_identity Email, user ID, atau chat ID reviewer.
decision approved atau revision.
feedback Catatan reviewer.
approved_at Waktu approval jika approved.
action_at Waktu action terjadi.
audit_id ID catatan audit trail.

Jangan hanya mengandalkan tombol approve tanpa identitas. Jika ada artikel finansial, kesehatan, hukum, atau artikel yang mengandung klaim sensitif, wajib gunakan approval manual yang lebih ketat dan pastikan klaim diverifikasi oleh orang yang kompeten.

7. Pisahkan jalur approved dan revision dengan IF atau Switch

Setelah keputusan reviewer masuk, gunakan IF atau Switch node.

Logika sederhana:

  • Jika decision adalah approved, update status menjadi approved, simpan approved_at, lalu lanjut ke HTTP Request publish.
  • Jika decision adalah revision, update status menjadi revision, simpan feedback, lalu kirim notifikasi kembali ke editor.
  • Jika decision tidak valid, jangan publish. Simpan sebagai error atau manual review.

Contoh kondisi IF:

{{$json.decision === 'approved'}}

Untuk jalur revision, notifikasi ke editor bisa berisi:

Draft butuh revisi.
Judul: {{$json.working_title}}
Reviewer: {{$json.reviewer}}
Feedback: {{$json.feedback}}
Link draft: [REVIEW_LINK]

8. Publish ke CMS dengan HTTP Request setelah approved

HTTP Request node hanya boleh dijalankan setelah status approved tersimpan. Gunakan endpoint CMS Anda dengan placeholder berikut:

Parameter Contoh aman
Method POST
URL [CMS_API_URL]/posts
Authentication Credential dari n8n Credentials
Authorization header Bearer [REDACTED]
Idempotency-Key {{$json.id}}-publish-v1
Timeout Sesuaikan dengan batas aman workflow Anda.

Body request dapat berisi title, slug, content, meta description, status, dan source content ID. Jangan kirim field internal yang tidak diperlukan. Jangan kirim token approval, credential, atau audit log lengkap ke CMS.

Setelah CMS mengembalikan respons sukses, update row menjadi published dan isi published_at. Jika gagal, jangan mengulang publish tanpa kontrol. Masukkan ke jalur retry atau dead-letter.

9. Retry, duplicate prevention, dan manual recovery

Workflow approval perlu dirancang untuk kondisi gagal, bukan hanya kondisi ideal.

Rekomendasi praktis:

Risiko Solusi
Request CMS timeout Atur timeout dan retry terbatas.
Publish terkirim dua kali Gunakan idempotency key, misalnya content_id + publish-v1.
Reviewer klik approve dua kali Cek status terakhir sebelum publish. Jika sudah published, abaikan event kedua.
Rate limit API Tambahkan retry dengan jeda dan batasi concurrency.
Output AI tidak valid Simpan sebagai revision atau draft_error, lalu minta editor memperbaiki.
CMS error Simpan ke dead-letter table atau status publish_failed.
Notifikasi gagal Retry notifikasi, tetapi jangan publish karena notifikasi gagal.
Data duplikat dari form Buat duplicate prevention berdasarkan working_title, reviewer, deadline, dan idempotency key.

Untuk error workflow, buat alur terpisah yang menerima error dari workflow utama, lalu menyimpan ringkasan error ke database dan mengirim notifikasi ke admin. Redact request header, token, dan payload sensitif sebelum masuk log.

Notion vs Supabase untuk content pipeline

Aspek Notion Supabase
Kemudahan review Sangat nyaman untuk editor non-teknis. Perlu dashboard atau UI tambahan.
Struktur data Fleksibel, tetapi bisa longgar. Schema jelas dan konsisten.
Query dan filter Cukup untuk editorial ringan. Lebih kuat untuk reporting dan automation.
Audit trail Bisa dibuat, tetapi tidak seketat database. Lebih cocok untuk audit table dan constraint.
Skala workflow Cocok untuk tim kecil dan proses editorial sederhana. Lebih cocok untuk pipeline yang makin kompleks.
Integrasi teknis Mudah dibaca manusia. Lebih enak untuk aplikasi internal dan API.

Jika tim Anda banyak bekerja di dokumen, mulai dari Notion lebih praktis. Jika sejak awal Anda butuh audit, query, dan integrasi ke dashboard, Supabase lebih tepat.

Expected result

Setelah workflow selesai, hasil yang diharapkan:

  1. User mengisi content brief melalui form.
  2. n8n membersihkan dan memvalidasi input.
  3. AI membuat draft terstruktur beserta daftar klaim yang perlu diverifikasi.
  4. Draft tersimpan dengan status draft, lalu berubah menjadi review.
  5. Reviewer menerima notifikasi berisi link review dan ringkasan.
  6. Reviewer memilih approved atau revision.
  7. Jika revision, editor menerima feedback dan artikel tidak dipublish.
  8. Jika approved, workflow memanggil CMS API melalui HTTP Request.
  9. Setelah sukses, status berubah menjadi published dan published_at terisi.
  10. Semua perubahan status tercatat di audit trail.

Troubleshooting

Masalah Penyebab umum Solusi
Form submission tidak terlihat saat production Production URL berbeda dari Test URL. Saat debugging gunakan Test URL. Untuk production, cek execution logs dan penyimpanan data.
AI menghasilkan output tidak sesuai format Prompt kurang tegas atau output terlalu panjang. Minta output JSON terstruktur dan tambahkan fallback manual review.
Reviewer tidak menerima notifikasi Credential Telegram/email salah atau channel ID tidak sesuai. Cek credential di n8n Credentials dan kirim test message.
Approval tidak memicu workflow Webhook atau Wait URL salah. Pastikan URL aktif, workflow tersimpan, dan method request sesuai.
Artikel terpublish dua kali Tidak ada idempotency key atau status check. Cek status sebelum publish dan gunakan idempotency key.
CMS menolak request Payload tidak sesuai atau auth gagal. Validasi schema body dan credential, jangan hardcode token.
Draft berisi klaim tidak akurat AI mengisi informasi yang belum diverifikasi. Perkuat prompt guardrail dan wajibkan editor memeriksa claims_to_verify.

Security checklist

Sebelum menjalankan workflow di production, pastikan:

  • AI tidak pernah mempublish langsung ke CMS.
  • Credential disimpan di n8n Credentials, bukan Set node, form, workflow JSON, atau artikel.
  • Semua endpoint approval dan CMS menggunakan HTTPS.
  • Input form divalidasi, terutama URL, deadline, dan field teks bebas.
  • Notifikasi tidak berisi API key, password, token, JWT, private key, atau credential lain.
  • Log dan error message meredact data sensitif.
  • Reviewer identity diverifikasi sebelum approval diterima.
  • Status change disimpan di audit trail.
  • HTTP Request publish memakai least privilege.
  • Artikel finansial, kesehatan, hukum, atau klaim sensitif selalu melewati approval manual.
  • Workflow memiliki retry terbatas, timeout, duplicate prevention, dan manual recovery.

Batasan workflow

Workflow ini membantu mengatur proses editorial, tetapi tidak menggantikan editor. AI bisa membantu membuat draft, outline, meta description, dan checklist. Namun, editor tetap bertanggung jawab atas fakta, sumber, kualitas, gaya bahasa, konteks bisnis, legal risk, dan keputusan publikasi.

Workflow ini juga belum mencakup content calendar lengkap, assignment multi-editor, versioning detail per paragraf, plagiarism checking, atau fact-checking otomatis. Semua itu bisa ditambahkan bertahap setelah fondasi status dan approval rapi.

Checklist sebelum publikasi

Gunakan checklist ini sebelum mengaktifkan jalur publish:

  1. Form brief sudah memiliki field wajib dan helper text keamanan.
  2. Validasi judul, tujuan, URL referensi, dan deadline sudah aktif.
  3. Prompt AI sudah melarang fabrikasi fakta, klaim SEO yang tidak terverifikasi, dan penyalinan sumber.
  4. Draft tersimpan dengan status draft dan berpindah ke review setelah notifikasi dikirim.
  5. Reviewer identity, waktu approval, feedback, dan audit trail tersimpan.
  6. IF atau Switch node hanya mengizinkan publish jika status approved.
  7. HTTP Request CMS memakai [CMS_API_URL], credential di n8n Credentials, dan idempotency key.
  8. Error workflow, retry, timeout, dan dead-letter sudah disiapkan.
  9. Notifikasi sudah diuji tanpa membocorkan secret.
  10. Editor memahami bahwa AI hanya membantu draft, bukan pemilik keputusan publikasi.

Pengembangan berikutnya: content calendar

Setelah workflow approval ini stabil, langkah berikutnya adalah mengembangkannya menjadi content calendar. Anda bisa menambahkan field campaign, publish date, channel, owner, topic cluster, internal link target, dan performance review. Dari sana, n8n dapat membantu mengatur antrian konten mingguan, mengingatkan reviewer, dan membuat dashboard status produksi konten.

Bagi saya, inilah titik penting dari content automation: bukan sekadar membuat teks lebih cepat, tetapi membuat sistem yang menjaga kualitas tetap terkendali saat volume konten meningkat.

Referensi

  1. n8n Form, n8n Docs, https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.formtrigger/. Tanggal publish sumber: tidak terverifikasi dari materi rujukan yang tersedia.
  2. OpenAI node, n8n Docs, https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-langchain.openai/. Tanggal publish sumber: tidak terverifikasi dari materi rujukan yang tersedia.
  3. Notion node, n8n Docs, https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.notion/. Tanggal publish sumber: tidak terverifikasi dari materi rujukan yang tersedia.
  4. Supabase node, n8n Docs, https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.supabase/. Tanggal publish sumber: tidak terverifikasi dari materi rujukan yang tersedia.
  5. HTTP Request node, n8n Docs, https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/. Tanggal publish sumber: tidak terverifikasi dari materi rujukan yang tersedia.