Campaigns
Campaigns are automated, multi-step email sequences. Once a contact is enrolled, Gordon CRM automatically sends each email in the sequence at the configured interval — no manual intervention required.
Campaign Types
Gordon CRM supports two campaign types:
Evergreen (Drip) Campaigns
The default type. Each step is defined as a delay (in hours) from the contact's enrollment time.
Example: A welcome sequence that sends:
- Step 1: Immediately (0 hours after enrollment)
- Step 2: 24 hours after enrollment
- Step 3: 72 hours after enrollment
Every contact gets the same sequence, starting from whenever they were enrolled.
Date-Based (Event) Campaigns
Steps are anchored to an event's start time using the before_event timing mode. This lets you send countdown reminders leading up to an event.
Example: A conference reminder sequence:
- Step 1: 168 hours (7 days) before the event
- Step 2: 24 hours before the event
- Step 3: 1 hour before the event
Date-based campaigns can also mix delay and before_event steps in the same sequence. The campaign engine sorts all steps by their calculated absolute timestamp, regardless of timing mode.
Campaign Lifecycle
| Status | Description |
|---|---|
draft | The campaign is being configured. No emails are sent. |
active | The campaign is live. The sweeper will process due enrollments. |
paused | Temporarily suspended. Enrollments are preserved but no emails are sent. Resumes when re-activated. |
archived | Permanently deactivated. |
Campaign Steps
Each step represents one email in the sequence:
| Field | Description |
|---|---|
| Sequence Order | The display order in the campaign builder (not used for scheduling). |
| Timing Mode | delay (hours after enrollment) or before_event (hours before event start). |
| Timing Value | Number of hours for the delay or countdown. Set to 0 for immediate send. |
| Email Subject | Subject line, supports merge fields. |
| Email Body | HTML email body, supports merge fields. |
| Sender Identity | The verified email address to send from. Falls back to workspace default if not set. |
Enrollments
A contact enters a campaign via an automation trigger or manual enrollment. Each enrollment tracks:
| Field | Description |
|---|---|
status | active → processing → completed / cancelled / failed |
current_step_id | The next step to be sent. |
next_action_at | When the sweeper should process this enrollment next. |
completed_step_ids | Array of step IDs already sent (prevents re-sends). |
trigger_event_id | For date-based campaigns, the event whose start time anchors the schedule. |
retry_count | Number of failed attempts (max 3 before marking as failed). |
Enrollment Statuses
| Status | Meaning |
|---|---|
active | Waiting for the next scheduled step. |
processing | Currently being processed by the sweeper (prevents double-sends). |
completed | All steps have been sent. |
cancelled | Manually cancelled by a workspace member, or by a remove_campaign automation. |
failed | Failed after 3 retry attempts (e.g., no sender identity, persistent errors). |
The Campaign Sweeper
A background CRON job runs on a schedule and processes due enrollments:
- Fetch — Queries for
activeenrollments wherenext_action_at ≤ NOW(). - Lock — Sets the enrollment to
processingto prevent duplicate sends. - Validate — Checks the campaign is still
activeand the contact is eligible (not suppressed/unsubscribed). - Send — Resolves merge fields, picks the sender identity, and dispatches via the Resend API.
- Advance — Uses the Universal Step Calculator to determine the next step and updates
next_action_at. If no steps remain, marks the enrollment ascompleted.
The Universal Step Calculator
The engine calculates the absolute timestamp for each remaining step:
- Delay steps:
enrolled_at + timing_value_hours - Before-event steps:
event_start_time - timing_value_hours
It then sorts all eligible steps chronologically, picks the earliest one, and schedules it. This allows mixed-mode campaigns (both delay and before_event steps) to interleave correctly.
5-minute tolerance: Steps due within the past 5 minutes are still eligible. This prevents
delay: 0(immediate) steps from being skipped when the sweeper runs shortly after enrollment.
Pausing and Resuming
When you pause a campaign:
- The sweeper skips all enrollments for that campaign
- Enrollment records are preserved with their current state
- When you re-activate, all enrollments resume from where they left off
Deleting Steps
If you delete a step from an active campaign:
- Enrollments that were waiting on that step will have the sweeper recalculate their next step automatically
- Already-sent emails are unaffected (the email log is preserved)