DEE Docs
Channels

Email Channel

Sending deterministic, trackable outbound emails through the execution engine.

Overview

The email channel handles outbound email delivery as a deterministic step in an execution plan. Every email sent is tracked, logged, and idempotent.

Configuration

import { EmailChannel } from '@dee/channels-email';

const email = new EmailChannel({
  provider: 'smtp',
  host: process.env.SMTP_HOST,
  port: 587,
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
  defaults: {
    from: 'outreach@example.com',
    replyTo: 'team@example.com',
  },
  tracking: {
    opens: true,    // pixel tracking
    clicks: true,   // link wrapping
    domain: 'track.example.com',
  },
});

Templates

Email templates use Handlebars syntax with access to the execution context:

Subject: {{subject}}

Hi {{contact.firstName}},

{{#if previousStep.result.opened}}
I noticed you opened my previous email — wanted to follow up.
{{else}}
I wanted to make sure my last message didn't get buried.
{{/if}}

Best,
{{sender.name}}

Available template variables:

VariableDescription
contact.*Contact attributes (email, firstName, company, etc.)
sender.*Sender information
previousStep.*Result of the previous step
run.*Current execution run metadata
unsubscribeUrlOne-click unsubscribe link

Events

The email channel emits events that feed back into the execution context:

EventTriggerTypical Delay
email.deliveredSMTP acceptedImmediate
email.bouncedHard/soft bounceSeconds to minutes
email.openedTracking pixel loadedMinutes to days
email.clickedTracked link clickedMinutes to days
email.repliedReply received (via webhook)Minutes to days
email.unsubscribedUnsubscribe link clickedImmediate

These events are ingested into the ordered event queue and become available to subsequent branch steps.

Deliverability

The engine enforces deliverability best practices:

  • Rate limiting — Respects per-domain send limits to avoid throttling
  • Warm-up — Gradually increases send volume for new domains/IPs
  • Bounce handling — Automatically pauses runs for hard-bounced contacts
  • Unsubscribe — Stops all runs for a contact when they unsubscribe
  • Suppression list — Global suppression list checked before every send

Error Handling

ErrorBehavior
SMTP connection failureRetry with exponential backoff (max 3 attempts)
Rate limit (429)Pause and retry on next tick
Hard bounceMark contact as undeliverable, end run
Soft bounceRetry up to 3 times over 24 hours
Template render errorFail step, log error with context

On this page