@appcifictechnologies/email-service
v1.0.0
Published
Reusable AWS SES email service for Appcific products
Downloads
16
Maintainers
Readme
@appcifictechnologies/email-service
A reusable AWS SES email service for Appcific products. Handles contact forms, waitlist signups, and custom emails with built-in validation, rate limiting, and beautiful HTML templates.
Features
- 📧 Contact Form Emails - Pre-built templates for contact form submissions
- 📝 Waitlist Management - Handle waitlist signups with optional user confirmations
- 🎨 Beautiful HTML Templates - Professional, responsive email templates
- 🛡️ Rate Limiting - Built-in protection against spam
- ✅ Validation - Input validation for all email types
- 🔧 Fully Customizable - Override templates, destinations, and settings per email
- 📦 TypeScript Support - Full TypeScript definitions included
Installation
npm install @appcifictechnologies/email-service @aws-sdk/client-sesQuick Start
1. Initialize the Service
import { EmailService } from '@appcifictechnologies/email-service';
const emailService = new EmailService(
{
region: 'ap-southeast-2',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
defaultFromEmail: '[email protected]',
defaultToEmail: '[email protected]',
},
// Optional: Rate limiting config
{
windowMs: 15 * 60 * 1000, // 15 minutes
maxRequests: 5, // 5 requests per window
}
);2. Send Contact Form Emails
try {
await emailService.sendContactForm(
{
name: 'John Doe',
email: '[email protected]',
message: 'I would like to learn more about your services.',
},
{
to: '[email protected]', // Optional: override default
rateLimitKey: req.ip, // Optional: for rate limiting
}
);
res.json({ success: true, message: 'Thank you! We will get back to you soon.' });
} catch (error) {
if (error.name === 'ValidationError') {
res.status(400).json({ error: error.message });
} else {
res.status(500).json({ error: 'Failed to send message' });
}
}3. Send Waitlist Emails
try {
await emailService.sendWaitlistNotification(
{
email: '[email protected]',
name: 'Jane Smith',
productName: 'MyAwesomeApp',
additionalInfo: {
interests: 'AI features',
company: 'Acme Corp',
},
},
{
to: '[email protected]',
sendConfirmation: true, // Send confirmation email to user
rateLimitKey: req.ip,
}
);
res.json({ success: true, message: 'Welcome to the waitlist!' });
} catch (error) {
// Handle errors
}4. Send Custom Emails
await emailService.sendEmail({
to: '[email protected]',
from: '[email protected]',
subject: 'Custom Email',
text: 'Plain text content',
html: '<p>HTML content</p>',
replyTo: '[email protected]',
});Usage Examples
Next.js App Router (API Route)
// app/api/contact/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { EmailService, ValidationError } from '@appcifictechnologies/email-service';
const emailService = new EmailService(
{
region: process.env.AWS_REGION!,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
defaultFromEmail: process.env.FROM_EMAIL!,
defaultToEmail: process.env.TO_EMAIL!,
},
{
windowMs: 15 * 60 * 1000,
maxRequests: 5,
}
);
export async function POST(request: NextRequest) {
try {
const data = await request.json();
await emailService.sendContactForm(data, {
rateLimitKey: request.ip || request.headers.get('x-forwarded-for') || 'unknown',
});
return NextResponse.json({
success: true,
message: 'Thank you for contacting us!',
});
} catch (error) {
if (error instanceof ValidationError) {
return NextResponse.json({ error: error.message }, { status: 400 });
}
if (error.message.includes('Rate limit')) {
return NextResponse.json({ error: error.message }, { status: 429 });
}
return NextResponse.json(
{ error: 'Failed to send message' },
{ status: 500 }
);
}
}Express.js
// server.ts
import express from 'express';
import { EmailService, ValidationError } from '@appcifictechnologies/email-service';
const app = express();
app.use(express.json());
const emailService = new EmailService(
{
region: process.env.AWS_REGION!,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
defaultFromEmail: process.env.FROM_EMAIL!,
defaultToEmail: process.env.TO_EMAIL!,
},
{
windowMs: 15 * 60 * 1000,
maxRequests: 5,
}
);
app.post('/api/contact', async (req, res) => {
try {
await emailService.sendContactForm(req.body, {
rateLimitKey: req.ip,
});
res.json({ success: true, message: 'Thank you for contacting us!' });
} catch (error) {
if (error instanceof ValidationError) {
return res.status(400).json({ error: error.message });
}
if (error.message.includes('Rate limit')) {
return res.status(429).json({ error: error.message });
}
res.status(500).json({ error: 'Failed to send message' });
}
});Product-Specific Configuration
You can create product-specific configurations while sharing the same infrastructure:
// Product 1: Website
const websiteEmailService = new EmailService({
region: 'ap-southeast-2',
credentials: { /* shared credentials */ },
defaultFromEmail: '[email protected]',
defaultToEmail: '[email protected]',
});
// Product 2: MyApp
const myAppEmailService = new EmailService({
region: 'ap-southeast-2',
credentials: { /* shared credentials */ },
defaultFromEmail: '[email protected]',
defaultToEmail: '[email protected]',
});Environment Variables
AWS_REGION=ap-southeast-2
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
[email protected]
[email protected]API Reference
EmailService
Constructor
new EmailService(config: EmailServiceConfig, rateLimitConfig?: RateLimitConfig)Methods
sendContactForm(data, options?)- Send contact form emailsendWaitlistNotification(data, options?)- Send waitlist notificationsendEmail(options)- Send custom emailtestConnection()- Test email service configuration
License
MIT
Support
For issues and questions, please contact [email protected]
