Field SOP
Field SOP

RSS to AI Rewrite to Multi-Platform Auto-Publish: An n8n Workflow SOP

Build an n8n workflow that triggers on RSS Feed Read Trigger, rewrites each item into per-platform formats via an AI Agent node, routes through a Switch on category, and fans out to Telegram, Email Send, and a Feishu webhook via HTTP Request - with real node names, key parameters, $json/$env expressions, guid-based dedup, 6 pitfalls, and 5 FAQ.

Published August 6, 20268 min read
<!-- rss-to-social-publish-workflow-sop | sop | RSS to AI Rewrite to Multi-Platform Auto-Publish: An n8n Workflow SOP -->

Anyone running one-person multi-platform content has lived this: every morning open a dozen RSS feeds, pick what is worth posting, rewrite it into the formats that fit Telegram, an email list, a Feishu group, and a newsletter, then paste into each platform one by one. Two hours gone -- and you still miss posts, send to the wrong channel, or mangle the formatting. The bottleneck is not content ability; it is hauling. Repetitive, mechanical, error-prone work that a human should never own.

This SOP ships a reusable n8n workflow template: an RSS Feed Read Trigger pulls sources -> an AI node rewrites and adapts each item to per-platform formats -> a Switch node routes by content type -> multiple outputs fan out to Telegram, email, and a Feishu (Lark) webhook. Every step gives the real node name, key parameters, and expressions so you can reproduce it on the canvas. Node names follow the n8n official docs; parameters I could not verify online are marked "per official docs" rather than fabricated.

One-line framing: this workflow is not "AI writes your articles." It is "AI takes one RSS item and rewrites it into N platform-specific formats, then publishes them automatically." It kills the distribution hauling, not the creative work.


One: Scenario and Pain Points

Picture an AI-tools reviewer who subscribes to 20 AI news RSS feeds (Hacker News, vendor blogs, GitHub Releases). Hundreds of new items a day -- you cannot post them all, but you cannot afford to miss the ones that matter. The pain clusters in three places:

  • Hauling is exhausting. The same story needs a short sentence plus link for Telegram, a long summary for the email list, and a tagged structured card for the Feishu group. Rewriting it three times by hand burns every hour on copy-paste.
  • Missed and mistaken posts. Paste into the wrong channel, forget a platform, or ship a draft as the final. Manual scheduling has no state tracking, so errors are hard to trace.
  • Lost timing. A breaking story two hours late loses most of its traffic. By the time you are free to handle it manually, the moment is gone.

The root tension: distribution is a deterministic pipeline (receive content -> transform -> deliver), but it gets packaged as a creative task that needs a human watching it. n8n turns it back into an automated pipeline -- humans own only the selection rules and the prompt, machines own the hauling.


Two: Tool Selection -- Why n8n

Plenty of tools do multi-platform distribution. Why build this pipeline on n8n:

Dimensionn8nCozeZapier/Make
HostingSelf-hostable (Docker), data stays in-housePure SaaS, data in cloudPure SaaS
Integrations400+ nodes + arbitrary HTTPDomestic ecosystem focusedMany but pricey
AI nodesNative AI Agent / Language Model, any OpenAI-compatible modelBuilt-in ByteDance modelsNeeds third-party glue
CostSelf-host free, only hardware limitsFree tierPer-task billing, expensive
CustomHTTP Request hits any webhook, Code node runs JSClosed loop, weak external APIsMedium flexibility

The core reasons to pick n8n: self-host free + native AI nodes + HTTP Request can hit any platform webhook. Feishu has no official n8n node, but a Feishu custom bot is just a webhook -- one HTTP Request and it works, which is exactly n8n's "eats anything" value. Coze onboards faster but is closed-source, cloud-only, and weak at external webhooks, making "multi-platform webhook fan-out" awkward.

Prerequisites: an n8n instance (self-host with docker run -d --name n8n -p 5678:5678 -v ~/.n8n:/home/node/.n8n n8nio/n8n, or use the n8n.io cloud), an API key for an OpenAI-compatible model, and per-platform credentials (Telegram Bot Token, SMTP, Feishu bot webhook URL).


Three: Build Step by Step -- RSS -> AI Rewrite -> Multi-Platform

The main trunk is five nodes plus a dedup step. Draw the trunk first, harden it after.

text
RSS Feed Read Trigger -> [Dedup Filter] -> AI Agent (rewrite) -> Switch (route) -> Multi-output
                                                                    |-> Telegram
                                                                    |-> Email Send
                                                                    |-> HTTP Request (Feishu webhook)

Step 1: Trigger -- RSS Feed Read Trigger

Drag in an RSS Feed Read Trigger node. It is itself a trigger (with built-in polling), so you do not need a separate Schedule Trigger. Key config:

text
URL: https://hnrss.org/frontpage          # your RSS source URL
Limit: 20                                  # max items per pull
Poll Times: every 30 minutes              # poll frequency, set by source refresh rate

Each item the node emits has fields (from the underlying rss-parser; per official docs): title, link, content, contentSnippet, pubDate, guid, isoDate, creator. The AI node and the dedup step both rely on these.

You can also combine Schedule Trigger + RSS Feed Read (the non-trigger version): Schedule runs on a timer, RSS Feed Read reads once. The difference is that the trigger version remembers state for "new items only"; the combo forces you to dedup yourself. For beginners, RSS Feed Read Trigger is less hassle.

Step 2: AI Rewrite -- Adapt to Each Platform's Format

Drag in an AI Agent node, feed it the RSS output. Attach a Language Model sub-node (pick OpenAI Chat Model; store the API key as an n8n Credential -- never hardcode; for domestic models pick the OpenAI-compatible type and set the Base URL).

The AI job here is not "freelance writing"; it is "rewrite one RSS item into three platform formats plus a category tag," so the output shape must be pinned down. Example System Prompt:

text
You are a multi-platform distribution rewriter. You receive one RSS item (title + link + content).
Output strict JSON with these fields:
- telegram: a summary <=200 chars, ending with the link
- email: a 300-500 word summary, Markdown, keeping the link
- feishu: a one-line title plus 3 bullet points
- category: one of [breaking, digest, skip]
Rules: do not fabricate facts not in the source; items unrelated to AI get category=skip; output JSON only, no markdown code fence.

The AI Agent emits text; downstream needs structured fields, so add a Code node to parse the JSON string into an object:

javascript
// Code node: parse the AI output JSON
const raw = $json.text || $json.output; // field name per your AI Agent output
const parsed = JSON.parse(raw);
return { json: { ...$('RSS Feed Read Trigger').item.json, ...parsed } };

For something simpler, swap AI Agent for a Basic LLM Chain node -- it is single-turn prompt -> LLM -> output, with no tools or memory, which is exactly what a deterministic rewrite needs. AI Agent's edge is attaching tools (e.g. letting the model fetch the full article); this example does not need that.

Step 3: Switch Routing

Drag in a Switch node, feed it the Code node output. Switch routes data to different exits by condition. Here we route on the category the AI assigned:

text
Routing:
  Rule 1: {{ $json.category }} equals "breaking"  -> output 0 (instant Telegram push)
  Rule 2: {{ $json.category }} equals "digest"    -> output 1 (email digest + Feishu)
  Rule 3: {{ $json.category }} equals "skip"      -> output 2 (drop)
  Fallback (no match)                             -> output 3 (manual review queue)

Switch earns its keep by conditional delivery: breaking goes the instant lane, digest goes the batch lane, skip gets dropped -- so not every item blasts every platform.

Step 4: Multi-Output

Each Switch output wires to its publishing node.

Telegram (instant push) -- use the Telegram node:

text
Credential: Telegram Bot API (store Bot Token, from @BotFather)
Resource / Operation: Message / Send
Chat ID: {{ $env.TELEGRAM_CHANNEL_ID }}     # channel ID, via env var, not hardcoded
Text: {{ $json.telegram }}                  # reference the AI-generated short summary

Email (digest subscription) -- use the Email Send node (SMTP credential):

text
Credential: SMTP (store SMTP account/password)
To: [email protected]
Subject: AI News Daily - {{ $now.toFormat('yyyy-MM-dd') }}
Text / HTML: {{ $json.email }}

Feishu webhook (group card) -- no official n8n node for Feishu; use an HTTP Request to hit the custom bot webhook:

text
Method: POST
URL: {{ $env.FEISHU_WEBHOOK_URL }}       # Feishu group bot webhook URL
Headers: Content-Type: application/json
Body (JSON):
{
  "msg_type": "text",
  "content": { "text": "{{ $json.feishu }}" }
}

Feishu bots support interactive cards (msg_type: interactive); the card JSON is involved -- per the Feishu Open Platform docs. Get the text message working first, then upgrade to cards.

Step 5: Dedup and Activate

RSS Feed Read Trigger ships with "new items only," but if you restart the instance or swap the trigger, old items will re-fire. Harden it: before the AI node, add a Filter or Code node that dedups on guid -- store processed guids in a Postgres / SQLite / Google Sheets node, and filter out the ones already seen each pull:

javascript
// Code node: simple dedup (pseudocode; data source per your chosen store)
const seen = $('Postgres').item.json.ids || []; // query stored guid set, per official docs
const fresh = $('RSS Feed Read Trigger').all.filter(
  item => !seen.includes(item.json.guid)
);
return fresh;

Once it works, click the top-right Active toggle and the workflow runs on its Poll Times. While testing, use a Manual Trigger to feed data by hand -- do not enable polling until it works.


Four: Pitfall Quick Reference

PitfallSymptomFix
RSS source rate-limitsSource returns 429; RSS node errors or returns emptyWiden Poll Times (e.g. 30 min -> 1 hour); stagger high-frequency sources with Schedule Trigger; some sources are User-Agent sensitive -- use HTTP Request with a custom Header (per source rules)
AI rewrite drops key infoSummary loses the link, numbers, or namesSystem Prompt must require "keep the link, do not fabricate facts"; have the AI output structured JSON fields, not free text -- structure cuts information loss; pass critical fields (link) through directly with {{ $json.link }}, never through the AI
Platform formats differSame text is too long for Telegram, too short for emailDo not "one draft, many posts." Have the AI emit three length-specific fields (telegram/email/feishu) at once; each downstream reads its own field; write length thresholds into the prompt
Duplicate publishingRestart re-fires old items; same guid pushed twiceDedup on guid; store in Postgres/Google Sheets; Filter node drops processed items; "new items only" depends on instance state -- do not wipe the DB casually
Hardcoded API key leaksExported workflow JSON carries the tokenStore every Key/Token in n8n Credentials; reference the credential by name in nodes; env vars via {{ $env.XXX }}; confirm credentials are excluded before exporting JSON; use sk-xxx placeholders, never real values
Feishu webhook failsHTTP Request returns 200 but no message in the groupIf signature verification is on, a missing timestamp/sign in the Body is silently dropped; check that msg_type is valid; per Feishu Open Platform docs

FAQ

Q1: What is the difference between RSS Feed Read Trigger and RSS Feed Read? A: The former is a trigger with built-in polling and "new items only" state memory -- once active it runs itself. The latter is a regular node that reads once and returns all items; it needs a Schedule Trigger to run on a timer and forces you to dedup yourself. Beginners should use the trigger version; use the combo when you want fine control over polling logic.

Q2: Can I skip AI and forward the original text to every platform? A: Yes. Remove the AI Agent and Code node; wire Switch straight to the RSS output; downstream passes through {{ $json.contentSnippet }}. But then every platform gets the same format -- Telegram overflows, email is too thin -- which defeats the point of distribution. The AI rewrite exists precisely for "one source, many shapes."

Q3: How do I connect DeepSeek / Qwen and other domestic models? A: In the Language Model sub-node pick the OpenAI-compatible type, set the Base URL to the provider's OpenAI-compatible endpoint, store the API key as a Credential, and set the model name per the provider's docs. DeepSeek, Qwen, and Zhipu all offer OpenAI-compatible endpoints; exact endpoints and model names per each provider's docs.

Q4: Feishu has no n8n node -- what do I do? A: Use an HTTP Request node to hit the Feishu custom bot webhook URL, with the Body in Feishu's message JSON format (msg_type + content). This is n8n's universal answer -- any platform with a webhook or API is reachable via HTTP Request, with no need for an official node.

Q5: What specs does self-hosted n8n need for this workflow? A: 2-core 4GB is enough for personal testing. This pipeline is light; what eats resources is AI call frequency and RSS pull volume. If you connect many sources and poll densely, scale to 4-core 8GB. For production, always add a reverse proxy + HTTPS + a strong password + the N8N_ENCRYPTION_KEY env var to encrypt credentials.


References

This article is AI-assisted and human-edited. Last updated: 2026-08-06

FAQ

What is the difference between RSS Feed Read Trigger and RSS Feed Read?
The former is a trigger with built-in polling and "new items only" state memory -- once active it runs itself. The latter is a regular node that reads once and returns all items; it needs a Schedule Trigger to run on a timer and forces you to dedup yourself. Beginners should use the trigger version; use the combo when you want fine control over polling logic.
Can I skip AI and forward the original text to every platform?
Yes. Remove the AI Agent and Code node; wire Switch straight to the RSS output; downstream passes through `{{ $json.contentSnippet }}`. But then every platform gets the same format -- Telegram overflows, email is too thin -- which defeats the point of distribution. The AI rewrite exists precisely for "one source, many shapes."
How do I connect DeepSeek / Qwen and other domestic models?
In the Language Model sub-node pick the OpenAI-compatible type, set the Base URL to the provider's OpenAI-compatible endpoint, store the API key as a Credential, and set the model name per the provider's docs. DeepSeek, Qwen, and Zhipu all offer OpenAI-compatible endpoints; exact endpoints and model names per each provider's docs.
Feishu has no n8n node -- what do I do?
Use an HTTP Request node to hit the Feishu custom bot webhook URL, with the Body in Feishu's message JSON format (`msg_type` + `content`). This is n8n's universal answer -- any platform with a webhook or API is reachable via HTTP Request, with no need for an official node.
What specs does self-hosted n8n need for this workflow?
2-core 4GB is enough for personal testing. This pipeline is light; what eats resources is AI call frequency and RSS pull volume. If you connect many sources and poll densely, scale to 4-core 8GB. For production, always add a reverse proxy + HTTPS + a strong password + the `N8N_ENCRYPTION_KEY` env var to encrypt credentials. --- **References** - n8n official docs: https://docs.n8n.io - n8n integration node library: https://docs.n8n.io/integrations - RSS Feed Read Trigger node docs: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.rssfeedreadtrigger/ - n8n template library (RSS workflow templates): https://n8n.io/workflows/ - n8n GitHub repo (n8n-io/n8n): https://github.com/n8n-io/n8n - Feishu Open Platform - custom bot: https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot - Node names and parameters in this article follow the official n8n docs; due to network restrictions I could not verify each node parameter online, so unverified items are marked "per official docs" -- cross-check against docs.n8n.io while building

Related