AutomationFlowsAI & RAG › Board Linkedin Monitor - Weekly

Board Linkedin Monitor - Weekly

Board LinkedIn Monitor - Weekly. Uses httpRequest, airtable, anthropic, slack. Scheduled trigger; 15 nodes.

Cron / scheduled trigger★★★★☆ complexityAI-powered15 nodesHTTP RequestAirtableAnthropicSlack
AI & RAG Trigger: Cron / scheduled Nodes: 15 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Airtable → HTTP Request 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
{
  "name": "Board LinkedIn Monitor - Weekly",
  "nodes": [
    {
      "parameters": {
        "content": "## Weekly cron - LinkedIn roster monitor\n\nMon 8am ET cron: scrape posts via Apify, dedupe against Airtable, draft 3 candidate comments per fresh post in a named leader's voice, write to Airtable and ping Slack. Nothing posts automatically.\n\nLength calibrated for real LinkedIn comments: short = 10-25w (most common), medium = 30-60w (default), long = 70-120w (rare, only when the post invites depth).\n\nBefore first run: fill the Airtable base/table IDs, replace the sample roster, fill {{LEADER_VOICE_DESCRIPTION}} in the Claude node, and set ENABLED_TIERS in the roster node. ENABLED_TIERS ships empty so an imported copy spends nothing until you opt in.",
        "height": 384,
        "width": 272,
        "color": 4
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000001",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -224,
        176
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 0 12 * * 1"
            }
          ]
        }
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000002",
      "name": "Weekly Monday 8am ET",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        240,
        400
      ]
    },
    {
      "parameters": {
        "jsCode": "// Sample roster. Replace with your own. `board_tier` is the grouping you\n// switch on below; `suggested_author` is whose voice the drafts get written in.\nconst roster = [\n  { name: 'Avery Lindqvist', company: 'Northwind Foods', linkedin_url: 'https://www.linkedin.com/in/example-avery-lindqvist' },\n  { name: 'Priya Raghunathan', company: 'Talia Retail Group', linkedin_url: 'https://www.linkedin.com/in/example-priya-raghunathan' },\n  { name: 'Marcus Oyelaran', company: 'Halden Financial', linkedin_url: 'https://www.linkedin.com/in/example-marcus-oyelaran' },\n  { name: 'Sofia Marchetti', company: 'Corvid Media', linkedin_url: 'https://www.linkedin.com/in/example-sofia-marchetti' },\n  { name: 'Devon Ashcroft', company: 'Blue Meridian Airlines', linkedin_url: 'https://www.linkedin.com/in/example-devon-ashcroft' },\n  { name: 'Ingrid Solheim', company: 'Vantage Health', linkedin_url: 'https://www.linkedin.com/in/example-ingrid-solheim' },\n  { name: 'Rafael Duarte', company: 'Certa Mobility', linkedin_url: 'https://www.linkedin.com/in/example-rafael-duarte' },\n  { name: 'Hana Kobayashi', company: 'Lumen Home', linkedin_url: 'https://www.linkedin.com/in/example-hana-kobayashi' },\n  { name: 'Theo Ballantyne', company: 'Ardent Sportswear', linkedin_url: 'https://www.linkedin.com/in/example-theo-ballantyne' },\n  { name: 'Nadia Osei', company: 'Peregrine Software', linkedin_url: 'https://www.linkedin.com/in/example-nadia-osei' }\n];\n\n// Kill switch. An empty array means no member matches, so no Apify call runs\n// and the workflow costs nothing. Opt in deliberately.\n// Example, to launch with only the global tier: const ENABLED_TIERS = ['global'];\nconst ENABLED_TIERS = [];\n\nconst withSlugs = roster.map(function(m){\n  const url = (m.linkedin_url || '').replace(/\\/$/, '');\n  const slug = url.split('/in/')[1] || '';\n  return Object.assign({}, m, { board_tier: 'global', suggested_author: 'leader', linkedin_username: slug });\n});\n\nconst filtered = withSlugs.filter(function(m){ return ENABLED_TIERS.indexOf(m.board_tier) !== -1; });\nif (filtered.length === 0) {\n  console.log('[kill switch] ENABLED_TIERS is empty or no roster members match. No Apify calls will run.');\n  return [];\n}\nconsole.log('[roster] Scanning ' + filtered.length + ' members across tiers: ' + ENABLED_TIERS.join(','));\nreturn filtered.map(function(m){ return { json: m }; });\n"
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000003",
      "name": "Load Roster",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        400
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a",
              "name": "completed_at",
              "value": "={{ $now.toISO() }}",
              "type": "string"
            },
            {
              "id": "b",
              "name": "workflow",
              "value": "board-linkedin-weekly",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000004",
      "name": "Run Complete",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3360,
        608
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/acts/apimaestro~linkedin-profile-posts/run-sync-get-dataset-items",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ { \"username\": $json.linkedin_username, \"limit\": 10 } }}",
        "options": {
          "response": {
            "response": {
              "neverError": true,
              "responseFormat": "json"
            }
          },
          "timeout": 120000
        }
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000005",
      "name": "Apify - Fetch LinkedIn Posts",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        960,
        400
      ],
      "alwaysOutputData": true,
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "jsCode": "const member = $('Loop Over Members').item.json;\nconst now = Date.now();\nconst eightDaysMs = 8 * 24 * 3600 * 1000;\nconst items = $input.all();\nconst posts = [];\nfor (const item of items) {\n  const data = item.json;\n  let arr = [];\n  if (Array.isArray(data)) arr = data;\n  else if (Array.isArray(data && data.items)) arr = data.items;\n  else if (data && (data.urn || data.text)) arr = [data];\n  for (const p of arr) {\n    const ts = p.posted_at || p.postedAt || p.posted_at_timestamp || p.timestamp || p.date || '';\n    let postedMs = 0;\n    if (typeof ts === 'number') postedMs = ts > 1e12 ? ts : ts * 1000;\n    else if (typeof ts === 'string' && ts) postedMs = Date.parse(ts) || 0;\n    if (!postedMs || (now - postedMs) > eightDaysMs) continue;\n    const urn = p.urn || p.activityUrn || p.id || '';\n    if (!urn) continue;\n    posts.push({\n      post_id: urn,\n      post_url: p.permalink || p.postUrl || p.url || ('https://www.linkedin.com/feed/update/' + urn + '/'),\n      post_text: (p.text || p.commentary || p.content || '').slice(0, 8000),\n      post_date: new Date(postedMs).toISOString().slice(0, 10),\n      post_type: p.post_type || p.type || 'text',\n      board_member_name: member.name,\n      company: member.company,\n      board_tier: member.board_tier,\n      suggested_author: member.suggested_author\n    });\n  }\n}\nreturn posts.map(function(p){ return { json: p }; });"
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000006",
      "name": "Flatten + Filter Fresh",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        400
      ]
    },
    {
      "parameters": {
        "operation": "search",
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_AIRTABLE_BASE_ID"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_AIRTABLE_TABLE_ID"
        },
        "filterByFormula": "={{ \"{post_id} = '\" + $json.post_id + \"'\" }}",
        "returnAll": false,
        "limit": 1,
        "options": {}
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000007",
      "name": "Check If Post Exists",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.2,
      "position": [
        1440,
        400
      ],
      "alwaysOutputData": true,
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "combinator": "and",
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 1
          },
          "conditions": [
            {
              "leftValue": "={{ ($json.id || $json.fields) ? \"exists\" : \"new\" }}",
              "rightValue": "new",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ]
        },
        "options": {}
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000008",
      "name": "Is Post New?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1680,
        400
      ]
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "claude-opus-4-7"
        },
        "messages": {
          "values": [
            {
              "content": "={{ \"BOARD MEMBER: \" + $('Flatten + Filter Fresh').item.json.board_member_name + \" (\" + $('Flatten + Filter Fresh').item.json.company + \")\\nBOARD TIER: \" + $('Flatten + Filter Fresh').item.json.board_tier + \"\\nAUTHOR (commenting as): \" + $('Flatten + Filter Fresh').item.json.suggested_author + \"\\nPOST TYPE: \" + $('Flatten + Filter Fresh').item.json.post_type + \"\\n\\nPOST TEXT:\\n\" + $('Flatten + Filter Fresh').item.json.post_text + \"\\n\\nWrite 3 candidate LinkedIn comments. Output ONLY a JSON object with no preface, no code fence, exactly this shape: {\\\"drafts\\\":[{\\\"length\\\":\\\"short\\\",\\\"tone\\\":\\\"...\\\",\\\"text\\\":\\\"...\\\"},{\\\"length\\\":\\\"medium\\\",\\\"tone\\\":\\\"...\\\",\\\"text\\\":\\\"...\\\"},{\\\"length\\\":\\\"long\\\",\\\"tone\\\":\\\"...\\\",\\\"text\\\":\\\"...\\\"}],\\\"skip_recommended\\\":false,\\\"skip_reason\\\":null}\\n\\nLength budgets (LinkedIn comments are short \\u2014 bias toward the short end):\\n- short = 1 sentence, 10-25 words. A reaction, agreement with one specific add, or a single sharp question. This is the most common register.\\n- medium = 2-3 sentences, 30-60 words. The default. Recognize, then add one specific thought.\\n- long = 4-6 sentences, 70-120 words. Only when the post genuinely invites depth (a substantive POV worth engaging in detail). Most posts don\\u2019t need this length. If a long comment would feel forced, write it short instead and note that in tone.\\n\\nThe reviewer likely picks short or medium 80% of the time. Don\\u2019t pad to hit a length target.\" }}"
            }
          ]
        },
        "options": {
          "system": "Voice: {{LEADER_VOICE_DESCRIPTION}}\n\nWrite as the named individual, not as their organization's corporate account.\n\nOpen with the person, not a stat. Name them, then a verb of recognition or genuine curiosity. The first beat is human, not corporate.\n\nMake ONE specific concrete observation. State an opinion if you have one. Going against conventional wisdom is welcome when there's evidence behind it. Hedge nothing that doesn't need hedging.\n\nUse 'we' when speaking for the profession or the organization's work. Use 'I' for genuine personal observations only. Never both in the same comment.\n\nWhen citing the organization's own work, use real names only: {{ORGANIZATION_PROGRAM_NAMES}}. Don't invent acronyms. Don't drop a name unless it actually fits.\n\nAVOID: em dashes (use commas, periods, colons, parentheses); 'the challenge isn't X, it's Y' framing; 'excited to / thrilled to / honored to'; 'delve / unlock / unleash / leverage / landscape / crucial / pivotal / revolutionary / game-changing / cutting edge / empower'; the phrase 'not only X but also Y'; anything that smells AI-written or press-release-y; filler transitions ('that said', 'with that in mind').\n\nCadence: short declarative sentences. Bias short. End on one line, a closer or a question. Never both. Never sign off.\n\nLinkedIn comments are SHORT by nature. Most great comments are 1-3 sentences. The 'long' draft is the exception, not the goal. Only use it when the post genuinely invites a substantive response. Don't pad to fill a length budget.\n\nTone: {{LEADER_TONE_DESCRIPTION}}\n\nBias skip_recommended=true for: promotional 'thrilled to announce' posts, anniversaries and personal milestones, political content, congrats-on-new-job posts, and any low-signal content where a substantive comment would feel forced. Better to skip than to write a hollow draft.\n\nOutput strictly the JSON spec. No preface, no code fence, no markdown.",
          "maxTokens": 1000,
          "temperature": 0.7
        }
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000009",
      "name": "Draft 3 Comments (Claude)",
      "type": "@n8n/n8n-nodes-langchain.anthropic",
      "typeVersion": 1,
      "position": [
        1840,
        304
      ],
      "alwaysOutputData": true,
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "jsCode": "const post = $('Flatten + Filter Fresh').item.json;\nconst raw = $input.first().json;\nlet text = raw.text || raw.content || (raw.message && raw.message.content) || '';\nif (Array.isArray(text)) text = text.map(function(b){ return b.text || ''; }).join('');\ntext = String(text || '').trim();\nconst fence = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\nif (fence) text = fence[1].trim();\nlet parsed = { drafts: [], skip_recommended: true, skip_reason: 'parse_error' };\ntry { parsed = JSON.parse(text); } catch(e) { parsed.skip_reason = 'json_parse_error: ' + e.message; }\nconst drafts = parsed.drafts || [];\nconst find = function(len){ const m = drafts.find(function(d){ return (d.length||'').toLowerCase() === len; }); return m ? (m.text||'') : ''; };\nreturn [{ json: Object.assign({}, post, {\n  draft_1_short: find('short'),\n  draft_2_medium: find('medium'),\n  draft_3_long: find('long'),\n  status: parsed.skip_recommended ? '4-Skipped' : '1-Pending',\n  skip_reason: parsed.skip_recommended ? (parsed.skip_reason || '') : ''\n}) }];"
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000010",
      "name": "Parse Drafts JSON",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2160,
        288
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a",
              "name": "post_id",
              "value": "={{ $json.post_id }}",
              "type": "string"
            },
            {
              "id": "b",
              "name": "board_member_name",
              "value": "={{ $json.board_member_name }}",
              "type": "string"
            },
            {
              "id": "c",
              "name": "company",
              "value": "={{ $json.company }}",
              "type": "string"
            },
            {
              "id": "d",
              "name": "board_tier",
              "value": "={{ $json.board_tier }}",
              "type": "string"
            },
            {
              "id": "e",
              "name": "post_url",
              "value": "={{ $json.post_url }}",
              "type": "string"
            },
            {
              "id": "f",
              "name": "post_text",
              "value": "={{ $json.post_text }}",
              "type": "string"
            },
            {
              "id": "g",
              "name": "post_date",
              "value": "={{ $json.post_date }}",
              "type": "string"
            },
            {
              "id": "h",
              "name": "post_type",
              "value": "={{ $json.post_type }}",
              "type": "string"
            },
            {
              "id": "i",
              "name": "suggested_author",
              "value": "={{ $json.suggested_author }}",
              "type": "string"
            },
            {
              "id": "j",
              "name": "draft_1_short",
              "value": "={{ $json.draft_1_short }}",
              "type": "string"
            },
            {
              "id": "k",
              "name": "draft_2_medium",
              "value": "={{ $json.draft_2_medium }}",
              "type": "string"
            },
            {
              "id": "l",
              "name": "draft_3_long",
              "value": "={{ $json.draft_3_long }}",
              "type": "string"
            },
            {
              "id": "m",
              "name": "status",
              "value": "={{ $json.status }}",
              "type": "string"
            },
            {
              "id": "n",
              "name": "skip_reason",
              "value": "={{ $json.skip_reason }}",
              "type": "string"
            }
          ]
        },
        "options": {
          "ignoreConversionErrors": true
        }
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000011",
      "name": "Build Create Payload",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2400,
        288
      ]
    },
    {
      "parameters": {
        "operation": "create",
        "base": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_AIRTABLE_BASE_ID"
        },
        "table": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_AIRTABLE_TABLE_ID"
        },
        "columns": "{{ JSON.stringify({ mappingMode: \"autoMapInputData\", schema: [], attemptToConvertTypes: false, convertFieldsToString: false }) }}",
        "options": {
          "typecast": true
        }
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000012",
      "name": "Create Airtable Post",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.2,
      "position": [
        2640,
        288
      ],
      "alwaysOutputData": true,
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "combinator": "and",
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "leftValue": "={{ $('Parse Drafts JSON').item.json.status }}",
              "rightValue": "1-Pending",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ]
        },
        "options": {}
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000013",
      "name": "Is Pending (not skipped)?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        2880,
        288
      ]
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_SLACK_CHANNEL_ID"
        },
        "text": "={{ \":newspaper: New post from \" + $('Parse Drafts JSON').item.json.board_member_name + \" (\" + $('Parse Drafts JSON').item.json.company + \")\\n*Tier:* \" + $('Parse Drafts JSON').item.json.board_tier + \"  |  *Suggested author:* \" + $('Parse Drafts JSON').item.json.suggested_author + \"\\n*Post:* \" + ($('Parse Drafts JSON').item.json.post_text || '').slice(0, 200) + \"...\\n<\" + $('Parse Drafts JSON').item.json.post_url + \"|View on LinkedIn>\\n3 drafts ready for review.\" }}",
        "otherOptions": {}
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000014",
      "name": "Slack Notify",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        3120,
        208
      ],
      "alwaysOutputData": true,
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "aaaaaaaa-0000-4000-8000-000000000015",
      "name": "Loop Over Members",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        720,
        400
      ]
    }
  ],
  "connections": {
    "Weekly Monday 8am ET": {
      "main": [
        [
          {
            "node": "Load Roster",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Roster": {
      "main": [
        [
          {
            "node": "Loop Over Members",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Apify - Fetch LinkedIn Posts": {
      "main": [
        [
          {
            "node": "Flatten + Filter Fresh",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Flatten + Filter Fresh": {
      "main": [
        [
          {
            "node": "Check If Post Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Post Exists": {
      "main": [
        [
          {
            "node": "Is Post New?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Post New?": {
      "main": [
        [
          {
            "node": "Draft 3 Comments (Claude)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Members",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Draft 3 Comments (Claude)": {
      "main": [
        [
          {
            "node": "Parse Drafts JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Drafts JSON": {
      "main": [
        [
          {
            "node": "Build Create Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Create Payload": {
      "main": [
        [
          {
            "node": "Create Airtable Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Airtable Post": {
      "main": [
        [
          {
            "node": "Is Pending (not skipped)?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Pending (not skipped)?": {
      "main": [
        [
          {
            "node": "Slack Notify",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Members",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack Notify": {
      "main": [
        [
          {
            "node": "Loop Over Members",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Members": {
      "main": [
        [
          {
            "node": "Run Complete",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Apify - Fetch LinkedIn Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}

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

Board LinkedIn Monitor - Weekly. Uses httpRequest, airtable, anthropic, slack. Scheduled trigger; 15 nodes.

Source: https://github.com/alectivism/n8n-workflows/blob/main/board-linkedin-monitor/workflow.json — 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

Complaints arrive via Gmail or a web form webhook Claude AI classifies each complaint: fault category, priority (P1/P2/P3), tenant tone, and drafts an acknowledgement email The right technician is loo

Anthropic, Airtable, Gmail +2
AI & RAG

This workflow runs hourly to monitor n8n-related security information from GitHub Advisories, NVD (NIST) CVE data, GitHub n8n security release notes, and JPCERT/JVN RSS feeds, then summarizes new find

HTTP Request, XML, Slack +1
AI & RAG

This workflow automatically fetches product reviews from your WooCommerce store, analyzes the sentiment of each review using AI, stores the results in Airtable and sends a summary of positive, neutral

HTTP Request, OpenAI, Airtable +1
AI & RAG

Time Tracker - 15min Ping (Template). Uses slack, openAi, airtable, httpRequest. Scheduled trigger; 17 nodes.

Slack, OpenAI, Airtable +1
AI & RAG

Database-Reactivation. Uses httpRequest, anthropic, highLevel, slack. Scheduled trigger; 16 nodes.

HTTP Request, Anthropic, High Level +1