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.
Ready-to-import templates
Skip the blank-workflow intimidation — we ship three production workflows you can drop straight into n8n:
- [Blog Autopilot](/docs/templates/n8n/blog-autopilot.json) — pulls a task from your content queue every 2h, runs Claude for the article body + Gemini for the SEO metadata, generates featured + inline images, uploads, and publishes. 31 nodes, fully wired.
- [Auto Content Generator (Gemini)](/docs/templates/n8n/auto-content-gemini.json) — simpler Gemini-only pipeline for faster, cheaper drafts.
- [RSS → AI-rewritten Posts](/docs/templates/n8n/rss-to-posts-ai.json) — ingests an RSS feed, rewrites each item with your chosen LLM, publishes to jekcms on a schedule.
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.
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:
- Settings → API Keys → Create new token
- Name it "n8n" so you know what it's for
- Select scopes: at minimum
posts:read,posts:write,media:read,media:write— add more as your workflows demand - Copy the token (shown once — you can't view it again)
This is the token n8n uses to authenticate against jekcms's REST API.
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.