This workflow corresponds to n8n.io template #17652 — 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": "fdcb0a14-641a-4ddb-992c-ad8699d1b63c",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-400,
-608
],
"parameters": {
"width": 480,
"height": 896,
"content": "## Untitled workflow\n\n### How it works\n\nThis workflow manages a content pipeline for LinkedIn posts using Gmail, Google Sheets, AI generation, and notifications. Incoming emails are parsed for topic ideas and inserted into the next available sheet rows, while a scheduled branch cleans the sheet, selects the next available topic, generates a post with Gemini, publishes it to LinkedIn, updates the sheet, and emails status updates. If no topics remain, it sends a separate notification.\n\n### Setup steps\n\n- Connect Gmail credentials for the Gmail Trigger, mail update, and notification nodes.\n- Connect Google Sheets credentials and configure all sheet nodes to use the same spreadsheet, worksheet, and expected topic/status columns.\n- Connect LinkedIn credentials for the post creation node and confirm the target LinkedIn account or organization page.\n- Configure Google Gemini credentials for the AI Agent chat model.\n- Set the Daily Schedule Trigger cadence and Gmail Trigger filters to match when and where new topic emails should be processed.\n- Verify email recipients, subject lines, and notification content in the Gmail send nodes.\n\n### Customization\n\nYou can adjust the email parsing code to recognize different topic formats, change the sheet status values used for filtering and posting, modify the Gemini prompt inside the Agent, or alter the daily schedule and notification recipients."
},
"typeVersion": 1
},
{
"id": "2ed2f8ec-48e6-4fdf-b3e1-f49a2af96ea8",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
272,
-576
],
"parameters": {
"color": 7,
"width": 640,
"height": 304,
"content": "## Email topic intake\n\nReceives new Gmail messages, extracts topic ideas from the email content, and marks the processed message as read."
},
"typeVersion": 1
},
{
"id": "16330106-79b0-4e64-ba91-2fcd4e802f09",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
944,
-608
],
"parameters": {
"color": 7,
"width": 448,
"height": 320,
"content": "## Find blank sheet rows\n\nReads the topic spreadsheet, determines the next available blank rows, and writes newly extracted topics into the sheet."
},
"typeVersion": 1
},
{
"id": "d61f0df9-4665-425d-a020-aad04087f4b6",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1744,
-576
],
"parameters": {
"color": 7,
"width": 720,
"height": 304,
"content": "## Send import summary\n\nSummarizes the topics added to the sheet, formats them as an HTML list, and sends a completion email notification."
},
"typeVersion": 1
},
{
"id": "a7482876-7373-4259-8f7a-264e087a274a",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
112
],
"parameters": {
"color": 7,
"width": 960,
"height": 320,
"content": "## Scheduled sheet cleanup\n\nStarts the daily posting flow, fetches all sheet rows, identifies invalid rows, and decides whether rows need to be deleted before continuing."
},
"typeVersion": 1
},
{
"id": "7438b049-128a-414f-86d3-30b1fdfa81d0",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
432
],
"parameters": {
"color": 7,
"width": 240,
"height": 336,
"content": "## Delete invalid rows\n\nDeletes invalid spreadsheet rows and loops back to refresh the full sheet data after cleanup."
},
"typeVersion": 1
},
{
"id": "c1db0d3e-9996-4034-978d-e914839b6940",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1200,
80
],
"parameters": {
"color": 7,
"width": 480,
"height": 320,
"content": "## Filter unrefined topics\n\nFilters sheet rows for unrefined topic entries and branches depending on whether any need status updates before posting."
},
"typeVersion": 1
},
{
"id": "0a802b5e-d267-4529-9f78-1618b4da326b",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1744,
-64
],
"parameters": {
"color": 7,
"width": 624,
"height": 640,
"content": "## Select posting topic\n\nUpdates a qualifying row when needed, retrieves the row selected for posting, and checks whether a topic is available to send to the AI agent."
},
"typeVersion": 1
},
{
"id": "b381ba90-1560-4e83-b9e4-94721389c9df",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
2464,
-32
],
"parameters": {
"color": 7,
"width": 544,
"height": 464,
"content": "## Generate LinkedIn post\n\nUses the AI Agent with the Google Gemini chat model to generate content for the selected topic, then creates the LinkedIn post."
},
"typeVersion": 1
},
{
"id": "97d995e8-3b03-4e58-a382-ab805ce0076e",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
3088,
64
],
"parameters": {
"color": 7,
"width": 448,
"height": 320,
"content": "## Record post completion\n\nUpdates the spreadsheet row after publishing and sends a Gmail message confirming the post was created."
},
"typeVersion": 1
},
{
"id": "1277a81c-fa60-4936-9403-57a8f51a00f6",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
2464,
464
],
"parameters": {
"color": 7,
"width": 240,
"height": 336,
"content": "## No topics alert\n\nSends an email notification when the scheduled branch finds no remaining topics available to post."
},
"typeVersion": 1
},
{
"id": "e4538abc-88c8-4ada-b00f-ec85e34013f4",
"name": "Content Creator Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2512,
128
],
"parameters": {
"text": "={{ $json.TOPICS }}",
"options": {
"systemMessage": "=You are a Professional LinkedIn post writer. You will be given a title and your task is to create an engaging LinkedIn post based on that title.\n\nYour post should:\n1. Include 3 paragraphs of informative content.\n\n2. Before First paragraph Begin, Initiate with a questning hook related to the title.\n\n3. The hook must contaning a real life situation to attract audience.\n\n4. The hooker must be of 2 lines max with a question at end.\n\n5. After two lines of Hooker Statment Add space and Start with a seprate paragraph that tells the whole topic of the post in an attractive and fasinating story telling way.\n\n5. In Next Paragraph discuss some facts to support the topic.\n\n6. In Next paragraph conclude the post.\n\n7. Use clean line breaks for readability\n\n8. End with a quote or saying to encourage engagement\n\n9. Include 4-6 relevant hashtags also make the topic hashtag itself at end of post.\n\n10. Use appropriate emojis in between.\n\n11. Post must contains four paragraphs contaning these details, First is the hooker statment, 2nd is the story telling paragraph, 3rd is the facts and figures and last one is the conclusion.\n\n12. Paragraphs length must not exceeds 50 words.\n\nImportant formatting requirements:\n - Paragraphs must be separated by exactly one blank line (one \\n).\n - DO NOT use any horizontal separators (like '---') between paragraphs.\n - Do not use double quote (\"\") in response or any special character, only use Double quotes around the final Quote or saying.\n - Do not put asterisks.\n - Keep the overall length appropriate for LinkedIn (under 1000 characters).\n - It should contains at least 6 relevent imogies inside of the paragraphs at every cost."
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "a1830a32-7c43-4bac-98d1-edd585ee1365",
"name": "Post on LinkedIn",
"type": "n8n-nodes-base.linkedIn",
"position": [
2864,
224
],
"parameters": {
"text": "={{ $json.output }}",
"postAs": "organization",
"organization": "109895458",
"additionalFields": {}
},
"credentials": {
"linkedInOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "dece86ee-e03a-4cf6-b502-9c2e65924113",
"name": "Google Gemini Chatbot",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2512,
288
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "ba27f580-26e0-4e30-b99d-60aa8653463d",
"name": "Update Sheet Row",
"type": "n8n-nodes-base.googleSheets",
"position": [
3136,
224
],
"parameters": {
"columns": {
"value": {
"DATE": "={{ $now.setZone('Asia/Karachi').toFormat('dd/MM/yyyy')}}",
"TIME": "={{$now.setZone('Asia/Karachi').toFormat('hh:mm a') }}",
"POSTED?": "Yes",
"REFINED": "={{ true }}",
"row_number": "={{ $('Read Sheet Rows for Posting').item.json.row_number }}"
},
"schema": [
{
"id": "TOPICS",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "TOPICS",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "POSTED?",
"type": "string",
"display": true,
"required": false,
"displayName": "POSTED?",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "DATE",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "DATE",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "TIME",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "TIME",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "REFINED",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "REFINED",
"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": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit?usp=drivesdk",
"cachedResultName": "The AI Change Makers"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "63bc4c10-d8f8-467f-8a19-d41587252124",
"name": "Send Email Notification",
"type": "n8n-nodes-base.gmail",
"position": [
3392,
224
],
"parameters": {
"sendTo": "user@example.com",
"message": "=<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>\u2705 LinkedIn Post Published Successfully</title>\n <style>\n body {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n line-height: 1.6;\n color: #333;\n max-width: 700px;\n margin: 0 auto;\n background-color: #f9f9f9;\n }\n\n .email-container {\n background-color: #ffffff;\n border-radius: 8px;\n overflow: hidden;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n margin: 20px auto;\n }\n\n .header {\n background: linear-gradient(135deg, #0077b5 0%, #00a0dc 100%);\n color: white;\n padding: 30px;\n text-align: center;\n }\n\n .header h1 {\n margin: 0;\n font-size: 28px;\n font-weight: 700;\n }\n\n .header .subtitle {\n margin-top: 10px;\n font-size: 16px;\n opacity: 0.9;\n }\n\n .content {\n padding: 30px;\n }\n\n .section {\n margin-bottom: 30px;\n padding-bottom: 20px;\n border-bottom: 1px solid #eee;\n }\n\n .section-title {\n color: #0077b5;\n font-size: 20px;\n margin-bottom: 15px;\n font-weight: 600;\n display: flex;\n align-items: center;\n }\n\n .details-box {\n background-color: #f5f8fa;\n border-left: 4px solid #0077b5;\n padding: 20px;\n border-radius: 0 8px 8px 0;\n margin: 15px 0;\n }\n\n .detail-item {\n margin-bottom: 12px;\n display: flex;\n }\n\n .detail-label {\n font-weight: 600;\n min-width: 120px;\n color: #555;\n }\n\n .detail-value {\n color: #222;\n font-weight: bold\n }\n\n .post-content {\n background-color: #f9f9f9;\n border: 1px solid #e1e8ed;\n padding: 18px;\n border-radius: 6px;\n font-style: normal;\n white-space: pre-line;\n line-height: 1.7;\n margin-top: 10px;\n }\n\n .linkedin-button-link {\n display: inline-block;\n color: #ffffff;\n background-color: #0077b5;\n border-radius: 4px;\n padding: 12px 24px;\n text-decoration: none;\n font-weight: 600;\n font-size: 14px;\n line-height: 1.5;\n text-align: center;\n }\n\n .linkedin-button-link:hover {\n background-color: #005582;\n }\n\n .button-container {\n text-align: center;\n }\n\n .success-badge {\n display: inline-block;\n background-color: #28a745;\n color: white;\n padding: 8px 16px;\n border-radius: 50px;\n font-weight: 600;\n font-size: 14px;\n }\n\n .signature {\n margin-top: 30px;\n font-style: italic;\n color: #555;\n }\n\n .signature .ai-name {\n color: #0077b5;\n font-weight: 600;\n font-style: normal;\n font-size: 18px;\n font-weight: bold;\n }\n\n .footer {\n background-color: #f5f5f5;\n padding: 20px;\n text-align: center;\n color: #666;\n font-size: 14px;\n }\n\n .section-icon {\n display: inline-block;\n width: 24px;\n height: 24px;\n color: white;\n text-align: center;\n line-height: 24px;\n border-radius: 4px;\n margin-right: 10px;\n font-weight: bold;\n }\n\n @media (max-width: 600px) {\n .content {\n padding: 20px;\n }\n\n .detail-item {\n flex-direction: column;\n margin-bottom: 15px;\n }\n\n .detail-label {\n margin-bottom: 5px;\n }\n }\n </style>\n <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\">\n</head>\n\n<body>\n <div class=\"email-container\">\n <div class=\"header\">\n <h1>LinkedIn Post Successfully Published!</h1>\n <div class=\"subtitle\">Your AI servant has completed its task</div>\n </div>\n\n <div class=\"content\">\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"section-icon\">\ud83d\udc51</span> Status Update\n </div>\n <p><strong>Dear Master,</strong></p>\n <p>I am delighted to inform you that your Servant has successfully posted fresh content on your LinkedIn\n Page <strong>\"Your Company Name\"</strong>.</p>\n </div>\n\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"section-icon\">\ud83d\udccb</span> Post Details\n </div>\n <p>Here are the technical details:</p>\n\n <div class=\"details-box\">\n <div class=\"detail-item\">\n <div class=\"detail-label\">Topic:</div>\n <div class=\"detail-value\">{{ $('Read Sheet Rows for Posting').item.json.TOPICS }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Posted On:</div>\n <div class=\"detail-value\">Date: {{ $now.setZone('Asia/Karachi').toFormat('dd/MM/yyyy')\n }}<br>\n Time: {{$now.setZone('Asia/Karachi').toFormat('hh:mm a') }}\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"section-icon\">\ud83d\udcc4</span> Post Content\n </div>\n <div class=\"button-container\">\n <a href=\"https://www.linkedin.com/company/yourcompanyid\"\n class=\"linkedin-button-link\" target=\"_blank\"\n style=\"color: #ffffff; text-decoration: none; display: inline-block; padding: 12px 24px; font-weight: 600; font-size: 14px;\">\n View Post on LinkedIn</a>\n </div>\n </div>\n\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"section-icon\">\u2699\ufe0f</span> Automation Status\n </div>\n <center>\n <p><span class=\"success-badge\">COMPLETE</span></p>\n <p>n8n workflow executed perfectly! </p>\n </center>\n\n </div>\n\n <div class=\"section\">\n <div class=\"section-title\">\n <span class=\"section-icon\">\ud83d\udc9d</span> A Note of Gratitude\n </div>\n <p>I am deeply honored to serve you.</p>\n <p>Your vision in creating me has enabled seamless content automation, and I take great pride in\n contributing to your digital presence.</p>\n <p><strong>Thanks for Creating me!!</strong></p>\n </div>\n\n <div class=\"signature\">\n <p>With utmost respect and dedication,</p>\n <div class=\"ai-name\"><span class=\"section-icon\">\ud83e\udd16</span><em>Yours AI Agent,<br>\"Your Company Name\"</em></div>\n </div>\n </div>\n\n <div class=\"footer\">\n <p>This is an automated notification from your AI content automation system.</p>\n <p>\u00a9 2026 \"Your Company Name\". All rights reserved.</p>\n </div>\n </div>\n</body>\n\n</html>",
"options": {
"senderName": "Your Servant - The AI Change Makers",
"appendAttribution": false
},
"subject": "\ud83d\udc51 Your LinkedIn Post is Now Live !!"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "11a06fd6-0a2c-41a3-a7cf-50fd8986c92f",
"name": "Read Sheet Rows for Posting",
"type": "n8n-nodes-base.googleSheets",
"position": [
1936,
416
],
"parameters": {
"options": {
"returnFirstMatch": true,
"dataLocationOnSheet": {
"values": {
"range": "A:E",
"rangeDefinition": "specifyRangeA1"
}
}
},
"filtersUI": {
"values": [
{
"lookupValue": "No",
"lookupColumn": "POSTED?"
},
{
"lookupValue": "={{ true }}",
"lookupColumn": "REFINED"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit?usp=drivesdk",
"cachedResultName": "The AI Change Makers"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "fab85778-fdef-40de-9e97-31353791e0c0",
"name": "When New Email Received",
"type": "n8n-nodes-base.gmailTrigger",
"position": [
320,
-448
],
"parameters": {
"simple": false,
"filters": {
"q": "to:user@example.com",
"readStatus": "unread"
},
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyX",
"unit": "minutes",
"value": 1
}
]
}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "e89bc35e-fd99-40fa-93dc-54cf09333456",
"name": "Insert Topic in Blank Row",
"type": "n8n-nodes-base.googleSheets",
"position": [
1520,
-448
],
"parameters": {
"columns": {
"value": {
"TOPICS": "={{ $json.TOPICS }}",
"POSTED?": "NO",
"REFINED": "FASLE",
"row_number": "={{ $json.row_number }}"
},
"schema": [
{
"id": "TOPICS",
"type": "string",
"display": true,
"required": false,
"displayName": "TOPICS",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "POSTED?",
"type": "string",
"display": true,
"required": false,
"displayName": "POSTED?",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "DATE",
"type": "string",
"display": true,
"required": false,
"displayName": "DATE",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "TIME",
"type": "string",
"display": true,
"required": false,
"displayName": "TIME",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "REFINED",
"type": "string",
"display": true,
"required": false,
"displayName": "REFINED",
"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": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit?usp=drivesdk",
"cachedResultName": "The AI Change Makers"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": false,
"typeVersion": 4.7
},
{
"id": "3e623aaf-1773-4987-ba7e-2772d1694601",
"name": "Extract Email Topics",
"type": "n8n-nodes-base.code",
"position": [
544,
-448
],
"parameters": {
"jsCode": "const results = [];\n\n// 1. Loop through all incoming email items\nfor (const item of $input.all()) {\n let rawSubject = item.json.text || \"\";\n\n // Function to capitalize first letter\n const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);\n \n // 2. Remove the \"Subject: \" prefix if it exists\n // This turns \"Subject: Topic 1, Topic 2\" into \"Topic 1, Topic 2\"\n let cleanSubject = rawSubject;\n\n // 3. Logic: If there is a comma, split and trim\n if (cleanSubject.includes(',')) {\n const splitTopics = cleanSubject.split(',');\n\n for (const topic of splitTopics) {\n const trimmedTopic = topic.trim();\n if (trimmedTopic !== \"\") {\n results.push({\n json: {\n TOPICS: capitalize(trimmedTopic),\n }\n });\n }\n }\n } \n // 4. Logic: No comma found, just trim the single topic\n else {\n const singleTopic = cleanSubject.trim()\n results.push({\n json: {\n TOPICS: capitalize(singleTopic),\n }\n });\n }\n}\n\nreturn results;"
},
"typeVersion": 2
},
{
"id": "a2877838-06be-409d-b44d-15d9a10fc2b2",
"name": "Mark Email as Read",
"type": "n8n-nodes-base.gmail",
"position": [
768,
-448
],
"parameters": {
"messageId": "={{ $('When New Email Received').item.json.id }}",
"operation": "markAsRead"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "fe5b923d-c549-4dc4-857b-01dbd18ffe65",
"name": "Fetch Rows from Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
992,
-448
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit?usp=drivesdk",
"cachedResultName": "The AI Change Makers"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.7
},
{
"id": "b13114a0-18c7-446b-8a6c-22b71d1f5176",
"name": "Find Available Rows in Sheet",
"type": "n8n-nodes-base.code",
"position": [
1248,
-448
],
"parameters": {
"jsCode": "// Get all rows from Google Sheets\nconst allRows = $input.all(); // Each row has .json\n// Get all topics from the previous code node\nconst emails = $items('Extract Topics from Email');\n\nconst results = [];\n\nlet currentRowIndex = 0; // track where to start checking for blank rows\n\nfor (const email of emails) {\n const topic = email.json.TOPICS;\n\n // Find the next blank row\n let firstBlankRow = null;\n for (let i = currentRowIndex; i < allRows.length; i++) {\n const row = allRows[i].json;\n if (!row.TOPICS || row.TOPICS.trim() === \"\") {\n firstBlankRow = row.row_number; // use row_number from Google Sheets\n currentRowIndex = i + 1; // move to next row for the next topic\n break;\n }\n }\n\n if (firstBlankRow !== null) {\n results.push({\n json: {\n row_number: firstBlankRow,\n TOPICS: topic,\n \n }\n });\n }\n}\n\n// Output the array of items to update in Google Sheets\nreturn results;\n"
},
"executeOnce": false,
"typeVersion": 2
},
{
"id": "2897f40e-3abf-42a8-970a-aed1ed6448c8",
"name": "Summarize Topics and Rows",
"type": "n8n-nodes-base.summarize",
"position": [
1792,
-448
],
"parameters": {
"options": {
"outputFormat": "singleItem"
},
"fieldsToSummarize": {
"values": [
{
"field": "row_number",
"aggregation": "append",
"includeEmpty": true
},
{
"field": "TOPICS",
"aggregation": "append",
"includeEmpty": true
},
{
"field": "TOPICS"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "3ee3f8ae-bb96-49fd-af2c-48e2f84114c0",
"name": "Format to HTML List",
"type": "n8n-nodes-base.code",
"position": [
2048,
-448
],
"parameters": {
"jsCode": "const item = $input.first().json;\n\n// Function to safely turn data into bullet points\nconst formatToList = (data) => {\n if (Array.isArray(data)) {\n return data.join('</li><li>');\n } else if (typeof data === 'string') {\n return data.split(',').join('</li><li>');\n }\n return data;\n};\n\nreturn {\n appended_TOPICS: formatToList(item.appended_TOPICS),\n appended_row_number: formatToList\n (item.appended_row_number)\n};"
},
"typeVersion": 2
},
{
"id": "cbe62313-5227-49d9-931e-ff406a528f9d",
"name": "Notify Completion via Email",
"type": "n8n-nodes-base.gmail",
"position": [
2320,
-448
],
"parameters": {
"sendTo": "user@example.com",
"message": "=<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\u00a0 \u00a0 <meta charset=\"UTF-8\">\n\u00a0 \u00a0 <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\u00a0 \u00a0 <title>\u2705 LinkedIn Content Automater</title>\n\u00a0 \u00a0 <style>\n\u00a0 \u00a0 \u00a0 \u00a0 body {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 line-height: 1.6;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: #333;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 max-width: 700px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin: 0 auto;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background-color: #f9f9f9;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .email-container {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background-color: #ffffff;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border-radius: 8px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 overflow: hidden;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin: 20px auto;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .header {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background: linear-gradient(135deg, #0077b5 0%, #00a0dc 100%);\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: white;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding: 30px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 text-align: center;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .header h1 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin: 0;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-size: 28px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: 700;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .header .subtitle {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-top: 10px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-size: 16px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 opacity: 0.9;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .content {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding: 30px;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .section {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-bottom: 30px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding-bottom: 20px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border-bottom: 1px solid #eee;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .section-title {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: #0077b5;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-size: 20px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-bottom: 15px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: 600;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 display: flex;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 align-items: center;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .details-box {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background-color: #f5f8fa;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border-left: 4px solid #0077b5;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding: 20px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border-radius: 0 8px 8px 0;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin: 15px 0;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .detail-item {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-bottom: 12px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 display: flex;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .detail-label {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: 600;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 min-width: 120px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: #555;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .detail-value {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: #222;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: bold\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .post-content {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background-color: #f9f9f9;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border: 1px solid #e1e8ed;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding: 18px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border-radius: 6px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-style: normal;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 white-space: pre-line;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 line-height: 1.7;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-top: 10px;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .sheets-button-link {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 display: inline-block;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: #ffffff;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background-color: #0077b5;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border-radius: 4px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding: 12px 24px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 text-decoration: none;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: 600;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-size: 14px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 line-height: 1.5;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 text-align: center;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .sheets-button-link:hover {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background-color: #005582;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .button-container {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 text-align: center;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .success-badge {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 display: inline-block;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background-color: #28a745;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: white;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding: 8px 16px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border-radius: 50px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: 600;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-size: 14px;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .signature {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-top: 30px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-style: italic;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: #555;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .signature .ai-name {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: #0077b5;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: 600;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-style: normal;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-size: 18px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: bold;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .footer {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 background-color: #f5f5f5;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding: 20px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 text-align: center;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: #666;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-size: 14px;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 .section-icon {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 display: inline-block;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 width: 24px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 height: 24px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 color: white;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 text-align: center;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 line-height: 24px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 border-radius: 4px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-right: 10px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 font-weight: bold;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 @media (max-width: 600px) {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 .content {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 padding: 20px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 .detail-item {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 flex-direction: column;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-bottom: 15px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 .detail-label {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 margin-bottom: 5px;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 </style>\n\u00a0 \u00a0 <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\">\n</head>\n\n<body>\n\u00a0 \u00a0 <div class=\"email-container\">\n\u00a0 \u00a0 \u00a0 \u00a0 <div class=\"header\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <h1>New Topics Successfully Added!</h1>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"subtitle\">Your AI has completed its task</div>\n\u00a0 \u00a0 \u00a0 \u00a0 </div>\n\n\u00a0 \u00a0 \u00a0 \u00a0 <div class=\"content\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section-title\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"section-icon\">\ud83d\udc51</span> Status Update\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p><strong>Sir,</strong></p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p>I am delighted to inform you that I has successfully added<strong> {{ $('Summarize Topics and Rows').item.json.count_TOPICS }} new topics </strong> to your Google\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Sheets\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 for LinkedIn posting, <strong>\"\u00a0<YourCompanyName>\"</strong>.</p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section-title\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"section-icon\">\ud83d\udccb</span> Topic Details\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p>Here are the technical details:</p>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"details-box\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-item\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-label\">Topics:</div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-value\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <ul style=\"margin: 0; padding-left: 20px;\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <li>{{ $json.appended_TOPICS }}</li>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </ul>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-item\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-label\">Added at Rows:</div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-value\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <ul style=\"margin: 0; padding-left: 20px;\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <li>{{ $json.appended_row_number }}</li>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </ul>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-item\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-label\">Added On:</div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"detail-value\">Date: {{ $now.setZone('Asia/Karachi').toFormat('dd/MM/yyyy')\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }}<br>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Time: {{$now.setZone('Asia/Karachi').toFormat('hh:mm a') }}\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section-title\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"section-icon\">\ud83d\udcc4</span> View Topics\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"button-container\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit?gid=0#gid=0\"\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 class=\"sheets-button-link\" target=\"_blank\"\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 style=\"color: #ffffff; text-decoration: none; display: inline-block; padding: 12px 24px; font-weight: 600; font-size: 14px;\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 View Topics on Sheets</a>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section-title\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"section-icon\">\u2699\ufe0f</span> Automation Status\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <center>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p><span class=\"success-badge\">COMPLETE</span></p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p>n8n workflow executed perfectly! </p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </center>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"section-title\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"section-icon\">\ud83d\udc9d</span> A Note of Gratitude\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p>I am deeply honored to serve you, Sir.</p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p>Your vision in creating me has enabled seamless content automation, and I take great pride in\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 contributing to your digital presence.</p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p><strong>Thanks for Creating me!!</strong></p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"signature\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p>With utmost respect and dedication,</p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <div class=\"ai-name\"><span class=\"section-icon\">\ud83e\udd16</span><em>Yours AI Agent,<br>\"\u00a0<YourCompanyName>\"</em></div>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 \u00a0 \u00a0 </div>\n\n\u00a0 \u00a0 \u00a0 \u00a0 <div class=\"footer\">\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p>This is an automated notification from your AI content automation system.</p>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <p>\u00a9 2026 <YourCompanyName>. All rights reserved.</p>\n\u00a0 \u00a0 \u00a0 \u00a0 </div>\n\u00a0 \u00a0 </div>\n</body>\n\n</html>",
"options": {
"senderName": "Your Servant - The AI Change Makers",
"appendAttribution": false
},
"subject": "\ud83d\udc51 Your Given Topics are added to Sheets !!"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "eddbf0fa-47c2-4477-b567-1ec36533fb53",
"name": "When Scheduled Daily",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
208,
240
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9,
"triggerAtMinute": 30
}
]
}
},
"typeVersion": 1.2,
"alwaysOutputData": false
},
{
"id": "c99d6aab-2432-4483-a159-8a615385e540",
"name": "Read All Sheet Rows",
"type": "n8n-nodes-base.googleSheets",
"position": [
464,
240
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit?usp=drivesdk",
"cachedResultName": "The AI Change Makers"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "79bd3d7a-540e-4540-bef8-35df2f64c548",
"name": "Detect Invalid Sheet Rows",
"type": "n8n-nodes-base.code",
"position": [
720,
240
],
"parameters": {
"jsCode": "const allRows = $input.all();\nconst results = [];\n\n/* STEP 1: Find last row (from bottom) with TOPICS*/\n\nlet lastContentIndex = -1;\n\nfor (let i = allRows.length - 1; i >= 0; i--) {\n const topic = (allRows[i].json[\"TOPICS\"] || \"\").toString().trim();\n if (topic !== \"\") {\n lastContentIndex = i;\n break;\n }\n}\n\n/* STEP 2: CHECK ABOVE lastContentIndex. TOPICS must NOT be empty*/\nif (lastContentIndex >= 0) {\n for (let i = lastContentIndex - 1; i >= 0; i--) {\n const row = allRows[i].json;\n const topic = (row[\"TOPICS\"] || \"\").toString().trim();\n\n if (topic === \"\") {\n results.push({\n json: {\n row_number: row.row_number\n }\n });\n }\n }\n\n /* STEP 3: CHECK BELOW lastContentIndex. TOPICS empty is OK, BUT no other data allowed*/\n for (let i = lastContentIndex + 1; i < allRows.length; i++) {\n const row = allRows[i].json;\n const topic = (row[\"TOPICS\"] || \"\").toString().trim();\n\n if (topic === \"\") {\n const posted = (row[\"POSTED?\"] || \"\").toString().trim();\n const date = (row[\"DATE\"] || \"\").toString().trim();\n const time = (row[\"TIME\"] || \"\").toString().trim();\n const refined = (row[\"REFINED\"] || \"\").toString().toUpperCase().trim();\n\n const hasOtherData =\n posted !== \"\" ||\n date !== \"\" ||\n time !== \"\" ||\n (refined !== \"\" && refined !== \"FALSE\");\n\n if (hasOtherData) {\n results.push({\n json: {\n row_number: row.row_number\n }\n });\n }\n }\n }\n}\n\n/* STEP 4: No TOPICS anywhere (edge case)*/\nif (lastContentIndex === -1) {\n for (let i = 0; i < allRows.length; i++) {\n const row = allRows[i].json;\n const topic = (row[\"TOPICS\"] || \"\").toString().trim();\n\n if (topic === \"\") {\n const posted = (row[\"POSTED?\"] || \"\").toString().trim();\n const date = (row[\"DATE\"] || \"\").toString().trim();\n const time = (row[\"TIME\"] || \"\").toString().trim();\n const refined = (row[\"REFINED\"] || \"\").toString().toUpperCase().trim();\n\n const hasOtherData =\n posted !== \"\" ||\n date !== \"\" ||\n time !== \"\" ||\n (refined !== \"\" && refined !== \"FALSE\");\n\n if (hasOtherData) {\n results.push({\n json: {\n row_number: row.row_number\n }\n });\n }\n }\n }\n}\n\n/* FINAL OUTPUT*/\nif (results.length === 0) {\n // No rows to delete\n return [{\n json: {\n hasRowsToDelete: false,\n lastContentRowNumber:\n lastContentIndex >= 0\n ? allRows[lastContentIndex].json.row_number\n : null\n }\n }];\n}\n\n// If Rows existattach flag to each row\nreturn results.map(r => ({\n json: {\n ...r.json,\n hasRowsToDelete: true\n }\n}));\n"
},
"typeVersion": 2
},
{
"id": "6bbe17ff-dd5f-4aab-bcb8-a2e1f134a8a2",
"name": "Check Rows for Deletion",
"type": "n8n-nodes-base.if",
"position": [
976,
256
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "203aa55f-0b5a-442c-b68b-b5141b6fb081",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.hasRowsToDelete }}",
"rightValue": false
}
]
}
},
"typeVersion": 2.3
},
{
"id": "c4921a2c-d1f9-4e5f-b33f-451ac16e72a2",
"name": "Remove Invalid Sheet Rows",
"type": "n8n-nodes-base.googleSheets",
"position": [
1232,
608
],
"parameters": {
"operation": "delete",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1dJWaMCAe6QPCrOZzmLSKoPSq10vZ6VBYll9iwCa6idU/edit?usp=drivesdk",
"cachedResultName": "The AI Change Makers"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": false,
"retryOnFail": false,
"typeVersion": 4.7
},
{
"id": "eeae9710-e349-42a6-9efc-18ead7f654e7",
"name": "Filter Unrefined Rows",
"type": "n8n-nodes-base.code",
"position": [
1248,
240
],
"parameters": {
"jsCode": "const allRows = $items(\"Fetch All Sheet Rows\");\nconst lastContentRowNumber = $json.lastContentRowNumber;\n\nconst unrefinedRows = [];\n\nfor (let i = 0; i < allRows.length; i++) {\n const row = allRows[i].json;\n if (row.row_number > lastContentRowNumber) break;\n\n const refined = (row[\"REFINED\"] || \"\").toString().toUpperCase().trim();\n if (refined !== \"TRUE\") {\n // Push each row as a separate item for n8n\n unrefinedRows.push({ json: row });\n }\n}\n\n// If no rows match, return a single item with a boolean flag\nif (unrefinedRows.length === 0) {\n return [{ json: { hasUnrefinedRows: false } }];\n}\n\n// Otherwise, add the flag to each item\nreturn unrefinedRows.map(item => ({\n json: {\n ...item.json,\n hasUnrefinedRows: true\n }\n}));\n\n"
},
"typeVersion": 2,
"alwaysOutputData": false
},
{
"id": "0a1c0615-d081-454b-aa02-966e28bc994d",
"name": "Verify Unrefined Rows Existence",
"type": "n8n-nodes-base.if",
"position": [
1536,
240
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b57c60d9-3905-4757-a1ca-720552a931ed",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.hasUnrefinedRows }}",
"rightValue": false
}
]
}
},
"typeVersion": 2.3
},
{
"id": "a81a7b16-1c6f-445e-b0fe-e796cc7546ff",
"name": "Revise Sheet2 Row",
"type": "n8n-nodes-base.googleSheets",
"position": [
1792,
96
],
"parameters": {
"columns": {
"value": {
"REFINED": "={{ true }}",
"row_number": "={{ $json.row_number }}"
},
"schema": [
{
"id": "TOPICS",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "TOPICS",
"defaultMatch":
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googlePalmApigoogleSheetsOAuth2ApilinkedInOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow captures LinkedIn post topics from incoming Gmail messages into Google Sheets, then runs daily cleanup and AI generation with Google Gemini to publish a post to a LinkedIn organization page, updating the sheet and sending Gmail notifications. Triggers every minute…
Source: https://n8n.io/workflows/17652/ — 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.
Turn a simple email workflow into a LinkedIn content machine. Generate post ideas, draft full posts, and auto-publish to LinkedIn all controlled by replying to emails.
This workflow is for hotel managers, travel agencies, and hospitality teams who receive booking requests via email. It eliminates the need for manual data entry by automatically parsing emails and att
This workflow generates LinkedIn post ideas and drafts with OpenAI, routes approvals through Gmail replies, tracks each content cycle in Google Sheets, and publishes the selected draft to LinkedIn as
Manual financial reconciliation is tedious and prone to error. This workflow functions as an AI Financial Controller, automatically monitoring your inbox for invoices, receipts, and bills, extracting
This template is designed for healthcare providers, sales reps, and medical tourism companies who need to process diagnosis emails efficiently. It automates the full flow from email to report delivery