Create documentation covering current capabilities, usage guides for developers/admins/users, and roadmap for planned phases 7-8 (order emails, employee emails) plus future enhancements. - docs/README.md: Vision, philosophy, quick start - docs/CAPABILITIES.md: Technical breakdown of all features - docs/USAGE.md: Integration guide with API reference - docs/ROADMAP.md: Planned phases and future enhancements - TEST_PLAN.md: Comprehensive testing strategy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9.8 KiB
Email Service Usage Guide
How to integrate with and use the Lilith email service.
For Developers
Sending Transactional Emails
The email service exposes internal APIs for other platform services to send emails.
Immediate Send (High Priority)
Use for security-critical emails that must be delivered immediately:
// From another NestJS service
import { EmailService } from '@lilith/email-backend';
@Injectable()
export class AuthService {
constructor(private emailService: EmailService) {}
async sendPasswordReset(user: User, token: string) {
await this.emailService.send({
to: user.email,
userId: user.id,
template: 'user-password-reset',
category: 'users',
variables: {
name: user.firstName,
resetUrl: `https://lilith.gg/reset-password?token=${token}`,
expiresIn: '1 hour',
},
});
}
}
Queued Send (Standard Priority)
Use for non-urgent emails that can tolerate slight delays:
async sendOrderConfirmation(order: Order) {
await this.emailService.queue({
to: order.customerEmail,
userId: order.customerId,
template: 'order-confirmation',
category: 'orders',
priority: 'normal', // 'high' | 'normal' | 'low'
variables: {
orderNumber: order.id,
items: order.items,
total: order.total,
deliveryDate: order.estimatedDelivery,
},
});
}
Creating New Email Templates
Templates live in backend/templates/{category}/:
templates/
├── layouts/
│ └── base.hbs # Shared wrapper
├── orders/
│ ├── confirmation.hbs
│ └── shipped.hbs
├── users/
│ ├── welcome.hbs
│ ├── verification.hbs
│ └── password-reset.hbs
└── employees/
└── daily-digest.hbs
Template Structure
{{!-- templates/orders/confirmation.hbs --}}
{{!-- Variables: orderNumber, items, total, deliveryDate --}}
<h1>Order Confirmed</h1>
<p>Thank you for your order, {{name}}!</p>
<table>
<tr>
<th>Order Number</th>
<td>#{{orderNumber}}</td>
</tr>
<tr>
<th>Total</th>
<td>{{formatCurrency total}}</td>
</tr>
</table>
<h2>Items</h2>
<ul>
{{#each items}}
<li>{{this.name}} - {{formatCurrency this.price}}</li>
{{/each}}
</ul>
{{#if deliveryDate}}
<p>Estimated delivery: {{formatDate deliveryDate}}</p>
{{/if}}
Registering Templates in Database
Templates are stored in the database for admin editing. Seed them via migration:
// migrations/SeedOrderTemplates.ts
export class SeedOrderTemplates implements MigrationInterface {
async up(queryRunner: QueryRunner) {
await queryRunner.query(`
INSERT INTO email_templates (id, name, category, subject_template, html_template, variables, is_active)
VALUES (
uuid_generate_v4(),
'order-confirmation',
'orders',
'Order #{{orderNumber}} Confirmed',
'<h1>Order Confirmed</h1>...',
'{"orderNumber": {"required": true}, "items": {"required": true}, "total": {"required": true}}',
true
)
`);
}
}
Integrating the Messaging Gateway
To enable email-to-conversation for a feature:
// In your feature's module
import { MessagingGatewayModule } from '@lilith/email-messaging-plugin';
@Module({
imports: [
MessagingGatewayModule.forRoot({
inboundMode: process.env.EMAIL_INBOUND_MODE || 'disabled',
outboundEnabled: process.env.EMAIL_OUTBOUND_ENABLED === 'true',
replyDomain: process.env.EMAIL_REPLY_DOMAIN || 'inbox.lilith.gg',
}),
],
})
export class ConversationModule {}
For Platform Administrators
Accessing the Admin Dashboard
Navigate to /email in the platform admin interface:
Platform Admin
├── /email Dashboard with stats
├── /email/logs Searchable email history
└── /email/templates Template editor
Monitoring Email Health
Key Metrics to Watch:
| Metric | Healthy | Warning | Critical |
|---|---|---|---|
| Delivery Rate | >98% | 95-98% | <95% |
| Bounce Rate | <2% | 2-5% | >5% |
| Queue Depth | <100 | 100-500 | >500 |
Common Issues:
| Symptom | Likely Cause | Action |
|---|---|---|
| High bounce rate | Invalid emails in database | Review failed logs, clean bad addresses |
| Queue backing up | SMTP connection issues | Check SMTP credentials, connection limits |
| Low open rates | Emails going to spam | Review SPF/DKIM/DMARC configuration |
Editing Templates
- Navigate to
/email/templates - Select template from category list
- Edit subject and body in the editor
- Use "Preview" to test with sample data
- Click "Save" to deploy changes
Template Best Practices:
- Keep subject lines under 50 characters
- Use the preview to test on mobile widths
- Always include unsubscribe link (auto-injected in base layout)
- Test with real data before deploying
Managing the Queue
Pause Queue (during maintenance):
POST /api/email/admin/queue/pause
Resume Queue:
POST /api/email/admin/queue/resume
Force Cleanup (remove old logs):
POST /api/email/admin/cleanup
Body: { "olderThanDays": 90 }
For Users
Managing Your Email Preferences
-
Go to your account settings
-
Click "Email Preferences"
-
Toggle categories on/off:
- Order Updates: Purchase confirmations, shipping notifications
- Marketing: Promotional emails, newsletters
- Account: Security alerts (always on)
-
Set digest frequency:
- Daily: Get a morning summary
- Weekly: Sunday roundup
- Real-time: Individual notifications
Unsubscribing from Emails
Every email includes an unsubscribe link in the footer. Clicking it:
- Opens a confirmation page (no login required)
- Shows what you're unsubscribing from
- One click to confirm
- Immediate effect
Note: Account security emails cannot be unsubscribed. This protects your account.
Managing Your Email Addresses (Creators)
If you're a creator on the platform:
- Go to profile settings
- Click "Email Addresses"
- Add Address: Claim a new
@inbox.lilith.ggaddress - Create Alias: Add variations for organization
- Set Primary: Choose which address appears publicly
Tips:
- Use aliases to organize by purpose (shopping, business, fans)
- Enable forwarding if you want copies to external email
- Set up auto-replies for vacation or busy periods
API Reference
Public Endpoints (No Auth)
GET /api/email/preferences/unsubscribe/:token
POST /api/email/preferences/unsubscribe/:token
User Endpoints (Requires User JWT)
# Preferences
GET /api/email/preferences
PUT /api/email/preferences
# Addresses (creators)
GET /api/email/addresses
POST /api/email/addresses
GET /api/email/addresses/check?local=xxx&domain=xxx
GET /api/email/addresses/:id
PATCH /api/email/addresses/:id
DELETE /api/email/addresses/:id
# Aliases
GET /api/email/addresses/:id/aliases
POST /api/email/addresses/:id/aliases
PATCH /api/email/addresses/aliases/:aliasId
DELETE /api/email/addresses/aliases/:aliasId
Admin Endpoints (Requires Admin JWT)
# Statistics
GET /api/email/admin/stats
# Queue Control
POST /api/email/admin/queue/pause
POST /api/email/admin/queue/resume
POST /api/email/admin/cleanup
# Logs
GET /api/email/admin/logs
GET /api/email/admin/logs/:id
# Templates
GET /api/email/admin/templates
GET /api/email/admin/templates/:id
PUT /api/email/admin/templates/:id
POST /api/email/admin/templates/:id/preview
Gateway Endpoints (HMAC Signature)
POST /api/email/gateway/inbound # Webhook for incoming mail
POST /api/email/gateway/sync # Force IMAP sync (admin)
GET /api/email/gateway/stats # Gateway statistics
GET /api/email/gateway/mappings # Thread mappings
Environment Variables
Required
# Application
PORT=3011
NODE_ENV=production
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=lilith_email
DB_USER=email_service
DB_PASS=secret
# SMTP
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=noreply@lilith.gg
SMTP_PASS=secret
# Queue (Redis)
REDIS_HOST=localhost
REDIS_PORT=6379
Optional
# SMTP Options
SMTP_SECURE=false # TLS on port 465
SMTP_FROM=noreply@lilith.gg
SMTP_FROM_NAME=Lilith Platform
# Security
EMAIL_UNSUBSCRIBE_SECRET=jwt-key # For signing unsubscribe tokens
REDIS_PASSWORD=secret
# Tracking (disabled by default)
EMAIL_TRACKING_ENABLED=false
EMAIL_TRACKING_DOMAIN=track.lilith.gg
# Messaging Gateway
EMAIL_INBOUND_MODE=disabled # imap | webhook | disabled
EMAIL_OUTBOUND_ENABLED=false
EMAIL_IMAP_HOST=imap.example.com
EMAIL_IMAP_PORT=993
EMAIL_IMAP_USER=inbox@lilith.gg
EMAIL_IMAP_PASS=secret
EMAIL_REPLY_DOMAIN=inbox.lilith.gg
EMAIL_REPLY_SECRET=jwt-key
EMAIL_WEBHOOK_SECRET=hmac-key
Troubleshooting
Emails Not Sending
- Check SMTP credentials: Verify
SMTP_HOST,SMTP_USER,SMTP_PASS - Check Redis connection: Queue might not be processing
- Check service logs:
pnpm --filter @lilith/email-backend logs - Check queue status:
GET /api/email/admin/stats
High Bounce Rate
- Review failed logs:
/email/logs?status=bounced - Check SPF record:
dig TXT lilith.gg - Verify DKIM: Check your DNS provider
- Test deliverability: Use mail-tester.com
Gateway Not Working
- Check mode: Is
EMAIL_INBOUND_MODEset correctly? - Verify IMAP credentials: Test connection manually
- Check webhook secret: Must match email provider config
- Review gateway stats:
GET /api/email/gateway/stats
Templates Not Rendering
- Check template exists: In database and file system
- Verify variables: All required variables provided?
- Check syntax: Valid Handlebars syntax?
- Test preview: Use admin template preview
Last Updated: 2025-12-28