{
  "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
          }
        ]
      ]
    }
  }
}