n8n Workflow Setup
n8n is a self-hosted automation platform — think Zapier but open source and running on your own infrastructure. jekcms ships with native n8n integration so you can wire up workflows like "every time a post publishes, post to X and Pinterest" or "every Monday, generate 5 drafts from trending keywords."
This guide walks through the full setup: installing n8n, connecting it to jekcms, and building your first workflow.
Before you automate content: automatically generated or imported content may contain inaccurate, repetitive, or low-value information. Publishing without review can affect search visibility and publisher trust. You decide whether to save as draft, schedule, or publish directly — see "Choosing your publishing mode" below.
Ready-to-import templates
Skip the blank-workflow intimidation — we ship three example workflows you can drop straight into n8n and adapt:
- Blog Content Pipeline — pulls a task from your content queue every 2h, runs Claude for the article body + Gemini for the SEO metadata, generates featured + inline images, and uploads them, then calls the jekcms API to create the post. 31 nodes, fully wired. As shipped, the final node publishes directly — see "Choosing your publishing mode" below if you'd rather route it through review first.
- Auto Content Generator (Gemini) — simpler Gemini-only pipeline for faster, cheaper drafts.
- RSS → AI-rewritten Posts — ingests an RSS feed and rewrites each item with your chosen LLM. Read "Rewriting other people's content" below before you turn this on.
How to import: In n8n click Workflows → Import from file → pick the JSON → review the placeholder nodes (you'll see {{YOUR_EMAIL}}, your-site.example, etc. — replace with your real values) → fill in credentials on each AI node → save.
Each template is fully sanitized — no personal URLs, emails, or credentials. You will need to:
- Replace
https://your-site.examplewith your jekcms URL in every HTTP Request node - Add an
Authorization: Bearer <API_TOKEN>header where you see empty auth — generate the token under Settings → API Keys in admin - Connect your own AI credentials on nodes marked Claude, Gemini, or Anthropic — the templates reference the node but don't carry a key
- Replace
{{YOUR_EMAIL}}/{{YOUR_NAME}}/{{SITE_NAME}}placeholders in sticky notes and body templates with your real values
Tweak from there — change the schedule, add a Slack notification, swap Claude for OpenAI, etc.
Choosing your publishing mode
Every template above ends with an HTTP Request node that calls the jekcms API. What that node points to decides what happens to the content it produces:
- Review first (recommended while you're testing a new template or prompt). Send the webhook
action: "draft"instead ofaction: "publish". The article is created as a draft post — it shows up in Posts with the draft status, and nothing is visible on the site until you open it, read it, and hit publish. - Publish directly. Send
action: "publish", as the shipped templates do out of the box. Content goes live the moment the workflow finishes, with no human in the loop.
There is no queue API endpoint — the API creates posts, not content queue items. If you want work to land in the queue instead, feed the queue from a Google Sheet or a JSON/CSV import; that page explains how.
Both modes are legitimate uses of the API. Which one you pick depends on how much you trust the template's output and how much editorial risk you're willing to carry. Automated drafts can be inaccurate, repetitive or thin; publishing them unread can cost you search visibility and reader trust, and the final call is always yours. A sane pattern: run a new template as drafts for the first few dozen items, read them, and only switch that node to direct publish once you have seen the output hold up unattended.
Rewriting other people's content
The RSS template exists because people ask for it, not because it's a good default. Passing someone else's article through an LLM and republishing it — even reworded — carries little editorial value for the reader, and it's close to the pattern search engines describe as scaled content abuse. If you use it:
- Attribute the source clearly — link back to the original, credit the publisher
- Add something the source doesn't have: your own analysis, local context, an opinion, updated numbers
- Route it through the review queue (above), not direct publish — a person should read every rewritten piece before it goes live
- Expect scrutiny: a domain made mostly of rewritten RSS content reads as a content farm to readers and search engines alike
Treat this template as a starting point for a curation workflow, not a way to multiply someone else's work without adding to it.
Prerequisites
- A running jekcms install with admin access
- A machine (VPS, Raspberry Pi, local workstation) that can run n8n — 1 GB RAM minimum
- Docker, or Node.js 18+ if you prefer the npm install path
Step 1 — Install n8n
The simplest path is Docker:
docker run -d \
--name n8n \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n
Then open http://your-server-ip:5678 in a browser. First-run asks you to create an owner account. Use a strong password — n8n holds API keys for every service you connect.
For production, put n8n behind an HTTPS reverse proxy (Caddy or nginx) and enable N8N_BASIC_AUTH_ACTIVE=true as a belt-and-braces measure.
Step 2 — Generate a jekcms API token
In the jekcms admin:
- API Keys → Create new token
- Name it "n8n" so you know what it's for
- Copy the token (shown once — you can't view it again)
This is the token n8n uses to authenticate against jekcms's REST API.
jekcms tokens have no scopes: a token acts as the user it was created for, and it can do exactly what that user's role can do. So the way to keep an automation least-privilege is to create a dedicated editor (or author) account and issue the token from that account, rather than handing n8n an admin token. See API Authentication for the details.
Step 3 — Configure jekcms to accept the webhook
In jekcms admin:
- Settings → Integrations → n8n
- Base URL:
https://your-n8n-host(orhttp://localhost:5678for local dev) - Webhook secret: click Generate — this secret gets included in every outbound webhook signature so n8n can verify the request actually came from your jekcms
- Save
Step 4 — Build the webhook in n8n
- In n8n, New workflow → Add first step → Webhook
- Set HTTP method to POST
- Path: pick something descriptive, e.g.,
jekcms-post-published - Turn on Test URL, then the Production URL shows — copy it
Step 5 — Register the webhook in jekcms
Back in jekcms admin:
- Automation → Webhooks → Add webhook
- Event:
post.published(other events:post.updated,post.deleted,comment.approved,order.completed) - URL: paste the n8n webhook URL from step 4
- Save
Step 6 — Test the connection
Publish a post (draft → publish). jekcms fires the webhook; n8n receives the payload and shows a green checkmark on the test run. Payload shape:
{
"event": "post.published",
"timestamp": "2026-04-22T10:15:00Z",
"signature": "sha256=...",
"data": {
"post": { "id": 123, "title": "...", "slug": "...", "excerpt": "...", "url": "..." },
"author": { "id": 1, "name": "...", "email": "..." },
"categories": [ "Nutrition" ],
"tags": [ "protein" ]
}
}
In n8n, you can now chain nodes — HTTP Request to post to X/LinkedIn, Pinterest node to post the featured image, OpenAI node to generate a social caption, etc.
Step 7 — Verify webhook signature in n8n
n8n's Webhook node receives the raw body. Add a Function node immediately after with:
const crypto = require('crypto');
const secret = $env.JEKCMS_WEBHOOK_SECRET; // set this in n8n env vars
const rawBody = JSON.stringify($json);
const computed = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
if (computed !== $json.signature) {
throw new Error('Invalid signature — possible replay attack');
}
return $json;
This rejects requests that don't come from your jekcms install. Critical if your n8n webhook URL is public on the internet.
Common workflows
Auto-share new posts to X
Trigger: post.published → X node (posts the title + link)
Daily digest email
Trigger: cron (8 AM) → jekcms API "get posts from last 24h" → OpenAI "summarize" → Send Email node
AI-generated weekly pitches
Trigger: cron (Monday 9 AM) → Google Trends node → OpenAI (turn 5 trends into post pitches) → jekcms API "create draft" → Email Slack channel with links to review
Moderate comments with AI
Trigger: comment.created → OpenAI classification node → If classified "spam", call jekcms API /comments/{id}/delete; if "approved", call /comments/{id}/approve
Troubleshooting
Webhook not firing. Check Automation → Webhooks → Logs in jekcms admin — every attempt logs with the HTTP response code. If the log shows curl: 7 (connection refused), n8n isn't running or the URL is wrong.
Signature verification fails. Make sure the secret in n8n env vars matches exactly what jekcms shows in Settings → Integrations → n8n. Even a trailing whitespace breaks the hash.
n8n can't reach jekcms API. If n8n runs in Docker and jekcms runs on the host, use host.docker.internal (not localhost) in the n8n HTTP Request URL.