EMAIL SERVICE - nself-org/nchat GitHub Wiki
Complete guide to the email service in Ι³Chat v0.9.1.
- Overview
- Architecture
- Configuration
- Email Templates
- Usage Examples
- Development with Mailpit
- Production with SendGrid
- Troubleshooting
Ι³Chat includes a unified email service that supports multiple providers:
- Console (Development): Logs emails to console for testing
- SMTP (Development): Mailpit for local email testing
- SendGrid (Production): Transactional email delivery
- Automatic provider selection based on environment
- React Email templates for beautiful emails
- Welcome emails, password resets, email verification, 2FA codes
- Login notifications and security alerts
- Sensitive data filtering
- Error handling and retry logic
Location: src/lib/email/email.service.ts
The EmailService class provides a unified interface for all email operations:
class EmailService {
// Send generic email
async send(options: EmailOptions): Promise<boolean>
// Authentication emails
async sendEmailVerification(options: EmailVerificationOptions): Promise<boolean>
async sendPasswordReset(options: PasswordResetOptions): Promise<boolean>
async send2FACode(options: TwoFactorCodeOptions): Promise<boolean>
async sendMagicLink(options: MagicLinkOptions): Promise<boolean>
// Notification emails
async sendWelcomeEmail(options: WelcomeEmailOptions): Promise<boolean>
async sendNewLoginNotification(options: NewLoginOptions): Promise<boolean>
async sendPasswordChangedNotification(options: PasswordChangedOptions): Promise<boolean>
}The service automatically selects the provider:
constructor() {
const hasSendGrid = !!process.env.SENDGRID_API_KEY
const hasSmtp = !!process.env.SMTP_HOST
const isDevelopment = process.env.NODE_ENV === 'development'
if (hasSendGrid) {
this.provider = 'sendgrid' // Production
} else if (hasSmtp) {
this.provider = 'smtp' // Development with Mailpit
} else if (isDevelopment) {
this.provider = 'console' // Fallback for dev
}
}Add to .env.local:
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# EMAIL CONFIGURATION
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Email provider: sendgrid | smtp | console
EMAIL_PROVIDER=console
# SendGrid (Production)
SENDGRID_API_KEY=SG.your-sendgrid-api-key
# Email sender details
[email protected]
EMAIL_FROM_NAME=Ι³Chat
# SMTP Configuration (Development with Mailpit)
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_SECURE=false
SMTP_USER=
SMTP_PASSWORD=
# SMTP Configuration (Production)
# Example: Gmail, SendGrid SMTP, AWS SES
# SMTP_HOST=smtp.gmail.com
# SMTP_PORT=587
# SMTP_SECURE=true
# [email protected]
# SMTP_PASSWORD=your-app-passwordMailpit is a local email testing tool that captures all emails:
- Install Mailpit:
# macOS
brew install mailpit
# Or run with Docker
docker run -d \
--name mailpit \
-p 1025:1025 \
-p 8025:8025 \
axllent/mailpit- Start Mailpit:
mailpit- View emails:
- Web UI: http://localhost:8025
- SMTP server: localhost:1025
- Configure Ι³Chat:
# .env.local
SMTP_HOST=localhost
SMTP_PORT=1025-
Create SendGrid account: https://sendgrid.com
-
Generate API key:
- Go to Settings β API Keys
- Create API Key with "Mail Send" permissions
- Copy the API key
-
Configure Ι³Chat:
# .env.local
SENDGRID_API_KEY=SG.your-sendgrid-api-key
[email protected]
EMAIL_FROM_NAME=Your App Name- Verify sender domain:
- Go to Settings β Sender Authentication
- Verify your domain or single sender email
All templates are built with React Email for responsive, beautiful emails.
Template: src/emails/templates/email-verification.tsx
Usage:
import { emailService } from '@/lib/email/email.service'
await emailService.sendEmailVerification({
to: '[email protected]',
userName: 'John Doe',
verificationUrl: 'https://nchat.app/verify-email?token=abc123',
verificationCode: '123456', // Optional
expiresInHours: 24,
})Template: src/emails/templates/password-reset.tsx
Usage:
await emailService.sendPasswordReset({
to: '[email protected]',
userName: 'John Doe',
resetUrl: 'https://nchat.app/reset-password?token=abc123',
expiresInMinutes: 60,
ipAddress: '192.168.1.1',
userAgent: 'Mozilla/5.0...',
})Template: Inline HTML (in email.service.ts)
Usage:
await emailService.send2FACode({
to: '[email protected]',
userName: 'John Doe',
code: '123456',
expiresInMinutes: 10,
})Template: Inline HTML (in email.service.ts)
Usage:
await emailService.sendMagicLink({
to: '[email protected]',
userName: 'John Doe',
magicLinkUrl: 'https://nchat.app/magic-login?token=abc123',
expiresInMinutes: 15,
})Template: src/emails/templates/welcome.tsx
Usage:
await emailService.sendWelcomeEmail({
to: '[email protected]',
userName: 'John Doe',
loginUrl: 'https://nchat.app/login',
})Template: src/emails/templates/new-login.tsx
Usage:
await emailService.sendNewLoginNotification({
to: '[email protected]',
userName: 'John Doe',
ipAddress: '192.168.1.1',
location: 'San Francisco, CA',
userAgent: 'Mozilla/5.0...',
})Template: src/emails/templates/password-changed.tsx
Usage:
await emailService.sendPasswordChangedNotification({
to: '[email protected]',
userName: 'John Doe',
ipAddress: '192.168.1.1',
})Email service is integrated in all authentication routes:
Location: src/app/api/auth/signup/route.ts
import { emailService } from '@/lib/email/email.service'
// Send welcome email after successful signup
await emailService.sendWelcomeEmail({
to: email,
userName: displayName,
loginUrl: `${process.env.NEXT_PUBLIC_APP_URL}/login`,
})
// Send verification email if required
await emailService.sendEmailVerification({
to: email,
userName: displayName,
verificationUrl: `${process.env.NEXT_PUBLIC_APP_URL}/verify-email?token=${verificationToken}`,
expiresInHours: 24,
})Location: src/app/api/auth/password-reset/route.ts
// Send password reset email
await emailService.sendPasswordReset({
to: email,
userName: user.displayName,
resetUrl: `${process.env.NEXT_PUBLIC_APP_URL}/reset-password?token=${resetToken}`,
expiresInMinutes: 60,
ipAddress: req.headers['x-forwarded-for'] || req.ip,
userAgent: req.headers['user-agent'],
})Location: src/app/api/auth/2fa/verify-setup/route.ts
// Send 2FA code during setup
await emailService.send2FACode({
to: user.email,
userName: user.displayName,
code: verificationCode,
expiresInMinutes: 10,
})import { emailService } from '@/lib/email/email.service'
// Send custom email
const success = await emailService.send({
to: '[email protected]',
subject: 'Custom Email Subject',
html: '<h1>Hello World</h1><p>This is a custom email.</p>',
text: 'Hello World\n\nThis is a custom email.',
})
if (success) {
console.log('Email sent successfully')
} else {
console.error('Failed to send email')
}// Send to multiple recipients
await emailService.send({
to: ['[email protected]', '[email protected]', '[email protected]'],
subject: 'Announcement',
html: '<p>Important announcement for all users.</p>',
})- No API keys required: Works locally without external services
- Email testing: View all sent emails in web UI
- Fast development: Instant email delivery
- Email debugging: Inspect HTML, headers, attachments
- Link testing: Click links directly from emails
- Start Mailpit:
mailpit - Open web UI: http://localhost:8025
- Send emails from Ι³Chat
- View emails in real-time
- Inbox: View all captured emails
- Search: Search by subject, recipient, date
- Raw view: View raw email source
- HTML view: Render HTML emails
- Plain text view: View plain text version
- Headers: Inspect email headers
- Download: Download email as .eml file
- Create SendGrid account
- Generate API key with "Mail Send" permissions
- Add API key to
.env.local - Verify sender domain or email
- Test email sending
- Monitor email delivery in SendGrid dashboard
- Domain Verification: Verify your domain for better deliverability
- SPF/DKIM: Set up SPF and DKIM records
- Suppression Lists: Manage bounces and unsubscribes
- Rate Limiting: Respect SendGrid's rate limits
- Monitoring: Monitor delivery rates in dashboard
- Templates: Use SendGrid templates for consistent branding
- Activity: View sent emails and delivery status
- Stats: Email delivery metrics
- Suppressions: Manage bounces, blocks, spam reports
- Settings: Configure sender authentication, webhooks
- Free tier: 100 emails/day
- Essentials: $19.95/month for 40,000 emails
- Pro: $89.95/month for 100,000 emails
1. "Email not sent"
- Check provider is configured correctly
- Verify environment variables are set
- Check email service logs:
logger.info('[Email]') - Test with console provider first
2. "SendGrid authentication failed"
- Verify
SENDGRID_API_KEYis correct - Check API key permissions (needs "Mail Send")
- Ensure API key hasn't expired
3. "Emails going to spam"
- Verify sender domain in SendGrid
- Set up SPF and DKIM records
- Avoid spam trigger words in subject
- Include unsubscribe link
4. "SMTP connection failed"
- Check Mailpit is running:
ps aux | grep mailpit - Verify SMTP_HOST and SMTP_PORT
- Check firewall rules
5. "Template rendering error"
- Ensure React Email is installed:
@react-email/render - Check template file exists
- Verify template props match interface
Enable email debug logging:
import { logger } from '@/lib/logger'
// In email.service.ts
logger.info('[Email] Sending email', {
to: options.to,
subject: options.subject,
provider: this.provider,
})// Test email sending
import { emailService } from '@/lib/email/email.service'
// Test console provider
process.env.NODE_ENV = 'development'
await emailService.send({
to: '[email protected]',
subject: 'Test Email',
html: '<p>This is a test email.</p>',
})
// Check console for email content
// Should see: [Email] Console mode - Email would be sent- SendGrid Docs: https://docs.sendgrid.com
- Mailpit GitHub: https://github.com/axllent/mailpit
- React Email: https://react.email
- Email Best Practices: https://sendgrid.com/blog/email-best-practices
For issues or questions:
- GitHub Issues: https://github.com/nself-org/nself-chat/issues
- Discord: https://discord.gg/nself
- Email: [email protected]