AutomationFlowsAI & RAG › Create Daily AI News Briefings From Google Sheets with Claude, Notion, and Slack

Create Daily AI News Briefings From Google Sheets with Claude, Notion, and Slack

ByAkshay Chug @akshaychug on n8n.io

This scheduled workflow pulls article URLs from Google Sheets, scrapes each page, uses Anthropic Claude to generate a structured news briefing, saves results to Notion, posts a compiled digest to Slack, and appends a processing log back to Google Sheets. Runs on a weekday…

Cron / scheduled trigger★★★★☆ complexityAI-powered18 nodesGoogle SheetsHTTP RequestChain LlmAnthropic ChatNotionSlack
AI & RAG Trigger: Cron / scheduled Nodes: 18 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Chainllm → Google Sheets 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": "ILoEiELklK8FtIKu",
  "name": "AI Web Scraper News Briefing Agent using Claude and Notion",
  "tags": [],
  "nodes": [
    {
      "id": "7d48c54f-2789-45d2-b37e-ffaafbc9fb13",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -752,
        80
      ],
      "parameters": {
        "color": 0,
        "width": 500,
        "height": 796,
        "content": "## AI Web Scraper News Briefing Agent using Claude and Notion\n\nThis workflow scrapes article URLs from Google Sheets every day, uses Claude to write a structured briefing for each article, saves each briefing to Notion, sends a Slack digest, and logs all results to a Google Sheets log.\n\n## How it works\n\n1. Schedule Trigger fires daily at your chosen time\n2. Configure Settings node defines all keys, IDs, and prompts in one place\n3. Google Sheets reads the list of article URLs to process\n4. HTTP Request fetches the raw text of each article URL\n5. Claude AI chain reads the content and writes a structured briefing: headline, summary, why it matters, and a relevance score\n6. Notion creates a new briefing page for each article\n7. Slack posts a daily digest of all briefings to your channel\n8. Google Sheets log appends every briefing for record keeping\n\n## Setup steps\n\n- [ ] **Google Sheets URL list** \u2014 Create a sheet with a column named url and paste article URLs one per row\n- [ ] **Anthropic credential** \u2014 Add your Anthropic API key in n8n credentials as an Anthropic Account\n- [ ] **Notion integration** \u2014 Add your Notion token and replace YOUR_NOTION_DATABASE_ID in the Configure Settings node\n- [ ] **Slack credential** \u2014 Add your Slack credentials and replace YOUR_SLACK_CHANNEL with your target channel\n- [ ] **Sheet IDs** \u2014 Replace YOUR_GOOGLE_SHEET_ID and YOUR_LOG_SHEET_ID in Configure Settings\n- [ ] **Schedule** \u2014 Open the Schedule Trigger and set your preferred time\n\n### Customization\n\nAdd more source URLs to the Google Sheets list at any time. Adjust the Claude prompt in Configure Settings to change the briefing format or focus area."
      },
      "typeVersion": 1
    },
    {
      "id": "9c5fe344-6021-41ae-b3a2-06bf476d2ad4",
      "name": "Section: Trigger and Config",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 420,
        "height": 508,
        "content": "## Trigger and config\n\nThe workflow starts on a daily schedule and reads all user-editable settings from the Configure Settings node. Edit only this node to change API keys, IDs, channels, and prompts."
      },
      "typeVersion": 1
    },
    {
      "id": "07ad6b22-e3c1-41e9-aab6-0645ef210b31",
      "name": "Section: Scrape and Analyse",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 1352,
        "height": 700,
        "content": "## Scrape and analyse\n\nReads article URLs from Google Sheets, fetches the page content of each URL, then passes each article to Claude to generate a structured briefing with headline, summary, relevance score, and key insight."
      },
      "typeVersion": 1
    },
    {
      "id": "770e78fe-be57-4341-92b8-e76db118d032",
      "name": "Section: Store and Notify",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1776,
        -32
      ],
      "parameters": {
        "color": 7,
        "width": 1012,
        "height": 716,
        "content": "## Store and notify\n\nSaves each Claude briefing as a new Notion page in your briefings database, then sends a Slack digest of all articles and logs every record to Google Sheets for long-term storage."
      },
      "typeVersion": 1
    },
    {
      "id": "6b6edad2-7680-4b3e-8bf6-99ecb8e079e9",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -80,
        288
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 7 * * 1-5"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "26384f26-76bc-404e-b9eb-50d3e6172665",
      "name": "Configure Settings",
      "type": "n8n-nodes-base.code",
      "position": [
        144,
        288
      ],
      "parameters": {
        "jsCode": "const config = {\n  googleSheetId: 'YOUR_GOOGLE_SHEET_ID',\n  googleSheetName: 'urls',\n  logSheetId: 'YOUR_LOG_SHEET_ID',\n  logSheetName: 'log',\n  notionDatabaseId: 'YOUR_NOTION_DATABASE_ID',\n  slackChannel: 'YOUR_SLACK_CHANNEL',\n  maxArticles: 10,\n  briefingPrompt: 'You are a professional news analyst. Read the article text provided and write a structured briefing. Return only a JSON object with these exact keys: headline (string, max 12 words), summary (string, 2 sentences), why_it_matters (string, 1 sentence), relevance_score (integer 1-10). Do not include any text outside the JSON object.',\n  digestIntro: 'Daily AI news briefing is ready. Here are the top stories for today.'\n};\n\nreturn [{ json: config }];"
      },
      "typeVersion": 2
    },
    {
      "id": "ffcf3ca6-7318-4fed-a7a6-9513817325d1",
      "name": "Read URL List from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        384,
        288
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.googleSheetName }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.googleSheetId }}"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "99f4b456-2b23-4baf-99c8-7d111b6c543f",
      "name": "Limit to Max Articles",
      "type": "n8n-nodes-base.limit",
      "position": [
        608,
        288
      ],
      "parameters": {
        "maxItems": 10
      },
      "typeVersion": 1
    },
    {
      "id": "35c056a4-fc69-4d52-afed-2d4923a4b0a9",
      "name": "Fetch Article Content",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        816,
        288
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "timeout": 15000,
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d7637555-b160-48e6-934b-08e37d95572c",
      "name": "Prepare Article Text",
      "type": "n8n-nodes-base.code",
      "position": [
        1040,
        288
      ],
      "parameters": {
        "jsCode": "const rawHtml = $input.item.json.data || '';\nconst url = $input.item.json.url || $('Read URL List from Sheets').item.json.url || '';\n\n// Strip HTML tags without regex lookbehind\nconst noScript = rawHtml.split('<script').map(function(p, i) { return i === 0 ? p : p.split('</script>').slice(1).join('</script>'); }).join('');\nconst noStyle = noScript.split('<style').map(function(p, i) { return i === 0 ? p : p.split('</style>').slice(1).join('</style>'); }).join('');\nconst noTags = noStyle.replace(/<[^>]+>/g, ' ');\nconst decoded = noTags.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '\"').replace(/&#39;/g, \"'\").replace(/&nbsp;/g, ' ');\nconst clean = decoded.replace(/\\s+/g, ' ').trim();\nconst truncated = clean.length > 4000 ? clean.slice(0, 4000) + '...' : clean;\n\nreturn [{\n  json: {\n    url: url,\n    articleText: truncated,\n    charCount: truncated.length\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "48d1fe53-cfb4-47ea-b19c-664c20b79778",
      "name": "Claude AI Chain",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1200,
        288
      ],
      "parameters": {
        "text": "={{ 'You are a professional news analyst. Read the article text below and write a structured briefing. Return ONLY a valid JSON object with these exact keys: headline (string, max 12 words), summary (string, 2 sentences), why_it_matters (string, 1 sentence), relevance_score (integer 1-10). Do not add any text outside the JSON object.\\n\\nARTICLE TEXT:\\n' + $json.articleText }}",
        "promptType": "define"
      },
      "typeVersion": 1.4
    },
    {
      "id": "6043bf3a-6f6d-4194-b29b-08abba5149ad",
      "name": "Claude Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        1232,
        496
      ],
      "parameters": {
        "model": "claude-sonnet-4-6",
        "options": {
          "temperature": 0.3
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ed4c8236-7f7e-4c66-ade1-2d3d0a930236",
      "name": "Parse Claude Briefing",
      "type": "n8n-nodes-base.code",
      "position": [
        1504,
        272
      ],
      "parameters": {
        "jsCode": "const raw = $input.item.json.text || '';\nconst url = $('Prepare Article Text').item.json.url || '';\n\nlet briefing = { headline: 'No headline', summary: '', why_it_matters: '', relevance_score: 5 };\n\ntry {\n  const startBrace = raw.indexOf('{');\n  const endBrace = raw.lastIndexOf('}');\n  if (startBrace !== -1 && endBrace !== -1) {\n    const jsonStr = raw.slice(startBrace, endBrace + 1);\n    briefing = JSON.parse(jsonStr);\n  }\n} catch (e) {\n  briefing.summary = 'Could not parse Claude response';\n}\n\nreturn [{\n  json: {\n    url: url,\n    headline: briefing.headline || 'No headline',\n    summary: briefing.summary || '',\n    why_it_matters: briefing.why_it_matters || '',\n    relevance_score: briefing.relevance_score || 5,\n    processedAt: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "95d7bf29-2144-4e70-b9f6-d4638a897c75",
      "name": "Save to Notion",
      "type": "n8n-nodes-base.notion",
      "position": [
        1936,
        240
      ],
      "parameters": {
        "title": "={{ $json.headline }}",
        "pageId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        },
        "options": {}
      },
      "typeVersion": 2.2
    },
    {
      "id": "5f6a3984-5929-4fbf-a4f4-bb8757694852",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2160,
        240
      ],
      "parameters": {
        "columns": {
          "value": {},
          "mappingMode": "autoMapInputData"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_LOG_SHEET_ID"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e4f7c8eb-6b10-4ad1-a705-ef0eaf8da009",
      "name": "Aggregate Briefings",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        2160,
        432
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "bd03a76a-b7c9-4515-9c00-28ef5dcdeb68",
      "name": "Build Slack Digest",
      "type": "n8n-nodes-base.code",
      "position": [
        2384,
        432
      ],
      "parameters": {
        "jsCode": "const items = $input.item.json.data || [];\nconst today = new Date().toDateString();\n\nconst lines = items.map(function(item, i) {\n  const rank = i + 1;\n  const score = item.relevance_score || '?';\n  const hl = item.headline || 'No headline';\n  const summ = item.summary || '';\n  const url = item.url || '';\n  return rank + '. [Score: ' + score + '/10] ' + hl + ' -- ' + summ + ' Source: ' + url;\n});\n\nconst message = 'Daily AI News Briefing | ' + today + '\\n' + lines.join('\\n\\n');\n\nreturn [{ json: { message: message, count: items.length } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "d83466de-00e9-4a9d-bbea-bae4127b824f",
      "name": "Send Slack Digest",
      "type": "n8n-nodes-base.slack",
      "position": [
        2608,
        432
      ],
      "parameters": {
        "text": "={{ $json.message }}",
        "otherOptions": {}
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "f28cd6a1-6f53-4d32-911f-3bc05821fd44",
  "connections": {
    "Claude Model": {
      "ai_languageModel": [
        [
          {
            "node": "Claude AI Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Save to Notion": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude AI Chain": {
      "main": [
        [
          {
            "node": "Parse Claude Briefing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Configure Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Slack Digest": {
      "main": [
        [
          {
            "node": "Send Slack Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure Settings": {
      "main": [
        [
          {
            "node": "Read URL List from Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Briefings": {
      "main": [
        [
          {
            "node": "Build Slack Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Article Text": {
      "main": [
        [
          {
            "node": "Claude AI Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Article Content": {
      "main": [
        [
          {
            "node": "Prepare Article Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit to Max Articles": {
      "main": [
        [
          {
            "node": "Fetch Article Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Claude Briefing": {
      "main": [
        [
          {
            "node": "Save to Notion",
            "type": "main",
            "index": 0
          },
          {
            "node": "Aggregate Briefings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read URL List from Sheets": {
      "main": [
        [
          {
            "node": "Limit to Max Articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This scheduled workflow pulls article URLs from Google Sheets, scrapes each page, uses Anthropic Claude to generate a structured news briefing, saves results to Notion, posts a compiled digest to Slack, and appends a processing log back to Google Sheets. Runs on a weekday…

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

SaaS product managers, startup founders, and marketing teams who need to stay informed about competitor movements without manual monitoring. Perfect for teams who want to automate competitive intellig

HTTP Request, Chain Llm, Anthropic Chat +3
AI & RAG

This workflow automates Invoice & Payment Tracking (with Approvals) across Notion and Slack. Ingest — You drop invoices/receipts (PDF/IMG/JSON) into the flow. Extract — OCR + parsing pulls out key fie

HTTP Request, Chain Llm, Anthropic Chat +5
AI & RAG

This n8n workflow orchestrates a powerful suite of AI Agents and automations to manage and optimize various aspects of an e-commerce operation, particularly for platforms like Shopify. It leverages La

Google Sheets, HTTP Request, Slack +10
AI & RAG

This workflow empowers app developers and community management teams by automating the generation and posting of responses to user reviews on the Apple App Store. Designed to streamline the engagement

Jwt, HTTP Request, Slack +5
AI & RAG

The Recap AI - Short Form News Script Generator. Uses httpRequest, s3, chainLlm, slack. Scheduled trigger; 42 nodes.

HTTP Request, S3, Chain Llm +3