{
  "name": "Pièces jointes classées automatiquement dans un stockage",
  "nodes": [
    {
      "id": "b1821e7c-2e7c-4230-a3b0-cf0800c74758",
      "name": "Nouvel e-mail avec pièces jointes",
      "type": "n8n-nodes-base.emailReadImap",
      "typeVersion": 2.2,
      "position": [
        100,
        300
      ],
      "parameters": {
        "mailbox": "INBOX",
        "postProcessAction": "read",
        "format": "simple",
        "downloadAttachments": true,
        "options": {}
      },
      "credentials": {}
    },
    {
      "id": "63da49ba-1baf-4598-be1f-7d6a704993a5",
      "name": "Séparer et nommer les pièces jointes",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        300,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const sortie = [];\nconst entrees = $input.all();\nfor (let i = 0; i < entrees.length; i++) {\n  const item = entrees[i];\n  const from = String(item.json.from || \"\");\n  const trouve = from.match(/<([^>]+)>/);\n  const adresse = (trouve ? trouve[1] : from).trim().toLowerCase();\n  const domaine = (adresse.split(\"@\")[1] || \"expediteur-inconnu\").replace(/[^a-z0-9.-]/g, \"\");\n  const recu = item.json.date ? new Date(item.json.date) : new Date();\n  const d = isNaN(recu.getTime()) ? new Date() : recu;\n  const mois = d.getFullYear() + \"-\" + String(d.getMonth() + 1).padStart(2, \"0\");\n  const dossier = domaine + \"/\" + mois;\n  for (const cle of Object.keys(item.binary || {})) {\n    const brut = item.binary[cle].fileName || (cle + \".bin\");\n    const fichier = brut.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\").replace(/[^A-Za-z0-9._-]+/g, \"-\");\n    sortie.push({\n      json: {\n        expediteur: adresse,\n        domaine: domaine,\n        fichier: fichier,\n        dossier: dossier,\n        chemin: dossier + \"/\" + fichier,\n        date: d.toISOString().slice(0, 10),\n        sujet: item.json.subject || \"\"\n      },\n      binary: { data: Object.assign({}, item.binary[cle], { fileName: fichier }) },\n      pairedItem: { item: i }\n    });\n  }\n}\nreturn sortie;"
      }
    },
    {
      "id": "2f91150f-7a63-4ce8-a98d-d42d003ec36f",
      "name": "Déposer dans le stockage",
      "type": "n8n-nodes-base.s3",
      "typeVersion": 1,
      "position": [
        500,
        300
      ],
      "parameters": {
        "resource": "file",
        "operation": "upload",
        "bucketName": "À REMPLIR : Nom de votre bucket, par exemple documents-clients",
        "fileName": "={{ $json.fichier }}",
        "binaryData": true,
        "binaryPropertyName": "data",
        "additionalFields": {
          "parentFolderKey": "={{ $json.dossier }}"
        }
      },
      "credentials": {}
    },
    {
      "id": "b93ed11e-3476-4519-afb6-f0239674d4eb",
      "name": "Journaliser dans le tableur",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        700,
        300
      ],
      "parameters": {
        "resource": "sheet",
        "operation": "append",
        "authentication": "oAuth2",
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Journal des pièces jointes (à choisir)"
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Journal"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Date": "={{ $(\"Séparer et nommer les pièces jointes\").item.json.date }}",
            "Expéditeur": "={{ $(\"Séparer et nommer les pièces jointes\").item.json.expediteur }}",
            "Fichier": "={{ $(\"Séparer et nommer les pièces jointes\").item.json.fichier }}",
            "Chemin": "={{ $(\"Séparer et nommer les pièces jointes\").item.json.chemin }}",
            "Sujet": "={{ $(\"Séparer et nommer les pièces jointes\").item.json.sujet }}"
          },
          "schema": [
            {
              "id": "Date",
              "displayName": "Date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Expéditeur",
              "displayName": "Expéditeur",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Fichier",
              "displayName": "Fichier",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Chemin",
              "displayName": "Chemin",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Sujet",
              "displayName": "Sujet",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {}
      },
      "credentials": {}
    },
    {
      "id": "554b3b55-0c19-4a91-9c50-725960b7f02a",
      "name": "À configurer",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        64,
        208
      ],
      "parameters": {
        "content": "## À configurer\n- **IMAP** : connectez la boîte qui reçoit les documents.\n- **S3 ou MinIO** : renseignez l'adresse du serveur, les clés d'accès et le nom du bucket. Pour MinIO, activez l'option de style de chemin (path style) dans l'identifiant.\n- **Google Sheets** : choisissez votre tableur. L'onglet « Journal » doit contenir les colonnes Date, Expéditeur, Fichier, Chemin, Sujet.",
        "color": 4,
        "width": 368,
        "height": 224
      }
    },
    {
      "id": "bc0ac810-dccc-417a-9e3c-6c874f4d2a8c",
      "name": "L'idée",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        464,
        208
      ],
      "parameters": {
        "content": "## L'idée\nChaque pièce jointe reçue est rangée automatiquement par expéditeur et par mois, par exemple atelier-martin.fr/2026-09/facture.pdf, puis notée dans un journal consultable par toute l'équipe.",
        "color": 7,
        "width": 368,
        "height": 224
      }
    }
  ],
  "connections": {
    "Nouvel e-mail avec pièces jointes": {
      "main": [
        [
          {
            "node": "Séparer et nommer les pièces jointes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Séparer et nommer les pièces jointes": {
      "main": [
        [
          {
            "node": "Déposer dans le stockage",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Déposer dans le stockage": {
      "main": [
        [
          {
            "node": "Journaliser dans le tableur",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}