Appearance
Newsletter Subscription Backend
Backend implementation for the newsletter subscription feature that integrates with Brevo for list management and Resend for welcome emails.
Architecture
API Endpoint
Route: POST /newsletter/subscribe
Controller: SubscriptionsController.subscribe()
Location: apps/server/app/controllers/subscriptions_controller.ts
Service Layer
The system uses two main services:
- BrevoService - Newsletter list management
- ResendService - Transactional email delivery
Data Flow
User Input → Validation → Brevo (List) → Resend (Welcome Email) → Success Response1
Implementation
Controller
typescript
export default class SubscriptionsController {
async subscribe({ request, response }: HttpContext) {
const { email } = await request.validateUsing(subscribeValidator)
try {
// Add to Brevo mailing list
await BrevoService.addSubscriber(email, listId)
// Send welcome email via Resend
await ResendService.sendWelcomeEmail(email)
return response.created(
renderSuccessResponsePayload({
message: 'Successfully subscribed to the newsletter.',
})
)
} catch (error) {
// Handle errors appropriately
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Validation
Email validation is handled by apps/server/app/validators/subscription.ts:
typescript
export const subscribeValidator = vine.compile(
vine.object({
email: vine.string().email().trim(),
})
)1
2
3
4
5
2
3
4
5
Error Handling
The system handles several error scenarios:
- Duplicate Subscribers - Returns 409 Conflict
- Invalid Email - Returns 400 Bad Request
- Service Errors - Returns 500 Internal Server Error
Email Services
The newsletter subscription feature uses the Email Infrastructure for:
- Brevo - Subscriber list management and newsletter campaigns
- Resend - Welcome email delivery and transactional emails
For detailed configuration and service information, see the Email Infrastructure documentation.
Email Templates
Welcome Email
Template: apps/server/resources/views/emails/welcome.edge
Features:
- Responsive design
- Branded styling
- Clear call-to-action
- Unsubscribe link
Content Structure:
html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Jubiloop!</title>
</head>
<body>
<h1>Welcome to Jubiloop!</h1>
<p>Thank you for joining our early access list...</p>
<!-- More content -->
</body>
</html>1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Environment Configuration
Development
bash
# Brevo Configuration
BREVO_API_KEY=dev_brevo_api_key
BREVO_NEWSLETTER_SUBSCRIBER_LIST_ID=dev_list_id
# Resend Configuration
RESEND_API_KEY=dev_resend_api_key
RESEND_FROM_NAME=Jubiloop Dev Team
RESEND_FROM_EMAIL=noreply@dev.jubiloop.ca1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
QA
bash
# Brevo Configuration
BREVO_API_KEY=qa_brevo_api_key
BREVO_NEWSLETTER_SUBSCRIBER_LIST_ID=qa_list_id
# Resend Configuration
RESEND_API_KEY=qa_resend_api_key
RESEND_FROM_NAME=Jubiloop QA Team
RESEND_FROM_EMAIL=noreply@qa.jubiloop.ca1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Production
bash
# Brevo Configuration
BREVO_API_KEY=prod_brevo_api_key
BREVO_NEWSLETTER_SUBSCRIBER_LIST_ID=prod_list_id
# Resend Configuration
RESEND_API_KEY=prod_resend_api_key
RESEND_FROM_NAME=Jubiloop Team
RESEND_FROM_EMAIL=noreply@jubiloop.ca1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
API Reference
Subscribe Endpoint
POST /newsletter/subscribe
Request Body:
json
{
"email": "user@example.com"
}1
2
3
2
3
Success Response (201):
json
{
"success": true,
"message": "Successfully subscribed to the newsletter."
}1
2
3
4
2
3
4
Error Responses:
400 Bad Request (Invalid Email):
json
{
"success": false,
"errorMessage": "Validation failed",
"errors": {
"email": ["The email field must be a valid email address"]
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
409 Conflict (Duplicate Subscriber):
json
{
"success": false,
"errorMessage": "This email is already subscribed to the newsletter."
}1
2
3
4
2
3
4
500 Internal Server Error:
json
{
"success": false,
"errorMessage": "Failed to subscribe to the newsletter."
}1
2
3
4
2
3
4
Testing
Manual Testing
Test Valid Subscription:
bash
curl -X POST http://localhost:3333/newsletter/subscribe \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com"}'1
2
3
2
3
Test Invalid Email:
bash
curl -X POST http://localhost:3333/newsletter/subscribe \
-H "Content-Type: application/json" \
-d '{"email":"invalid-email"}'1
2
3
2
3
Test Duplicate Subscription:
bash
# Run the same email twice
curl -X POST http://localhost:3333/newsletter/subscribe \
-H "Content-Type: application/json" \
-d '{"email":"duplicate@example.com"}'1
2
3
4
2
3
4
Automated Testing
Currently, there are no automated tests for the newsletter subscription feature. Tests should be added for:
- Email validation logic
- Controller response handling
- Brevo/Resend service integration
- Error handling scenarios
Monitoring
Logging
The system logs all subscription attempts:
typescript
logger.info('Newsletter subscription attempt', { email })
logger.error('Newsletter subscription failed', { error, email })1
2
2
Metrics to Track
Subscription Volume
- Daily signup count
- Hourly signup patterns
- Geographic distribution
Success Rates
- Validation success rate
- Brevo integration success rate
- Resend delivery success rate
Error Rates
- Invalid email attempts
- Duplicate subscription attempts
- Service integration failures
Health Checks
Monitor service health through:
bash
# Check Brevo connectivity
curl -H "Authorization: Bearer $BREVO_API_KEY" \
https://api.brevo.com/v3/contacts
# Check Resend connectivity
curl -H "Authorization: Bearer $RESEND_API_KEY" \
https://api.resend.com/domains1
2
3
4
5
6
7
2
3
4
5
6
7
Security
Input Validation
- Email format validation
- Rate limiting (future enhancement)
- XSS protection via Edge templates
Data Protection
- Email addresses stored securely
- GDPR compliance considerations
- Unsubscribe functionality
API Security
- CORS configuration
- Request size limits
- Error message sanitization
Troubleshooting
Common Issues
Brevo API Errors:
- Check API key validity
- Verify list ID exists
- Check API rate limits
Resend Delivery Failures:
- Verify sender email domain
- Check email content
- Monitor bounce rates
Validation Errors:
- Check email format
- Verify request structure
- Review validation rules
Debug Commands
bash
# Check environment variables
echo $BREVO_API_KEY
echo $RESEND_API_KEY
# Test Brevo connection
curl -H "Authorization: Bearer $BREVO_API_KEY" \
https://api.brevo.com/v3/contacts
# Test Resend connection
curl -H "Authorization: Bearer $RESEND_API_KEY" \
https://api.resend.com/emails
# Check server logs
docker logs server | grep subscription1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
Future Enhancements
Planned Features
- Double Opt-in - Email verification before subscription
- Rate Limiting - Prevent abuse of signup endpoint
- Analytics Integration - Track conversion rates
- A/B Testing - Test different email templates
- Segmentation - Group subscribers by interests
Technical Improvements
- Queue System - Async email processing
- Retry Logic - Handle temporary service failures
- Webhook Support - Real-time delivery status
- Template Management - Dynamic email templates
- Unsubscribe API - Programmatic unsubscribe endpoint