Portal Community

Example 1: Send Email with PDF Attachment

Scenario: A monthly invoicing workflow generates a PDF report and emails it to a client. The PDF has been produced by an upstream node and stored as a binary field named reportPdf.

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

Scenario: A scheduled workflow runs every 30 minutes, fetches all unread support emails received in the last hour, and loops through them to create CRM tickets.

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

Scenario: A contract approval workflow generates a counter-proposal email body and saves it as a draft in the sales team's Gmail, ready for a human to review and send manually.

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

Scenario: After an AI classification node determines an inbound email is an invoice, apply a custom "Invoice-Received" label, remove INBOX to archive it, and apply IMPORTANT so it surfaces in priority views.

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)

Scenario: When a support ticket is marked as resolved in the CRM, automatically reply to the customer's original email thread with a resolution summary, copy the account manager, and mark the thread as read.

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.