← All projects
LIVE DEMO

Gmail label to case file in Drive

One n8n workflow that turns a labeled email into a fixed PDF in the right case folder

STACKn8n 2.31.6 / Gmail API / Google Drive API / Google Sheets API / Node.js / Docker
CONTEXTSpec project (Upwork brief)
DATE2026-07
Open recruiter demo gmail-case-docs-to-drive-demo.aaron.cv
EVIDENCE, NOT CLAIMS

Twelve scenarios that run the delivered export, not a description of it

The console starts the same workflow JSON you can download, inside n8n, and reads back the execution, every Google API call it made, the state of the sandbox mailbox afterwards and the PDF it produced. Each card states its expected behaviour before you run it.

424/424 checks passed on the live demo 42 scenario runs against the public URL on 2026-07-29, no failures
147/147 unit and contract tests passed MIME decoding, case lookup, file naming and the log lines
28 end to end scenarios in n8n 405 checks, all passed, 50.9 s for the full matrix
6 executions against the real Gmail, Drive and Sheets 2026-07-28, five scenarios in a throwaway Google account
1 per message PDFs when two polls overlap Without the reservation the same scenario produced two per message
Not measured Shared Drive writes, quota and throughput at real volume The test account is a consumer account and cannot create a Shared Drive
01

It never documents an email twice

The Gmail search excludes the done label, and that label is only set after the upload answered. A message that was documented does not come back in the next poll, and two polls that overlap produce one PDF and one label call per message.

VERIFY: Run Already documented, then Two polls at once
02

It stops instead of guessing

No mapping row, a folder id Drive answers 404 on, or two mapping rows that both match: each ends with the exact line from the brief, no upload and no label, and the trigger label stays on the message so it is picked up after the cause is fixed.

VERIFY: Run Sender not in the mapping sheet, Folder id does not exist and Two cases, one sender
03

The label goes on the message, not the thread

The done label is set with messages.modify on the one documented message. The console shows every message in the sandbox mailbox afterwards, so you can see the rest of the thread come back without it.

VERIFY: Open the sandbox mailbox panel under any successful run
04

The document is the deliverable

Date and time, sender, recipient, subject, full body and the earlier thread context from newest to oldest, with the context section left out on the first message of a thread. The PDF the run produced is downloadable from the result.

VERIFY: Run Received message in a thread and First message in a thread
05

A failed upload never leaves a labeled message behind

The upload retries once. If both attempts fail the run logs the failure, removes the temporary document and leaves the trigger label in place, because a labeled message is never looked at again.

VERIFY: Run Drive fails once, then accepts and Drive refuses the upload
06

You can break it yourself

Write your own email and mapping row in the console, with or without thread context, and switch on an unmapped sender, a missing folder or a Drive that refuses the upload.

VERIFY: Use the Or write your own email form
TRY THESE CASES
Received message in a threadPDF named Case Name - YYYY-MM-DD - Sender Domain in the mapped folder, four earlier messages as context, done label on that message
First message in a threadNo context section anywhere in the document
Already documentedThe search returns nothing, no thread read, no Drive call, no log line
Two polls at onceThree PDFs for three messages, three label calls, three lines reporting the other run
Sender not in the mapping sheetNo case match found for sender: [address], no upload, no label
Folder id does not existFolder not found for folder ID: [id], no upload, no label
Drive fails once, then acceptsA failed attempt, a successful retry, the label only after that
Drive refuses the uploadUpload failed after retry, no label, temporary document removed
Two cases, one senderMultiple case matches for sender: [address], the workflow stops instead of picking a folder
Case name full of special charactersEmoji dropped, slashes and quotes become spaces, accents kept, sender domain as fallback
RUNTIME PATH
  1. A schedule fires every minute and the Gmail search is the filter, so the label is what starts the work
  2. The mapping tab in Google Sheets is read once per run and matched on address, domain or the other people on the thread
  3. The full thread is fetched and decoded, including sent mail, html only bodies and other charsets
  4. The labels of the message are read again right before the work starts, so a message another run finished is dropped
  5. The document is rendered as html and converted to PDF through a temporary Google Doc, which doubles as the reservation
  6. The PDF is uploaded to the folder id from the mapping row, with supportsAllDrives on every Drive call
  7. Only after the upload answers does the done label go on that one message
  8. Every branch appends one line to the Log tab and then releases the reservation
DATA BOUNDARY

The demo has no Google account connected: a local sandbox answers the Gmail, Drive and Sheets calls from recorded fixtures over https, so the workflow runs unchanged.

  • Synthetic mailbox, synthetic mapping sheet and synthetic case folders. No real email is involved.
  • There is no language model in this workflow, so no message content leaves the stack.
  • The n8n editor and the sandbox are not published. The public surface is the console.
  • The email you compose in the console stays in memory and is replaced by the next run.
  • At a client the workflow uses their own Gmail, Sheets and Drive credentials; nothing is stored outside their Google account and their n8n.

Legal work has a documentation duty: correspondence about a matter has to end up in the case file, readable and not editable. Doing that by hand means printing a thread to PDF, remembering which folder belongs to which counterparty and hoping nobody documents the same email twice. The brief asked for one label click to be enough.

The workflow polls Gmail with the search that makes the label the trigger: label:"Case Docs" -label:"Uploaded to Drive". Gmail has no event for a label being added, so a poll is the only route that also catches an email from last week that is labeled today. It reads the sender to case folder mapping from Google Sheets once per run, fetches the whole thread, decodes every message, and renders a document with date and time, sender, recipient, subject, the full body and the earlier thread context from newest to oldest. The context section is left out entirely when the labeled message is the first in its thread.

The file name is sanitized rather than rejected: characters Drive and Windows refuse are stripped, accents survive, a name longer than 255 characters is cut back and a name already in the folder gets a numbered suffix. Only after the upload answers does the done label go on that one message with messages.modify, never on the thread, so a documented email never comes back in a later poll.

The hard part turned out to be the trigger itself. n8n 2.31 fires a schedule again while the previous run is still busy, and a measurement on the trigger confirmed it: six executions exactly 60 seconds apart while a run took 100 seconds. The second run finds precisely the messages the first has not labeled yet. The workflow now reserves a message with the temporary Google Doc it creates anyway, and the run whose copy is the oldest continues. Without that reservation, two overlapping runs over three messages produced six PDFs; with it, three.

Built on a public brief with no client behind it. It has run against the real Gmail, Drive and Sheets in a throwaway Google account, and the demo runs the delivered export against a local sandbox of those APIs so anyone can try the edge cases without a mailbox.

What it does

Scenario cards on the demo console, each stating the expected behaviour before the run
Twelve scenarios, from the happy path to two polls landing on the same message. Every card states what it expects first.
Result panel showing fourteen passed checks against the expected behaviour
One run of the happy path: expected versus actual, with the file name, the label call and the log line checked separately.
Result panel showing the file name, the log line, the produced PDF and the labels in the sandbox mailbox
What the run wrote to Drive, the PDF it produced, and the mailbox afterwards: only the documented message carries the done label.
The list of Gmail, Drive and Sheets API calls the workflow made during one run
Every Google API call of one run, in order, including the search query and supportsAllDrives on the Drive calls.
n8n canvas of the delivered workflow with its sticky notes
The delivered workflow: 50 nodes, four error branches and a sticky note at every decision.

Want something like this for your business?

Next one
yours?

Send a short description of what eats your time. You will usually see a working prototype before you have paid anything.

© 2026 aaron.cv · Torhout, Belgium (CET) aaronsinnaeve5@gmail.com Upwork