Send Email Automation Processor
Overview
The Send Email automation sends emails to contacts (persons/businesses) associated with deals when they enter a specific pipeline stage. It supports attachments, merge fields, templating, and tracks delivery status.
Source File: queue-manager/queues/deals/automations/email.js
Triggered By: queue-manager/services/deals/automations.js
Business Impact: HIGH - Customer communication
Processing Logic
sequenceDiagram
participant AUTO as Automation Service
participant QUEUE as Email Queue
participant DEAL as Deals
participant CONTACT as Persons/Businesses
participant MAIL as Mail Utility
participant SENDGRID as SendGrid API
AUTO->>QUEUE: Add automation job
QUEUE->>DEAL: Find eligible deals
QUEUE->>CONTACT: Fetch contact details
loop For Each Deal
QUEUE->>QUEUE: Prepare email body<br/>(merge fields)
QUEUE->>QUEUE: Attach files (if any)
QUEUE->>MAIL: Send email
MAIL->>SENDGRID: Deliver via API
SENDGRID-->>MAIL: Email ID
MAIL-->>QUEUE: Email record created
QUEUE->>DEAL: Log email sent
end
Key Features
Email Components
- Recipients: From deal's person/business contacts
- Subject: Template with merge fields
- Content: HTML/Text with merge fields
- Attachments: File buffers from storage
- Reply-To: Configurable reply address
- Sender: From automation config or user
Merge Fields
Supports dynamic fields:
{{deal.name}}{{person.first_name}}{{business.company}}{{user.name}}- Custom deal fields
Fallback Values
If contact data missing, uses fallback entity values.
Core Code Pattern
// Get email data
const emailData = await getEmailData(automationData);
const { account, user, deals, stage_id, automation, type } = emailData;
const emailBody = emailData.emailBody;
// Send each email
for (const e of emailBody) {
const {
files,
recipients,
subject,
reply_to,
sender,
content,
origin,
business,
person,
deal,
fallback_entity,
} = e;
const emailUtil = new Mail();
const sentEmail = await emailUtil.send({
mailBody: {
files,
recipients,
reply_to,
subject,
sender,
content,
origin,
},
accountID: account,
userID: user,
personID: person,
businessID: business,
fallbackValues: fallback_entity,
});
if (sentEmail._id) {
// Success: email record created
}
}
Collections Used
Input: deal-automation
- Email configuration
Query: deal
- Find eligible deals
Query: person / business
- Get contact details
Create: communication
- Email records
Email Data Structure
{
recipients: ['email@example.com'],
subject: 'Welcome to {{stage.name}}',
content: '<html>...</html>',
sender: {
name: 'Sales Team',
email: 'sales@company.com'
},
reply_to: 'support@company.com',
files: [
{
filename: 'brochure.pdf',
content: Buffer,
type: 'application/pdf'
}
],
origin: 'automation'
}
Error Handling
Common Errors
- No Recipients: Contact has no email
- Invalid Email: Malformed email address
- SendGrid Failure: API error
- Attachment Too Large: File size limit
- Template Error: Merge field missing
Error Response
{
message: "Something went wrong while sending email.",
deal: dealID,
business: businessID,
person: personID,
additional_info: {...}
}
Use Cases
Example 1: Welcome Email
// Automation
{
stage_id: "new_lead",
action: "send_email",
data: {
subject: "Welcome {{person.first_name}}!",
content: "<p>Thank you for your interest...</p>",
recipients: "person"
},
delay: 0
}
Example 2: Follow-Up with Attachment
// Automation
{
stage_id: "proposal_sent",
action: "send_email",
data: {
subject: "Your Proposal from {{user.name}}",
content: "<p>Please review the attached proposal...</p>",
files: ["proposal-template.pdf"],
recipients: "person,business"
},
delay: 3600 // 1 hour
}
Performance
Execution Time: 500-2000ms per email
Batch Size: All eligible deals (sent in parallel)
Rate Limiting: SendGrid limits apply
Retry Strategy: 3 attempts with exponential backoff
Complexity: MEDIUM-HIGH
Lines of Code: 296