{
  "name": "RSS to AI Slack Digest",
  "nodes": [
    {
      "parameters": {
        "content": "## RSS to AI-Summarized Slack Digest\n\nReplace 30 minutes of morning news-skimming with an AI-written digest of your industry feeds, delivered to Slack before you sit down.\n\n**Setup time:** 15 minutes  ·  **Level:** Intermediate\n\n**You'll need accounts/credentials for:** Schedule, RSS, OpenAI, Slack\n\n**Replace these before running:**\n- `REPLACE_WITH_CHANNEL`\n\n**Setup steps:**\n1. Open the RSS Read node and set your feed URL (any RSS/Atom feed works).\n2. Add your OpenAI API credential to the AI node - or swap it for the Anthropic/Google node.\n3. Connect Slack and pick your channel in the Slack node.\n4. Adjust the schedule time to your morning, then activate.\n5. Run it once manually to see your first digest.\n\nFree templates and updates: navkhan103.github.io",
        "height": 618,
        "width": 400,
        "color": 4
      },
      "id": "sticky-setup",
      "name": "Setup — read me first",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -440,
        -40
      ]
    },
    {
      "parameters": {
        "content": "### How it runs\n\nStarts from **Weekday Mornings**.\n\n1. A Schedule Trigger fires every weekday morning at 7:30.\n2. An RSS Read node pulls the latest items from your chosen feed.\n3. A Code node keeps only items published in the last 24 hours and trims them to title + snippet.\n4. An AI node (OpenAI, or swap for Claude/Gemini) writes a short digest: top 5 stories, one line each, with links.\n5. A Slack node posts the digest to your channel.",
        "height": 374,
        "width": 400,
        "color": 7
      },
      "id": "sticky-how",
      "name": "How it runs",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -440,
        618
      ]
    },
    {
      "parameters": {
        "content": "### If something breaks\n\nThe read and AI nodes here **retry 3× automatically** (5s apart), which absorbs rate limits and brief timeouts.\n\nNodes that **send or write deliberately do not retry** — a send that reached the far end but lost its response would otherwise fire twice, so you'd get duplicate messages or duplicate rows.\n\nTo be told when one of those fails, build a workflow starting with an **Error Trigger** node that posts to Slack or email, then set it under **three-dot menu > Settings > Error Workflow**. Do it once and point every workflow at it.",
        "height": 400,
        "width": 400,
        "color": 3
      },
      "id": "sticky-fail",
      "name": "If something breaks",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -440,
        1032
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "30 7 * * 1-5"
            }
          ]
        }
      },
      "id": "c3d4e5f6-0001-4000-8000-000000000001",
      "name": "Weekday Mornings",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "url": "https://hnrss.org/frontpage"
      },
      "id": "c3d4e5f6-0002-4000-8000-000000000002",
      "name": "Read RSS Feed",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.1,
      "position": [
        220,
        0
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "jsCode": "const cutoff = Date.now() - 24*60*60*1000;\nconst items = $input.all()\n  .map(i => i.json)\n  .filter(j => new Date(j.pubDate || j.isoDate || 0).getTime() > cutoff)\n  .slice(0, 15)\n  .map(j => ({ title: j.title, link: j.link, snippet: (j.contentSnippet || '').slice(0, 200) }));\nreturn [{ json: { stories: items } }];"
      },
      "id": "c3d4e5f6-0003-4000-8000-000000000003",
      "name": "Filter Last 24h",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        440,
        0
      ]
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.6-luna"
        },
        "messages": {
          "values": [
            {
              "content": "=You are a sharp industry analyst. From the following stories, pick the 5 most important and write a Slack digest: one bold headline line each with the link, plus a one-sentence why-it-matters. Keep the whole digest under 150 words.\n\n{{ JSON.stringify($json.stories) }}",
              "role": "user"
            }
          ]
        }
      },
      "id": "c3d4e5f6-0004-4000-8000-000000000004",
      "name": "AI Digest",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        660,
        0
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_WITH_CHANNEL"
        },
        "text": "={{ $json.message.content }}",
        "otherOptions": {}
      },
      "id": "c3d4e5f6-0005-4000-8000-000000000005",
      "name": "Post to Slack",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        880,
        0
      ]
    }
  ],
  "connections": {
    "Weekday Mornings": {
      "main": [
        [
          {
            "node": "Read RSS Feed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read RSS Feed": {
      "main": [
        [
          {
            "node": "Filter Last 24h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Last 24h": {
      "main": [
        [
          {
            "node": "AI Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Digest": {
      "main": [
        [
          {
            "node": "Post to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}