This workflow corresponds to n8n.io template #14525 — we link there as the canonical source.
This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "32ecd7ff-c51c-45bb-82fe-767fae4764f5",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
7808,
240
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "daec3abd-41ad-4484-bbb6-7becc4c6a2fc",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
8640,
176
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "0fd324b7-b255-4573-9a32-9fc3b09b4bc5",
"name": "Create a post",
"type": "n8n-nodes-base.linkedIn",
"onError": "continueErrorOutput",
"position": [
8448,
-32
],
"parameters": {
"text": "={{ $('Format Response').item.json.linkedin_teaser }}",
"postAs": "organization",
"additionalFields": {},
"shareMediaCategory": "ARTICLE"
},
"typeVersion": 1
},
{
"id": "425c99b0-448d-4be0-8c39-c5439a254bdc",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
7200,
80
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "747c30c8-465d-4ea1-b666-a44e66d3acf1",
"operator": {
"type": "number",
"operation": "lt"
},
"leftValue": "={{ $json.LastProcessedID }}",
"rightValue": "={{ $('Fetch Blog').item.json.id }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "6e614e05-f17f-4824-8d3c-25223e31185d",
"name": "data cleanse",
"type": "n8n-nodes-base.code",
"position": [
7616,
64
],
"parameters": {
"jsCode": "// Change this line to point specifically to your WordPress node name\nconst raw = $node[\"Fetch Blog\"].json; \n\n// 1. Strip HTML tags from the content\nconst cleanContent = raw.content.rendered.replace(/<[^>]*>?/gm, '').trim();\n\n// 2. Clean HTML entities from the title\nconst cleanTitle = raw.title.rendered.replace(/’/g, \"'\").replace(/–/g, \"-\");\n\n// 3. Extract the Image URL safely\nconst imageUrl = raw._embedded?.['wp:featuredmedia']?.[0]?.source_url || \"\";\n\nreturn {\n id: raw.id,\n title: cleanTitle,\n content: cleanContent,\n link: raw.link,\n image_url: imageUrl\n};"
},
"typeVersion": 2
},
{
"id": "be721f70-0848-4b24-8a80-79478416ead9",
"name": "Last ID",
"type": "n8n-nodes-base.googleSheets",
"position": [
7024,
80
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 350289368,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_DOCUMENT_ID/edit#gid=350289368",
"cachedResultName": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEETS_DOCUMENT_ID",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_DOCUMENT_ID/edit?usp=drivesdk",
"cachedResultName": "Newsletter pipeline"
}
},
"typeVersion": 4.7
},
{
"id": "dfbb3db9-6ecf-4029-814e-661d54f6739e",
"name": "Update Last ID",
"type": "n8n-nodes-base.googleSheets",
"position": [
7424,
64
],
"parameters": {
"columns": {
"value": {
"row_number": "={{ $json.row_number }}",
"LastProcessedID": "={{ $('Fetch Blog').item.json.id }}"
},
"schema": [
{
"id": "LastProcessedID",
"type": "string",
"display": true,
"required": false,
"displayName": "LastProcessedID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 350289368,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_DOCUMENT_ID/edit#gid=350289368",
"cachedResultName": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEETS_DOCUMENT_ID",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_DOCUMENT_ID/edit?usp=drivesdk",
"cachedResultName": "Newsletter pipeline"
}
},
"typeVersion": 4.7
},
{
"id": "0b442536-87b5-49a0-9ad8-c5a9efb99747",
"name": "Format Response",
"type": "n8n-nodes-base.code",
"position": [
8160,
64
],
"parameters": {
"jsCode": "let rawAI = $input.item.json.output || $input.item.json.text || \"\";\n\ntry {\n const cleanJSON = rawAI.replace(/```json/g, '').replace(/```/g, '').trim();\n const parsed = JSON.parse(cleanJSON);\n\n // CRITICAL: This must match the name \"data cleanse\" exactly as seen in your Step 2\n const sourceData = $node[\"data cleanse\"].json;\n\n return {\n subject_line: parsed.subject_line,\n newsletter_body: parsed.newsletter_body,\n linkedin_teaser: parsed.linkedin_teaser,\n image_url: sourceData.image_url || \"\",\n link: sourceData.link || \"\"\n };\n} catch (error) {\n return {\n error: \"Parsing failed\",\n ai_raw: rawData\n };\n}"
},
"typeVersion": 2
},
{
"id": "3949e608-5a90-4ad5-9a72-b78ae20ac06a",
"name": "Email List",
"type": "n8n-nodes-base.googleSheets",
"position": [
8448,
176
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_DOCUMENT_ID/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEETS_DOCUMENT_ID",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_DOCUMENT_ID/edit?usp=drivesdk",
"cachedResultName": "Recepient Listt"
}
},
"typeVersion": 4.7
},
{
"id": "78dca46a-cca9-4570-9db6-3f08d3b3bbdc",
"name": "Send Email",
"type": "n8n-nodes-base.gmail",
"position": [
8864,
192
],
"parameters": {
"sendTo": "={{ $json['email list'] }}",
"message": "=<!DOCTYPE html>\n<html lang=\"en\">\n<body style=\"margin: 0; padding: 0; background-color: #f0f2f5; font-family: sans-serif;\">\n \n <div style=\"display: none; max-height: 0px; overflow: hidden;\">\n Insights on {{ $('Format Response').item.json.subject_line }}\n </div>\n\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"max-width: 600px; background-color: #ffffff; border-radius: 32px; overflow: hidden; margin: 40px auto;\">\n \n <tr>\n <td style=\"padding: 16px;\">\n <img src=\"{{ $('Format Response').item.json.image_url }}\" alt=\"Header\" width=\"100%\" style=\"display: block; border-radius: 24px; height: auto;\">\n </td>\n </tr>\n\n <tr>\n <td style=\"padding: 24px 40px;\">\n <h1 style=\"color: #1a1a1a; font-size: 24px;\"> \n{{ $('Format Response').item.json.subject_line }}\n</h1>\n \n <div style=\"color: #4a4a4a; font-size: 12px; line-height: 1.8;\">\n {{ $('Format Response').item.json.newsletter_body }}\n</div>\n\n <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"margin-top: 40px;\">\n <tr>\n <td style=\"border-radius: 16px; background: #6c5ce7;\" align=\"center\">\n <a href=\" {{ $('Format Response').item.json.link }} \" target=\"_blank\" style=\"padding: 18px 32px; color: #ffffff; text-decoration: none; font-weight: 700; display: inline-block;\">\n Read the Full Article\n </a>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n</body>\n</html>",
"options": {
"appendAttribution": false
},
"subject": "=Daily Newsletter : {{ $('Format Response').item.json.subject_line }}"
},
"typeVersion": 2.2
},
{
"id": "82e3e539-88b7-4983-984d-d945af0d7efe",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
6128,
-176
],
"parameters": {
"width": 464,
"height": 608,
"content": "## Blog to Social & Newsletter Automator\n\n### How it works\nThis workflow automatically fetches the latest blog post from a WordPress API and checks whether it has already been processed using a Google Sheets tracker. If the post is new, the workflow cleans and formats the blog data, then sends it to an AI agent powered by Google Gemini to generate a newsletter and LinkedIn teaser.\n\nThe formatted output is then distributed across channels. A LinkedIn post is published automatically, and a list of subscribers is retrieved from Google Sheets. The workflow loops through each recipient and sends a personalized HTML email newsletter using Gmail.\n\n### Setup steps\n1. Connect your Google Sheets account for both tracking (LastProcessedID) and email subscriber list.\n2. Add your Google Gemini API credentials to enable AI content generation.\n3. Connect your LinkedIn account for automated posting.\n4. Connect your Gmail account for sending newsletters.\n5. Update the WordPress API endpoint in the HTTP Request node."
},
"typeVersion": 1
},
{
"id": "a32609aa-5236-4ee8-9a9d-4a670baf0435",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
6608,
-176
],
"parameters": {
"color": 7,
"width": 944,
"height": 608,
"content": "## Step 1: Detect & Filter\nFetch latest blog post and compare ID with Google Sheets to avoid duplicate processing."
},
"typeVersion": 1
},
{
"id": "b6745e6f-2156-4a7d-b28c-cfced081239a",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
7568,
-176
],
"parameters": {
"color": 7,
"width": 528,
"height": 608,
"content": "## Step 2: AI Content Generation\nClean blog data and use Gemini AI to generate newsletter content and LinkedIn teaser."
},
"typeVersion": 1
},
{
"id": "ae4fedc4-6818-4fc5-9dec-6d58e2e7f6ad",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
6656,
80
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.3
},
{
"id": "53c2bf0d-b832-40f8-892a-10cfc59756e6",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
8112,
-176
],
"parameters": {
"color": 7,
"width": 912,
"height": 608,
"content": "## Step 3: Distribution\nPost to LinkedIn and send personalized emails to subscribers via Gmail."
},
"typeVersion": 1
},
{
"id": "bbcd72e5-e891-483e-a652-4b112e666d3e",
"name": "AI Agent2",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
7792,
64
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "62d4caad-7579-4aeb-8844-c0d2088f85f5",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
6848,
80
],
"parameters": {
"url": "https://vaguefoundation.com/blog/wp-json/wp/v2/posts?_embed&per_page=1",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"typeVersion": 4.3
}
],
"connections": {
"If": {
"main": [
[
{
"node": "Update Last ID",
"type": "main",
"index": 0
}
]
]
},
"Last ID": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"AI Agent2": {
"main": [
[
{
"node": "Format Response",
"type": "main",
"index": 0
}
]
]
},
"Email List": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Send Email": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Last ID",
"type": "main",
"index": 0
}
]
]
},
"data cleanse": {
"main": [
[
{
"node": "AI Agent2",
"type": "main",
"index": 0
}
]
]
},
"Update Last ID": {
"main": [
[
{
"node": "data cleanse",
"type": "main",
"index": 0
}
]
]
},
"Format Response": {
"main": [
[
{
"node": "Email List",
"type": "main",
"index": 0
},
{
"node": "Create a post",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Send Email",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent2",
"type": "ai_languageModel",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow fetches the latest blog post from a WordPress API and checks against a Google Sheets tracker to prevent duplicate processing. If a new post is found, the workflow updates the tracker and cleans the blog data. The cleaned content is then sent to a Gemini-powered AI…
Source: https://n8n.io/workflows/14525/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
The Multi-Model Agency Content Engine is a high-performance editorial system designed for agencies. It solves the "blank page" problem by alternating between real-world social proof and strategic expe
This project is an automated news publisher for LinkedIn. It uses RSS feeds to fetch news, processes the content with the Gemini API to generate precise summaries, and automatically publishes to Linke
This workflow automates the process of generating, reviewing, and publishing blog posts across multiple platforms, now enhanced with support for RSS Feeds as a content source. It streamlines the manag
Automate LinkedIn content creation by managing ideas in Google Sheets, generating professional AI-written posts, intelligently selecting relevant Unsplash images, sending drafts for email approval, an
This workflow helps you find and evaluate job opportunities automatically, without spending hours searching and comparing roles. It uses your resume to look for relevant jobs on LinkedIn, checks how w