Workflow n8n

Automatisation Google Drive avec n8n : gestion des factures par email

Ce workflow n8n a pour objectif d'automatiser la gestion des factures reçues par email, en utilisant Google Drive pour le stockage et OpenAI pour le traitement des données. Dans un contexte où les entreprises reçoivent quotidiennement de nombreux documents, ce processus permet de gagner un temps précieux en organisant automatiquement les pièces jointes. Le workflow commence par un déclencheur Webhook qui capte les emails entrants. Ensuite, il utilise le nœud 'Get emails with attachments' pour récupérer les emails contenant des pièces jointes. Les fichiers sont ensuite filtrés pour déterminer s'ils sont des PDF ou non, grâce à des conditions spécifiques. Les fichiers PDF sont lus et traités par OpenAI pour extraire des informations pertinentes. Les factures sont ensuite stockées dans Google Drive, où un dossier est créé pour chaque nouvelle facture. Enfin, le workflow permet d'envoyer un email à votre comptable avec les factures jointes, simplifiant ainsi le processus de comptabilité. Cette automatisation n8n offre une solution efficace pour réduire les erreurs humaines et optimiser le temps de traitement des documents, apportant ainsi une valeur ajoutée significative aux équipes comptables.

Tags clés :automatisationGoogle Drivefacturesn8nemail
Catégorie: Webhook · Tags: automatisation, Google Drive, factures, n8n, email0

Workflow n8n Google Drive, factures, email : vue d'ensemble

Schéma des nœuds et connexions de ce workflow n8n, généré à partir du JSON n8n.

Workflow n8n Google Drive, factures, email : détail des nœuds

  • OpenAI

    Ce noeud utilise l'API OpenAI pour générer des réponses basées sur les messages fournis.

  • Configure

    Ce noeud configure des valeurs spécifiques dans le workflow.

  • Iterate over email attachments

    Ce noeud itère sur les pièces jointes d'un email pour effectuer un traitement personnalisé.

  • Not a PDF

    Ce noeud ne réalise aucune action, servant de point de passage dans le workflow.

  • Is text within token limit?

    Ce noeud vérifie si le texte respecte la limite de tokens définie.

  • Merge

    Ce noeud fusionne les données provenant de plusieurs branches du workflow.

  • Is matched

    Ce noeud évalue une condition pour déterminer le chemin à suivre dans le workflow.

  • Upload file to folder

    Ce noeud télécharge un fichier dans un dossier spécifique sur Google Drive.

  • Webhook

    Ce noeud reçoit des requêtes via un webhook à une URL spécifiée.

  • Respond to Webhook

    Ce noeud répond à une requête de webhook avec des données spécifiques.

  • Create folder

    Ce noeud crée un nouveau dossier sur Google Drive.

  • Aggregate attachments

    Ce noeud agrège les pièces jointes d'emails pour un traitement ultérieur.

  • Send email with invoices?

    Ce noeud vérifie si des factures doivent être envoyées par email.

  • Send to my accountant

    Ce noeud envoie un email à un comptable avec les informations spécifiées.

  • Get emails with attachments

    Ce noeud récupère les emails contenant des pièces jointes selon des critères définis.

  • Read PDF email attachments

    Ce noeud lit les pièces jointes des emails au format PDF.

  • Is attachment a PDF?

    Ce noeud vérifie si une pièce jointe est au format PDF.

  • Optional filter for emails

    Ce noeud applique un filtre optionnel sur les emails selon des conditions spécifiées.

  • Sticky Note

    Ce noeud crée une note autocollante avec le contenu et les dimensions spécifiées.

  • Sticky Note1

    Ce noeud crée une seconde note autocollante avec des paramètres similaires.

Inscris-toi pour voir l'intégralité du workflow

Inscription gratuite

S'inscrire gratuitementBesoin d'aide ?
{
  "meta": {
    "instanceId": "d1b60f1865ef6504ee3af5be4ef9a7387762b4132615a52de808456d52e8d336",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "c84f3a9a-66b3-4a09-b06a-9b399ea574b8",
      "name": "OpenAI",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        420,
        -240
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=Does this PDF file look like a {{ $(\"Configure\").first().json[\"Match on\"] }}? Return \"true\" if it is a {{ $(\"Configure\").first().json[\"Match on\"] }} and \"false\" if not. Only reply with lowercase letters \"true\" or \"false\".\n\nThis is the PDF filename:\n```\n{{ $binary.data.fileName }}\n```\n\nThis is the PDF text content:\n```\n{{ $json.text }}\n```"
            }
          ]
        }
      },
      "credentials": {
        "openAiApi": {
          "id": "prYAbsQvWl1pPbdL",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "ea1fbc5b-1859-4d65-8401-30baa95fcc52",
      "name": "Configure",
      "type": "n8n-nodes-base.set",
      "position": [
        -700,
        0
      ],
      "parameters": {
        "values": {
          "number": [
            {
              "name": "maxTokenSize",
              "value": 8000
            },
            {
              "name": "replyTokenSize",
              "value": 50
            }
          ],
          "string": [
            {
              "name": "Match on",
              "value": "receipt or invoice that can be considered a software engineering business cost"
            },
            {
              "name": "Google Drive folder to upload matched PDFs",
              "value": "https://drive.google.com/drive/folders/[put_folder_id_here]"
            },
            {
              "name": "sendInvoicesTo"
            }
          ],
          "boolean": [
            {
              "name": "sendEmail",
              "value": "={{ $('Webhook').item.json.body.sendEmail === \"true\" }}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "3ee63612-c1e7-40e6-a38f-f77f5ee3efa4",
      "name": "Iterate over email attachments",
      "type": "n8n-nodes-base.code",
      "position": [
        -200,
        0
      ],
      "parameters": {
        "jsCode": "// https://community.n8n.io/t/iterating-over-email-attachments/13588/3\nlet results = [];\n\nfor (const item of $input.all()) {\n  console.log(item);\n  for (const key of Object.keys(item.binary)) {\n    results.push({\n        json: {},\n        binary: {\n            data: item.binary[key],\n        }\n    });\n  }\n}\n\nreturn results;"
      },
      "typeVersion": 1
    },
    {
      "id": "3e638471-c1c5-4bab-aa2a-12a1777225ec",
      "name": "Not a PDF",
      "type": "n8n-nodes-base.noOp",
      "position": [
        120,
        80
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b5af902b-2d59-49ee-b6d8-e387c59b89fd",
      "name": "Is text within token limit?",
      "type": "n8n-nodes-base.if",
      "position": [
        300,
        -100
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.text.length() / 4 <= $('Configure').first().json.maxTokenSize - $('Configure').first().json.replyTokenSize }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a0a8895c-ef8b-44e7-9294-1bcf629d0973",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        720,
        -120
      ],
      "parameters": {
        "mode": "combine",
        "options": {
          "clashHandling": {
            "values": {
              "resolveClash": "preferInput1"
            }
          }
        },
        "combinationMode": "mergeByPosition"
      },
      "typeVersion": 2
    },
    {
      "id": "7565118a-6d44-4583-a19f-cb4177378d33",
      "name": "Is matched",
      "type": "n8n-nodes-base.if",
      "position": [
        880,
        -120
      ],
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.message.content }}",
              "value2": "true"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "074ffb7a-f83e-44b8-84fe-7b85f7245bb0",
      "name": "Upload file to folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1100,
        -140
      ],
      "parameters": {
        "name": "={{ $binary.data.fileName }}",
        "options": {},
        "parents": [
          "={{ $('Create folder').first().json.id }}"
        ],
        "binaryData": true
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "xXHySx4T77sDdTqY",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "7681eb62-ba86-4c89-9b88-3ce6fc438bd4",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1080,
        0
      ],
      "webhookId": "cded3af3-31df-47c2-a826-ff84eb4a41df",
      "parameters": {
        "path": "cded3af3-31df-47c2-a826-ff84eb4a41df",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode",
        "authentication": "headerAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "90SsOYPPIe3Qv5Rq",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "aab3d940-55c2-40d3-917a-83412d4e378d",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -720,
        -240
      ],
      "parameters": {
        "options": {
          "responseCode": 202
        },
        "respondWith": "json",
        "responseBody": "={\n  \"status\": \"Accepted\",\n  \"driveFolderUrl\": \"{{ \"https://drive.google.com/drive/folders/\" + $json.id }}\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "29a4122f-0112-4157-a50d-0a6cf83ab7fd",
      "name": "Create folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -920,
        0
      ],
      "parameters": {
        "name": "={{ \"invoices_\" + $json.body.startDate.split('T')[0] }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        },
        "resource": "folder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "xXHySx4T77sDdTqY",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "df86428f-7e63-4fd9-944c-f48af72af495",
      "name": "Aggregate attachments",
      "type": "n8n-nodes-base.code",
      "position": [
        1200,
        -340
      ],
      "parameters": {
        "jsCode": "// \"items\" is the array coming from the previous node (14 items)\nconst merged = { json: {}, binary: {} };\n\nfor (const item of $input.all()) {\n  const data = {\n    [item.binary.data.fileName]: item.binary.data\n  };\n  Object.assign(merged.binary, data); // copy every file property\n}\n\nreturn [merged];     // one single item goes out"
      },
      "typeVersion": 2
    },
    {
      "id": "72a21bfa-6e3b-421a-a4ca-dea9e09a5b0b",
      "name": "Send email with invoices?",
      "type": "n8n-nodes-base.if",
      "position": [
        1000,
        -320
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "63caf3d8-39bd-4300-aa7e-8c0ecfc87576",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $('Configure').first().json.sendEmail }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "bb038635-eb69-447b-a85b-e9c3caebfe3a",
      "name": "Send to my accountant",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1360,
        -280
      ],
      "webhookId": "3ea4dac1-58fe-4d0e-811b-065ecaef77df",
      "parameters": {
        "sendTo": "test@example.com",
        "message": "Hello, here are my invoices and receipts.",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {
                "property": "={{ Object.keys($binary).join(',') }}"
              }
            ]
          }
        },
        "subject": "={{ \n  (() => {\n    const startDate = $node['Webhook'].json.body.startDate.split('T')[0];\n    const endDate = $node['Webhook'].json.body.endDate.split('T')[0];\n    return `Dokumenty kosztowe za okres od ${startDate} do ${endDate}`;\n  })() \n}}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "PPgHF95PrpAMBlbG",
          "name": "Gmail account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "7b2e5c6c-0a95-4347-97a9-c9ffbc0e3af2",
      "name": "Get emails with attachments",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -500,
        0
      ],
      "webhookId": "6e2ca9f7-6d22-4d94-86bc-8a299bc8e752",
      "parameters": {
        "simple": false,
        "filters": {
          "q": "has:attachment",
          "sender": "",
          "receivedAfter": "={{ $('Webhook').item.json.body.startDate }}",
          "receivedBefore": "={{ $('Webhook').item.json.body.endDate }}"
        },
        "options": {
          "downloadAttachments": true,
          "dataPropertyAttachmentsPrefixName": "attachment_"
        },
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "PPgHF95PrpAMBlbG",
          "name": "Gmail account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "6d5b2c1b-657d-44bf-980d-fd428fd8d832",
      "name": "Read PDF email attachments",
      "type": "n8n-nodes-base.readPDF",
      "onError": "continueErrorOutput",
      "position": [
        120,
        -80
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "3166f45c-306f-483a-b2c6-6768abc916a0",
      "name": "Is attachment a PDF?",
      "type": "n8n-nodes-base.if",
      "position": [
        -40,
        0
      ],
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $binary.data.fileExtension }}",
              "value2": "pdf"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "866b286a-7b9b-4506-aa6b-d2049b249991",
      "name": "Optional filter for emails",
      "type": "n8n-nodes-base.filter",
      "position": [
        -360,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "687c4cd0-ada5-4dc1-8707-1a9c3b551251",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.to.value[0].address }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "56133dba-bc93-4f65-be42-995164a45c03",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1600,
        -340
      ],
      "parameters": {
        "width": 440,
        "height": 880,
        "content": "## Gmail PDF Invoice/Receipt Classifier & Google Drive Uploader (via n8n & OpenAI)\n\n_**DISCLAIMER**: AI classification isn't perfect. Always double-check that the correct documents were identified and uploaded._\n\nThis n8n workflow, triggered via a webhook, scans your Gmail for emails within a specified date range, extracts PDF attachments, and uses OpenAI to determine if each PDF matches a defined category (defaulting to \"receipt or invoice\"). Matched PDFs are then uploaded to a uniquely named Google Drive folder based on the date range. You can customize the classification term (e.g., change \"receipt or invoice\" to \"contract\") and optionally have the workflow email the collected PDFs to a specified address.\n\n### How it works\n1.  Triggers via a `Webhook` receiving a start date, end date, and an optional flag to send an email.\n2.  Creates a dated folder in `Google Drive` (e.g., `invoices_YYYY-MM-DD_YYYY-MM-DD`).\n3.  Fetches emails with attachments from `Gmail` within the specified date range.\n4.  Iterates through each attachment, filtering specifically for `PDF` files.\n5.  Extracts text from each PDF (skipping if the text exceeds token limits set in the `Configure` node).\n6.  Uses the `OpenAI` node to ask if the PDF content and filename look like the item defined in the `Configure` node's \"Match on\" field (e.g., \"receipt or invoice\").\n7.  If OpenAI responds with \"true\", the original `PDF` file is uploaded to the `Google Drive` folder created in step 2.\n8.  If the initial webhook request included the flag to send an email, it aggregates all successfully matched PDFs and sends them via `Gmail` to the address specified in the `Configure` node.\n\nWorkflow written by [Tom](https://browsewiz.com)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "aa5d8126-e2ec-4476-886d-c46379f1c6e2",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -780,
        -40
      ],
      "parameters": {
        "width": 260,
        "height": 1000,
        "content": "## Parameters\n\n\n\n\n\n\n\n\n\n* **`maxTokenSize`** (Number)\n    *   **Limits PDF text length** (estimated input tokens) sent to OpenAI for classification. Prevents errors/high costs on long documents.\n    *   *Default: 8000*\n\n*   **`replyTokenSize`** (Number)\n    *   **Reserves tokens for OpenAI's reply** ('true'/'false'). Ensures total tokens stay within limits.\n    *   *Default: 50*\n\n*   **`Match on`** (String)\n    *   **The keyword/phrase OpenAI uses** to identify the desired document type (e.g., \"receipt or invoice\", \"contract\"). Defines what you're searching for.\n    *   *Default: \"receipt or invoice\"*\n\n*   **`sendInvoicesTo`** (String)\n    *   **Recipient email address** for the final collection of matched PDFs. Used only if `sendEmail` is true.\n    *   *Example: \"accounting@example.com\"*\n\n*   **`sendEmail`** (Boolean)\n    *   **Turns the final email step on (`true`) or off (`false`)**. Set via the initial webhook trigger. If false, files are only uploaded to Drive.\n    *   *Example: `true` or `false`*"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Is matched",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Create folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure": {
      "main": [
        [
          {
            "node": "Get emails with attachments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is matched": {
      "main": [
        [
          {
            "node": "Upload file to folder",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send email with invoices?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create folder": {
      "main": [
        [
          {
            "node": "Configure",
            "type": "main",
            "index": 0
          },
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is attachment a PDF?": {
      "main": [
        [
          {
            "node": "Read PDF email attachments",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Not a PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate attachments": {
      "main": [
        [
          {
            "node": "Send to my accountant",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send to my accountant": {
      "main": [
        []
      ]
    },
    "Upload file to folder": {
      "main": [
        []
      ]
    },
    "Send email with invoices?": {
      "main": [
        [
          {
            "node": "Aggregate attachments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Optional filter for emails": {
      "main": [
        [
          {
            "node": "Iterate over email attachments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read PDF email attachments": {
      "main": [
        [
          {
            "node": "Is text within token limit?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get emails with attachments": {
      "main": [
        [
          {
            "node": "Optional filter for emails",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is text within token limit?": {
      "main": [
        [
          {
            "node": "OpenAI",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ],
        []
      ]
    },
    "Iterate over email attachments": {
      "main": [
        [
          {
            "node": "Is attachment a PDF?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Workflow n8n Google Drive, factures, email : pour qui est ce workflow ?

Ce workflow s'adresse aux PME et TPE qui gèrent un volume important de factures par email. Il est idéal pour les équipes comptables et administratives, ainsi que pour les entreprises souhaitant automatiser leurs processus sans nécessiter de compétences techniques avancées.

Workflow n8n Google Drive, factures, email : problème résolu

Ce workflow résout le problème de la gestion manuelle des factures reçues par email, qui peut être chronophage et source d'erreurs. En automatisant le processus, il élimine les pertes de temps liées à la recherche et au stockage des documents, tout en réduisant le risque d'erreurs humaines. Les utilisateurs bénéficient d'une organisation efficace de leurs factures, d'un accès rapide aux documents nécessaires et d'une communication simplifiée avec leur comptable.

Workflow n8n Google Drive, factures, email : étapes du workflow

Étape 1 : Le déclencheur Webhook capte les emails entrants.

  • Étape 1 : Le nœud 'Get emails with attachments' récupère les emails contenant des pièces jointes.
  • Étape 2 : Les fichiers sont filtrés pour déterminer s'ils sont des PDF grâce au nœud 'Is attachment a PDF?'.
  • Étape 3 : Les fichiers PDF sont lus par le nœud 'Read PDF email attachments'.
  • Étape 4 : Les informations pertinentes sont extraites à l'aide d'OpenAI.
  • Étape 5 : Un dossier est créé dans Google Drive pour chaque facture via le nœud 'Create folder'.
  • Étape 6 : Les factures sont stockées dans Google Drive avec le nœud 'Upload file to folder'.
  • Étape 7 : Enfin, un email est envoyé à votre comptable avec les factures jointes grâce au nœud 'Send to my accountant'.

Workflow n8n Google Drive, factures, email : guide de personnalisation

Pour personnaliser ce workflow, vous pouvez modifier le chemin du Webhook pour l'adapter à votre système de réception d'emails. Assurez-vous d'ajuster les filtres dans le nœud 'Get emails with attachments' pour correspondre à vos critères spécifiques. Vous pouvez également personnaliser le message et le sujet de l'email envoyé à votre comptable dans le nœud 'Send to my accountant'. Enfin, adaptez les paramètres du nœud 'Create folder' pour organiser vos factures selon vos préférences.