AutomationFlowsAI & RAG › Generate End-to-end Blog Content From Slack with Gemini AI and RSS Feeds

Generate End-to-end Blog Content From Slack with Gemini AI and RSS Feeds

ByNijan @nijan on n8n.io

This workflow turns Slack into your content control hub and automates the full blog creation pipeline — from sourcing trending headlines, validating topics, drafting posts, and preparing content for your CMS.

Event trigger★★★★☆ complexityAI-powered15 nodesRSS Feed ReadSlack TriggerGoogle GeminiSlack
AI & RAG Trigger: Event Nodes: 15 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #7974 — we link there as the canonical source.

This workflow follows the Slack → Slack Trigger 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": "sbb4vrO0WsNieVjJ",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "My workflow",
  "tags": [],
  "nodes": [
    {
      "id": "7506a331-0426-43ca-86ee-c912e10312c7",
      "name": "RSS Read",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        384,
        176
      ],
      "parameters": {
        "url": "https://skift.com/feed/",
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "f15bc30b-b95c-4a15-8a1d-b249b15713de",
      "name": "RSS Read1",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        368,
        -16
      ],
      "parameters": {
        "url": "https://news.google.com/rss/search?q=hotel+technology+OR+hospitality+tech+when:7d&hl=en-US&gl=US&ceid=US:en",
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "02bacaaa-a811-4362-9618-85e5818a7fc7",
      "name": "RSS Read2",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        368,
        -240
      ],
      "parameters": {
        "url": "https://news.google.com/rss/search?q=YOUR_AWS_SECRET_KEY_HERE+when:7d&hl=en-US&gl=US&ceid=US:en",
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "c2385ad6-4fac-4643-9d41-28ae2f5d4730",
      "name": "Slack: Incoming messages",
      "type": "n8n-nodes-base.slackTrigger",
      "position": [
        -400,
        -16
      ],
      "parameters": {
        "options": {},
        "trigger": [
          "message"
        ],
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "C09C3Q4QCF3"
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ff12ac88-4c97-4503-b6b3-c5f76ca10962",
      "name": "Code: parse_slack_command",
      "type": "n8n-nodes-base.code",
      "position": [
        -128,
        -16
      ],
      "parameters": {
        "jsCode": "// --- Slack Event Normalizer ---\n// Works with Slack Trigger (test) or Production webhook body\n\nconst ev =\n  $json.event ??\n  $json.body?.event ??   // prod webhook\n  $json;                 // fallback (test)\n\nif (!ev) {\n  console.log('No Slack event in payload:', $json);\n  return [];\n}\n\n// Ignore bot/system messages and edits\nif (ev.bot_id || ev.subtype === 'bot_message' || ev.subtype === 'message_changed') {\n  return [];\n}\n\n// Strip a leading @mention like \"<@U123...> \"\nlet text = (ev.text || '').replace(/^<@[^>]+>\\s*/g, '').trim();\nconst lower = text.toLowerCase();\n\nlet cmd = null, pick = null, notes = null;\n\n// start/stop/done/revise\nif (lower === 'start') {\n  cmd = 'start';\n} else if (lower === 'stop') {\n  cmd = 'stop';\n} else if (lower === 'done') {\n  cmd = 'done';\n} else if (/^revise\\[(.*)\\]$/i.test(text)) {\n  cmd = 'revise';\n  notes = text.match(/^revise\\[(.*)\\]$/i)[1].trim();\n}\n\n// gen (supports \"2\" or \"gen 2\")\nconst m = lower.match(/^gen\\s*(\\d+)$/i);\nif (!cmd && m) {\n  cmd = 'gen';\n  pick = parseInt(m[1], 10);\n} else if (!cmd && /^\\d+$/.test(lower)) {\n  cmd = 'gen';\n  pick = parseInt(lower, 10);\n}\n\nreturn [{\n  json: {\n    cmd,\n    pick,\n    notes,\n    channel: ev.channel || $json.channel,\n    ts: ev.ts || $json.ts,\n    thread_ts: ev.thread_ts || ev.ts || $json.thread_ts || $json.ts,\n    user: ev.user || $json.user,\n    text,\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "c10ea145-13b8-4f8f-bc68-301dbbb3353e",
      "name": "Switch: route_by_command",
      "type": "n8n-nodes-base.switch",
      "position": [
        80,
        -32
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "92dd4e01-59ac-4266-985c-34b05f044bd6",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.cmd}}",
                    "rightValue": "start"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fa91281f-0b2f-4ac3-99b5-c35fa856ee96",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.cmd}}",
                    "rightValue": "gen"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "1814a166-2e90-45cf-8fbd-acaadfc0a1fd",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.cmd}}",
                    "rightValue": "revise"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "f004378f-f978-45dd-b507-337132ec4aaf",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.cmd}}",
                    "rightValue": "done"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "348766c0-42ad-4f96-888b-8ef20bd2261b",
      "name": "Merge: all_feeds",
      "type": "n8n-nodes-base.merge",
      "position": [
        656,
        0
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "a516595a-76ae-45b9-b654-7e547a31af61",
      "name": "Code: make_headline_payload",
      "type": "n8n-nodes-base.code",
      "position": [
        864,
        0
      ],
      "parameters": {
        "jsCode": "/**\n * Code1 \u2014 after Merge (Append)\n * Build clean, deduped article list and a compact text block for Gemini.\n */\n\n// ====== configuration ======\nconst MAX_HEADLINES = 60;   // <= how many headlines to pass to Gemini (try 50\u201380)\n\n// ====== helpers ======\nfunction stripHtml(html = '') {\n  // Remove tags\n  const noTags = String(html).replace(/<[^>]*>/g, ' ');\n  // Collapse whitespace\n  return noTags.replace(/\\s+/g, ' ').trim();\n}\n\nfunction truncate(str = '', n = 140) {\n  const s = String(str).trim();\n  return s.length > n ? s.slice(0, n) + '\u2026' : s;\n}\n\nfunction pickFirst(obj, keys) {\n  for (const k of keys) {\n    if (obj?.[k]) return obj[k];\n  }\n  return undefined;\n}\n\n// ====== collect & normalize ======\nconst items = $input.all();              // all merged items\nconst seen = new Set();                  // dedupe by *normalized title*\nconst articles = [];\n\nfor (const item of items) {\n  const j = item.json || {};\n\n  // Try common RSS/Atom/HTTP node fields\n  const rawTitle = pickFirst(j, [\n    'title', 'headline', 'name'\n  ]);\n\n  // If no title, skip (we need a key to dedupe and display)\n  if (!rawTitle) continue;\n\n  // For descriptions, try several fields and strip HTML\n  const rawDesc = pickFirst(j, [\n    'contentSnippet', 'description', 'summary', 'content', 'content:encoded'\n  ]);\n  const description = rawDesc ? stripHtml(rawDesc) : '';\n\n  // Links/guid\n  const link = pickFirst(j, [\n    'link', 'url', 'guid'\n  ]);\n\n  // Deduplicate by normalized title\n  const title = String(rawTitle).trim();\n  const key = title.toLowerCase();\n  if (seen.has(key)) continue;\n  seen.add(key);\n\n  articles.push({\n    title,\n    description,\n    link: link ? String(link).trim() : ''\n  });\n}\n\n// ====== choose how much to send to Gemini ======\nconst limited = articles.slice(0, MAX_HEADLINES);\n\n// Build compact arrays for Gemini + debugging\nconst headlines = limited.map(a => a.title);\n\n// If you want titles + a short blurb in the prompt, use this:\nconst articleText = limited\n  .map((a, i) => `${i + 1}. ${a.title}${a.description ? ` \u2014 ${truncate(a.description)}` : ''}`)\n  .join('\\n');\n\n// ====== output ======\nreturn [{\n  json: {\n    articles: limited,        // array of normalized items\n    headlines,                // array of titles only\n    articleText,              // numbered list for Gemini\n    articleCount: limited.length,\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "4d5de947-36b0-4d5b-9bdc-708ad24ab6aa",
      "name": "Gemini: cluster_to_topics",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        1168,
        0
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-1.5-flash",
          "cachedResultName": "models/gemini-1.5-flash"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are a hotel-industry editor.\n\nYou are given recent hospitality headlines & snippets:\n{{$json.articleText}}\n\nTask:\n- Select 10\u201330 of the most relevant, diverse themes.\n- For each theme, write a short, **paraphrased headline** in your own words (do NOT copy any headline verbatim).\n- Keep each headline concise and specific (\u2264 120 characters).\n- No emojis, no hashtags, no numbering, no quotes.\n\nReturn STRICT JSON ONLY, exactly in this shape:\n{\n  \"topics\": [\n    { \"topic\": \"Paraphrased headline 1\" },\n    { \"topic\": \"Paraphrased headline 2\" }\n  ]\n}"
            }
          ]
        },
        "jsonOutput": true
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e226a282-4ac1-4e7d-86c5-a2c69bd3736a",
      "name": "Code: parse_or_pass_topics",
      "type": "n8n-nodes-base.code",
      "position": [
        1568,
        0
      ],
      "parameters": {
        "jsCode": "// Code2 \u2014 normalize Gemini topics JSON for Slack\n\nconst raw =\n  $json.text ??\n  $json.content?.parts?.[0]?.text ??\n  '';\n\nlet out = { topics: [] };\n\ntry {\n  const cleaned = String(raw).replace(/```json|```/gi, '').trim();\n\n  // try full first, then last {...}\n  try {\n    out = JSON.parse(cleaned);\n  } catch {\n    const m = cleaned.match(/\\{[\\s\\S]*\\}$/);\n    if (m) out = JSON.parse(m[0]);\n  }\n} catch (e) {\n  console.log('Failed to parse Gemini output:', e, String(raw).slice(0, 300));\n  out = { topics: [] };\n}\n\n// --- normalize to [{topic: \"...\"}]\nlet topics = out?.topics ?? [];\nif (!Array.isArray(topics)) topics = [];\n\ntopics = topics\n  .map(t => {\n    if (typeof t === 'string') return { topic: t.trim() };\n    if (t && typeof t === 'object') {\n      return { topic: String(t.topic ?? t.headline ?? t.title ?? '').trim() };\n    }\n    return { topic: '' };\n  })\n  .filter(t => t.topic);\n\n// guardrail: de-dup & cap (optional)\nconst seen = new Set();\ntopics = topics.filter(t => {\n  const key = t.topic.toLowerCase();\n  if (seen.has(key)) return false;\n  seen.add(key);\n  return true;\n});\n\n// output to next nodes\nreturn [{\n  json: {\n    mode: 'topics',\n    topics\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "a84fa8a6-231d-443b-bbcd-72360a014980",
      "name": "Slack: post_topic_list",
      "type": "n8n-nodes-base.slack",
      "position": [
        2112,
        -96
      ],
      "parameters": {
        "text": "={{ (function () {\n  const t = $json.topics || [];\n  if (!Array.isArray(t) || !t.length) {\n    return 'No topics found. Try `start` again.';\n  }\n\n  // Show up to 30 items (or all)\n  const lines = t.map((x, i) => `${i + 1}) ${x.topic}`);\n  const body = lines.join('\\n');\n\n  return `Trending hotel topics (reply with a number, e.g. 2):\\n\\n${body}\\n\\nThen: \\`revise[ your notes ]\\` or \\`done\\`.\\nAutomated with this n8n workflow`;\n})() }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "C09C3Q4QCF3"
        },
        "otherOptions": {
          "thread_ts": {
            "replyValues": {
              "thread_ts": "={{$node[\"Code: parse_slack_command\"].json.thread_ts || $node[\"Code: parse_slack_command\"].json.ts}}"
            }
          }
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "56c5667f-18d7-401b-b300-cf7429eef2a3",
      "name": "Slack: fetch_thread_replies",
      "type": "n8n-nodes-base.slack",
      "position": [
        432,
        416
      ],
      "parameters": {
        "ts": "={{$node[\"Code: parse_slack_command\"].json.thread_ts || $node[\"Code: parse_slack_command\"].json.ts}}",
        "filters": {},
        "resource": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "C09C3Q4QCF3"
        },
        "operation": "replies"
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "36d792cc-bdc2-4de8-aa3e-fca5d7d9750a",
      "name": "Code: pick_topic_from_thread",
      "type": "n8n-nodes-base.code",
      "position": [
        1056,
        432
      ],
      "parameters": {
        "jsCode": "// post gen \u2014 map user number to the chosen headline from the thread\n\n// 1) get the user's pick from anywhere we can\nfunction num(x) {\n  const n = Number(x);\n  return Number.isFinite(n) ? n : undefined;\n}\n\nlet pick =\n  num($json.pick) ??\n  num($node[\"Code: parse_slack_command\"].json?.pick) ??                         // from your normalizer Code\n  num(($node[\"Code: parse_slack_command\"].json?.text || \"\").match(/\\d+/)?.[0]); // last resort\n\nif (!pick) {\n  return [{ json: { error: 'no_pick', msg: \"Reply with a number like 2 or 'gen 2'.\" } }];\n}\n\n// 2) normalize Slack replies shape to an array of message objects\n//    - Return All OFF: slack node gives { messages: [...] }\n//    - Return All ON:  slack node gives many items, one per message\nlet msgs = [];\nif (Array.isArray($json.messages)) {\n  msgs = $json.messages;\n} else if (Array.isArray($items().map(i => i.json))) {\n  // Return All ON case: collect all incoming items as messages\n  msgs = $items().map(i => i.json);\n}\n\n// 3) find the bot message that listed the topics\n//    Adapt the marker below to the exact first line you print in Slack\nconst LIST_MARKER = 'Trending hotel topics';\nlet listMsg = null;\n\n// try newest-first if provided by Slack, else do a defensive search\nfor (const m of msgs) {\n  if (typeof m.text === 'string' && m.text.includes(LIST_MARKER)) {\n    listMsg = m;\n    break;\n  }\n}\nif (!listMsg) {\n  for (let i = msgs.length - 1; i >= 0; i--) {\n    const m = msgs[i];\n    if (typeof m.text === 'string' && m.text.includes(LIST_MARKER)) {\n      listMsg = m;\n      break;\n    }\n  }\n}\nif (!listMsg) {\n  return [{ json: { error: 'no_list', msg: 'Could not find the topics list message in this thread.' } }];\n}\n\n// 4) parse numbered lines from the list message\n//    We accept both \"1) Title (12)\" and \"1) Title\" styles\nconst lines = (listMsg.text || '').split('\\n');\nconst topics = [];\nfor (const line of lines) {\n  // capture: number ) <headline> (optional (count))\n  const m = line.match(/^\\s*\\d+\\)\\s+(.+?)(?:\\s+\\(\\d+\\))?\\s*$/);\n  if (m) topics.push(m[1].trim());\n}\n\nif (!topics.length) {\n  return [{ json: { error: 'no_topics', msg: 'Could not parse any topics from the list message.' } }];\n}\n\n// clamp pick to available range\nconst idx = Math.max(1, Math.min(pick, topics.length)) - 1;\nconst topic = topics[idx];\n\n// 5) pass forward for Gemini post generation\nreturn [{\n  json: {\n    topic,\n    pick: idx + 1,\n    topicsCount: topics.length,\n    channel: $node[\"Code: parse_slack_command\"].json?.channel,\n    thread_ts: $node[\"Code: parse_slack_command\"].json?.thread_ts || $node[\"Code: parse_slack_command\"].json?.ts\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "bf46b6cb-b1a2-4c48-8095-0a0297b9dddb",
      "name": "Gemini: write_draft",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        1504,
        336
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-1.5-flash",
          "cachedResultName": "models/gemini-1.5-flash"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are a hotel-industry content writer.\nWrite a 250\u2013350 word LinkedIn-style post about:\n\n\u201c{{$json.topic}}\u201d\n\nUse insights from these recent headlines (signal, not quotes):\n{{$json.articleText || ''}}\n\nRequirements:\n- Start with a strong hook (1\u20132 sentences).\n- Include 3\u20135 concise bullets with specific, non-generic observations.\n- End with a one-sentence takeaway + a soft CTA.\n- Confident, analytical tone. No hashtags. No emojis.\n- Plain text only."
            }
          ]
        }
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "94761e71-40c5-4cfd-a127-3508489d331d",
      "name": "Slack: post_draft",
      "type": "n8n-nodes-base.slack",
      "position": [
        2112,
        160
      ],
      "parameters": {
        "text": "={{$json.text || $json.content?.parts?.[0]?.text || 'No content generated.'}}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "C09C3Q4QCF3"
        },
        "otherOptions": {
          "thread_ts": {
            "replyValues": {
              "thread_ts": "={{$node[\"Code: parse_slack_command\"].json.thread_ts || $node[\"Code: parse_slack_command\"].json.ts}}"
            }
          }
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "bb356e18-0314-47a2-bbf5-eb471741b079",
  "connections": {
    "RSS Read": {
      "main": [
        [
          {
            "node": "Merge: all_feeds",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "RSS Read1": {
      "main": [
        [
          {
            "node": "Merge: all_feeds",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "RSS Read2": {
      "main": [
        [
          {
            "node": "Merge: all_feeds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: all_feeds": {
      "main": [
        [
          {
            "node": "Code: make_headline_payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini: write_draft": {
      "main": [
        [
          {
            "node": "Slack: post_draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack: post_topic_list": {
      "main": [
        []
      ]
    },
    "Slack: Incoming messages": {
      "main": [
        [
          {
            "node": "Code: parse_slack_command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch: route_by_command": {
      "main": [
        [
          {
            "node": "RSS Read2",
            "type": "main",
            "index": 0
          },
          {
            "node": "RSS Read1",
            "type": "main",
            "index": 0
          },
          {
            "node": "RSS Read",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack: fetch_thread_replies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: parse_slack_command": {
      "main": [
        [
          {
            "node": "Switch: route_by_command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini: cluster_to_topics": {
      "main": [
        [
          {
            "node": "Code: parse_or_pass_topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: parse_or_pass_topics": {
      "main": [
        [
          {
            "node": "Slack: post_topic_list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: make_headline_payload": {
      "main": [
        [
          {
            "node": "Gemini: cluster_to_topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack: fetch_thread_replies": {
      "main": [
        [
          {
            "node": "Code: pick_topic_from_thread",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: pick_topic_from_thread": {
      "main": [
        [
          {
            "node": "Gemini: write_draft",
            "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

This workflow turns Slack into your content control hub and automates the full blog creation pipeline — from sourcing trending headlines, validating topics, drafting posts, and preparing content for your CMS.

Source: https://n8n.io/workflows/7974/ — 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

This workflow pulls commodity-related headlines from the CNBC RSS feed, filters and ranks the most relevant items, uses Google Gemini to generate an actionable commodity investment briefing, and posts

RSS Feed Read, Google Gemini, Slack
AI & RAG

This workflow helps you repurpose your YouTube videos across multiple social media platforms with zero manual effort. It’s designed for creators, businesses, and marketers who want to maximize reach w

HTTP Request, RSS Feed Read, Discord +4
AI & RAG

This workflow empowers marketing teams, agencies and solopreneurs to instantly generate on-brand, platform-optimized social media ads — without designers or complex setup. Running performance marketin

Form Trigger, HTTP Request, Slack +1
AI & RAG

Ride Booking App Monitoring. Uses slack, googleGemini, httpRequestTool, googleSheets. Event-driven trigger; 26 nodes.

Slack, Google Gemini, HTTP Request Tool +1
AI & RAG

This workflow pulls open Salesforce opportunities and their last-30-days activities, uses Google Gemini to predict escalation risk per deal, then flags high-risk opportunities in Salesforce and notifi

Salesforce, Slack, Google Gemini