Skip to content

Instantly share code, notes, and snippets.

@dhcgn
Created June 28, 2025 12:41
Show Gist options
  • Save dhcgn/59268778d04ef809d24400bf0dbdfd7b to your computer and use it in GitHub Desktop.
Save dhcgn/59268778d04ef809d24400bf0dbdfd7b to your computer and use it in GitHub Desktop.
Paperless NGX, n8n, Privatemode.ai

Strukturiert Zusammenfassung: n8n Workflow "Paperless"

1. Überblick (Kernpunkte)

  • Verwendung einer vertraulichen KI:
    Die Zusammenfassung und Klassifizierung von Dokumenten wird durch ein internes Confidential AI System (Privatemode.ai von Edgeless Systems) durchgeführt. Die gesamte Verarbeitung und Analyse erfolgt im geschützten internen Netz.
  • Datenschutz-Beachtung beim Prompting:
    Das KI-Prompt ist so gestaltet, dass bei medizinischen oder streng vertraulichen Inhalten keine sensiblen Informationen extrahiert oder per E-Mail versendet werden. In diesem Fall gibt die KI nur einen allgemeinen Hinweis auf die Vertraulichkeit des Dokuments aus – keine Details gelangen nach außen.
  • Flexible Betriebsmodi:
    Der Workflow unterscheidet zwischen test- und production-Modus
    • Im test-Modus gehen Benachrichtigungen an eine Testadresse.
    • Im production-Modus an die reguläre Empfängeradresse.

2. Beteiligte Systeme & Endpunkte

  • Paperless NGX (Dokumentenmanagement):
    • Intern: http://192.168.3.10:8000
    • Web-Frontend (SSO): https://my-domain
  • Confidential AI:
    • Intern: http://192.168.3.10:9876
  • E-Mail Versand: SMTP via smtp2go

3. Workflow-Ablauf (Schritt für Schritt)

3.1 Auslösung

  • Webhook (“Neues Dokument”):
    • Trigger bei neuen Dokumenten (POST-Webhook).

3.2 Datenaufbereitung

  • Felder zusammenfassen:
    • Extrahiert Dokumenten-ID, URL und Modus.

3.3 Dokumentdetails abfragen

  • API-Call an Paperless NGX:
    • Holt Details und OCR-Text des Dokuments (mit Authentifizierung).

3.4 Prompt für KI generieren

  • Erstelle Prompt:
    • Prompt gibt klare Anweisung:
      • Normale Dokumente: Titel + Zusammenfassung auf Basis der ersten 2000 OCR-Zeichen.
      • Vertrauliche Dokumente: Keine Details, nur Hinweis auf Vertraulichkeit und vager Hinweis.

3.5 KI-Zusammenfassung erzeugen

  • Anfrage an Confidential AI:
    • Prompt wird an das interne LLM-Modell geschickt und Antwort für die E-Mail genutzt.

3.6 Benachrichtigungs-E-Mail versenden

  • E-Mail mit KI-Infos:
    • Enthält Link zum Dokument und die KI-Zusammenfassung (nur sofern erlaubt).
    • Zieladresse abhängig von Modus (test/production).
  • Fehlerfall:
    • Bei Problemen mit der KI wird eine alternative Fehler-Mail verschickt.

4. Testmodus

  • Manuelle Ausführung:
    • Setzt Testdaten und simuliert den Workflow ohne echtes Dokument.

5. Besondere Hinweise

  • Keine sensiblen Infos nach außen:
    KI gibt bei vertraulichen Dokumenten ausschließlich einen Hinweis auf Vertraulichkeit, niemals Details.
  • Modusabhängige Empfängeradresse
    (test oder production)
  • Fehlerhandling:
    Fehler in der KI führen zu einer speziellen Fehlerbenachrichtigung.

6. Visualisierung (Ablaufdiagramm)

flowchart TD
    Start(Neues Dokument Webhook) --> Felder[Felder zusammenfassen]
    Felder --> Details[Get Details of Document]
    Details -->|OK| Prompt[Erstelle Prompt]
    Prompt --> KI[Erstelle Zusammenfassung]
    KI -->|OK| Mail("Mail @ Family")
    KI -->|Fehler| MailFehler("Mail @ Family (ohne KI)")
    Details -->|Fehler| MailFehler
    Manual(Manual Trigger) --> TestDaten(Test Daten)
    TestDaten --> Felder
Loading
{
"name": "Paperless",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "bd0736a2-d763-4050-aa8d-726630c30ca4",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
-760,
65
],
"id": "ca2ba509-7b8f-4608-aee9-25ec1cd37054",
"name": "Neues Dokument",
"webhookId": "bd0736a2-d763-4050-aa8d-726630c30ca4"
},
{
"parameters": {
"fromEmail": "[email protected]",
"toEmail": "={{ $('Felder zusammenfassen').item.json.executionMode === 'test' ? 'daniel@my-domain' : 'jd@my-domain' }}",
"subject": "Neues Dokument // my-domain",
"html": "=<h2>Neues Dokument vorhanden!</h2>\nUrl: {{ $('Felder zusammenfassen').item.json.url }}<br><br>\n<i>Login mit Google Konto</i>\n<h2>KI erstellte Informationen</h2>\n{{ $('Erstelle Zusammenfassung').item.json.choices[0].message.content }}",
"options": {}
},
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2.1,
"position": [
340,
-160
],
"id": "3832c560-d685-46ea-ac8d-5521557a0e4e",
"name": "Mail @ Family",
"webhookId": "a313e5e0-404a-4fa1-8b37-93648c72eb37",
"credentials": {
"smtp": {
"id": "6qreBlajONO4xda5",
"name": "smtp2go"
}
}
},
{
"parameters": {
"url": "=http://192.168.3.10:8000/api/documents/{{ $json.doc_id }}/",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Host",
"value": "my-domain"
}
]
},
"options": {
"redirect": {
"redirect": {}
},
"timeout": 10000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-320,
-35
],
"id": "22d18c8e-9510-47ab-9099-0853db5007fe",
"name": "Get Details of Document",
"credentials": {
"httpBearerAuth": {
"id": "g8h6qGSaGIf7O7ig",
"name": "OpenAI"
},
"httpHeaderAuth": {
"id": "6fTNakSihGODxSbc",
"name": "Paperless"
}
},
"onError": "continueErrorOutput"
},
{
"parameters": {
"method": "POST",
"url": "http://192.168.3.10:9876/v1/chat/completions",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"model\": \"ibnzterrell/Meta-Llama-3.3-70B-Instruct-AWQ-INT4\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": {{ $json.prompt.toJsonString() }}\n }\n ]\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
120,
-110
],
"id": "1b809d6e-772b-477c-926f-bf51873cb407",
"name": "Erstelle Zusammenfassung",
"onError": "continueErrorOutput"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "9134786e-df99-49a6-b8f5-8cc5044e8168",
"name": "prompt",
"value": "=Erstelle einen Titel und eine Zusammenfassung welche auf einem OCR eines Dokumentes beruht.\n\n- Gebe nur den Titel und die Zusammenfassung zurück!\n- Wenn das Dokument medizinische Informationen oder ander streng vertrauliche Informationen beinhaltet, gebe nur zurück, dass es sich um ein vetrauliches Dokument handelt. Gebe dann nur einen vagen Hinweis.\n\n# Format\n\n<b>Möglicher Title:<b> ... <br><br>\n<b>Zusammenfassung der Dokuments:<b><br><br> ... <br>\n\n# OCR (der ersten 2000 Zeichen)\n\n{{ $json.content.substring(0,2000) }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-100,
-110
],
"id": "c6346eae-8e57-4255-95ef-36a021b67f49",
"name": "Erstelle Prompt"
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-980,
-135
],
"id": "cdfe74aa-9088-479b-96a7-dfedf10af5fe",
"name": "When clicking ‘Execute workflow’"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "ea62bfc7-98c1-4032-b9b9-ebafb55b82f0",
"name": "body.url",
"value": "https://my-domain/documents/538/",
"type": "string"
},
{
"id": "bc596ab9-4f0d-4241-af75-1dbaa5c9e53a",
"name": "executionMode",
"value": "test",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-760,
-135
],
"id": "da9048e3-20aa-494f-bfae-01d58dd97de4",
"name": "Test Daten"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "d069de84-f063-4fdb-889f-5bf38112b012",
"name": "doc_id",
"value": "={{ $json.body.url.match(/\\/documents\\/(\\d+)\\//)[1] }}",
"type": "string"
},
{
"id": "263f0bba-c1fd-4d03-9f6a-f19e9af6b948",
"name": "url",
"value": "={{ $json.body.url }}",
"type": "string"
},
{
"id": "91e18ddf-7906-404e-b78d-39b6eaa3c530",
"name": "executionMode",
"value": "={{ $json.executionMode }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-540,
-35
],
"id": "699fca74-2d58-4360-bd09-451a76dfaf77",
"name": "Felder zusammenfassen"
},
{
"parameters": {
"fromEmail": "[email protected]",
"toEmail": "={{ $('Felder zusammenfassen').item.json.executionMode === 'test' ? 'daniel@my-domain' : 'jd@my-domain' }}",
"subject": "Neues Dokument // my-domain",
"html": "=<h2>Neues Dokument vorhanden!</h2>\nUrl: {{ $('Felder zusammenfassen').item.json.url }}<br><br>\n<i>Login mit Google Konto</i>\n<h2>KI erstellte Informationen</h2>\n<i>Es ist leider ein Fehler aufgetreten!<i>\n<pre>{{ $json.error.toJsonString() }}</pre>",
"options": {}
},
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2.1,
"position": [
340,
65
],
"id": "dec6c1a5-aeef-4e71-b7ea-1046df7a65f7",
"name": "Mail @ Family (ohne KI)",
"webhookId": "a313e5e0-404a-4fa1-8b37-93648c72eb37",
"credentials": {
"smtp": {
"id": "6qreBlajONO4xda5",
"name": "smtp2go"
}
}
}
],
"pinData": {},
"connections": {
"Neues Dokument": {
"main": [
[
{
"node": "Felder zusammenfassen",
"type": "main",
"index": 0
}
]
]
},
"Get Details of Document": {
"main": [
[
{
"node": "Erstelle Prompt",
"type": "main",
"index": 0
}
],
[
{
"node": "Mail @ Family (ohne KI)",
"type": "main",
"index": 0
}
]
]
},
"Erstelle Prompt": {
"main": [
[
{
"node": "Erstelle Zusammenfassung",
"type": "main",
"index": 0
}
]
]
},
"Erstelle Zusammenfassung": {
"main": [
[
{
"node": "Mail @ Family",
"type": "main",
"index": 0
}
],
[
{
"node": "Mail @ Family (ohne KI)",
"type": "main",
"index": 0
}
]
]
},
"When clicking ‘Execute workflow’": {
"main": [
[
{
"node": "Test Daten",
"type": "main",
"index": 0
}
]
]
},
"Test Daten": {
"main": [
[
{
"node": "Felder zusammenfassen",
"type": "main",
"index": 0
}
]
]
},
"Felder zusammenfassen": {
"main": [
[
{
"node": "Get Details of Document",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "d9e68ec9-2da6-4c68-bc67-d09391fcd2ca",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "688886ea8f3486359baa6ec61079ddd363b75572c8fc43d9da0322d3b687ed5b"
},
"id": "ofRYPXfA8JRUV9uD",
"tags": []
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment