{
  "name": "Brand news alerts to Discord every hour (GDELT, watch mode)",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 1
            }
          ]
        }
      },
      "id": "c1130000-0000-4000-8000-000000000001",
      "name": "Every hour",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/acts/datagleaner~gdelt-news-monitor/run-sync-get-dataset-items?maxTotalChargeUsd=1",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({\n  keywords: ['YOUR BRAND', 'YOUR PRODUCT'],\n  excludeKeywords: [],\n  languages: ['en'],\n  hoursBack: 6,\n  watchMode: true,\n  watchName: 'brand-alert-discord',\n  maxItems: 100\n}) }}",
        "options": {
          "timeout": 300000
        }
      },
      "id": "c1130000-0000-4000-8000-000000000002",
      "name": "GDELT News Monitor (Apify, watch mode)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        240,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "",
          "name": "Apify token (Authorization: Bearer ...)"
        }
      },
      "notes": "Edit keywords in the JSON body. Create a Header Auth credential: Name = Authorization, Value = Bearer YOUR_APIFY_TOKEN. Watch mode returns only articles not seen by the previous run; maxTotalChargeUsd=1 caps spend per run.",
      "notesInFlow": true
    },
    {
      "parameters": {
        "jsCode": "// One message for all new articles in this run (n8n skips this node when the Actor returned nothing).\nconst items = $input.all().map(i => i.json);\nconst SHOW = 15;\nconst lines = items.slice(0, SHOW).map(a => {\n  const tone = typeof a.tone === 'number' ? ` (tone ${a.tone.toFixed(1)})` : '';\n  const t = String(a.title || a.url).replace(/[\\[\\]<>|]/g, ' ').slice(0, 120);\n  return `- [${t}](<${a.url}>) - ${a.sourceDomain || ''}${tone}`;\n});\nconst more = items.length > SHOW ? `\\n...and ${items.length - SHOW} more in the Apify dataset.` : '';\nlet text = `${items.length} new news article${items.length === 1 ? '' : 's'} mentioning your brand:\\n` + lines.join('\\n') + more + '\\nData: GDELT Project (gdeltproject.org)';\nreturn [{ json: { text: text.slice(0, 1900) } }];"
      },
      "id": "c1130000-0000-4000-8000-000000000003",
      "name": "Build Discord message",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://discord.com/api/webhooks/YOUR/WEBHOOK",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ content: $json.text }) }}",
        "options": {}
      },
      "id": "c1130000-0000-4000-8000-000000000004",
      "name": "Post to Discord (webhook)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        720,
        0
      ],
      "notes": "Replace the URL with your own Discord channel webhook (Channel settings, Integrations, Webhooks). Discord caps a message at 2000 characters; the Code node cuts at 1900.",
      "notesInFlow": true
    },
    {
      "parameters": {
        "content": "## Brand news alert to Discord (GDELT)\n1. Edit `keywords` (and `languages`) in the Apify node's JSON body.\n2. Add a Header Auth credential with your own Apify token.\n3. Paste your Discord channel webhook URL into the last node.\n4. Activate the workflow. First run looks back `hoursBack` hours; later runs return only new articles. Cost: $0.002 per article returned, nothing when there are none.\n\nTemplate by Data Gleaner (Keencrest), which also makes the Actor. Data: GDELT Project, gdeltproject.org.",
        "width": 420,
        "height": 300
      },
      "id": "c1130000-0000-4000-8000-000000000005",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -340
      ]
    }
  ],
  "connections": {
    "Every hour": {
      "main": [
        [
          {
            "node": "GDELT News Monitor (Apify, watch mode)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GDELT News Monitor (Apify, watch mode)": {
      "main": [
        [
          {
            "node": "Build Discord message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Discord message": {
      "main": [
        [
          {
            "node": "Post to Discord (webhook)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": false
  }
}