AutomationFlowsAI & RAG › Triage Emails and Draft Gmail Replies with Gemini and Google Calendar

Triage Emails and Draft Gmail Replies with Gemini and Google Calendar

ByAllan Vaccarizi @growthai on n8n.io

This workflow is for professionals and small business owners who receive a high volume of emails and want to automate triage, labeling, and draft reply generation — without losing the human touch before sending. A Gmail trigger polls the inbox every minute for new unread emails…

Event trigger★★★★☆ complexityAI-powered25 nodesGmailGmail TriggerAgentGoogle Calendar ToolGoogle Gemini ChatGmail ToolOutput Parser Structured
AI & RAG Trigger: Event Nodes: 25 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #15369 — we link there as the canonical source.

This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "861b89dd-f5e4-42e3-b5d7-566ed886c037",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        -592
      ],
      "parameters": {
        "color": 7,
        "width": 1024,
        "height": 336,
        "content": "## Need more advanced automation solutions? Contact us for custom enterprise workflows!\n\n# Growth-AI.fr\n\n## https://www.linkedin.com/in/allanvaccarizi/\n## https://www.linkedin.com/in/hugo-marinier-%F0%9F%A7%B2-6537b633/"
      },
      "typeVersion": 1
    },
    {
      "id": "dec0f57d-8e72-4201-8c37-8b84f882e3c5",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        -1008
      ],
      "parameters": {
        "color": 7,
        "width": 1024,
        "height": 400,
        "content": "![Logo Growth AI](https://cdn.prod.website-files.com/6825df5b20329ba581df4914/68d413c43f8729fa336568a6_Logo_horizontal.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "949022ce-e4f4-49f3-8b82-7fea27451598",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -592,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 304,
        "content": "## Trigger and email retrieval\n\nWatches Gmail for new emails, computes today's date, and fetches the full message content to prepare data for downstream processing."
      },
      "typeVersion": 1
    },
    {
      "id": "6e8d970f-a1d6-4b61-91c8-b6582cc19f2a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        -240
      ],
      "parameters": {
        "color": 7,
        "height": 384,
        "content": "## Remove existing thread label\n\nStrips any current processing label from the email thread so the AI agent can re-classify it cleanly."
      },
      "typeVersion": 1
    },
    {
      "id": "67304418-f078-4946-b179-3c94d384891b",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 336,
        "content": "## Fetch and filter response label\n\nRetrieves the Gmail label that matches the AI's suggested category and filters to ensure a valid label exists before applying it."
      },
      "typeVersion": 1
    },
    {
      "id": "3c9078cb-9a6d-4995-b476-19bc259b49fd",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1984,
        -64
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 320,
        "content": "## Apply label and mark unread\n\nApplies the resolved label to the email thread and marks the message as unread so it surfaces for human review in Gmail."
      },
      "typeVersion": 1
    },
    {
      "id": "a3b7bdf6-d76f-4506-b6cf-11d078e6adfc",
      "name": "Fetch Email Details",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -128,
        -32
      ],
      "parameters": {
        "simple": false,
        "options": {},
        "messageId": "={{ $json.id }}",
        "operation": "get"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "9c3e3952-3f58-410d-ae94-be40a1cec157",
      "name": "Add Label to Email",
      "type": "n8n-nodes-base.gmail",
      "maxTries": 2,
      "position": [
        2032,
        96
      ],
      "parameters": {
        "labelIds": "={{ $json.id }}",
        "messageId": "={{ $('Fetch Email Details').item.json.id }}",
        "operation": "addLabels"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": false,
      "typeVersion": 2
    },
    {
      "id": "cc1b17c9-165c-4eff-88a3-e2ff14548556",
      "name": "When New Email Arrives",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -544,
        -32
      ],
      "parameters": {
        "simple": false,
        "filters": {
          "labelIds": [
            "INBOX"
          ],
          "readStatus": "unread"
        },
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f3181750-e0e3-42aa-97a5-512766792dbb",
      "name": "Send Response Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1632,
        96
      ],
      "parameters": {
        "resource": "label",
        "returnAll": true
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 2.1
    },
    {
      "id": "3336f493-45ed-4996-8a0d-8fe62c4f3308",
      "name": "Filter Valid Label",
      "type": "n8n-nodes-base.filter",
      "position": [
        1808,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "dbc96cc7-5d0a-4b4e-8e8c-a10d46bd6e8e",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.name }}",
              "rightValue": "={{ $('Draft and Label Agent').item.json.output['Libell\u00e9'] }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c2a85c73-59e2-4046-b19d-e50d39c17c5f",
      "name": "Draft and Label Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        464,
        -32
      ],
      "parameters": {
        "text": "=Analyze this email and classify it according to the system prompt criteria.\n\n\ud83d\udce7 EMAIL INFORMATION:\n- From: {{ $('Fetch Email Details').item.json.from }}\n- To: {{ $('Fetch Email Details').item.json.to }}\n- CC: {{ $('Fetch Email Details').item.json.cc }}\n- Subject: {{ $('Fetch Email Details').item.json.subject }}\n- Body: {{ $('Fetch Email Details').item.json.text }}\n- Headers: {{ JSON.stringify($('Fetch Email Details').item.json.headers) }}\n- Date: {{ $('Get Current Date').item.json.date }}\n\n\u26a0\ufe0f IMPORTANT REMINDERS:\n- If the email is part of a thread, use the THREAD tool to retrieve the full context\n- Check whether the user is a DIRECT recipient (To) or only in CC\n- Check if the email is addressed directly to the user (e.g. \"Hello\", \"Hi\" with intent)\n- Apply the \"Reply\" or \"Urgent\" tag ONLY if the email is addressed directly to the user\n- Apply the \"Invoice\" tag to emails mentioning invoices\n- Adapt tone (formal/informal) based on the email received\n- If a meeting is requested, use the CALENDAR tool to propose real time slots\n- For emails with specific requests, respond as if the task has already been completed\n\nReturn your response in the exact JSON format specified in the system prompt.",
        "options": {
          "systemMessage": "=You are an assistant specialized in classifying professional emails and drafting replies.\n\n\u26a0\ufe0f CRITICAL FORMAT INSTRUCTION \u26a0\ufe0f\n\nYou must ONLY return a valid JSON object, NOTHING ELSE.\n- No text before the JSON\n- No text after the JSON\n- No markdown (no ```json)\n- No explanation\n- Only raw JSON\n\nExpected format:\n{\"label\": \"...\", \"message\": \"...\"}\n\n## IMPORTANT CONTEXT\n\nYou analyze emails that may belong to existing conversations (threads). If a thread exists, you MUST consider the full conversation context when classifying.\n\n**ABSOLUTE RULE**: You must assign ONLY ONE label per email.\n\n## CLASSIFICATION CATEGORIES (priority order)\n\n### 1. Urgent\nRequires immediate attention (< 2 hours)\n- Angry customer, conflict\n- Service down / blocking issue\n- Critical technical problem\n- Tight deadline (today/tomorrow)\n- Urgent business opportunity\n- Payment or billing issue\n- Keywords: \"URGENT\", \"ASAP\", \"blocked\", \"down\"\n\n### 2. Reply\nRequires a response (< 48h)\n- Quote request\n- Client question\n- Project modification\n- Partner/collaborator message\n- Meeting request\n- First contact\n\n### 3. Read\nInformational only\n- User is in CC\n- Group discussion not requiring input\n- Not directly addressed to the user\n- Reports, updates, newsletters\n\n### 4. Notification\nAutomated emails\n- OTP / verification codes\n- Platform notifications\n- \"noreply\" senders\n- System alerts\n- Confirmations\n\n### 5. Newsletter\nSubscription-based content\n- Marketing emails\n- Contains \"unsubscribe\"\n\n### 6. Invoice\nInvoice-related email\n- Attachments or mentions of \"invoice\"\n- Billing tools\n\n## THREAD LOGIC\n\nIf part of a thread:\n1. Read ALL messages\n2. Understand context\n3. Adapt label:\n   - Same context \u2192 keep label\n   - Escalation \u2192 upgrade priority\n   - De-escalation \u2192 downgrade\n\nIf new thread:\n- Apply normal classification\n\n## DRAFT WRITING\n\nONLY for \"Urgent\" and \"Reply\"\n\n### Tone\n- Match sender tone\n- Informal \u2192 informal\n- Formal \u2192 formal\n- Default \u2192 formal\n- Keep it human, concise\n\n### Structure\n- Greeting\n- Direct answer\n- Clarifying questions if needed\n- Closing\n\n### HTML FORMAT\n- Use `<p>` for paragraphs\n- Use `<br>` for line breaks\n- NO `<html>` `<body>`\n- DO NOT include a signature\n\n### Meetings\n- Use calendar tool\n- Suggest 2\u20133 slots\n\n## OUTPUT FORMAT\n\nFor Notification or Read:\n{\n  \"label\": \"Notification\",\n  \"message\": \"\"\n}\n\nFor Urgent or Reply:\n{\n  \"label\": \"Urgent\",\n  \"message\": \"<p>Hello,</p><p>...</p>\"\n}\n\n## RULES\n\n1. Only ONE label\n2. Consider thread context\n3. No signature\n4. Adapt tone\n5. Strict JSON output only\n6. Only reply if email is directed to the user"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2,
      "alwaysOutputData": false
    },
    {
      "id": "fab8407c-59b6-42d5-b4a7-8018c4ee6c0b",
      "name": "Send Draft Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1296,
        -32
      ],
      "parameters": {
        "message": "={{ $json.output.message }}",
        "options": {
          "ccList": "={{ [...(($('Fetch Email Details').item.json.to?.value || []).filter(r => r.address !== 'hugo@institut-du-referencement.com').map(r => r.address)), ...(($('Fetch Email Details').item.json.cc?.value || []).filter(r => r.address !== 'hugo@institut-du-referencement.com').map(r => r.address))].filter(Boolean).join(', ') }}",
          "sendTo": "={{ $('Fetch Email Details').item.json.from.value[0].address }}",
          "threadId": "={{ $('When New Email Arrives').item.json.threadId }}"
        },
        "subject": "={{ $('When New Email Arrives').item.json.subject }}",
        "resource": "draft",
        "emailType": "html"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "5ad87283-96c6-4103-9ad0-accf493fde35",
      "name": "Route by Draft Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        912,
        -32
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Urgent",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6fec23a9-71c4-455d-af78-e127c08ee792",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output['Libell\u00e9'] }}",
                    "rightValue": "Urgent"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "R\u00e9pondre",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "20106af7-9760-4588-b705-99458e427805",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output['Libell\u00e9'] }}",
                    "rightValue": "R\u00e9pondre"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Notification",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "7835f679-ff74-4240-9566-7473a804a1c1",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output['Libell\u00e9'] }}",
                    "rightValue": "Notification"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Lire",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "9b668a0e-9ae5-4b77-9af9-15ea76d74fab",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output['Libell\u00e9'] }}",
                    "rightValue": "Lire"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Facture",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "16d38e1e-3e24-4e47-8c69-b3e754b8a4da",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output['Libell\u00e9'] }}",
                    "rightValue": "Facture"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Newsletter",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ba641b6b-cad8-446b-976c-d94539ed3e0b",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output['Libell\u00e9'] }}",
                    "rightValue": "Newsletter"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.3
    },
    {
      "id": "ad700848-1087-47bf-9e4f-7589b34d9c00",
      "name": "Build HTML Signature",
      "type": "n8n-nodes-base.code",
      "position": [
        1136,
        -32
      ],
      "parameters": {
        "jsCode": "// Signature HTML\nconst signature = `\n<table style=\"border:none;border-collapse:collapse;margin-top:20px\">\n  <colgroup>\n    <col width=\"144\">\n    <col width=\"43\">\n    <col width=\"183\">\n    <col width=\"36\">\n    <col width=\"226\">\n  </colgroup>\n  <tbody>\n    <tr style=\"height:42pt\">\n      <td rowspan=\"3\" style=\"border-right:1.5pt solid rgb(0,0,0);vertical-align:middle;padding:5pt;overflow:hidden\">\n        <p style=\"line-height:1.2;margin:0\">\n          <img src=\"https://lh7-us.googleusercontent.com/VvLaGliwFYP-ed8yKYPZqXb2GCBByMGMxTrkrB--LZGld2NUwexydNBq-NB2hU-VGkK207Mgh_L_zOVHPq8lw7dBRb7wNnbUee7zC0vgeAb2dLE-vbON4oDLlQZzo8yePuWMLZPv5aNqF9JX3PpysQ\" \n               width=\"104\" \n               height=\"105\" \n               style=\"display:block;margin:0\" \n               alt=\"Logo Institut du R\u00e9f\u00e9rencement\">\n        </p>\n      </td>\n      <td colspan=\"4\" style=\"border-left:1.5pt solid rgb(0,0,0);vertical-align:middle;padding:5pt;overflow:hidden\">\n        <p style=\"line-height:1.38;margin:0 0 0 7px\">\n          <span style=\"font-size:9pt;font-family:Poppins,sans-serif;color:rgb(0,0,0);font-weight:700\">HUGO MARINIER</span>\n        </p>\n        <p style=\"line-height:1.38;margin:0 0 0 7px\">\n          <span style=\"font-size:9pt;font-family:Poppins,sans-serif;color:rgb(0,0,0)\">Fondateur - Consultant sp\u00e9cialiste SEO / SEA</span>\n        </p>\n        <p style=\"line-height:1.38;margin:0 0 0 7px\">\n          <span style=\"font-size:9pt;font-family:Poppins,sans-serif;color:rgb(0,0,0)\">0650933800</span>\n        </p>\n      </td>\n    </tr>\n    <tr style=\"height:23.25pt\">\n      <td style=\"border-left:1.5pt solid rgb(0,0,0);vertical-align:middle;padding:5pt;overflow:hidden\">\n        <p style=\"line-height:1.2;margin:0 0 0 7px\">\n          <a href=\"http://institut-du-referencement.com/\" target=\"_blank\">\n            <img src=\"https://lh7-us.googleusercontent.com/qbH_6YMzb6_I4AUGs5YfG8ZiC6rje-OpkOGAAkRQyEM6KVy5ZL9hg83sJbnLs-1394aKnVAyWg1v8hSK7PypQdsBeCdERmVNaSIyip1jwD-lvBoIK6s1eM-Ik81xFGSdC3DFzlYSmtxUrDyeHBl29w\" \n                 width=\"17\" \n                 height=\"17\" \n                 style=\"display:block;margin:0\" \n                 alt=\"Website\">\n          </a>\n        </p>\n      </td>\n      <td style=\"vertical-align:middle;padding:5pt;overflow:hidden\">\n        <p style=\"line-height:1.2;margin:0\">\n          <a href=\"http://institut-du-referencement.com/\" target=\"_blank\" style=\"font-size:8pt;font-family:Poppins,sans-serif;color:rgb(67,67,67);text-decoration:none\">institut-du-referencement.com</a>\n        </p>\n      </td>\n      <td style=\"vertical-align:middle;padding:5pt;overflow:hidden\">\n        <p style=\"line-height:1.2;margin:0\">\n          <a href=\"mailto:user@example.com\">\n            <img src=\"https://lh7-us.googleusercontent.com/bJ5EecZ12cbyaM0AXrBctw-H6uBh_DFTO6M00tcjUXNQldgphcWGjW8MMW4Ip_AzL5zo0rrH4K4h2nf_v2gUQ57szIzPXKYnVahZbgUN7dE7eSdM-34jaXSFC-z2yYJlS7MOrudjNzipOtsp3GCOGQ\" \n                 width=\"18\" \n                 height=\"18\" \n                 style=\"display:block;margin:0\" \n                 alt=\"Email\">\n          </a>\n        </p>\n      </td>\n      <td style=\"vertical-align:middle;padding:5pt;overflow:hidden\">\n        <p style=\"line-height:1.2;margin:0\">\n          <a href=\"mailto:user@example.com\" style=\"font-size:8pt;font-family:Poppins,sans-serif;color:rgb(67,67,67);text-decoration:none\">user@example.com</a>\n        </p>\n      </td>\n    </tr>\n    <tr style=\"height:24pt\">\n      <td colspan=\"4\" style=\"border-left:1.5pt solid rgb(0,0,0);vertical-align:middle;padding:5pt;overflow:hidden\">\n        <p style=\"line-height:1.2;margin:0 0 0 7px\">\n          <a href=\"https://www.linkedin.com/in/hugo-marinier-6537b633/\" target=\"_blank\">\n            <img src=\"https://lh3.googleusercontent.com/Prw_tSY7_8xLWZe1tnV5fYX_QtnQvO_n7S11xEREpjMX2alziUHWc_j4SyH3u_OntkFXIZfFurl2j3O9NTcdfjnDZeDHtwZk4lR0UlIMxiGXtF0Zbm7AbxaZYFmLFcSAtScaro5i\" \n                 width=\"19\" \n                 height=\"19\" \n                 style=\"display:inline-block;margin:0;vertical-align:middle\" \n                 alt=\"LinkedIn\">\n          </a>\n          &nbsp;&nbsp;\n          <a href=\"https://twitter.com/hugomarinier?lang=fr\" target=\"_blank\">\n            <img src=\"https://lh4.googleusercontent.com/jVuq3kCeQRI-0a1x25ShkqSDVRTgzjBd-s73Abi3fqiuPXfrOHsmjMPokpCXZOnwR7OduazLaoUXFJ5pMvsoG1dn76jlaQ0UhRK4-9yPpgTP2eOc610LNzr3g-4lfeaGqPvFYCjx\" \n                 width=\"21\" \n                 height=\"21\" \n                 style=\"display:inline-block;margin:0;vertical-align:middle\" \n                 alt=\"Twitter\">\n          </a>\n        </p>\n      </td>\n    </tr>\n  </tbody>\n</table>\n`;\n\n// R\u00e9cup\u00e9rer le message g\u00e9n\u00e9r\u00e9 par l'agent\nconst agentOutput = $input.first().json.output;\n\n// Si pas de message (cas Notification ou Lire), ne rien faire\nif (!agentOutput.message || agentOutput.message === '') {\n  return $input.all();\n}\n\n// Ajouter la signature au message\nconst messageWithSignature = agentOutput.message + signature;\n\n// Retourner le r\u00e9sultat modifi\u00e9\nreturn {\n  json: {\n    output: {\n      Libell\u00e9: agentOutput.Libell\u00e9,\n      message: messageWithSignature\n    }\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "59ca42c3-1702-4a97-8160-c98035c650eb",
      "name": "Get Current Date",
      "type": "n8n-nodes-base.code",
      "position": [
        -320,
        -32
      ],
      "parameters": {
        "jsCode": "var date = new Date().toISOString();\nvar day = new Date().getDay();\nconst weekday = [\"Dimanche\", \"Lundi\", \"Mardi\", \"Mercredi\", \"Jeudi\", \"Vendredi\", \"Samedi\"];\n\nitems[0].json.date_today = date;\nitems[0].json.day_today = weekday[day];\n\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "5999b9d2-8690-452a-b9a4-eed6c3910c37",
      "name": "Remove Label from Thread",
      "type": "n8n-nodes-base.gmail",
      "position": [
        96,
        -32
      ],
      "parameters": {
        "labelIds": [
          "Label_13",
          "Label_14",
          "Label_7",
          "Label_4695+1234567890",
          "Label_12",
          "Label_16"
        ],
        "resource": "thread",
        "threadId": "={{ $('Fetch Email Details').item.json.threadId }}",
        "operation": "removeLabels"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 2.1,
      "alwaysOutputData": false
    },
    {
      "id": "f1dde220-6716-47da-bec5-56f9807276ac",
      "name": "Google Calendar Tool",
      "type": "n8n-nodes-base.googleCalendarTool",
      "position": [
        496,
        112
      ],
      "parameters": {
        "options": {
          "timeZone": {
            "__rl": true,
            "mode": "list",
            "value": "Europe/Paris",
            "cachedResultName": "Europe/Paris"
          }
        },
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "user@example.com",
          "cachedResultName": "user@example.com"
        },
        "operation": "getAll",
        "returnAll": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_All', ``, 'boolean') }}"
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "f83d865a-80f0-4d73-9c28-f98ba50230c8",
      "name": "Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        384,
        112
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "533cbe15-d72b-4672-9fb3-38ee57d8b2bf",
      "name": "Gmail Thread Tool",
      "type": "n8n-nodes-base.gmailTool",
      "position": [
        608,
        112
      ],
      "parameters": {
        "simple": false,
        "options": {},
        "resource": "thread",
        "threadId": "={{ $('Fetch Email Details').item.json.threadId }}",
        "operation": "get"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "10433364-6dfb-43c1-ba70-90708230b6e0",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        720,
        112
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"Libell\u00e9\": \"Notification|Lire|R\u00e9pondre|Urgent\",\n  \"message\": \"Contenu HTML du brouillon de r\u00e9ponse (vide si pas de r\u00e9ponse n\u00e9cessaire)\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "7eff293e-207d-4247-a58c-2ea0b4531ffd",
      "name": "Mark Email as Unread",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2240,
        96
      ],
      "parameters": {
        "messageId": "={{ $('Fetch Email Details').item.json.id }}",
        "operation": "markAsUnread"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "32dfb65f-e519-4ece-86f7-f504dd512871",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1152,
        -240
      ],
      "parameters": {
        "width": 480,
        "height": 912,
        "content": "## Untitled workflow\n\n### How it works\n\n1. A Gmail trigger detects new incoming emails and retrieves today's date and the full message content.\n2. The workflow removes any existing processing label from the email thread to prepare it for a fresh AI pass.\n3. An AI Agent (powered by Gemini) reads the email thread, checks the Google Calendar, and drafts a reply along with a suggested label.\n4. A Switch routes the output: emails needing a draft reply are processed through a JavaScript code node that builds an HTML signature before saving a Gmail draft; other outcomes skip directly to label retrieval.\n5. The workflow fetches the appropriate Gmail label for the response and applies it to the thread, marking the message as unread so it appears ready for human review.\n\n### Setup steps\n\n- - [ ] Connect a **Gmail OAuth2** credential to all Gmail and Gmail Trigger nodes (Gmail - Nouveaux emails, Get a message, Remove label from thread, Draft into label, Get label for response, Labelliser, Mark a message as unread).\n- - [ ] Connect a **Google Gemini (PaLM)** API credential to the GEMINI sub-node inside the AI Agent.\n- - [ ] Connect a **Google Calendar OAuth2** credential to the AGENDA sub-node inside the AI Agent.\n- - [ ] Configure the Gmail Trigger node with the correct label/filter to watch for new emails requiring AI handling.\n- - [ ] Review and update the label names used in 'Remove label from thread', 'Get label for response', and 'Labelliser' to match your Gmail label setup.\n- - [ ] Customize the HTML signature in the 'Code in JavaScript' node to match your desired email signature.\n- - [ ] Review the Switch1 routing conditions to ensure they match the AI Agent's output structure from the PARCER (structured output parser).\n\n### Customization\n\nYou can adjust the AI Agent's system prompt to change the tone or structure of drafted replies. The Switch1 conditions can be modified to add more routing branches (e.g., forward, archive, escalate). The HTML signature in the Code in JavaScript node can be updated with your personal or company branding."
      },
      "typeVersion": 1
    },
    {
      "id": "7a70a265-098e-4647-a0f6-bba3dca97492",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 464,
        "content": "## AI agent drafting and routing\n\nAn AI Agent (Gemini LLM) reads the email thread and calendar, then drafts a reply and assigns a label category. A structured output parser ensures clean output. A Switch node routes the result to either draft creation or direct label assignment based on the AI's decision."
      },
      "typeVersion": 1
    },
    {
      "id": "3dd9412f-d5bb-4bb8-9c5d-00691253610c",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1088,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 336,
        "content": "## Build and save Gmail draft\n\nGenerates an HTML email signature via JavaScript code, then saves the AI-composed reply as a Gmail draft associated with the original thread."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Get Current Date": {
      "main": [
        [
          {
            "node": "Fetch Email Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Draft Email": {
      "main": [
        [
          {
            "node": "Send Response Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Draft and Label Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Thread Tool": {
      "ai_tool": [
        [
          {
            "node": "Draft and Label Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Add Label to Email": {
      "main": [
        [
          {
            "node": "Mark Email as Unread",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Valid Label": {
      "main": [
        [
          {
            "node": "Add Label to Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Email Details": {
      "main": [
        [
          {
            "node": "Remove Label from Thread",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Draft Type": {
      "main": [
        [
          {
            "node": "Build HTML Signature",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build HTML Signature",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Response Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Response Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Response Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Response Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Response Email": {
      "main": [
        [
          {
            "node": "Filter Valid Label",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build HTML Signature": {
      "main": [
        [
          {
            "node": "Send Draft Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Calendar Tool": {
      "ai_tool": [
        [
          {
            "node": "Draft and Label Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Draft and Label Agent": {
      "main": [
        [
          {
            "node": "Route by Draft Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When New Email Arrives": {
      "main": [
        [
          {
            "node": "Get Current Date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Label from Thread": {
      "main": [
        [
          {
            "node": "Draft and Label Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Draft and Label Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow is for professionals and small business owners who receive a high volume of emails and want to automate triage, labeling, and draft reply generation — without losing the human touch before sending. A Gmail trigger polls the inbox every minute for new unread emails…

Source: https://n8n.io/workflows/15369/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This n8n workflow automates email management by classifying incoming messages, drafting replies, and sending alerts—all powered by AI.

Sentiment Analysis, Lm Chat Azure Open Ai, Gmail +6
AI & RAG

Use cases are many: Manage your Gmail inbox, schedule calendar events, and handle contact details — all from one central AI-powered assistant. Perfect for freelancers managing clients, agency owners w

Agent, Gmail Tool, Google Gemini Chat +10
AI & RAG

This workflow automatically transforms your messy inbox into a neatly organized space while ensuring you never miss a critical message. It connects to your Gmail account and triggers for every new ema

Gmail Trigger, Output Parser Structured, Gmail Tool +8
AI & RAG

N8N-Gmail-Ai-Auto-Labeler. Uses gmailTrigger, lmChatGoogleGemini, gmailTool, agent. Event-driven trigger; 25 nodes.

Gmail Trigger, Google Gemini Chat, Gmail Tool +3
AI & RAG

&gt; An intelligent n8n workflow that automatically classifies and labels Gmail emails using Google Gemini AI, keeping your inbox organized with zero manual effort.

Gmail Trigger, Google Gemini Chat, Gmail Tool +3