{"nodes":[{"id":"trigger-1d880950","name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[100,100],"parameters":{}},{"name":"IMAP Email","type":"n8n-nodes-base.emailReadImap","position":[240,420],"parameters":{"format":"resolved","mailbox":"Invoices","options":{"customEmailConfig":"[\"ALL\"]"}},"typeVersion":1,"id":"31df8847-cd37-466c-90df-05027172aa55","notes":"This emailReadImap node performs automated tasks as part of the workflow."},{"name":"Nextcloud","type":"n8n-nodes-base.nextCloud","position":[940,420],"parameters":{"path":"=Documents/Invoices/{{$json[\"date\"]}}_{{$json[\"from\"]}}_{{$binary.file.fileName}}","binaryDataUpload":true,"binaryPropertyName":"file"},"typeVersion":1,"id":"c1291023-48a2-464e-a490-00f33654a005","notes":"This nextCloud node performs automated tasks as part of the workflow."},{"name":"Map each attachment","type":"n8n-nodes-base.function","position":[620,420],"parameters":{"functionCode":"const _ = require('lodash')\n\nconst sanitize = str => _.chain(str)\n  .replace(/[^A-Za-z0-9&.-]/g, '-') // sanitise via whitelist of characters\n  .replace(/-(?=-)/g, '') // remove repeated dashes - {{ $env.WEBHOOK_URL }}\n  .trim('-') // trim any leading/trailing dashes\n  .truncate({\n    length: 60,\n    omission: '-' // when the string ends with '-', you'll know it was truncated\n  })\n  .value()\n\nconst result = _.flatMap(items.map(item => {\n  //console.log({item})\n\n  // Maps each attachment to a separate item\n  return _.values(item.binary).map(file => {\n    console.log(\"Saving attachement:\", file.fileName, 'from:', ...item.json.from.value)\n    \n    // sanitize filename but exclude extension\n    const filename_parts = file.fileName.split('.')\n    const ext = _.slice(filename_parts, filename_parts.length-1)\n    const filename_main = _.join(_.dropRight(filename_parts), '.')\n    file.fileName = sanitize(filename_main) + '.' + ext\n    \n    return {\n      json: {\n        from: sanitize(item.json.from.value[0].name),\n        date: sanitize(new Date(item.json.date).toISOString().split(\"T\")[0]) // get date part \"2020-01-01\"\n      }, \n      binary: { file }\n    }\n  })\n}))\n\n//console.log(result)\nreturn result"},"typeVersion":1,"id":"e8fd22ee-c2ce-4412-89fd-cb87c7df9528","notes":"This function node performs automated tasks as part of the workflow."}],"connections":{"IMAP Email":{"main":[[],[],[],[]]}},"name":"Emailreadimap Workflow","description":"Automated workflow: Emailreadimap Workflow. This workflow processes data and performs automated tasks.","settings":{"executionOrder":"v1","saveManualExecutions":true,"callerPolicy":"workflowsFromSameOwner","errorWorkflow":null,"timezone":"UTC","executionTimeout":3600,"maxExecutions":1000,"retryOnFail":true,"retryCount":3,"retryDelay":1000},"meta":{"instanceId":"workflow-f1147997","versionId":"1.0.0","createdAt":"2025-09-29T07:07:44.343459","updatedAt":"2025-09-29T07:07:44.343471","owner":"n8n-user","license":"MIT","category":"automation","status":"active","priority":"high","environment":"production"},"notes":"Excellent quality workflow: Emailreadimap Workflow. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}