message/reply
Reply to an existing message, keeping the conversation in-thread.
In-Thread Reply: This operation replies to an existing message by
messageId and preserves the Gmail thread. Use thread/reply if you want to target the thread by threadId instead.
When to Use
- Auto-reply to customer inquiries: An IMAP trigger detects a new support email, the workflow classifies intent, and sends a categorized auto-reply in the same thread.
- CRM-triggered client follow-up: A CRM event marks a lead as qualified and triggers a reply to the lead's initial inquiry email.
- Approval request acknowledgment: When an approval request email arrives, acknowledge receipt with a reply containing the ticket reference number.
- Support ticket closure: When a ticket is resolved in the help-desk system, reply to the original customer email confirming resolution.
- Receipt acknowledgment: Automatically acknowledge inbound forms or orders by replying to the submitter's email within the same thread.
Configuration
Connection
| Field | Type | Description |
|---|---|---|
credentialId | Guid required | OAuth2 credential ID from the BizFirst Credentials Manager. Requires gmail.send scope. |
Operation Fields
| Field | Type | Default | Description |
|---|---|---|---|
messageId | string required | — | Gmail message ID of the message being replied to. The reply is added to the same thread. |
message | string required | — | Reply body content. HTML or plain text depending on emailType. |
emailType | enum optional | html | Content type: html or text. |
senderName | string optional | — | Display name for the replying sender. |
ccList | string optional | — | Comma-separated CC addresses for the reply. |
bccList | string optional | — | Comma-separated BCC addresses for the reply. |
attachmentBinaryFields | string[] optional | — | Binary field names from upstream node outputs to attach to the reply. |
replyToSenderOnly | bool optional | false | When true, replies only to the original sender. When false, replies to all original recipients (Reply-All). |
Sample Configuration
{
"nodeType": "Gmail",
"operation": "message/reply",
"credentialId": "a3f9d12b-44e1-4c89-b7d2-9f0a1e2b3c4d",
"messageId": "{{trigger.messageId}}",
"message": "<p>Thank you for contacting support. Your ticket <strong>#{{ticket.id}}</strong> has been created. We will respond within 24 hours.</p>",
"emailType": "html",
"senderName": "BizFirst Support",
"replyToSenderOnly": true
}
Validation Errors
| Error | Cause | Resolution |
|---|---|---|
MISSING_FIELD: messageId | messageId is empty or not provided | Ensure the upstream trigger or node provides a valid Gmail message ID |
MISSING_FIELD: message | Reply body is empty | Provide non-empty message content |
MESSAGE_NOT_FOUND | Provided messageId does not exist or is inaccessible | Verify the message ID is from the authenticated account |
INVALID_CREDENTIAL | credentialId not found or OAuth token expired | Re-authenticate the credential in BizFirst Credentials Manager |
QUOTA_EXCEEDED | Daily send limit reached | Wait for quota reset or switch to Google Workspace account |
Output
Success Port
| Field | Type | Description |
|---|---|---|
messageId | string | Gmail message ID of the new reply message |
threadId | string | Thread ID the reply was added to (same as original message thread) |
labelIds | string[] | Labels applied to the reply message (e.g. ["SENT"]) |
status | string | success |
errorCode | string | Empty on success |
Error Port
On failure, routes to the error port with status: "error", errorCode, and errorMessage.
Sample Output
{
"messageId": "18e4b3c1a2d4e5f6",
"threadId": "18e4a2f9d3c0b1a7",
"labelIds": ["SENT"],
"status": "success",
"errorCode": ""
}
Expression Reference
| Expression | Resolves To | Example Use |
|---|---|---|
{{trigger.messageId}} | Message ID from IMAP trigger or upstream node | messageId field |
{{ticket.id}} | Support ticket number created by upstream node | Reply body reference |
{{agent.name}} | Assigned support agent name | Personalizing reply signature |
{{$now | dateFormat:'YYYY-MM-DD'}} | Current date | SLA deadline in reply body |
{{resolution.summary}} | Ticket resolution summary from upstream | Closure reply body content |
Node Policies & GuardRails
| Policy | Rule |
|---|---|
| Credential Storage | Store OAuth credentials in BizFirst Credentials Manager — never hardcode tokens in workflow configuration |
| Reply-All Risk | Default replyToSenderOnly: false is Reply-All — set to true for automated workflows to avoid unintended broadcast replies |
| PII Protection | Do not log reply body content in workflow execution history |
| Quota Management | message/reply costs 100 quota units per send — monitor against 250 units/user/second limit |
| Daily Send Limit | Personal Gmail: 500/day; Workspace: 2,000/day — throttle high-volume reply workflows |
| Thread Integrity | Always use the messageId from the triggering message to preserve thread context |
Examples
Example 1: Auto-Reply to Support Inquiry
An IMAP trigger fires on new support emails. The workflow creates a ticket, then replies with the ticket reference.
{
"nodeType": "Gmail",
"operation": "message/reply",
"credentialId": "a3f9d12b-44e1-4c89-b7d2-9f0a1e2b3c4d",
"messageId": "{{imapTrigger.messageId}}",
"message": "<p>Hi {{imapTrigger.from.name}},</p><p>Your support request has been logged as ticket <strong>#{{helpdesk.ticketId}}</strong>. Expected response time: 24 hours.</p>",
"emailType": "html",
"senderName": "BizFirst Support",
"replyToSenderOnly": true
}
Example 2: CRM Lead Follow-Up
A CRM trigger marks a lead as qualified. The workflow finds the lead's initial inquiry email and sends a follow-up reply.
{
"nodeType": "Gmail",
"operation": "message/reply",
"credentialId": "a3f9d12b-44e1-4c89-b7d2-9f0a1e2b3c4d",
"messageId": "{{crm.lead.initialMessageId}}",
"message": "<p>Hi {{crm.lead.firstName}},</p><p>Thank you for your interest in BizFirst! I'd love to schedule a 30-minute call to learn more about your needs. <a href='{{calendar.bookingLink}}'>Book a time here</a>.</p>",
"emailType": "html",
"senderName": "{{crm.assignedRep.name}}",
"replyToSenderOnly": true
}
Example 3: Ticket Resolution Reply
When a help-desk ticket is closed, reply to the original customer email with the resolution summary.
{
"nodeType": "Gmail",
"operation": "message/reply",
"credentialId": "a3f9d12b-44e1-4c89-b7d2-9f0a1e2b3c4d",
"messageId": "{{ticket.originalMessageId}}",
"message": "<p>Hi {{ticket.customerName}},</p><p>Your ticket #{{ticket.id}} has been resolved: <em>{{ticket.resolutionNote}}</em></p><p>Please let us know if you need further assistance.</p>",
"emailType": "html",
"replyToSenderOnly": true
}