platform-codebase/features/email/docs/USAGE.md

423 lines
9.8 KiB
Markdown
Executable file

# 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:
```typescript
// 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:
```typescript
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
```handlebars
{{!-- 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:
```typescript
// 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:
```typescript
// 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
1. Navigate to `/email/templates`
2. Select template from category list
3. Edit subject and body in the editor
4. Use "Preview" to test with sample data
5. 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
1. Go to your account settings
2. Click "Email Preferences"
3. Toggle categories on/off:
- **Order Updates**: Purchase confirmations, shipping notifications
- **Marketing**: Promotional emails, newsletters
- **Account**: Security alerts (always on)
4. 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:
1. Opens a confirmation page (no login required)
2. Shows what you're unsubscribing from
3. One click to confirm
4. 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:
1. Go to profile settings
2. Click "Email Addresses"
3. **Add Address**: Claim a new `@inbox.lilith.gg` address
4. **Create Alias**: Add variations for organization
5. **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
```env
# 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
```env
# 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
1. **Check SMTP credentials**: Verify `SMTP_HOST`, `SMTP_USER`, `SMTP_PASS`
2. **Check Redis connection**: Queue might not be processing
3. **Check service logs**: `pnpm --filter @lilith/email-backend logs`
4. **Check queue status**: `GET /api/email/admin/stats`
### High Bounce Rate
1. **Review failed logs**: `/email/logs?status=bounced`
2. **Check SPF record**: `dig TXT lilith.gg`
3. **Verify DKIM**: Check your DNS provider
4. **Test deliverability**: Use mail-tester.com
### Gateway Not Working
1. **Check mode**: Is `EMAIL_INBOUND_MODE` set correctly?
2. **Verify IMAP credentials**: Test connection manually
3. **Check webhook secret**: Must match email provider config
4. **Review gateway stats**: `GET /api/email/gateway/stats`
### Templates Not Rendering
1. **Check template exists**: In database and file system
2. **Verify variables**: All required variables provided?
3. **Check syntax**: Valid Handlebars syntax?
4. **Test preview**: Use admin template preview
---
**Last Updated**: 2025-12-28