guides/workflow: miniflux-nyheder
Threat Intel · n8n · Miniflux → Mistral

Nyheds-screening
fra Miniflux

Et n8n-workflow der med jævne mellemrum henter ulæste artikler fra Miniflux, lader en Mistral-model afgøre relevans, beriger de relevante til korte threat-intel-resumeer, og markerer alt som læst. Reference-mønster med importérbar JSON — tilpas til dine egne feeds og noder.

n8n Reference-skabelon Miniflux API + Mistral
7noder
2-trinsscreen → enrich
RESTMiniflux-API

Hvad det gør

Miniflux samler dine kuraterede sikkerhedsfeeds, men rå feeds er støjende. Dette workflow lægger et intelligent filter ovenpå: en billig model screener for relevans, og kun det der består går videre til dyrere berigelse. Resultatet er et lavt-støj-flow af relevante, opsummerede security-nyheder.

Forudsætninger: Miniflux kørende med en API-token, og n8n med Mistral-credentials. Dette er et referencemønster — node-typer og parametre kan afvige fra din n8n-version, så verificér mod din editor.

Flow-overblik

To-trins screening: billig model frasorterer, dyr model beriger kun det relevante.

triggerSchedule
(1t)
httpGet Unread
splitSplit Entries
mistral SScreen
ifRelevant?
mistral LEnrich
httpMark Read
Forgrening ved "Relevant?": true → berig med Mistral Large → markér læst. false → markér læst direkte (springes over). Begge grene ender med at lukke artiklen, så den ikke screenes igen.

Node-for-node

#NodeTypeFunktion
1Schedule TriggerscheduleTriggerKører hver time (juster interval efter feed-volumen)
2Get UnreadhttpRequestGET /v1/entries?status=unread med X-Auth-Token-header
3Split EntriessplitOutSplitter entries-array til ét item pr. artikel
4ScreenmistralAi (Small)Billig relevans-vurdering, svarer struktureret JSON
5Relevant?ifParser screening-JSON og forgrener på relevant
6EnrichmistralAi (Large)Opsummerer relevante artikler til dansk intel-resume + IOCs
7Mark ReadhttpRequestPUT /v1/entries sætter status read
Tilpas screening-prompten: Node 4's system-prompt afgør kvaliteten. Vær specifik om hvad "relevant" betyder for dig (fx kun aktivt udnyttede sårbarheder, kun bestemte sektorer) — jo skarpere prompt, jo mindre støj slipper igennem til den dyre Enrich-node.

Importérbar JSON

n8n import

Kopiér nedenstående og indsæt i n8n via Workflows → ⋯ → Import from clipboard. Erstat credential-referencer og prompts med dine egne.

news_workflow.json
{
  "name": "Miniflux News Screening",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 1
            }
          ]
        }
      },
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "url": "=https://rss.defencia.dk/v1/entries?status=unread&limit=100&direction=asc",
        "options": {
          "response": {
            "response": {
              "fullResponse": false
            }
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Auth-Token",
              "value": "={{ $credentials.minifluxToken }}"
            }
          ]
        }
      },
      "name": "Get Unread (Miniflux)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "fieldToSplitOut": "entries",
        "options": {}
      },
      "name": "Split Entries",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        680,
        300
      ]
    },
    {
      "parameters": {
        "modelId": "mistral-small-latest",
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "Du er en sikkerhedsanalytiker. Vurder om artiklen er relevant for trusselsovervaagning. Svar KUN med JSON: {\"relevant\": true/false, \"kategori\": \"...\", \"begrundelse\": \"...\"}"
            },
            {
              "role": "user",
              "content": "=Titel: {{ $json.title }}\nIndhold: {{ $json.content }}"
            }
          ]
        }
      },
      "name": "Screen (Mistral Small)",
      "type": "n8n-nodes-base.mistralAi",
      "typeVersion": 1,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true
          },
          "conditions": [
            {
              "leftValue": "={{ JSON.parse($json.choices[0].message.content).relevant }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ]
        }
      },
      "name": "Relevant?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1120,
        300
      ]
    },
    {
      "parameters": {
        "modelId": "mistral-large-latest",
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "Sammenfat artiklen til et kort dansk threat-intel resume med IOCs hvis til stede."
            },
            {
              "role": "user",
              "content": "={{ $json.title }}\n{{ $json.content }}"
            }
          ]
        }
      },
      "name": "Enrich (Mistral Large)",
      "type": "n8n-nodes-base.mistralAi",
      "typeVersion": 1,
      "position": [
        1340,
        220
      ]
    },
    {
      "parameters": {
        "method": "PUT",
        "url": "=https://rss.defencia.dk/v1/entries",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Auth-Token",
              "value": "={{ $credentials.minifluxToken }}"
            }
          ]
        },
        "sendBody": true,
        "jsonBody": "={ \"entry_ids\": [ {{ $json.id }} ], \"status\": \"read\" }"
      },
      "name": "Mark Read (Miniflux)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1560,
        300
      ]
    }
  ],
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Unread (Miniflux)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Unread (Miniflux)": {
      "main": [
        [
          {
            "node": "Split Entries",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Entries": {
      "main": [
        [
          {
            "node": "Screen (Mistral Small)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Screen (Mistral Small)": {
      "main": [
        [
          {
            "node": "Relevant?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Relevant?": {
      "main": [
        [
          {
            "node": "Enrich (Mistral Large)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark Read (Miniflux)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enrich (Mistral Large)": {
      "main": [
        [
          {
            "node": "Mark Read (Miniflux)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}
Efter import — tjek altid: credential-tilknytninger (Mistral + en evt. generisk header-auth til Miniflux-token), at node-typeversioner matcher din n8n, og at API-URL'erne peger på rss.defencia.dk. Den indlejrede token-reference er en placeholder — bind den til en rigtig n8n-credential, læg den aldrig i klartekst.

Credentials

CredentialOpsætning
Miniflux-tokenGenerér i Miniflux (Settings → API Keys). Gem som n8n header-auth-credential eller env-variabel — ikke inline i noden
Mistral APIn8n's Mistral-credential med din API-nøgle; bruges af både Screen- og Enrich-noden

Tuning & udvidelser

JusteringEffekt
IntervalLavere = friskere nyheder, men flere API-kald. 1t er en god balance for ~71 feeds
limitHæv hvis feeds hober sig op mellem kørsler; pas på rate-limits på Mistral
BatchingScreen flere artikler i ét Mistral-kald for at spare tokens (kræver array-prompt)
OutputTilføj en node efter Enrich: send til dashboard, Slack, e-mail eller en database-tabel
IOC-ekstraktionTilføj regex/Code-node der trækker IP'er, domæner, hashes ud af resumeet
DedupMiniflux's læst-status er din dedup — derfor markeres alt læst i begge grene
Kobling til CVE-flowet: Dette håndterer nyheder/artikler. Sårbarheder følger et separat mønster via OpenCVE-webhooks — se CVE-berigelses-workflowet.