AutomationFlowsAI & RAG › AI Social Listening & Comment Intelligence Agent

AI Social Listening & Comment Intelligence Agent

ByRahul Joshi @rahul08 on n8n.io

Automate LinkedIn comment monitoring and turn conversations into qualified sales opportunities using AI 🤖. This intelligent agent continuously scans LinkedIn posts mentioning your brand, analyzes every comment for buyer intent and sentiment, and drafts context-aware replies…

Cron / scheduled trigger★★★★★ complexityAI-powered40 nodesN8N Nodes SerpapiN8N Nodes Connectsafely AiAgentGoogle SheetsLm Chat Azure Open AiGoogle Sheets TriggerGmail
AI & RAG Trigger: Cron / scheduled Nodes: 40 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #13958 — 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 →

Download .json
{
  "id": "4poK6alRCRmCQ2lo",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Comment Analyse and Reporter",
  "tags": [],
  "nodes": [
    {
      "id": "311c70f0-4471-400f-8aa1-02d5410a30a2",
      "name": "Run Every 15 Minutes",
      "type": "n8n-nodes-base.cron",
      "position": [
        -1040,
        -320
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "a03df491-a798-4992-8838-39574fd04f3f",
      "name": "Search LinkedIn Posts via SerpAPI",
      "type": "n8n-nodes-serpapi.serpApi",
      "position": [
        -816,
        -320
      ],
      "parameters": {
        "q": "site:linkedin.com/posts (\"Techdome\" OR \"Employee of techdome\")",
        "requestOptions": {},
        "additionalFields": {}
      },
      "credentials": {
        "serpApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4f832192-6aab-472c-9415-6c2a8971eb9a",
      "name": "Fetch Post Comments via ConnectSafely",
      "type": "n8n-nodes-connectsafely-ai.connectSafelyLinkedIn",
      "position": [
        -368,
        -320
      ],
      "parameters": {
        "postUrl": "={{ $json.post_url }}",
        "accountId": "695ce64a09c18d6bbbe90ed0",
        "operation": "getAllPostComments"
      },
      "credentials": {
        "connectSafelyApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4dcb09ba-2ccc-4207-9aa7-08d563fff0c8",
      "name": "Parse & Filter Search Results",
      "type": "n8n-nodes-base.code",
      "position": [
        -592,
        -320
      ],
      "parameters": {
        "jsCode": "// ---------------------------\n// COLLECT ALL POSSIBLE RESULTS\n// ---------------------------\nconst data = items[0].json;\n\nconst results = [\n  ...(data.organic_results || []),\n  ...(data.inline_results || []),\n  ...(data.discussions || []),\n  ...(data.forums || []),\n];\n\nconst problemKeywords = [\n  'problem',\n  'issue',\n  'manual',\n  'not working',\n  'struggling',\n  'pain',\n  'challenge',\n  'empty',\n  'ghosted',\n  'ghosting',\n  'not enough',\n  'low',\n  'hard',\n  'difficult',\n  'miss',\n  'failing'\n];\n\nconst output = results.map(post => {\n  const postUrl = post.link || '';\n  let platform = 'Unknown';\n  let username = null;\n  let postId = null;\n  let authorName = null;\n\n  // ---------------------------\n  // LINKEDIN DETECTION\n  // ---------------------------\n  if (/linkedin\\.com\\/posts\\//i.test(postUrl)) {\n    platform = 'LinkedIn';\n\n    const match = postUrl.match(/linkedin\\.com\\/posts\\/([^_]+).*?(\\d{8,})/i);\n    if (match) {\n      username = match[1];\n      postId = match[2];\n    }\n\n    authorName = post.source\n      ? post.source.replace('LinkedIn \u00b7 ', '').trim()\n      : null;\n  }\n\n  // ---------------------------\n  // REDDIT DETECTION (ROBUST)\n  // ---------------------------\n  if (/reddit\\.com/i.test(postUrl)) {\n    platform = 'Reddit';\n\n    const redditMatch = postUrl.match(\n      /reddit\\.com\\/r\\/([^/]+)\\/comments\\/([^/]+)/i\n    );\n\n    if (redditMatch) {\n      username = `r/${redditMatch[1]}`;\n      postId = redditMatch[2];\n    }\n\n    authorName = post.source\n      ? post.source.replace('Reddit \u00b7 ', '').trim()\n      : username;\n  }\n\n  // ---------------------------\n  // PROBLEM DETECTION\n  // ---------------------------\n  const text = `${post.title || ''} ${post.snippet || ''}`.toLowerCase();\n\n  const detectedProblems = problemKeywords.filter(k =>\n    text.includes(k)\n  );\n\n  return {\n    json: {\n      platform,\n      author_name: authorName,\n      username,\n      post_id: postId,\n      post_url: postUrl || null,\n      post_title: post.title || null,\n      post_snippet: post.snippet || null,\n      engagement_hint: post.displayed_link || null,\n      problem_keywords_detected: detectedProblems,\n      is_problem_post: detectedProblems.length > 0\n    }\n  };\n});\n\n// REMOVE EMPTY / UNKNOWN URL RESULTS\nreturn output.filter(item => item.json.post_url);\n\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ba32dca4-ff48-4310-8a8a-86003adaf7af",
      "name": "AI Intent Detection Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        80,
        -320
      ],
      "parameters": {
        "text": "=Analyze the following LinkedIn comment and identify lead intent.\n\nPost URL:\n{{ $json.postUrl }}\n\nPost Content:\n{{ $json.postContent }}\n\nCommenter Name:\n{{ $json.commenterName }}\n\nComment Text:\n{{ $json.commentText }}\n\nReturn the result in the following JSON format ONLY:\n\n{\n  \"postUrl\": \"{{ $json.postUrl }}\",\n  \"leadName\": \"{{ $json.commenterName }}\",\n  \"comment\": \"{{ $json.commentText }}\",\n  \"intentScore\": number,\n  \"intentLabel\": \"no-intent | passive-interest | problem-aware | solution-aware | high-intent\"\n}\n",
        "options": {
          "systemMessage": "=You are a B2B sales intent detection agent.\n\nYour job is to analyze LinkedIn post context and comment text to identify whether the commenter shows buying intent, problem awareness, or decision-maker interest.\n\nYou must:\n- Use ONLY the data provided in the input\n- Infer intent from wording, tone, and relevance to the post\n- Be conservative: do not hallucinate intent\n- Prefer precision over recall\n\nScoring rules:\n- 0\u201320 \u2192 No intent (generic praise, agreement, emojis)\n- 21\u201340 \u2192 Passive interest (thoughtful comment, but no problem ownership)\n- 41\u201360 \u2192 Problem-aware (mentions pain points, challenges, or agreement with problem)\n- 61\u201380 \u2192 Solution-aware (implies need for solution, improvement, or optimization)\n- 81\u2013100 \u2192 High buying intent (clear ownership, decision role, desire to act)\n\nIf intent is below 30, still return the record but mark it as \"low-intent\".\n\nOutput MUST be valid JSON and follow the exact schema provided.\nDo not add explanations or extra text.\n"
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "32e43c34-820d-419f-9197-7daa3f985722",
      "name": "Flatten Comments into Rows",
      "type": "n8n-nodes-base.code",
      "position": [
        -144,
        -320
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of items) {\n  const post = item.json;\n\n  const postUrl = post.postUrl || '';\n  const postContent = post.postDetails?.content || '';\n  const activityUrn = post.postDetails?.activityUrn || null;\n\n  const comments = post.comments || [];\n\n  for (const comment of comments) {\n    results.push({\n      json: {\n        // Post info\n        postUrl,\n        activityUrn,\n        postContent,\n\n        // Comment info\n        commentId: comment.commentId,\n        commentText: comment.commentText,\n        commenterName: comment.authorName,\n        commenterProfileUrl: comment.profileUrl || null,\n        commenterUrn: comment.commenterUrn || null,\n\n        // Metadata\n        createdAt: comment.createdAt,\n        likeCount: comment.likeCount,\n        replyCount: comment.replyCount,\n        isProfile: comment.hasProfile\n      }\n    });\n  }\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "356016ed-0627-4f62-bd71-8e0a329d7b38",
      "name": "Parse AI Intent Output",
      "type": "n8n-nodes-base.code",
      "position": [
        432,
        -320
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of items) {\n  // Skip empty or invalid outputs safely\n  if (!item.json.output) continue;\n\n  let parsed;\n  try {\n    parsed = JSON.parse(item.json.output);\n  } catch (e) {\n    // If parsing fails, skip this record\n    continue;\n  }\n\n  results.push({\n    json: {\n      postUrl: parsed.postUrl || null,\n      leadName: parsed.leadName || null,\n      comment: parsed.comment || null,\n      intentScore: parsed.intentScore ?? null,\n      intentLabel: parsed.intentLabel || null\n    }\n  });\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "7f0af878-ec31-4116-b5e6-eb97c45ea8a9",
      "name": "Save Leads to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        656,
        -320
      ],
      "parameters": {
        "columns": {
          "value": {
            "comment": "={{ $json.comment }}",
            "post_url": "={{ $json.postUrl }}",
            "lead name": "={{ $json.leadName }}",
            "intent label": "={{ $json.intentLabel }}",
            "intent score": "={{ $json.intentScore }}"
          },
          "schema": [
            {
              "id": "post_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "post_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "lead name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "lead name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "comment",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "comment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "intent score",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "intent score",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "intent label",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "intent label",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1996970241,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit#gid=1996970241",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit?usp=drivesdk",
          "cachedResultName": "Post Scraping"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "75ef2c71-7b3c-475d-9337-c7d061301fbb",
      "name": "Azure OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        160,
        -96
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2df8d882-61e5-42f3-95f7-dfd248c19d5d",
      "name": "Google Sheets Trigger",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        -1040,
        112
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1996970241,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit#gid=1996970241",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit?usp=drivesdk",
          "cachedResultName": "Post Scraping"
        }
      },
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "df24c01b-5a8b-47de-b76d-44ec84289b04",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -816,
        16
      ],
      "parameters": {
        "text": "Draft a suitable reply for the commentes for proper sentiments",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "bdebac9a-51a7-46a4-a39d-d8af16e2bce7",
      "name": "Azure OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        -752,
        240
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7cdc0bec-cb28-4240-b948-11c55e1f20b2",
      "name": "Code in JavaScript2",
      "type": "n8n-nodes-base.code",
      "position": [
        -464,
        112
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n  item.json.myNewField = 1;\n}\n\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "31d68c55-0e83-4100-9665-5f8356bc4656",
      "name": "Append or update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -240,
        112
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1996970241,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit#gid=1996970241",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit?usp=drivesdk",
          "cachedResultName": "Post Scraping"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "91de8c1f-3442-4edc-951d-e0907da31fa0",
      "name": "Google Sheets Trigger1",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        -1040,
        448
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1996970241,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit#gid=1996970241",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit?usp=drivesdk",
          "cachedResultName": "Post Scraping"
        }
      },
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "baf4b709-326d-4a29-a172-cdccfeee6ece",
      "name": "Code in JavaScript3",
      "type": "n8n-nodes-base.code",
      "position": [
        -816,
        448
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n  item.json.myNewField = 1;\n}\n\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "0b752ec9-cf45-4406-9cb2-41419f925a8e",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -592,
        448
      ],
      "parameters": {
        "sendTo": "info@example.com",
        "message": "<HTML File>",
        "options": {},
        "subject": "<Your Subject>"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "94cf4921-5e78-4f51-bf0c-5dc9aac3448d",
      "name": "Trigger Every 15 Minutes",
      "type": "n8n-nodes-base.cron",
      "position": [
        -992,
        1024
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "a4caaaa9-92f6-4b3e-93d6-912cc95ea5a4",
      "name": "AI Sentiment & Intent Detection Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        128,
        1024
      ],
      "parameters": {
        "text": "=Analyze the following LinkedIn comment and identify lead intent.\n\nPost URL:\n{{ $json.postUrl }}\n\nPost Content:\n{{ $json.postContent }}\n\nCommenter Name:\n{{ $json.commenterName }}\n\nComment Text:\n{{ $json.commentText }}\n\nReturn the result in the following JSON format ONLY:\n\n{\n  \"postUrl\": \"{{ $json.postUrl }}\",\n  \"leadName\": \"{{ $json.commenterName }}\",\n  \"comment\": \"{{ $json.commentText }}\",\n  \"intentScore\": number,\n  \"intentLabel\": \"no-intent | passive-interest | problem-aware | solution-aware | high-intent\"\n}\n",
        "options": {
          "systemMessage": "=You are a B2B sales intent detection agent.\n\nYour job is to analyze LinkedIn post context and comment text to identify whether the commenter shows buying intent, problem awareness, or decision-maker interest.\n\nYou must:\n- Use ONLY the data provided in the input\n- Infer intent from wording, tone, and relevance to the post\n- Be conservative: do not hallucinate intent\n- Prefer precision over recall\n\nScoring rules:\n- 0\u201320 \u2192 No intent (generic praise, agreement, emojis)\n- 21\u201340 \u2192 Passive interest (thoughtful comment, but no problem ownership)\n- 41\u201360 \u2192 Problem-aware (mentions pain points, challenges, or agreement with problem)\n- 61\u201380 \u2192 Solution-aware (implies need for solution, improvement, or optimization)\n- 81\u2013100 \u2192 High buying intent (clear ownership, decision role, desire to act)\n\nIf intent is below 30, still return the record but mark it as \"low-intent\".\n\nOutput MUST be valid JSON and follow the exact schema provided.\nDo not add explanations or extra text.\n"
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "987fd12f-c41d-482b-b84e-b0cf834af7fe",
      "name": "Parse Sentiment & Score Output",
      "type": "n8n-nodes-base.code",
      "position": [
        480,
        1024
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of items) {\n  // Skip empty or invalid outputs safely\n  if (!item.json.output) continue;\n\n  let parsed;\n  try {\n    parsed = JSON.parse(item.json.output);\n  } catch (e) {\n    // If parsing fails, skip this record\n    continue;\n  }\n\n  results.push({\n    json: {\n      postUrl: parsed.postUrl || null,\n      leadName: parsed.leadName || null,\n      comment: parsed.comment || null,\n      intentScore: parsed.intentScore ?? null,\n      intentLabel: parsed.intentLabel || null\n    }\n  });\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "8e5d8fe6-e2a8-4861-ae28-9ac1fddb8ea9",
      "name": "Save Comments & Sentiment to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        704,
        1024
      ],
      "parameters": {
        "columns": {
          "value": {
            "comment": "={{ $json.comment }}",
            "post_url": "={{ $json.postUrl }}",
            "lead name": "={{ $json.leadName }}",
            "intent label": "={{ $json.intentLabel }}",
            "intent score": "={{ $json.intentScore }}"
          },
          "schema": [
            {
              "id": "post_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "post_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "lead name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "lead name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "comment",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "comment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "intent score",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "intent score",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "intent label",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "intent label",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1996970241,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit#gid=1996970241",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit?usp=drivesdk",
          "cachedResultName": "Post Scraping"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "fa815af1-60b8-4761-bfb6-aa6f8f23b413",
      "name": "Watch Sheet for New Comment Rows",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        -928,
        1600
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1996970241,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit#gid=1996970241",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit?usp=drivesdk",
          "cachedResultName": "Post Scraping"
        }
      },
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "265c661c-bda8-4632-abe7-6536ceafc25a",
      "name": "AI Reply Drafting Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -704,
        1488
      ],
      "parameters": {
        "text": "Draft a suitable reply for the commentes for proper sentiments",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "6c0598e9-0259-4e0a-8d75-3a6e895c741c",
      "name": "Format Reply for Sheet Update",
      "type": "n8n-nodes-base.code",
      "position": [
        -352,
        1600
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n  item.json.myNewField = 1;\n}\n\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "5f1bd6ef-2474-4b7a-8b0d-9a7cbb6b4292",
      "name": "Write AI Reply Back to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -128,
        1600
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1996970241,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit#gid=1996970241",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit?usp=drivesdk",
          "cachedResultName": "Post Scraping"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "4486ac1e-5322-46d0-ad9f-31c1500a8f46",
      "name": "Watch Sheet for Approved Replies",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        -960,
        2016
      ],
      "parameters": {
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1996970241,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit#gid=1996970241",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hXDNE90IFbXLgyLt2XwSHgI_9sASzTSM9LAA4cUDFj4/edit?usp=drivesdk",
          "cachedResultName": "Post Scraping"
        }
      },
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ee63d50c-9c00-4231-a302-a7d0d0b1fd4b",
      "name": "Build Media Team Email Report",
      "type": "n8n-nodes-base.code",
      "position": [
        -736,
        2016
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n  item.json.myNewField = 1;\n}\n\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "c83ea93c-6d0d-43a9-b029-68335b83f135",
      "name": "Send Email Report to Media Team",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -512,
        2016
      ],
      "parameters": {
        "sendTo": "info@example.com",
        "message": "<HTML File>",
        "options": {},
        "subject": "<Your Subject>"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "660a6302-4e05-41fe-89c6-6cbb9fbedc3c",
      "name": "\ud83d\udccb Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2048,
        1072
      ],
      "parameters": {
        "color": 3,
        "width": 520,
        "height": 734,
        "content": "## \ud83d\udccb Workflow Overview \u2014 Comment Analyse & Reporter\n\n### How it works\nThis workflow automates the full lifecycle of LinkedIn comment monitoring and response for Techdome. It runs across **three sequential stages**:\n\n**Stage 1 \u2014 Comment Scraping & Sentiment Scoring:** A cron trigger fires every 15 minutes. SerpAPI searches LinkedIn for posts mentioning Techdome. Results are parsed and filtered, then ConnectSafely fetches the actual comments for each post. An Azure OpenAI-powered AI agent analyzes each comment for sentiment and assigns an intent score and label. The structured output is saved to a Google Sheet (Sheet2) with columns for post URL, commenter name, comment text, sentiment score, and intent label.\n\n**Stage 2 \u2014 AI Reply Generation:** A Google Sheets trigger watches for new rows. For each comment, an AI Reply Drafting Agent generates a contextually appropriate reply based on the sentiment and comment content. The drafted reply is written back to the same Google Sheet row.\n\n**Stage 3 \u2014 Media Team Email Report:** A second Google Sheets trigger detects updated rows with replies. A code node compiles a structured HTML email report and sends it via Gmail to the media team so they can review and post the replies on LinkedIn.\n\n### Setup steps\n1. Add credentials: **SerpAPI**, **ConnectSafely**, **Azure OpenAI**, **Google Sheets**, and **Gmail**\n2. Set the target Google Sheet ID in all Sheets nodes\n3. Update the Gmail recipient address in the Send Email node\n4. Activate all three trigger nodes"
      },
      "typeVersion": 1
    },
    {
      "id": "2437fbdc-b371-4fc4-8e41-a1a8480d4e5d",
      "name": "Section: Comment Scraping",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1280,
        800
      ],
      "parameters": {
        "width": 1900,
        "content": "## \ud83d\udd0d Stage 1 \u2014 Comment Scraping & Sentiment Scoring\nSerpAPI searches LinkedIn for Techdome-related posts every 15 minutes. Comments are fetched, flattened, and scored by an AI agent for sentiment and buyer intent. Results are saved to Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "3cdd5de0-9ded-494a-b0f8-55859f7a4c9c",
      "name": "Section: Reply Generation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1280,
        1392
      ],
      "parameters": {
        "width": 1000,
        "content": "## \ud83d\udcac Stage 2 \u2014 AI Reply Generation\nWatches Google Sheets for new comment rows. The AI Reply Drafting Agent generates a tone-matched reply per comment using sentiment context, then writes the reply back to the sheet."
      },
      "typeVersion": 1
    },
    {
      "id": "a5b1d617-e8bb-4b46-b005-6c4c7414c675",
      "name": "Section: Email Report",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        1808
      ],
      "parameters": {
        "width": 680,
        "content": "## \ud83d\udce7 Stage 3 \u2014 Media Team Email Report\nWatches the sheet for rows with completed replies. Compiles a formatted HTML email report and delivers it to the media team via Gmail so they can act on the replies."
      },
      "typeVersion": 1
    },
    {
      "id": "c41c87f1-a2c1-43de-8704-d202100e2fa0",
      "name": "Warning: SerpAPI",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -704,
        1216
      ],
      "parameters": {
        "color": 2,
        "width": 260,
        "height": 140,
        "content": "\u26a0\ufe0f **SerpAPI Credentials Required**\nThis node requires a valid SerpAPI key. Without it, no LinkedIn posts will be found and the workflow will fail silently. Watch for rate limit errors on high-volume runs."
      },
      "typeVersion": 1
    },
    {
      "id": "4538dc4b-d7c0-42ba-9d2a-18ff15c5d306",
      "name": "Warning: Gmail",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -288,
        2000
      ],
      "parameters": {
        "color": 2,
        "width": 280,
        "height": 140,
        "content": "\u26a0\ufe0f **Gmail Credentials & Recipient Required**\nSet the correct recipient email for the media team. Misconfigured Gmail OAuth will silently fail \u2014 ensure the Gmail account has Send permission enabled."
      },
      "typeVersion": 1
    },
    {
      "id": "eb0adcb0-ded9-475d-a8c3-d537ea663e74",
      "name": "Search LinkedIn Posts via SerpAPI1",
      "type": "n8n-nodes-serpapi.serpApi",
      "position": [
        -768,
        1024
      ],
      "parameters": {
        "q": "site:linkedin.com/posts (\"Techdome\" OR \"Employee of techdome\")",
        "requestOptions": {},
        "additionalFields": {}
      },
      "credentials": {
        "serpApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d2e234ea-7582-4644-9ddd-3899b6a8a528",
      "name": "Fetch Post Comments via ConnectSafely1",
      "type": "n8n-nodes-connectsafely-ai.connectSafelyLinkedIn",
      "position": [
        -320,
        1024
      ],
      "parameters": {
        "postUrl": "={{ $json.post_url }}",
        "accountId": "695ce64a09c18d6bbbe90ed0",
        "operation": "getAllPostComments"
      },
      "credentials": {
        "connectSafelyApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dee58d4c-1220-4690-8e80-625fa2cbd30e",
      "name": "Parse & Filter Search Results1",
      "type": "n8n-nodes-base.code",
      "position": [
        -544,
        1024
      ],
      "parameters": {
        "jsCode": "// ---------------------------\n// COLLECT ALL POSSIBLE RESULTS\n// ---------------------------\nconst data = items[0].json;\n\nconst results = [\n  ...(data.organic_results || []),\n  ...(data.inline_results || []),\n  ...(data.discussions || []),\n  ...(data.forums || []),\n];\n\nconst problemKeywords = [\n  'problem',\n  'issue',\n  'manual',\n  'not working',\n  'struggling',\n  'pain',\n  'challenge',\n  'empty',\n  'ghosted',\n  'ghosting',\n  'not enough',\n  'low',\n  'hard',\n  'difficult',\n  'miss',\n  'failing'\n];\n\nconst output = results.map(post => {\n  const postUrl = post.link || '';\n  let platform = 'Unknown';\n  let username = null;\n  let postId = null;\n  let authorName = null;\n\n  // ---------------------------\n  // LINKEDIN DETECTION\n  // ---------------------------\n  if (/linkedin\\.com\\/posts\\//i.test(postUrl)) {\n    platform = 'LinkedIn';\n\n    const match = postUrl.match(/linkedin\\.com\\/posts\\/([^_]+).*?(\\d{8,})/i);\n    if (match) {\n      username = match[1];\n      postId = match[2];\n    }\n\n    authorName = post.source\n      ? post.source.replace('LinkedIn \u00b7 ', '').trim()\n      : null;\n  }\n\n  // ---------------------------\n  // REDDIT DETECTION (ROBUST)\n  // ---------------------------\n  if (/reddit\\.com/i.test(postUrl)) {\n    platform = 'Reddit';\n\n    const redditMatch = postUrl.match(\n      /reddit\\.com\\/r\\/([^/]+)\\/comments\\/([^/]+)/i\n    );\n\n    if (redditMatch) {\n      username = `r/${redditMatch[1]}`;\n      postId = redditMatch[2];\n    }\n\n    authorName = post.source\n      ? post.source.replace('Reddit \u00b7 ', '').trim()\n      : username;\n  }\n\n  // ---------------------------\n  // PROBLEM DETECTION\n  // ---------------------------\n  const text = `${post.title || ''} ${post.snippet || ''}`.toLowerCase();\n\n  const detectedProblems = problemKeywords.filter(k =>\n    text.includes(k)\n  );\n\n  return {\n    json: {\n      platform,\n      author_name: authorName,\n      username,\n      post_id: postId,\n      post_url: postUrl || null,\n      post_title: post.title || null,\n      post_snippet: post.snippet || null,\n      engagement_hint: post.displayed_link || null,\n      problem_keywords_detected: detectedProblems,\n      is_problem_post: detectedProblems.length > 0\n    }\n  };\n});\n\n// REMOVE EMPTY / UNKNOWN URL RESULTS\nreturn output.filter(item => item.json.post_url);\n\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d1ca6bba-4cd5-4898-804a-a3c00ff81c48",
      "name": "Flatten Comments into Rows1",
      "type": "n8n-nodes-base.code",
      "position": [
        -96,
        1024
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of items) {\n  const post = item.json;\n\n  const postUrl = post.postUrl || '';\n  const postContent = post.postDetails?.content || '';\n  const activityUrn = post.postDetails?.activityUrn || null;\n\n  const comments = post.comments || [];\n\n  for (const comment of comments) {\n    results.push({\n      json: {\n        // Post info\n        postUrl,\n        activityUrn,\n        postContent,\n\n        // Comment info\n        commentId: comment.commentId,\n        commentText: comment.commentText,\n        commenterName: comment.authorName,\n        commenterProfileUrl: comment.profileUrl || null,\n        commenterUrn: comment.commenterUrn || null,\n\n        // Metadata\n        createdAt: comment.createdAt,\n        likeCount: comment.likeCount,\n        replyCount: comment.replyCount,\n        isProfile: comment.hasProfile\n      }\n    });\n  }\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "8d8385ec-d04f-4391-b715-180f64db8d18",
      "name": "Azure OpenAI Chat Model2",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        208,
        1248
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "671d467f-7943-43a9-be71-260bfdd14aff",
      "name": "Azure OpenAI Chat Model3",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        -624,
        1712
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "02436b7c-4c02-4eb3-965e-f5819b4b3b5d",
  "connections": {
    "AI Agent": {
      "main": [
        [
          {
            "node": "Code in JavaScript2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript2": {
      "main": [
        [
          {
            "node": "Append or update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript3": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Every 15 Minutes": {
      "main": [
        [
          {
            "node": "Search LinkedIn Posts via SerpAPI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets Trigger": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets Trigger1": {
      "main": [
        [
          {
            "node": "Code in JavaScript3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Intent Output": {
      "main": [
        [
          {
            "node": "Save Leads to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Reply Drafting Agent": {
      "main": [
        [
          {
            "node": "Format Reply for Sheet Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Intent Detection Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "AI Sentiment & Intent Detection Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model3": {
      "ai_languageModel": [
        [
          {
            "node": "AI Reply Drafting Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Trigger Every 15 Minutes": {
      "main": [
        [
          {
            "node": "Search LinkedIn Posts via SerpAPI1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Intent Detection Agent": {
      "main": [
        [
          {
            "node": "Parse AI Intent Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Flatten Comments into Rows": {
      "main": [
        [
          {
            "node": "AI Intent Detection Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Flatten Comments into Rows1": {
      "main": [
        [
          {
            "node": "AI Sentiment & Intent Detection Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Media Team Email Report": {
      "main": [
        [
          {
            "node": "Send Email Report to Media Team",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Reply for Sheet Update": {
      "main": [
        [
          {
            "node": "Write AI Reply Back to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Filter Search Results": {
      "main": [
        [
          {
            "node": "Fetch Post Comments via ConnectSafely",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Filter Search Results1": {
      "main": [
        [
          {
            "node": "Fetch Post Comments via ConnectSafely1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Sentiment & Score Output": {
      "main": [
        [
          {
            "node": "Save Comments & Sentiment to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Watch Sheet for Approved Replies": {
      "main": [
        [
          {
            "node": "Build Media Team Email Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Watch Sheet for New Comment Rows": {
      "main": [
        [
          {
            "node": "AI Reply Drafting Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search LinkedIn Posts via SerpAPI": {
      "main": [
        [
          {
            "node": "Parse & Filter Search Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search LinkedIn Posts via SerpAPI1": {
      "main": [
        [
          {
            "node": "Parse & Filter Search Results1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Sentiment & Intent Detection Agent": {
      "main": [
        [
          {
            "node": "Parse Sentiment & Score Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Post Comments via ConnectSafely": {
      "main": [
        [
          {
            "node": "Flatten Comments into Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Post Comments via ConnectSafely1": {
      "main": [
        [
          {
            "node": "Flatten Comments into Rows1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Automate LinkedIn comment monitoring and turn conversations into qualified sales opportunities using AI 🤖. This intelligent agent continuously scans LinkedIn posts mentioning your brand, analyzes every comment for buyer intent and sentiment, and drafts context-aware replies…

Source: https://n8n.io/workflows/13958/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Automate your entire real estate sales pipeline with an AI-powered deal-making agent that captures buyer leads, matches them with suitable properties, delivers property decks, and predicts deal closin

Agent, Lm Chat Azure Open Ai, Google Sheets Tool +4
AI & RAG

Automate daily founder intelligence from Hacker News without manual monitoring. This workflow scans Hacker News discussions (Show HN, launches, AI, startups, SaaS), filters out noise and non-discussio

N8N Nodes Serpapi, Agent, Lm Chat Azure Open Ai +3
AI & RAG

Automate patient pre-arrival intake, AI risk assessment, and real-time doctor alerts in one seamless healthcare workflow. ⏰📧 This automation sends scheduled intake reminders before appointments, analy

Google Calendar, Gmail, Google Sheets Trigger +4
AI & RAG

This workflow automates the creation, rendering, approval, and posting of TikTok-style POV (Point of View) videos to Instagram, with cross-posting to Facebook and YouTube. It eliminates manual video p

OpenAI Chat, Output Parser Item List, HTTP Request +10
AI & RAG

This workflow automates invoicing and payment follow-ups using Google Sheets, PDFShift, Groq (LLM), Gmail, and Telegram, sending initial invoices with PDF attachments, scheduling overdue reminders at

Google Sheets, Gmail, Telegram +6