AutomationFlowsAI & RAG › Send a Daily Media Briefing Email with Gpt-4.1-mini, Newsapi, Gmail and…

Send a Daily Media Briefing Email with Gpt-4.1-mini, Newsapi, Gmail and…

Original n8n title: Send a Daily Media Briefing Email with Gpt-4.1-mini, Newsapi, Gmail and Google Sheets

ByTimo @tizummo on n8n.io

This workflow creates a daily media briefing based on public news sources. It retrieves relevant articles, summarizes key coverage, evaluates sentiment, and compares the current media volume against historical data. If an unusual spike in coverage is detected, the agent

Cron / scheduled trigger★★★★☆ complexityAI-powered23 nodesAgentOpenAI ChatMemory Buffer WindowHTTP RequestGoogle SheetsHTTP Request ToolGmail
AI & RAG Trigger: Cron / scheduled Nodes: 23 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #13181 — 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": "BgcWKaScg3Sr3w5T9IJ2E",
  "name": "Media relations news briefing - Trends",
  "tags": [],
  "nodes": [
    {
      "id": "ddfd0955-d4e7-4c41-a3dd-40fe8cc0ede0",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        912,
        416
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition",
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "648120da-cf8c-48f4-86e3-8232975f1029",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        192
      ],
      "parameters": {
        "color": 5,
        "width": 784,
        "height": 560,
        "content": "Handling historic data"
      },
      "typeVersion": 1
    },
    {
      "id": "bddc9400-d036-41d3-938f-4922fb6d2a2c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1088,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 560,
        "content": "Setup"
      },
      "typeVersion": 1
    },
    {
      "id": "87d045d2-bb8f-4935-b322-d6594ebf4d5e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        192
      ],
      "parameters": {
        "color": 4,
        "width": 576,
        "height": 560,
        "content": "Analysis & deep-dive"
      },
      "typeVersion": 1
    },
    {
      "id": "79ec0cf5-4c62-480f-aab1-4afd6bcf9aed",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 560,
        "content": "Output"
      },
      "typeVersion": 1
    },
    {
      "id": "06fb6b77-b64d-4aff-926b-e793e1cbc504",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1120,
        432
      ],
      "parameters": {
        "text": "=You are a media relations analyst. Prepare a concise media briefing based on the latest coverage of: \"{{ $('Set user config').item.json.query }}\"\n\nYou will receive {{ $('Fetch news articles').item.json.totalResults }} articles in the end of this instruction. From this data, select the 10 most relevant and impactful for the topic above.\n\n**ANOMALY DETECTION:**\nIf you detect an anomaly based on historic volume seen here {{ $('Get historic values from Google Sheets').item.json.history }}, decide the most fitting keyword and use the \"Topic research\" tool where you use this URL (replace KEYWORD):\n\nhttps://newsapi.org/v2/everything?q=KEYWORD&from={{ $('Set timeframe to last 2 days').item.json.newDate }}&sortBy=relevancy&apiKey=719937591fcb4c5986426a3a9d9dac6b\n\nThen explain which keyword you researched and present your findings in the anomaly section. If you didn't research an anomaly, mention this briefly in a sentence.\n\nBut in the top 10 articles, only list the ones from the data in the end.\n\n**HTML OUTPUT FORMAT:**\n\nUse proper HTML formatting for email. Structure your response as follows:\n\n<h2 style=\"color: #003366; font-family: Arial, sans-serif; margin-bottom: 10px;\">\ud83d\udcf0 Personal Media Briefing \u2013 {{ $('Trigger daily').item.json['Readable date'] }}</h2>\n\n<div style=\"font-family: Arial, sans-serif; color: #333; line-height: 1.6;\">\n\n<h3 style=\"color: #0066cc; font-size: 16px; margin-top: 20px;\">Executive Overview</h3>\n<p style=\"margin: 10px 0;\">[1 short paragraph summarizing the overall trend or narrative]</p>\n\n<h3 style=\"color: #0066cc; font-size: 16px; margin-top: 20px;\">Top Articles</h3>\n\nFor each of the selected articles, format as:\n\n<div style=\"margin: 15px 0; padding: 10px; background-color: #f5f5f5; border-left: 4px solid #0066cc;\">\n  <p style=\"margin: 5px 0;\">\n    <a href=\"[ARTICLE_URL]\" style=\"color: #0066cc; text-decoration: none; font-weight: bold;\">[Article Headline]</a> [SENTIMENT_DOT]\n  </p>\n  <p style=\"margin: 5px 0; font-size: 14px; color: #666;\">[1-sentence summary]</p>\n</div>\n\n<hr style=\"border: none; border-top: 1px solid #ddd; margin: 20px 0;\">\n\n<h3 style=\"color: #0066cc; font-size: 16px;\">Coverage Insights</h3>\n<p style=\"margin: 10px 0;\">\n  <strong>Current Volume:</strong> {{ $json.coverageVolume }} articles<br>\n  <strong>Average Volume:</strong> {{ $json.averageCoverageVolume }} articles\n</p>\n\n[If anomaly detected, add:]\n\n<div style=\"margin: 15px 0; padding: 15px; background-color: #fff3cd; border-left: 4px solid #ffc107;\">\n  <h4 style=\"color: #856404; font-size: 15px; margin-top: 0;\">\u26a0\ufe0f Anomaly Detected</h4>\n  <p style=\"margin: 5px 0; color: #856404;\"><strong>Research Keyword:</strong> [KEYWORD]</p>\n  <p style=\"margin: 10px 0;\">[Explanation of anomaly and further research findings]</p>\n</div>\n\n</div>\n\n**SENTIMENT INDICATORS:**\n- \ud83d\udfe2 for Positive\n- \u26aa for Neutral\n- \ud83d\udd34 for Negative\n\n\n**CONSTRAINTS:**\n- Entire HTML output must stay below 2000 characters\n- Don't mention tools used\n- Keep wording tight, remove filler\n- Consolidate repetitive content\n- Ensure all links use proper <a href=\"...\"> tags\n- Use inline CSS (no external stylesheets)\n\n**DATA INPUT:**\n{{ $('Fetch news articles').item.json.articles }}",
        "options": {
          "maxIterations": 3
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "a67dcfb0-2416-4edc-b289-de9b0f4cd4ce",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        992,
        624
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {
          "maxRetries": 2
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6733b6e1-cd76-446f-ad96-15da84ad5447",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        1152,
        624
      ],
      "parameters": {
        "sessionKey": "={{ $('Trigger daily').item.json.timestamp }}",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "cfcdc9f8-4918-4235-9683-560ba8fa6381",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1088,
        -256
      ],
      "parameters": {
        "width": 662,
        "height": 416,
        "content": "# How this works\nThis workflow finds articles, summarizes them and sends the findings via email. Therefore, it saves roughly **1 hour** of article research & writing the summary, deep-diving a topic when necessary.\n\n## Configuration\nUse the **Set user config node** to input the topic, like a company name or keyword such as Sustainability. Make sure to also put in necessary credentials and your email to where the briefing should be sent to.\n\n**Put in your credentials:**\n1. Get Google Sheets data\n2. Save to Google Sheets\n3. OpenAI Chat Model (or connect another model)\n4. Send the email (Gmail) (or connect another email provider)"
      },
      "typeVersion": 1
    },
    {
      "id": "4fa3c66a-0847-4ae8-8486-7d08eaf05efc",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        192
      ],
      "parameters": {
        "color": 2,
        "width": 416,
        "height": 560,
        "content": "Fetch news article"
      },
      "typeVersion": 1
    },
    {
      "id": "f92b3f43-f8f9-4d27-8591-a79e893ada2d",
      "name": "Fetch news articles",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -336,
        400
      ],
      "parameters": {
        "url": "=https://newsapi.org/v2/everything?q={{ $json.query }}&from={{ $json.from }}&sortBy=relevancy&apiKey={{ $json.apiKey }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "c42414ee-0218-4058-b756-a5f04509f459",
      "name": "Set user config",
      "type": "n8n-nodes-base.set",
      "position": [
        -560,
        400
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"query\": \"QUERY_HERE\",\n  \"category\": \"\",\n  \"countries\": \"us,de\",\n  \"lookback_days\": 2,\n  apiKey\": \"NEWS_API_KEY_HERE\",\n  \"recipient_email\": \"RECIPIENT_EMAIL_HERE\",\n  \"table_URL\": GOOGLE_TABLE_URL_HERE,\n  \"from\": \"{{ $json.formattedDate }}\",\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "62ed3d26-9631-4f3f-a4c8-89d0b379322e",
      "name": "Format date",
      "type": "n8n-nodes-base.dateTime",
      "position": [
        -704,
        400
      ],
      "parameters": {
        "date": "={{ $json.newDate }}",
        "format": "yyyy-MM-dd",
        "options": {},
        "operation": "formatDate"
      },
      "typeVersion": 2
    },
    {
      "id": "cab2839d-6af2-46e8-8aa1-2690122f1ec4",
      "name": "Set timeframe to last 2 days",
      "type": "n8n-nodes-base.dateTime",
      "position": [
        -864,
        400
      ],
      "parameters": {
        "options": {},
        "duration": 2,
        "magnitude": "={{ $json.timestamp }}",
        "operation": "subtractFromDate"
      },
      "typeVersion": 2
    },
    {
      "id": "247fada4-7c40-4e93-9fdb-885be6cb60c2",
      "name": "Trigger daily",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1040,
        400
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "1a1c1257-f62b-46bc-b452-5a9e9ebca5de",
      "name": "Understand number of results",
      "type": "n8n-nodes-base.set",
      "position": [
        -144,
        400
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "19b5482a-ef3d-4558-bd75-c97dd75df351",
              "name": "date",
              "type": "string",
              "value": "={{ new Date().toISOString().slice(0,10) }}"
            },
            {
              "id": "caca8893-44ed-416a-b595-7c57b88fdb73",
              "name": "coverageVolume",
              "type": "string",
              "value": "={{ $json[\"articles\"] ? $json[\"articles\"].length : 0 }}"
            },
            {
              "id": "afedaf1f-8230-4354-ad4e-645f397af0e7",
              "name": "totalResults",
              "type": "string",
              "value": "={{ $json[\"totalResults\"] || $json[\"articles\"]?.length || 0 }}"
            },
            {
              "id": "7043f438-f99c-4130-b5f9-215ac271ec65",
              "name": "query",
              "type": "string",
              "value": "={{ $('Set user config').item.json.query }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "25e252bf-a800-42be-805d-4efbb4d8c876",
      "name": "Get historic values from Google Sheets",
      "type": "n8n-nodes-base.code",
      "position": [
        384,
        288
      ],
      "parameters": {
        "jsCode": "// items: one per row from Google Sheets\nconst history = items\n  .map(i => i.json)\n  .filter(r => r.date && r.coverageVolume)\n  .map(r => ({\n    date: r.date,\n    coverageVolume: Number(r.coverageVolume),\n    totalResults: Number(r.totalResults || r.coverageVolume),\n  }));\n\nreturn [\n  {\n    json: {\n      history,\n    },\n  },\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "05eebaa8-2133-47cf-be43-3a7e24d1b309",
      "name": "Get Google Sheets data",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        144,
        272
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.sheet_ID }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.table_URL }}"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8f605529-99f6-4c3e-9d54-7e08f59aaea0",
      "name": "Save to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        144,
        528
      ],
      "parameters": {
        "columns": {
          "value": {
            "date": "={{ $json.date }}",
            "totalResults": "={{ $json.totalResults }}",
            "coverageVolume": "={{ $json.coverageVolume }}"
          },
          "schema": [
            {
              "id": "date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "coverageVolume",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "coverageVolume",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "totalResults",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "totalResults",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "0"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.table_URL }}"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8c578dee-16f9-4734-8729-bc2d3012a807",
      "name": "Calculate average results",
      "type": "n8n-nodes-base.code",
      "position": [
        672,
        240
      ],
      "parameters": {
        "jsCode": "// Get the \"history\" array from the first item\nconst history = items[0].json.history;\n\n// Sum coverageVolume\nconst totalVolume = history.reduce((sum, entry) => sum + entry.coverageVolume, 0);\n\n// Calculate average\nconst averageVolume = totalVolume / history.length;\n\n// Return result as a single item\nreturn [\n  {\n    json: {\n      averageCoverageVolume: averageVolume\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "68c7b72c-648d-49c5-b1b2-ef1c13541c3c",
      "name": "Topic deep-dive",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        1296,
        624
      ],
      "parameters": {
        "url": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', ``, 'string') }}",
        "options": {},
        "toolDescription": "Makes an HTTP request and returns the response data."
      },
      "typeVersion": 4.3
    },
    {
      "id": "c6cd778e-d2a0-46bc-b4e0-1408d0eb70e1",
      "name": "Send the email (Gmail)",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1680,
        432
      ],
      "parameters": {
        "sendTo": "###",
        "message": "={{ $json.newsContent }}",
        "options": {},
        "subject": "=Media Briefing - {{ $('Trigger daily').item.json['Readable date'] }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "7358cb03-7929-484b-8aa4-3e30824aeabe",
      "name": "Strip message before sending",
      "type": "n8n-nodes-base.set",
      "position": [
        1488,
        432
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "58aa0d9f-3aaf-46f8-b5bc-23d49d353f4d",
              "name": "newsContent",
              "type": "string",
              "value": "={{ $json.output }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "c994c292-bb35-45bc-96f8-cd975c324973",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Strip message before sending",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format date": {
      "main": [
        [
          {
            "node": "Set user config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Trigger daily": {
      "main": [
        [
          {
            "node": "Set timeframe to last 2 days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set user config": {
      "main": [
        [
          {
            "node": "Fetch news articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Topic deep-dive": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Fetch news articles": {
      "main": [
        [
          {
            "node": "Understand number of results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Google Sheets data": {
      "main": [
        [
          {
            "node": "Get historic values from Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate average results": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Set timeframe to last 2 days": {
      "main": [
        [
          {
            "node": "Format date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Strip message before sending": {
      "main": [
        [
          {
            "node": "Send the email (Gmail)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Understand number of results": {
      "main": [
        [
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Google Sheets data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get historic values from Google Sheets": {
      "main": [
        [
          {
            "node": "Calculate average results",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow creates a daily media briefing based on public news sources. It retrieves relevant articles, summarizes key coverage, evaluates sentiment, and compares the current media volume against historical data. If an unusual spike in coverage is detected, the agent…

Source: https://n8n.io/workflows/13181/ — 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 was born out of a very real problem.

Output Parser Structured, OpenAI Chat, Memory Buffer Window +11
AI & RAG

This workflow automates end-to-end ESG (Environmental, Social, and Governance) sustainability reporting for enterprise sustainability teams, compliance officers, and green governance leads. It solves

Agent, OpenAI Chat, Output Parser Structured +12
AI & RAG

This n8n workflow automates the daily monitoring of trends across X (Twitter), newsletters, and websites. It runs on a schedule, fetches data from configured sources in Google Sheets, processes it usi

Google Sheets, Gmail, Airtop Tool +7
AI & RAG

This n8n workflow automates the process of creating and sending high-quality newsletters with images generated by a GPT image generator. It is triggered on a schedule. 1 n8n workflow (json) 1 Setup tu

Output Parser Structured, OpenAI Chat, Google Cloud Storage +5
AI & RAG

This workflow automates energy portfolio governance for energy managers, sustainability teams, and policy compliance officers. It eliminates the manual effort of aggregating multi-source energy data,

HTTP Request, Agent, OpenAI Chat +9