Examples
Five real-world Gmail workflow configurations: send with attachment, search and process unread emails, create a draft, manage labels on incoming emails, and thread reply workflow.
Example 1: Send Email with PDF Attachment
Node: Gmail — message/send
{
"Resource": "message",
"Operation": "send",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"SendTo": "{{ vars.clientEmail }}",
"Subject": "Monthly Report — {{ vars.reportMonth }} {{ vars.reportYear }}",
"EmailType": "html",
"SenderName": "Acme Accounts",
"Message": "<p>Dear {{ vars.clientName }},</p><p>Please find your monthly activity report attached.</p><p>If you have any questions, reply to this email and we will respond within one business day.</p><p>Regards,<br>Acme Accounts Team</p>",
"AttachmentBinaryFields": ["reportPdf"],
"AppendAttribution": false
}
Expected outcome: The client receives an HTML email with the PDF report attached. The output
id and threadId are saved to workflow variables for any follow-up operations (e.g. storing the sent message ID in a CRM record).
Example 2: Search Unread Emails and Process Each One
Node: Gmail — message/getMany
{
"Resource": "message",
"Operation": "getMany",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ReturnAll": false,
"Limit": 100,
"Simplified": true,
"LabelIds": ["INBOX"],
"ReadStatus": "unread",
"ReceivedAfter": "{{ vars.lastRunTime }}",
"FilterQ": "to:support@mycompany.com",
"DownloadAttachments": false
}
Feed the
messages array output into a Loop node. Inside the loop, use message/get with Simplified: true to retrieve the full body for each message, then create a CRM ticket and call message/markAsRead to prevent reprocessing on the next poll cycle.
Loop body — Node: Gmail — message/markAsRead
{
"Resource": "message",
"Operation": "markAsRead",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"MessageId": "{{ vars.loopItem.id }}"
}
Example 3: Create a Draft and Save for Later Sending
Node: Gmail — draft/create
{
"Resource": "draft",
"Operation": "create",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ThreadId": "{{ nodes.getOriginalEmail.output.threadId }}",
"EmailType": "html",
"Message": "{{ nodes.aiDraftNode.output.proposalHtml }}",
"CcList": "{{ vars.salesManagerEmail }}",
"AttachmentBinaryFields": ["counterProposalPdf"]
}
Expected outcome: A draft appears in the sales Gmail inbox, pre-populated with the AI-generated counter-proposal body and the PDF attachment, associated with the original email thread. The sales rep reviews it and clicks Send. The draft ID is available as
{{ nodes.createDraft.output.id }} for tracking in a task management system.
Example 4: Apply Labels to Categorise Incoming Emails
Step 1 — Get the label ID (run once at setup, then cache the result)
{
"Resource": "label",
"Operation": "getMany",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Step 2 — Apply classification label
{
"Resource": "message",
"Operation": "addLabel",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"MessageId": "{{ nodes.triggerEmail.output.id }}",
"LabelIds": ["Label_7234891023", "IMPORTANT"]
}
Step 3 — Remove from INBOX (archive the message)
{
"Resource": "thread",
"Operation": "removeLabel",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ThreadId": "{{ nodes.triggerEmail.output.threadId }}",
"LabelIds": ["INBOX"]
}
Replace
Label_7234891023 with the actual ID of your "Invoice-Received" label, retrieved from label/getMany. System label IDs (INBOX, IMPORTANT, UNREAD, etc.) are fixed constants and do not require a lookup.
Example 5: Thread Reply Workflow (Support Ticket Resolution)
Step 1 — Send the resolution reply within the original thread
{
"Resource": "thread",
"Operation": "reply",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ThreadId": "{{ vars.customerThreadId }}",
"EmailType": "html",
"SenderName": "{{ vars.agentName }} — Acme Support",
"Message": "<p>Hi {{ vars.customerFirstName }},</p><p>Great news — your support request <strong>#{{ vars.ticketId }}</strong> has been resolved.</p><p>Resolution summary:</p><blockquote>{{ vars.resolutionSummary }}</blockquote><p>If you experience the issue again or have further questions, simply reply to this email.</p><p>Thank you for your patience,<br>{{ vars.agentName }}<br>Acme Support Team</p>",
"CcList": "{{ vars.accountManagerEmail }}",
"ReplyToSenderOnly": false
}
Step 2 — Apply "Resolved" label to the thread and mark as read
{
"Resource": "thread",
"Operation": "addLabel",
"CredentialId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ThreadId": "{{ vars.customerThreadId }}",
"LabelIds": ["Label_9012345678"]
}
Expected outcome: The customer receives the resolution reply within their original email thread, maintaining full context. The account manager is copied. The Gmail thread is labelled "Resolved" and removed from the active inbox. All steps complete without any manual intervention from the support agent — they only need to mark the ticket as resolved in the CRM.
Thread ID sourcing: The
ThreadId for reply operations must come from either a Gmail Trigger output, a message/get output, or a CRM field where the thread ID was stored when the original email was received. Never hardcode thread IDs in workflow configurations.