734 lines
26 KiB
JSON
734 lines
26 KiB
JSON
{
|
|
"id": "vbzQ3fgUalOPdcOq",
|
|
"name": "📄 Paperless — Bolletta Allegata",
|
|
"nodes": [
|
|
{
|
|
"id": "wb-bolletta",
|
|
"name": "📎 Webhook Bolletta",
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-2200,
|
|
0
|
|
],
|
|
"webhookId": "paperless-bolletta-001",
|
|
"parameters": {
|
|
"path": "paperless-bolletta",
|
|
"httpMethod": "POST",
|
|
"responseMode": "onReceived",
|
|
"options": {}
|
|
}
|
|
},
|
|
{
|
|
"id": "gmail-get-msg",
|
|
"name": "Gmail - Leggi Messaggio",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-1900,
|
|
0
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "=https://gmail.googleapis.com/gmail/v1/users/me/messages/{{ $json.body.email_id }}?format=full",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "gmailOAuth2",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"gmailOAuth2": {
|
|
"id": "qvOikS6IF0H5khr8",
|
|
"name": "Gmail account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "find-pdf",
|
|
"name": "Trova Allegato PDF",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-1600,
|
|
0
|
|
],
|
|
"parameters": {
|
|
"mode": "runOnceForAllItems",
|
|
"jsCode": "const msg = $input.first().json;\n// La risposta Gmail API ha payload.parts con le parti del messaggio\nfunction findAttachments(parts, results) {\n if (!parts) return;\n for (const part of parts) {\n if (part.parts) findAttachments(part.parts, results);\n if (part.body && part.body.attachmentId) {\n results.push({\n attachment_id: part.body.attachmentId,\n filename: part.filename || 'allegato.pdf',\n mime_type: part.mimeType || 'application/octet-stream',\n size: part.body.size || 0\n });\n }\n }\n}\n\nconst parts = msg.payload && msg.payload.parts ? msg.payload.parts : [];\nconst attachments = [];\nfindAttachments(parts, attachments);\n\nconst pdf = attachments.find(a =>\n a.mime_type === 'application/pdf' ||\n a.filename.toLowerCase().endsWith('.pdf')\n) || attachments[0];\n\nif (!pdf) {\n throw new Error('Nessun allegato trovato nel messaggio. Parts: ' + JSON.stringify(parts).substring(0,200));\n}\n\nreturn [{json: {\n email_id: msg.id,\n thread_id: msg.threadId || msg.id,\n attachment_id: pdf.attachment_id,\n filename: pdf.filename,\n mime_type: pdf.mime_type,\n from: msg.payload?.headers?.find(h=>h.name==='From')?.value || '',\n subject: msg.payload?.headers?.find(h=>h.name==='Subject')?.value || '',\n}}];"
|
|
}
|
|
},
|
|
{
|
|
"id": "dl-att",
|
|
"name": "Gmail - Download Allegato",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-1300,
|
|
0
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "=https://gmail.googleapis.com/gmail/v1/users/me/messages/{{ $json.email_id }}/attachments/{{ $json.attachment_id }}",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "gmailOAuth2",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"gmailOAuth2": {
|
|
"id": "qvOikS6IF0H5khr8",
|
|
"name": "Gmail account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "decode-att",
|
|
"name": "Decodifica Allegato",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-1000,
|
|
0
|
|
],
|
|
"parameters": {
|
|
"mode": "runOnceForAllItems",
|
|
"jsCode": "// La Gmail API restituisce il PDF in base64url (non standard base64)\nconst data = $input.first().json.data;\nif (!data) throw new Error('Nessun dato binario nella risposta attachment');\n\n// Converti base64url → base64 standard\nconst base64 = data.replace(/-/g, '+').replace(/_/g, '/');\nconst buffer = Buffer.from(base64, 'base64');\n\n// Prendi filename dal nodo precedente (Trova Allegato PDF)\nconst filename = $('Trova Allegato PDF').first().json.filename || 'bolletta.pdf';\nconst mimeType = $('Trova Allegato PDF').first().json.mime_type || 'application/pdf';\n\nconst binaryData = await this.helpers.prepareBinaryData(buffer, filename, mimeType);\nreturn [{json: {\n email_id: $('Trova Allegato PDF').first().json.email_id,\n filename,\n from: $('Trova Allegato PDF').first().json.from,\n subject: $('Trova Allegato PDF').first().json.subject,\n}, binary: { attachment: binaryData }}];"
|
|
}
|
|
},
|
|
{
|
|
"id": "pl-corresp",
|
|
"name": "Paperless - Corrispondenti",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-700,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "https://docs.mt-home.uk/api/correspondents/?page_size=100",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "uvGjLbrN5yQTQIzv",
|
|
"name": "Paperless-NGX API"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "pl-doctypes",
|
|
"name": "Paperless - Tipi Doc",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-400,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "https://docs.mt-home.uk/api/document_types/?page_size=100",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "uvGjLbrN5yQTQIzv",
|
|
"name": "Paperless-NGX API"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "pl-tags",
|
|
"name": "Paperless - Tag",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-100,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "https://docs.mt-home.uk/api/tags/?page_size=100",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "uvGjLbrN5yQTQIzv",
|
|
"name": "Paperless-NGX API"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "pl-paths",
|
|
"name": "Paperless - Percorsi",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
200,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "https://docs.mt-home.uk/api/storage_paths/?page_size=100",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "uvGjLbrN5yQTQIzv",
|
|
"name": "Paperless-NGX API"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "pl-search",
|
|
"name": "Paperless - Cerca Simili",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
500,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "=https://docs.mt-home.uk/api/documents/?page_size=5&ordering=-created&search={{ encodeURIComponent($('Trova Allegato PDF').first().json.from.replace(/.*<(.*)>.*/, '$1').split('@')[0]) }}",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "uvGjLbrN5yQTQIzv",
|
|
"name": "Paperless-NGX API"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "build-prompt",
|
|
"name": "Build Prompt Inferenza",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
800,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"mode": "runOnceForAllItems",
|
|
"jsCode": "const meta = $input.first().json;\nconst emailMeta = $('Decodifica Allegato').first().json;\n\n// Fetch all Paperless metadata from previous nodes\nconst correspondents = ($('Paperless - Corrispondenti').first().json.results || [])\n .map(c => `[${c.id}] ${c.name} (documenti: ${c.document_count||0})`).join('\\n');\n\nconst docTypes = ($('Paperless - Tipi Doc').first().json.results || [])\n .map(d => `[${d.id}] ${d.name}`).join('\\n');\n\nconst tags = ($('Paperless - Tag').first().json.results || [])\n .map(t => `[${t.id}] ${t.name}`).join('\\n');\n\nconst storagePaths = ($('Paperless - Percorsi').first().json.results || [])\n .map(s => `[${s.id}] ${s.name}`).join('\\n');\n\nconst similarDocs = ($('Paperless - Cerca Simili').first().json.results || []).slice(0, 5)\n .map(d => `- \"${d.title}\" → corrispondente: ${d.correspondent||'?'}, tipo: ${d.document_type||'?'}, tags: ${(d.tags||[]).join(',')}, path: ${d.storage_path||'?'}`)\n .join('\\n');\n\nconst prompt = `Sei un assistente che gestisce l'archivio documenti di Martin su Paperless-NGX.\nAnalizza questa email con allegato e scegli i metadati corretti per archiviare il documento.\n\nEMAIL:\n- Da: ${emailMeta.from}\n- Oggetto: ${emailMeta.subject}\n- Nome file allegato: ${emailMeta.filename}\n\nCORRISPONDENTI DISPONIBILI (usa l'ID numerico):\n${correspondents}\n\nTIPI DOCUMENTO DISPONIBILI:\n${docTypes}\n\nTAG DISPONIBILI:\n${tags}\n\nPERCORSI DI ARCHIVIAZIONE DISPONIBILI:\n${storagePaths}\n\nDOCUMENTI SIMILI GIÀ ARCHIVIATI (per riferimento):\n${similarDocs || 'Nessuno trovato'}\n\nISTRUZIONI:\n1. Identifica il corrispondente più adatto in base al mittente/oggetto. Se non esiste, metti null.\n2. Scegli il tipo documento più appropriato (Bolletta, Fattura, Ricevuta, etc.)\n3. Scegli i tag appropriati (puoi sceglierne più di uno)\n4. Scegli il percorso di archiviazione più adatto\n5. Genera un titolo breve e descrittivo in italiano (es: \"E.ON Bolletta Energia Mar 2026\")\n6. Inferisci la data del documento se possibile dall'oggetto/mittente (formato YYYY-MM-DD)\n\nRispondi SOLO con JSON valido:\n{\n \"correspondent_id\": 44,\n \"document_type_id\": 2,\n \"tag_ids\": [3],\n \"storage_path_id\": 2,\n \"title\": \"E.ON Bolletta Energia Marzo 2026\",\n \"created_date\": \"2026-03-01\",\n \"confidence_note\": \"Breve nota sul ragionamento\"\n}`;\n\nreturn [{ json: { prompt, ...meta } }];"
|
|
}
|
|
},
|
|
{
|
|
"id": "copilot-token",
|
|
"name": "Ottieni Token Copilot",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
1100,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "https://api.github.com/copilot_internal/v2/token",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "vBwUxlzKrX3oDHyN",
|
|
"name": "GitHub Copilot OAuth Token"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "gpt41-infer",
|
|
"name": "GPT-4.1 - Inferisci Metadati",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
1400,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "https://api.githubcopilot.com/chat/completions",
|
|
"authentication": "none",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Authorization",
|
|
"value": "={{ 'Bearer ' + $('Ottieni Token Copilot').first().json.token }}"
|
|
},
|
|
{
|
|
"name": "Content-Type",
|
|
"value": "application/json"
|
|
},
|
|
{
|
|
"name": "Copilot-Integration-Id",
|
|
"value": "vscode-chat"
|
|
},
|
|
{
|
|
"name": "Editor-Version",
|
|
"value": "vscode/1.85.0"
|
|
}
|
|
]
|
|
},
|
|
"sendBody": true,
|
|
"contentType": "raw",
|
|
"rawContentType": "application/json",
|
|
"body": "={{ JSON.stringify({\"model\":\"gpt-4.1\",\"messages\":[{\"role\":\"system\",\"content\":\"Rispondi SOLO con JSON valido.\"},{\"role\":\"user\",\"content\": $('Build Prompt Inferenza').first().json.prompt}],\"response_format\":{\"type\":\"json_object\"},\"max_tokens\":1024}) }}",
|
|
"options": {}
|
|
}
|
|
},
|
|
{
|
|
"id": "parse-gpt",
|
|
"name": "Parse Risposta GPT",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
1700,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"mode": "runOnceForAllItems",
|
|
"jsCode": "const raw = $input.first().json;\nconst content = (raw.choices && raw.choices[0] && raw.choices[0].message)\n ? raw.choices[0].message.content : (raw.text || '');\n\nconst cleaned = content.replace(/```json\\n?/g,'').replace(/```\\n?/g,'').trim();\n\nlet parsed;\ntry {\n parsed = JSON.parse(cleaned);\n} catch(e) {\n const m = cleaned.match(/\\{[\\s\\S]*\\}/);\n if (m) parsed = JSON.parse(m[0]);\n else throw new Error('Cannot parse GPT response: ' + content.substring(0,300));\n}\n\n// Merge with attachment binary from previous node\nconst attItem = $('Decodifica Allegato').first();\n\nreturn [{\n json: {\n correspondent_id: parsed.correspondent_id || null,\n document_type_id: parsed.document_type_id || null,\n tag_ids: parsed.tag_ids || [],\n storage_path_id: parsed.storage_path_id || null,\n title: parsed.title || 'Documento',\n created_date: parsed.created_date || null,\n confidence_note: parsed.confidence_note || '',\n filename: attItem.json.filename,\n from: attItem.json.from,\n subject: attItem.json.subject,\n },\n binary: attItem.binary\n}];"
|
|
}
|
|
},
|
|
{
|
|
"id": "prepara-upload",
|
|
"name": "Prepara Upload",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
1780,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"mode": "runOnceForAllItems",
|
|
"jsCode": "const meta = $('Parse Risposta GPT').first().json;\nconst decodeNode = $('Decodifica Allegato').first();\nconst emailMeta = decodeNode.json;\n\n// Titolo = filename allegato senza estensione (es: \"10968276\")\nconst filename = emailMeta.filename || 'bolletta.pdf';\nconst title = filename.replace(/\\.[^/.]+$/, '');\n\n// Data = data ricezione email (internalDate è in millisecondi)\nconst internalDate = $('Gmail - Leggi Messaggio').first().json.internalDate;\nconst receivedISO = internalDate\n ? new Date(parseInt(internalDate)).toISOString()\n : null;\n\n// Parse tag_ids\nlet tag_ids = meta.tag_ids;\nif (typeof tag_ids === 'string') {\n try { tag_ids = JSON.parse(tag_ids); } catch(e) { tag_ids = []; }\n}\n\nconst result = {\n title,\n filename,\n correspondent_id: meta.correspondent_id != null ? Number(meta.correspondent_id) : null,\n document_type_id: meta.document_type_id != null ? Number(meta.document_type_id) : null,\n storage_path_id: meta.storage_path_id != null ? Number(meta.storage_path_id) : null,\n tag_ids: Array.isArray(tag_ids) ? tag_ids.map(Number).filter(n => !isNaN(n)) : [],\n created_date: receivedISO,\n};\n\nreturn [{ json: result, binary: decodeNode.binary }];"
|
|
}
|
|
},
|
|
{
|
|
"id": "pl-upload",
|
|
"name": "Paperless - Upload Documento",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
2000,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "https://docs.mt-home.uk/api/documents/post_document/",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"contentType": "multipart-form-data",
|
|
"bodyParameters": {
|
|
"parameters": [
|
|
{
|
|
"parameterType": "formBinaryData",
|
|
"name": "document",
|
|
"inputDataFieldName": "attachment"
|
|
},
|
|
{
|
|
"name": "title",
|
|
"value": "={{ $json.title }}"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"response": {
|
|
"response": {
|
|
"responseFormat": "text"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "uvGjLbrN5yQTQIzv",
|
|
"name": "Paperless-NGX API"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "tg-confirm",
|
|
"name": "Telegram - Conferma Upload",
|
|
"type": "n8n-nodes-base.telegram",
|
|
"typeVersion": 1.2,
|
|
"position": [
|
|
2300,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"chatId": "-4814221197",
|
|
"text": "={{ '✅ *Documento archiviato su Paperless!*\\n\\n📄 *' + $('Prepara Upload').first().json.filename + '*\\n🗂 ' + $('Prepara Upload').first().json.title + '\\n' + ($('Estrai Document ID').first().json.is_duplicate ? '⚠️ _Duplicato — metadati aggiornati_\\n' : '') + '🔗 https://docs.mt-home.uk/documents/' + $json.id + '/details/' }}",
|
|
"additionalFields": {
|
|
"parse_mode": "Markdown"
|
|
}
|
|
},
|
|
"credentials": {
|
|
"telegramApi": {
|
|
"id": "uTXHLqcCJxbOvqN3",
|
|
"name": "Telegram account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "estrai-task-id",
|
|
"name": "Estrai Task ID",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
2220,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"mode": "runOnceForAllItems",
|
|
"jsCode": "// Paperless post_document risponde con {data: \"uuid\"} (responseFormat: text → n8n wrappa in {data:...})\nconst raw = $input.first().json;\nconst task_id = raw.data || raw.body || String(raw);\nconst meta = $('Prepara Upload').first().json;\n\n// Parse tag_ids se arriva come stringa\nlet tag_ids = meta.tag_ids;\nif (typeof tag_ids === 'string') {\n try { tag_ids = JSON.parse(tag_ids); } catch(e) { tag_ids = []; }\n}\n\nreturn [{ json: { \n task_id: task_id.replace(/\"/g,'').trim(),\n ...meta,\n tag_ids\n}}];"
|
|
}
|
|
},
|
|
{
|
|
"id": "wait-paperless",
|
|
"name": "⏳ Attendi Paperless",
|
|
"type": "n8n-nodes-base.wait",
|
|
"typeVersion": 1.1,
|
|
"position": [
|
|
2440,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"amount": 20,
|
|
"unit": "seconds"
|
|
},
|
|
"webhookId": "wait-paperless-bolletta"
|
|
},
|
|
{
|
|
"id": "get-task-status",
|
|
"name": "Paperless - Stato Task",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
2660,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "GET",
|
|
"url": "https://docs.mt-home.uk/api/tasks/",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"sendQuery": true,
|
|
"queryParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "task_id",
|
|
"value": "={{ $json.task_id }}"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "uvGjLbrN5yQTQIzv",
|
|
"name": "Paperless-NGX API"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "estrai-doc-id",
|
|
"name": "Estrai Document ID",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
2880,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"mode": "runOnceForAllItems",
|
|
"jsCode": "const tasks = $input.first().json;\nconst taskList = Array.isArray(tasks) ? tasks : [tasks];\nconst task = taskList[0];\nif (!task) throw new Error('Nessun task trovato');\n\nconst isDuplicate = task.status === 'FAILURE' && String(task.result || '').includes('duplicate');\nconst isSuccess = task.status === 'SUCCESS';\nif (!isSuccess && !isDuplicate) {\n throw new Error(`Task ${task.status}: ${task.result || task.task_error || ''}`);\n}\n\nconst doc_id = parseInt(String(task.related_document || '').replace(/\\D/g,''), 10);\nif (!doc_id) throw new Error('Document ID non trovato: ' + JSON.stringify(task));\n\nconst meta = $('Prepara Upload').first().json;\n\nlet tag_ids = meta.tag_ids;\nif (typeof tag_ids === 'string') {\n try { tag_ids = JSON.parse(tag_ids); } catch(e) { tag_ids = []; }\n}\n\n// created_date è già ISO completo (es: \"2026-03-18T21:26:51.000Z\"), prendi solo YYYY-MM-DD\nconst created_date = meta.created_date\n ? String(meta.created_date).substring(0, 10)\n : null;\n\nreturn [{ json: {\n doc_id,\n is_duplicate: isDuplicate,\n title: meta.title,\n correspondent_id: meta.correspondent_id != null ? Number(meta.correspondent_id) : null,\n document_type_id: meta.document_type_id != null ? Number(meta.document_type_id) : null,\n storage_path_id: meta.storage_path_id != null ? Number(meta.storage_path_id) : null,\n tag_ids: Array.isArray(tag_ids) ? tag_ids.map(Number).filter(n => !isNaN(n)) : [],\n created_date,\n}}];"
|
|
}
|
|
},
|
|
{
|
|
"id": "patch-doc-meta",
|
|
"name": "Paperless - Patch Metadati",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
3100,
|
|
-200
|
|
],
|
|
"parameters": {
|
|
"method": "PATCH",
|
|
"url": "=https://docs.mt-home.uk/api/documents/{{ $json.doc_id }}/",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ \n JSON.stringify(\n Object.fromEntries(\n Object.entries({\n correspondent: $json.correspondent_id,\n document_type: $json.document_type_id,\n storage_path: $json.storage_path_id,\n tags: $json.tag_ids && $json.tag_ids.length > 0 ? $json.tag_ids : undefined,\n created: $json.created_date || undefined\n }).filter(([_, v]) => v !== null && v !== undefined)\n )\n )\n}}",
|
|
"options": {}
|
|
},
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "uvGjLbrN5yQTQIzv",
|
|
"name": "Paperless-NGX API"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"connections": {
|
|
"📎 Webhook Bolletta": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gmail - Leggi Messaggio",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gmail - Leggi Messaggio": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Trova Allegato PDF",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Trova Allegato PDF": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gmail - Download Allegato",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gmail - Download Allegato": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Decodifica Allegato",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Decodifica Allegato": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Paperless - Corrispondenti",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Paperless - Corrispondenti": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Paperless - Tipi Doc",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Paperless - Tipi Doc": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Paperless - Tag",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Paperless - Tag": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Paperless - Percorsi",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Paperless - Percorsi": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Paperless - Cerca Simili",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Paperless - Cerca Simili": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Prompt Inferenza",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Build Prompt Inferenza": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Ottieni Token Copilot",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Ottieni Token Copilot": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "GPT-4.1 - Inferisci Metadati",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"GPT-4.1 - Inferisci Metadati": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Parse Risposta GPT",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Parse Risposta GPT": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Prepara Upload",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Paperless - Upload Documento": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Estrai Task ID",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Prepara Upload": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Paperless - Upload Documento",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Estrai Task ID": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "⏳ Attendi Paperless",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"⏳ Attendi Paperless": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Paperless - Stato Task",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Paperless - Stato Task": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Estrai Document ID",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Estrai Document ID": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Paperless - Patch Metadati",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Paperless - Patch Metadati": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Telegram - Conferma Upload",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"settings": {
|
|
"executionOrder": "v1",
|
|
"callerPolicy": "workflowsFromSameOwner",
|
|
"availableInMCP": false
|
|
},
|
|
"triggerCount": 1,
|
|
"versionId": "cd5d2a62-eea4-419d-b65f-1b4bc134fd33",
|
|
"owner": {
|
|
"type": "personal",
|
|
"projectId": "Hdttz401OqqtObPo",
|
|
"projectName": "Martin Tahiraj <tahiraj.martin@gmail.com>",
|
|
"personalEmail": "tahiraj.martin@gmail.com"
|
|
},
|
|
"parentFolderId": null,
|
|
"isArchived": true
|
|
} |