diff --git a/workflows/Create X and LinkedIn posts from Reddit threads with Gemini and human review-14007/readme-14007.md b/workflows/Create X and LinkedIn posts from Reddit threads with Gemini and human review-14007/readme-14007.md
new file mode 100644
index 000000000..ac737b1b9
--- /dev/null
+++ b/workflows/Create X and LinkedIn posts from Reddit threads with Gemini and human review-14007/readme-14007.md
@@ -0,0 +1,763 @@
+Create X and LinkedIn posts from Reddit threads with Gemini and human review
+
+https://n8nworkflows.xyz/workflows/create-x-and-linkedin-posts-from-reddit-threads-with-gemini-and-human-review-14007
+
+
+# Create X and LinkedIn posts from Reddit threads with Gemini and human review
+
+# 1. Workflow Overview
+
+This workflow takes a Reddit thread URL submitted through an n8n form, retrieves the thread via Reddit’s public JSON API, extracts the post and comment discussion, summarizes it with Google Gemini, generates platform-specific content for X and LinkedIn, then pauses for human review before optionally publishing to both networks.
+
+Its primary use cases are:
+- Turning Reddit discussions into social-ready content
+- Accelerating social content research and drafting
+- Keeping a human approval step before publishing
+- Supporting optional manual edits without changing the AI generation flow
+
+## 1.1 Input Reception and URL Normalization
+The workflow starts with a form where a user submits a Reddit thread URL. A code node validates the URL and derives Reddit API-friendly values such as subreddit, post ID, and `.json` endpoint.
+
+## 1.2 Reddit Data Retrieval and Structuring
+The workflow calls Reddit’s public JSON API, then parses the response into:
+- post metadata
+- a nested comment tree
+- a flattened AI-friendly text representation of the thread
+
+## 1.3 AI Summarization
+Gemini receives the structured thread text and produces a markdown summary covering overview, key topics, notable insights, sentiment, and actionable takeaways.
+
+## 1.4 AI Social Post Generation
+A second Gemini node converts the summary into two drafts:
+- one X post
+- one LinkedIn post
+
+The expected return format is strict JSON.
+
+## 1.5 Response Parsing and Validation
+A code node extracts the Gemini output, removes code fences if needed, parses the JSON, validates required keys, and enforces the X character limit.
+
+## 1.6 Human Review and Final Content Resolution
+A Wait/Form node pauses the workflow and displays both generated posts. The reviewer can approve, reject, or override either post. A code node merges overrides with AI output.
+
+## 1.7 Decision and Publishing
+An IF node checks the reviewer’s decision:
+- if approved, the workflow posts to X and LinkedIn
+- if rejected, it ends gracefully with a rejection status message
+
+---
+
+# 2. Block-by-Block Analysis
+
+## Block 1: Form Input and Reddit URL Parsing
+
+### Overview
+This block collects a Reddit thread URL from the user and transforms it into a normalized, API-ready structure. It is the workflow’s only entry point and ensures downstream nodes receive a valid Reddit thread reference.
+
+### Nodes Involved
+- Reddit URL Input
+- Parse Reddit URL
+
+### Node Details
+
+#### 1. Reddit URL Input
+- **Type and technical role:** `n8n-nodes-base.formTrigger`
+ Entry-point trigger node that exposes a hosted form and starts the workflow on submission.
+- **Configuration choices:**
+ - Form title: `Reddit Thread Post Generator`
+ - Description: indicates the form generates social media posts from a Reddit thread
+ - One field: `Reddit Thread URL`
+- **Key expressions or variables used:** None in parameters
+- **Input and output connections:**
+ - Input: none
+ - Output: `Parse Reddit URL`
+- **Version-specific requirements:** Uses `typeVersion: 2.5`; requires form trigger support in the installed n8n version
+- **Edge cases or potential failure types:**
+ - Empty field submission
+ - Invalid Reddit URL format passed downstream
+ - Form accessibility/webhook URL issues if n8n instance is not publicly reachable
+- **Sub-workflow reference:** None
+
+#### 2. Parse Reddit URL
+- **Type and technical role:** `n8n-nodes-base.code`
+ JavaScript transformation node that validates and parses the submitted Reddit URL.
+- **Configuration choices:**
+ - Reads `Reddit Thread URL` from the form output
+ - Trims whitespace
+ - Normalizes scheme and removes `www.` / `m.` prefixes
+ - Uses regex to extract:
+ - subreddit
+ - post ID
+ - Builds:
+ - `apiUrl`
+ - `cleanThreadUrl`
+ - original URL copy
+- **Key expressions or variables used:**
+ - `$input.first().json['Reddit Thread URL']`
+ - Output fields:
+ - `originalUrl`
+ - `subreddit`
+ - `postId`
+ - `apiUrl`
+ - `cleanThreadUrl`
+- **Input and output connections:**
+ - Input: `Reddit URL Input`
+ - Output: `Fetch Reddit Thread`
+- **Version-specific requirements:** `typeVersion: 2`
+- **Edge cases or potential failure types:**
+ - Throws explicit error for invalid standard Reddit thread URLs
+ - The comment says it supports `redd.it`, but the actual regex only matches full `reddit.com/r/.../comments/...` URLs; short links are not actually handled by this implementation
+ - Missing or malformed form field name would break expression access
+- **Sub-workflow reference:** None
+
+---
+
+## Block 2: Reddit Thread Retrieval and Content Extraction
+
+### Overview
+This block fetches the Reddit thread data and transforms raw Reddit JSON into a structured representation usable by both humans and AI. It extracts metadata and recursively traverses comments to create a flat prompt string.
+
+### Nodes Involved
+- Fetch Reddit Thread
+- Extract Thread Content
+
+### Node Details
+
+#### 3. Fetch Reddit Thread
+- **Type and technical role:** `n8n-nodes-base.httpRequest`
+ Performs the HTTP GET request against Reddit’s public JSON thread endpoint.
+- **Configuration choices:**
+ - URL: `={{ $json.apiUrl }}`
+ - Query parameters:
+ - `limit=100`
+ - `depth=3`
+ - Header:
+ - `User-Agent: n8n-workflow-automation/1.0`
+ - Sends query and headers explicitly
+- **Key expressions or variables used:**
+ - `{{ $json.apiUrl }}`
+- **Input and output connections:**
+ - Input: `Parse Reddit URL`
+ - Output: `Extract Thread Content`
+- **Version-specific requirements:** `typeVersion: 4.2`
+- **Edge cases or potential failure types:**
+ - Reddit rate limiting or temporary blocking
+ - Invalid or deleted thread causing non-useful response content
+ - NSFW/quarantined/private/community-restricted threads may not be accessible
+ - Network timeout or connectivity issues
+ - Reddit may return truncated discussion because `more` nodes are not expanded later
+- **Sub-workflow reference:** None
+
+#### 4. Extract Thread Content
+- **Type and technical role:** `n8n-nodes-base.code`
+ Parses Reddit API response into post metadata, nested comments, statistics, and a flattened AI-ready text block.
+- **Configuration choices:**
+ - Handles either:
+ - API response as one array item
+ - multiple items from the HTTP node
+ - Extracts post metadata such as:
+ - title
+ - body
+ - author
+ - score
+ - upvote ratio
+ - subreddit
+ - comment count
+ - permalink
+ - link/self-post information
+ - flair
+ - awards
+ - Recursively traverses comment replies
+ - Sorts siblings by score descending at every level
+ - Skips:
+ - `more` placeholders
+ - deleted/removed/empty comments
+ - Builds:
+ - `structuredComments`
+ - `totalExtracted`
+ - `maxDepthFound`
+ - `threadContent`
+- **Key expressions or variables used:**
+ - `$input.first().json`
+ - `$input.all()`
+ - Output fields include:
+ - `structuredComments`
+ - `threadContent`
+ - post metadata fields like `title`, `body`, `threadUrl`, `numComments`
+- **Input and output connections:**
+ - Input: `Fetch Reddit Thread`
+ - Output: `Summarize Thread`
+- **Version-specific requirements:** `typeVersion: 2`
+- **Edge cases or potential failure types:**
+ - Throws if Reddit response shape is unexpected
+ - Can miss comments hidden behind Reddit `more` stubs because no secondary expansion call is made
+ - Deep or large threads can create very large prompt payloads
+ - Deleted post bodies or removed comments reduce available context
+ - `maxDepthFound` is inferred from indentation in generated lines; functional but indirect
+- **Sub-workflow reference:** None
+
+---
+
+## Block 3: AI Summarization
+
+### Overview
+This block converts the extracted Reddit discussion into a structured markdown summary. It provides the strategic intermediate representation used by the social copy generator.
+
+### Nodes Involved
+- Summarize Thread
+
+### Node Details
+
+#### 5. Summarize Thread
+- **Type and technical role:** `@n8n/n8n-nodes-langchain.googleGemini`
+ Invokes Google Gemini to summarize the Reddit thread.
+- **Configuration choices:**
+ - Model: `models/gemini-3.1-flash-lite-preview`
+ - Prompt asks for markdown summary with sections:
+ - Thread Overview
+ - Key Topics Discussed
+ - Notable Insights & Perspectives
+ - Community Sentiment
+ - Actionable Takeaways
+ - Injects `threadContent`
+ - Options:
+ - `topK: 20`
+ - `temperature: 0.7`
+ - `maxToolsIterations: 5`
+ - Built-in tool enabled:
+ - `urlContext: true`
+ - `simplify: false`, so raw Gemini-style response structure is preserved
+- **Key expressions or variables used:**
+ - `{{ $json.threadContent }}`
+- **Input and output connections:**
+ - Input: `Extract Thread Content`
+ - Output: `Generate Social Posts`
+- **Version-specific requirements:**
+ - Requires the LangChain Gemini node package installed
+ - Requires valid `Google Gemini(PaLM) Api account` credentials
+ - Uses `typeVersion: 1.1`
+- **Edge cases or potential failure types:**
+ - Authentication or quota failures on Google Gemini
+ - Long Reddit threads may exceed model input limits
+ - Model may return incomplete or oddly structured output if prompt/token budget is constrained
+ - Preview model IDs may change or be deprecated over time
+- **Sub-workflow reference:** None
+
+---
+
+## Block 4: AI Social Post Generation
+
+### Overview
+This block turns the markdown summary into platform-specific social content. It instructs Gemini to output strict raw JSON with one X post and one LinkedIn post.
+
+### Nodes Involved
+- Generate Social Posts
+
+### Node Details
+
+#### 6. Generate Social Posts
+- **Type and technical role:** `@n8n/n8n-nodes-langchain.googleGemini`
+ Uses Gemini to generate social posts from the prior summary.
+- **Configuration choices:**
+ - Model: `models/gemini-3.1-flash-lite-preview`
+ - Prompt positions the model as an expert social media strategist
+ - Uses summary text from the previous Gemini node
+ - Requires exact JSON shape:
+ - `x_post`
+ - `linkedin_post`
+ - No markdown fences or explanatory text allowed
+- **Key expressions or variables used:**
+ - `{{ $json.candidates[0].content.parts[0].text }}`
+- **Input and output connections:**
+ - Input: `Summarize Thread`
+ - Output: `Parse Social Posts`
+- **Version-specific requirements:**
+ - Same Gemini credential requirement as above
+ - `typeVersion: 1.1`
+- **Edge cases or potential failure types:**
+ - Depends on raw response structure from previous node because `simplify` is disabled there
+ - If the prior node output shape changes, this expression may fail
+ - Model may still return fenced JSON or malformed JSON despite instructions
+ - X post may exceed 280 characters; downstream parser truncates it
+- **Sub-workflow reference:** None
+
+---
+
+## Block 5: Social JSON Parsing and Validation
+
+### Overview
+This block normalizes Gemini’s output into clean workflow fields. It is designed defensively to handle multiple possible Gemini response shapes and malformed JSON.
+
+### Nodes Involved
+- Parse Social Posts
+
+### Node Details
+
+#### 7. Parse Social Posts
+- **Type and technical role:** `n8n-nodes-base.code`
+ Extracts text from Gemini output, parses JSON, validates required fields, and enforces X length.
+- **Configuration choices:**
+ - Supports multiple response formats:
+ - array of candidates
+ - single candidate object
+ - `{ text: '...' }`
+ - nested `candidates`
+ - Removes code fences like ```json
+ - Tries `JSON.parse`
+ - Falls back to regex extraction for `x_post` and `linkedin_post`
+ - Trims content
+ - Truncates X text to 280 chars using `277 + '...'`
+- **Key expressions or variables used:**
+ - `$input.first().json`
+ - Output fields:
+ - `x_post`
+ - `linkedin_post`
+ - `x_char_count`
+- **Input and output connections:**
+ - Input: `Generate Social Posts`
+ - Output: `Human Approval`
+- **Version-specific requirements:** `typeVersion: 2`
+- **Edge cases or potential failure types:**
+ - Throws if no recognizable text field is present
+ - Throws if JSON cannot be parsed and regex fallback also fails
+ - Throws if parsed JSON lacks `x_post` or `linkedin_post`
+ - Character counting is simple string length; not tailored for every Unicode/display nuance on X
+- **Sub-workflow reference:** None
+
+---
+
+## Block 6: Human Review and Override Resolution
+
+### Overview
+This block introduces a human-in-the-loop approval checkpoint. The workflow pauses, displays both generated posts, captures approval or rejection, and merges any manual edits with the AI output.
+
+### Nodes Involved
+- Human Approval
+- Resolve Final Posts
+
+### Node Details
+
+#### 8. Human Approval
+- **Type and technical role:** `n8n-nodes-base.wait`
+ Pauses execution and resumes via a form submission.
+- **Configuration choices:**
+ - Resume mode: `form`
+ - Form title: `📋 Review & Approve Social Media Posts`
+ - Description dynamically displays:
+ - current X draft
+ - X character count
+ - current LinkedIn draft
+ - Form fields:
+ - `X Post Override (leave blank to use AI version)` textarea
+ - `LinkedIn Post Override (leave blank to use AI version)` textarea
+ - `Decision` dropdown with:
+ - `Approve & Publish`
+ - `Reject`
+ - `Decision` is required
+- **Key expressions or variables used:**
+ - `{{ $json.x_char_count }}`
+ - `{{ $json.x_post }}`
+ - `{{ $json.linkedin_post }}`
+- **Input and output connections:**
+ - Input: `Parse Social Posts`
+ - Output: `Resolve Final Posts`
+- **Version-specific requirements:** `typeVersion: 1.1`
+- **Edge cases or potential failure types:**
+ - Resume webhook/form must remain reachable
+ - Long waiting periods may be affected by workflow retention/execution settings
+ - User may submit blank overrides, which is expected
+ - If someone manually enters empty-looking but whitespace-only overrides, code trims them out
+- **Sub-workflow reference:** None
+
+#### 9. Resolve Final Posts
+- **Type and technical role:** `n8n-nodes-base.code`
+ Merges human overrides with the AI-generated drafts after the Wait node resumes.
+- **Configuration choices:**
+ - Reads resumed form submission from `$input.first().json`
+ - Explicitly references upstream node output:
+ - `$('Parse Social Posts').item.json`
+ - Logic:
+ - override wins if non-empty
+ - otherwise AI version is used
+ - Returns:
+ - `X Post`
+ - `LinkedIn Post`
+ - `usedOverrideX`
+ - `usedOverrideLi`
+- **Key expressions or variables used:**
+ - `$input.first().json`
+ - `$('Parse Social Posts').item.json`
+ - Form fields:
+ - `X Post Override (leave blank to use AI version)`
+ - `LinkedIn Post Override (leave blank to use AI version)`
+- **Input and output connections:**
+ - Input: `Human Approval`
+ - Output: `Approved?`
+- **Version-specific requirements:** `typeVersion: 2`
+- **Edge cases or potential failure types:**
+ - If node name `Parse Social Posts` changes, the explicit reference will break
+ - Throws if final X or LinkedIn post resolves to empty
+ - If execution data from prior node is unavailable due to retention or unusual execution mode, lookup could fail
+- **Sub-workflow reference:** None
+
+---
+
+## Block 7: Approval Routing and Publishing
+
+### Overview
+This final block evaluates the reviewer’s decision and either publishes both posts or exits cleanly without publishing. It is the enforcement point for human-controlled release.
+
+### Nodes Involved
+- Approved?
+- Post to X
+- Post to Linkedin
+- Rejected – End
+
+### Node Details
+
+#### 10. Approved?
+- **Type and technical role:** `n8n-nodes-base.if`
+ Branches execution based on approval form data.
+- **Configuration choices:**
+ - Compares `Decision` from `Human Approval`
+ - Condition: equals `Approve & Publish`
+ - True branch publishes
+ - False branch rejects
+- **Key expressions or variables used:**
+ - `={{ $('Human Approval').item.json['Decision'] }}`
+- **Input and output connections:**
+ - Input: `Resolve Final Posts`
+ - True output: `Post to X`, `Post to Linkedin`
+ - False output: `Rejected – End`
+- **Version-specific requirements:** `typeVersion: 2`
+- **Edge cases or potential failure types:**
+ - Depends on exact node name `Human Approval`
+ - Depends on exact dropdown value `Approve & Publish`
+ - Renaming form field or option text breaks condition logic
+- **Sub-workflow reference:** None
+
+#### 11. Post to X
+- **Type and technical role:** `n8n-nodes-base.twitter`
+ Publishes the final X post using X/Twitter OAuth2 credentials.
+- **Configuration choices:**
+ - Text: `={{ $json['X Post'] }}`
+- **Key expressions or variables used:**
+ - `{{ $json['X Post'] }}`
+- **Input and output connections:**
+ - Input: `Approved?` true branch
+ - Output: none
+- **Version-specific requirements:**
+ - Requires configured `X account` OAuth2 credentials
+ - Uses `typeVersion: 2`
+- **Edge cases or potential failure types:**
+ - Auth/token issues
+ - App permission limitations
+ - Duplicate content restrictions or policy-related API rejection
+ - Effective platform character rules may still reject certain content despite length truncation
+- **Sub-workflow reference:** None
+
+#### 12. Post to Linkedin
+- **Type and technical role:** `n8n-nodes-base.linkedIn`
+ Publishes the final LinkedIn post.
+- **Configuration choices:**
+ - Text: `={{ $json['LinkedIn Post'] }}`
+ - Person: `ID`
+- **Key expressions or variables used:**
+ - `{{ $json['LinkedIn Post'] }}`
+- **Input and output connections:**
+ - Input: `Approved?` true branch
+ - Output: none
+- **Version-specific requirements:**
+ - Requires configured `LinkedIn account` OAuth2 credentials
+ - Uses `typeVersion: 1`
+ - The `person` field must be set correctly for the authenticated profile/account context
+- **Edge cases or potential failure types:**
+ - OAuth permission issues
+ - Invalid author/person ID configuration
+ - LinkedIn API restrictions on posting scope
+ - Post formatting may differ from preview due to LinkedIn rendering
+- **Sub-workflow reference:** None
+
+#### 13. Rejected – End
+- **Type and technical role:** `n8n-nodes-base.set`
+ Creates a terminal structured output for the rejection path.
+- **Configuration choices:**
+ - Sets:
+ - `status = rejected`
+ - `message = Posts were reviewed and rejected by the user. No content was published.`
+- **Key expressions or variables used:** None
+- **Input and output connections:**
+ - Input: `Approved?` false branch
+ - Output: none
+- **Version-specific requirements:** `typeVersion: 3.4`
+- **Edge cases or potential failure types:**
+ - Minimal risk; primarily a terminal bookkeeping node
+- **Sub-workflow reference:** None
+
+---
+
+# 3. Summary Table
+
+| Node Name | Node Type | Functional Role | Input Node(s) | Output Node(s) | Sticky Note |
+|---|---|---|---|---|---|
+| Reddit URL Input | Form Trigger | Entry form for Reddit thread URL submission | | Parse Reddit URL | ## 📥 Reddit URL Input
**Type:** Form Trigger
**Purpose:** Entry point — presents a web form to collect a Reddit thread URL from the user.
**Input:** User submits a Reddit thread URL via the form.
**Output:** Raw URL string forwarded to the parse step. |
+| Parse Reddit URL | Code | Validate and decompose Reddit URL into API-ready fields | Reddit URL Input | Fetch Reddit Thread | ## 🔍 Parse Reddit URL
**Type:** Code (JavaScript)
**Purpose:** Validates and deconstructs the submitted Reddit URL.
**Input:** Raw URL string
**Function:** Regex extraction of subreddit + post ID. Handles standard, mobile (`m.`) and short `redd.it` links.
**Output:** `subreddit`, `postId`, `apiUrl`, `cleanThreadUrl` |
+| Fetch Reddit Thread | HTTP Request | Retrieve Reddit thread JSON from public API | Parse Reddit URL | Extract Thread Content | ## 🌐 Fetch Reddit Thread
**Type:** HTTP Request
**Purpose:** Retrieves the full thread via Reddit's public JSON API.
**Input:** `apiUrl` (e.g. `reddit.com/r/sub/comments/id.json`)
**Function:** GET with `limit=100`, `depth=3`.
**Output:** Raw Reddit API response — post listing + comments listing array. |
+| Extract Thread Content | Code | Extract metadata, comments, and AI-ready thread text | Fetch Reddit Thread | Summarize Thread | ## ⚙️ Extract Content
**Type:** Code (JavaScript)
**Purpose:** Parses raw Reddit JSON into structured, AI-ready content.
**Input:** Raw Reddit API response
**Function:** Extracts post metadata; recursively traverses all comments sorted by score at every depth; builds a flat indented string for AI.
**Output:** `threadContent` (AI prompt string), `structuredComments` (nested JSON), post metadata |
+| Summarize Thread | Google Gemini | Produce markdown summary of thread discussion | Extract Thread Content | Generate Social Posts | ## 🧠 Summarize Thread
**Type:** Google Gemini AI
**Purpose:** Produces a comprehensive markdown summary of the Reddit thread.
**Input:** `threadContent` from Extract node
**Function:** Gemini 3.1 Flash Lite → returns Thread Overview, Key Topics, Notable Insights, Community Sentiment, and Actionable Takeaways.
**Output:** Structured markdown summary text |
+| Generate Social Posts | Google Gemini | Generate X and LinkedIn post drafts from summary | Summarize Thread | Parse Social Posts | ## ✍️ Generate Social Posts
**Type:** Google Gemini AI
**Purpose:** Creates platform-optimized posts for X and LinkedIn.
**Input:** Thread summary from Summarize node
**Function:** Gemini generates: X post (≤280 chars, punchy + hashtags) and LinkedIn post (150–300 words, professional + hashtags). Returns strict JSON only.
**Output:** `{ "x_post": "...", "linkedin_post": "..." }` |
+| Parse Social Posts | Code | Parse and validate AI JSON response for social posts | Generate Social Posts | Human Approval | ## 🧹 Parse Social Posts
**Type:** Code (JavaScript)
**Purpose:** Safely extracts and validates Gemini's JSON response.
**Input:** Raw Gemini API response
**Function:** Strips markdown fences, parses JSON, falls back to regex if malformed. Enforces 280-char hard limit on X post.
**Output:** `x_post`, `linkedin_post`, `x_char_count` |
+| Human Approval | Wait | Pause for manual review, approval, or override | Parse Social Posts | Resolve Final Posts | ## 👤 Human Approval
**Type:** Wait (Form)
**Purpose:** Pauses the workflow so a human can review posts.
**Input:** `x_post`, `linkedin_post`, `x_char_count`
**Function:** Displays posts in a form. User can overrides or use AI version. Must select **Approve & Publish** or **Reject**.
**Output:** Form submission with `Decision` + optional override fields. |
+| Resolve Final Posts | Code | Merge manual overrides with AI-generated posts | Human Approval | Approved? | ## ✅ Resolve Final Posts
**Type:** Code (JavaScript)
**Purpose:** Merges human overrides with AI-generated posts.
**Input:** Form data + AI posts (referenced from Parse Social Posts node)
**Function:** Override wins if non-empty; otherwise falls back to the AI version. Throws if both are empty.
**Output:** `X Post`, `LinkedIn Post` (final content ready to publish) |
+| Approved? | IF | Route based on approval decision | Resolve Final Posts | Post to X; Post to Linkedin; Rejected – End | ## 🔀 Approved?
**Type:** IF Condition
**Purpose:** Routes the workflow based on the human's decision.
**Input:** `Decision` field from Human Approval form
**True →** Post to X + Post to LinkedIn
**False →** Rejected – End (nothing published) |
+| Post to X | X (Twitter) | Publish final post to X | Approved? | | ## 🐦 Post to X
**Type:** X (Twitter)
**Purpose:** Publishes the final post to X (Twitter).
**Input:** `X Post` (≤280 chars) from Resolve Final Posts
**Output:** Live tweet on the connected X account. |
+| Post to Linkedin | LinkedIn | Publish final post to LinkedIn | Approved? | | ## 💼 Post to LinkedIn
**Type:** LinkedIn
**Purpose:** Publishes the final post to LinkedIn.
**Input:** `LinkedIn Post` from Resolve Final Posts
**Output:** Live post on the connected LinkedIn account. |
+| Rejected – End | Set | Terminal rejection output without publishing | Approved? | | ## 🚫 Rejected – End
**Type:** Set
**Purpose:** Graceful termination — nothing is published.
**Input:** Rejection path from Approved? node
**Function:** Sets `status: 'rejected'` and a descriptive message.
**Output:** Terminal state — workflow ends here. |
+| 🗒️ Workflow Summary | Sticky Note | Documentation note | | | ## 🔁 Reddit → Social Media Automation
Converts any Reddit thread into ready-to-publish posts for **X (Twitter)** and **LinkedIn** — with a human review gate before anything goes live.
**📌 Data Flow:**
Reddit URL → Parse → Fetch API → Extract Content → AI Summarize → Generate Posts → Human Approval → Publish
**✨ Key Features:**
- Accepts any Reddit thread URL
- Extracts post + all nested comments (sorted by score)
- AI-powered thread summarization via Gemini
- Platform-optimized X + LinkedIn post generation
- Human-in-the-loop approval with override support
- Graceful rejection path — nothing published without approval
**🛠️ Tools Used:**
Google Gemini 3.1 Flash Lite · Reddit JSON API · X (Twitter) API · LinkedIn API |
+| 🌐 Node: Fetch Reddit Thread | Sticky Note | Documentation note | | | |
+| Sticky Note1 | Sticky Note | Documentation note | | | |
+| Sticky Note2 | Sticky Note | Documentation note | | | |
+| Sticky Note3 | Sticky Note | Documentation note | | | |
+| Sticky Note4 | Sticky Note | Documentation note | | | |
+| Sticky Note5 | Sticky Note | Documentation note | | | |
+| Sticky Note6 | Sticky Note | Documentation note | | | |
+| Sticky Note7 | Sticky Note | Documentation note | | | |
+| Sticky Note8 | Sticky Note | Documentation note | | | |
+| Sticky Note9 | Sticky Note | Documentation note | | | |
+| Sticky Note10 | Sticky Note | Documentation note | | | |
+| Sticky Note11 | Sticky Note | Documentation note | | | |
+| Sticky Note | Sticky Note | Documentation note | | | |
+
+---
+
+# 4. Reproducing the Workflow from Scratch
+
+1. **Create a new workflow**
+ - Name it something like: `Reddit Thread → AI Summary → Social Media Publisher (X + LinkedIn)`.
+ - Keep execution order at the default compatible mode used by your n8n version.
+
+2. **Add the Form Trigger node**
+ - Node type: `Form Trigger`
+ - Name: `Reddit URL Input`
+ - Form title: `Reddit Thread Post Generator`
+ - Form description: `generates social media posts based on reddit thread`
+ - Add one form field:
+ - Label: `Reddit Thread URL`
+ - This is the workflow entry point.
+
+3. **Add a Code node after the form**
+ - Node type: `Code`
+ - Name: `Parse Reddit URL`
+ - Paste JavaScript that:
+ - reads `Reddit Thread URL`
+ - trims it
+ - normalizes scheme/domain prefix
+ - extracts subreddit and post ID from standard Reddit thread URLs
+ - outputs `originalUrl`, `subreddit`, `postId`, `apiUrl`, `cleanThreadUrl`
+ - Connect: `Reddit URL Input` → `Parse Reddit URL`
+
+4. **Add an HTTP Request node**
+ - Node type: `HTTP Request`
+ - Name: `Fetch Reddit Thread`
+ - Method: `GET`
+ - URL: `={{ $json.apiUrl }}`
+ - Enable query parameters:
+ - `limit` = `100`
+ - `depth` = `3`
+ - Enable headers:
+ - `User-Agent` = `n8n-workflow-automation/1.0`
+ - Connect: `Parse Reddit URL` → `Fetch Reddit Thread`
+
+5. **Add a second Code node for Reddit extraction**
+ - Node type: `Code`
+ - Name: `Extract Thread Content`
+ - Paste JavaScript that:
+ - parses Reddit’s listing response
+ - extracts thread metadata
+ - recursively traverses comments
+ - sorts comments by score at each level
+ - skips invalid/deleted/removed comments
+ - creates:
+ - `structuredComments`
+ - `threadContent`
+ - `totalExtracted`
+ - `maxDepthFound`
+ - post metadata fields
+ - Connect: `Fetch Reddit Thread` → `Extract Thread Content`
+
+6. **Add a Google Gemini node for summarization**
+ - Node type: `Google Gemini` from the LangChain-compatible n8n package
+ - Name: `Summarize Thread`
+ - Credentials: create/select `Google Gemini(PaLM) Api account`
+ - Model: `models/gemini-3.1-flash-lite-preview`
+ - Set messages with one prompt that:
+ - injects `{{ $json.threadContent }}`
+ - requests a markdown summary with sections for overview, topics, insights, sentiment, and takeaways
+ - Recommended options from this workflow:
+ - `topK: 20`
+ - `temperature: 0.7`
+ - `maxToolsIterations: 5`
+ - Set `simplify` to `false`
+ - Enable built-in tool `urlContext` if available in your version
+ - Connect: `Extract Thread Content` → `Summarize Thread`
+
+7. **Add another Google Gemini node for social generation**
+ - Node type: `Google Gemini`
+ - Name: `Generate Social Posts`
+ - Reuse the same Gemini credentials
+ - Model: `models/gemini-3.1-flash-lite-preview`
+ - Prompt should:
+ - describe the model as an expert social strategist
+ - inject the summary from the previous node using:
+ `{{ $json.candidates[0].content.parts[0].text }}`
+ - ask for:
+ - X post under 280 chars with hashtags
+ - LinkedIn post 150–300 words with final-line hashtags
+ - require raw JSON only in the exact format:
+ - `x_post`
+ - `linkedin_post`
+ - Connect: `Summarize Thread` → `Generate Social Posts`
+
+8. **Add a Code node to parse Gemini JSON**
+ - Node type: `Code`
+ - Name: `Parse Social Posts`
+ - Paste JavaScript that:
+ - extracts response text from possible Gemini output shapes
+ - strips markdown fences
+ - tries `JSON.parse`
+ - falls back to regex extraction if needed
+ - validates `x_post` and `linkedin_post`
+ - truncates X content to 280 chars max
+ - outputs:
+ - `x_post`
+ - `linkedin_post`
+ - `x_char_count`
+ - Connect: `Generate Social Posts` → `Parse Social Posts`
+
+9. **Add a Wait node configured as a review form**
+ - Node type: `Wait`
+ - Name: `Human Approval`
+ - Resume mode: `Form`
+ - Form title: `📋 Review & Approve Social Media Posts`
+ - Form description should display the generated drafts using expressions:
+ - X post and char count
+ - LinkedIn post
+ - Add three form fields:
+ 1. Textarea: `X Post Override (leave blank to use AI version)`
+ 2. Textarea: `LinkedIn Post Override (leave blank to use AI version)`
+ 3. Dropdown: `Decision`
+ - `Approve & Publish`
+ - `Reject`
+ - mark as required
+ - Connect: `Parse Social Posts` → `Human Approval`
+
+10. **Add a Code node to resolve final content**
+ - Node type: `Code`
+ - Name: `Resolve Final Posts`
+ - Paste JavaScript that:
+ - reads form submission from `$input.first().json`
+ - references `$('Parse Social Posts').item.json`
+ - selects override values if non-empty
+ - falls back to AI values otherwise
+ - throws if final content is empty
+ - outputs:
+ - `X Post`
+ - `LinkedIn Post`
+ - `usedOverrideX`
+ - `usedOverrideLi`
+ - Important: keep the upstream parser node name exactly `Parse Social Posts`, or update the expression accordingly
+ - Connect: `Human Approval` → `Resolve Final Posts`
+
+11. **Add an IF node for approval routing**
+ - Node type: `IF`
+ - Name: `Approved?`
+ - Condition:
+ - left value: `={{ $('Human Approval').item.json['Decision'] }}`
+ - operator: equals
+ - right value: `Approve & Publish`
+ - Connect: `Resolve Final Posts` → `Approved?`
+
+12. **Add the X publishing node**
+ - Node type: `X` / `Twitter`
+ - Name: `Post to X`
+ - Credentials: create/select `X account` OAuth2
+ - Text field: `={{ $json['X Post'] }}`
+ - Connect from the **true** output of `Approved?` to `Post to X`
+
+13. **Add the LinkedIn publishing node**
+ - Node type: `LinkedIn`
+ - Name: `Post to Linkedin`
+ - Credentials: create/select `LinkedIn account` OAuth2
+ - Text field: `={{ $json['LinkedIn Post'] }}`
+ - Person/account field: configure the correct author context for the authenticated account
+ - In the provided workflow this is set to `ID`, which may need replacement with a real profile/person identifier depending on your n8n/LinkedIn setup
+ - Connect from the **true** output of `Approved?` to `Post to Linkedin`
+
+14. **Add a Set node for rejection**
+ - Node type: `Set`
+ - Name: `Rejected – End`
+ - Add fields:
+ - `status` = `rejected`
+ - `message` = `Posts were reviewed and rejected by the user. No content was published.`
+ - Connect from the **false** output of `Approved?` to `Rejected – End`
+
+15. **Configure credentials**
+ - **Google Gemini(PaLM) Api account**
+ - Required for both Gemini nodes
+ - Ensure the API key/project has access to the chosen Gemini model
+ - **X account OAuth2**
+ - Required for `Post to X`
+ - Verify write permissions for posting
+ - **LinkedIn account OAuth2**
+ - Required for `Post to Linkedin`
+ - Verify posting permissions and correct actor/person context
+
+16. **Optionally add documentation sticky notes**
+ - Add sticky notes around each logical region:
+ - Input
+ - URL parsing
+ - Reddit fetch
+ - content extraction
+ - summary
+ - social generation
+ - parsing
+ - review
+ - resolution
+ - approval
+ - publishing
+ - rejection
+
+17. **Test with a known public Reddit thread**
+ - Submit a standard URL like:
+ `https://www.reddit.com/r//comments///`
+ - Verify:
+ - URL parsing works
+ - Reddit fetch returns valid JSON
+ - Gemini generates summary and JSON social output
+ - approval form displays both drafts
+ - approve path posts successfully
+ - reject path ends with rejection status
+
+18. **Recommended hardening before production**
+ - Expand URL parser if you truly need `redd.it` short links
+ - Add retry/error handling around Reddit and Gemini nodes
+ - Validate LinkedIn person/author ID explicitly
+ - Consider content moderation/review rules before publishing
+ - Add logging or persistence for approved/rejected decisions
+
+### Sub-workflow setup
+This workflow does **not** invoke any sub-workflows and has only one entry point: the `Reddit URL Input` form trigger.
+
+---
+
+# 5. General Notes & Resources
+
+| Note Content | Context or Link |
+|---|---|
+| Converts any Reddit thread into ready-to-publish posts for X (Twitter) and LinkedIn, with a human review gate before publication. | Overall workflow purpose |
+| Data flow: Reddit URL → Parse → Fetch API → Extract Content → AI Summarize → Generate Posts → Human Approval → Publish | Overall workflow structure |
+| Key features: accepts Reddit thread URLs, extracts nested comments sorted by score, summarizes with Gemini, generates platform-specific drafts, includes human approval and rejection path. | Overall workflow capabilities |
+| Tools used: Google Gemini 3.1 Flash Lite, Reddit JSON API, X (Twitter) API, LinkedIn API. | Technology stack |
+| Important implementation note: the URL parsing code claims to support `redd.it` short links, but the current regex only matches full `reddit.com/r/.../comments/...` URLs. | Practical correction for maintainers |
+| Important implementation note: the comment extractor recursively traverses available replies, but does not expand Reddit `more` placeholders, so some comments may remain unextracted on large threads. | Data completeness limitation |
+| Important implementation note: both `Resolve Final Posts` and `Approved?` rely on hard-coded node names in expressions. Renaming those nodes requires updating the expressions too. | Maintenance consideration |
\ No newline at end of file