125 lines
4.3 KiB
Markdown
125 lines
4.3 KiB
Markdown
# Waitlist Email Sequence — Implementation Guide
|
|
|
|
## Overview
|
|
|
|
This document describes how to integrate the waitlist email templates into the waitlist signup flow. The 4-email welcome sequence is designed for new ShieldAI waitlist signups.
|
|
|
|
## Templates Added
|
|
|
|
| # | Template ID | Timing | Purpose |
|
|
|---|---|---|---|
|
|
| 1 | `waitlist_confirmation` | Immediate | Confirm waitlist signup, show position |
|
|
| 2 | `waitlist_intro` | Day +1 | Introduce ShieldAI and the problem it solves |
|
|
| 3 | `waitlist_features` | Day +3 | Deep dive into product features |
|
|
| 4 | `waitlist_launch_teaser` | Day +7 | Launch teaser, early adopter perks |
|
|
|
|
**File:** `packages/shared-notifications/src/templates/default-templates.ts`
|
|
- All 4 templates use `buildEmailHtml()` from `waitlist-email-layout.ts` for consistent dark-themed, responsive HTML email rendering with the ShieldAI brand (Inter font, #0a0f1e dark background, #3b82f6→#06b6d4 gradient accent).
|
|
- Spanish locale (`es`) is provided for template 1.
|
|
|
|
## Variables per Template
|
|
|
|
### `waitlist_confirmation`
|
|
| Variable | Type | Required | Default |
|
|
|---|---|---|---|
|
|
| `name` | string | no | "there" |
|
|
| `position` | string | **yes** | — |
|
|
| `unsubscribe_url` | string | no | `https://shieldai.com/unsubscribe` |
|
|
|
|
### `waitlist_intro`
|
|
| Variable | Type | Required | Default |
|
|
|---|---|---|---|
|
|
| `name` | string | no | "there" |
|
|
| `unsubscribe_url` | string | no | `https://shieldai.com/unsubscribe` |
|
|
|
|
### `waitlist_features`
|
|
| Variable | Type | Required | Default |
|
|
|---|---|---|---|
|
|
| `name` | string | no | "there" |
|
|
| `unsubscribe_url` | string | no | `https://shieldai.com/unsubscribe` |
|
|
|
|
### `waitlist_launch_teaser`
|
|
| Variable | Type | Required | Default |
|
|
|---|---|---|---|
|
|
| `name` | string | no | "there" |
|
|
| `referral_url` | string | no | `https://shieldai.com/waitlist` |
|
|
| `unsubscribe_url` | string | no | `https://shieldai.com/unsubscribe` |
|
|
|
|
## Integration Points
|
|
|
|
### 1. Immediate Email (on signup)
|
|
|
|
In `packages/api/src/routes/waitlist.routes.ts`, after `prisma.waitlistEntry.create()` succeeds:
|
|
|
|
```typescript
|
|
import { EmailService } from '@shieldai/shared-notifications';
|
|
|
|
// Send confirmation immediately
|
|
await EmailService.getInstance().sendWithTemplate(email, {
|
|
templateId: 'waitlist_confirmation',
|
|
locale: 'en', // derive from request if available
|
|
variables: {
|
|
name: body.name || 'there',
|
|
position: String(waitlistCount),
|
|
},
|
|
});
|
|
```
|
|
|
|
### 2. Scheduled Emails (Day 1, 3, 7)
|
|
|
|
Use a job queue (BullMQ is already planned) to schedule the subsequent emails:
|
|
|
|
```typescript
|
|
// On signup, enqueue 3 scheduled jobs
|
|
await emailQueue.add('send-waitlist-email', {
|
|
email: body.email,
|
|
name: body.name,
|
|
templateId: 'waitlist_intro',
|
|
}, { delay: 24 * 60 * 60 * 1000 }); // +1 day
|
|
|
|
await emailQueue.add('send-waitlist-email', {
|
|
email: body.email,
|
|
name: body.name,
|
|
templateId: 'waitlist_features',
|
|
}, { delay: 3 * 24 * 60 * 60 * 1000 }); // +3 days
|
|
|
|
await emailQueue.add('send-waitlist-email', {
|
|
email: body.email,
|
|
name: body.name,
|
|
templateId: 'waitlist_launch_teaser',
|
|
}, { delay: 7 * 24 * 60 * 60 * 1000 }); // +7 days
|
|
```
|
|
|
|
If BullMQ is not yet available, use `setTimeout` or a simple `cron`-based approach:
|
|
|
|
```typescript
|
|
// packages/api/src/jobs/waitlist-emails.ts
|
|
// Run on a cron every hour, check for pending scheduled emails
|
|
// Store scheduled_at in WaitlistEntry metadata or a separate table
|
|
```
|
|
|
|
### 3. Rate Limiting
|
|
|
|
The `EmailService` already enforces a default rate limit of 60 emails/minute per recipient. No additional rate limit config should be needed for the waitlist flow.
|
|
|
|
### 4. Unsubscribe Handling
|
|
|
|
The email footer includes an `{{unsubscribe_url}}` variable. Implement a standard unsubscribe endpoint:
|
|
|
|
- `GET /api/unsubscribe?token=<token>` — one-click unsubscribe
|
|
- Store unsubscribe preferences per email address
|
|
|
|
## Testing
|
|
|
|
1. **Unit test:** Verify template rendering with `TemplateService.getInstance().resolveTemplate()`
|
|
2. **Integration test:** Call `POST /api/waitlist/signup` and verify email is sent (use Resend test API keys)
|
|
3. **Manual test:** Use Resend email preview to verify rendering across Gmail, Outlook, Apple Mail
|
|
|
|
## Rollout Checklist
|
|
|
|
- [ ] Add `RESEND_API_KEY` to production environment
|
|
- [ ] Verify templates render correctly via Resend API
|
|
- [ ] Test unsubscribe flow
|
|
- [ ] Verify rate limits for launch-day traffic spike
|
|
- [ ] Monitor email delivery (bounce rate, open rate) post-launch
|