UNPKG

@c1x/nest-mailer

Version:

A flexible and easy-to-use mailer module for NestJS applications, supporting multiple email providers including SMTP, AWS SES, and SendGrid.

460 lines (383 loc) 11.1 kB
# @c1x/nest-mailer A flexible and easy-to-use mailer module for NestJS applications, supporting multiple email providers including SMTP, AWS SES, and SendGrid. ## Features - 📧 Multiple provider support (SMTP, AWS SES, SendGrid) - ⚙️ Environment-based configuration - 🚀 Asynchronous module configuration - 📎 Attachment support - 🎨 HTML email support - 💪 Type-safe implementation - 🔍 Detailed error logging ## Installation ```bash npm install @c1x/nest-mailer ``` ## Quick Start 1. Import the MailerModule in your app.module.ts: ```typescript import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { MailerModule } from '@c1x/nest-mailer'; import { join } from 'path'; @Module({ imports: [ ConfigModule.forRoot(), MailerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (configService: ConfigService) => ({ // Required: Provider configuration provider: configService.get('MAIL_PROVIDER', 'sendgrid'), credentials: { apiKey: configService.get('SENDGRID_API_KEY'), }, // Optional: Template configuration templatesDir: join(__dirname, 'templates'), // Only needed if using templates }), }), ], }) export class AppModule {} ``` 2. Configure your environment variables: ```env # Choose your preferred provider and configure accordingly # SendGrid Configuration SENDGRID_API_KEY=your_api_key MAIL_FROM_NAME=Your App Name MAIL_FROM_ADDRESS=noreply@yourapp.com # Or SMTP Configuration SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_SECURE=false SMTP_USER=your-email@gmail.com SMTP_PASS=your-app-password # Or AWS SES Configuration AWS_ACCESS_KEY_ID=your_access_key AWS_SECRET_ACCESS_KEY=your_secret_key AWS_REGION=your_region ``` 3. Use the MailerService in your application: ```typescript import { Injectable } from '@nestjs/common'; import { MailerService } from '@c1x/nest-mailer'; @Injectable() export class AppService { constructor(private readonly mailerService: MailerService) {} async sendWelcomeEmail(userEmail: string) { await this.mailerService.sendMail({ to: userEmail, fromName: 'Your App Name', // New: Separate sender name fromAddress: 'noreply@yourapp.com', // New: Separate sender email subject: 'Welcome to Our App!', text: 'Welcome to our application...', html: '<h1>Welcome!</h1><p>We're glad to have you on board.</p>', }); } } ``` ## Provider Configuration ### SendGrid Configuration ```typescript MailerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (configService: ConfigService) => ({ provider: 'sendgrid', credentials: { apiKey: configService.get('SENDGRID_API_KEY'), }, // Optional template support templatesDir: join(__dirname, 'templates'), }), }), ``` ### SMTP Configuration ```typescript MailerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (configService: ConfigService) => ({ provider: 'smtp', credentials: { host: configService.get('SMTP_HOST'), port: parseInt(configService.get('SMTP_PORT')), secure: configService.get('SMTP_SECURE') === 'true', auth: { user: configService.get('SMTP_USER'), pass: configService.get('SMTP_PASS'), }, }, }), }), ``` ### AWS SES Configuration ```typescript MailerModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (configService: ConfigService) => ({ provider: 'aws-ses', credentials: { accessKeyId: configService.get('AWS_ACCESS_KEY_ID'), secretAccessKey: configService.get('AWS_SECRET_ACCESS_KEY'), region: configService.get('AWS_REGION'), }, }), }), ``` ## API Reference ### MailOptions Interface ```typescript interface MailOptions { // Required fields to: string | string[]; fromName: string; // New: Sender name field fromAddress: string; // New: Sender email field subject: string; // Optional fields text?: string; // Plain text content html?: string; // HTML content template?: string; // Template name (if using templates) context?: any; // Template variables (if using templates) example context variables {'name':'json','email':'example@gmail.com'} attachments?: Array<{ filename: string; content: Buffer | string; contentType?: string; cid?: string; // For inline images }>; } ``` ### Provider Configurations ```typescript interface SmtpConfig { host: string; port: number; secure: boolean; auth: { user: string; pass: string; }; } interface AwsSesConfig { accessKeyId: string; secretAccessKey: string; region: string; } interface SendGridConfig { apiKey: string; } ``` ## Error Handling The module includes built-in error handling. Here's an example of how to handle errors: ```typescript try { await this.mailerService.sendMail({ to: 'user@example.com', from: 'noreply@yourapp.com', subject: 'Test Email', text: 'This is a test email', }); } catch (error) { // Handle specific error types if (error.code === 'EAUTH') { // Handle authentication error } else if (error.code === 'ETIMEDOUT') { // Handle timeout error } throw error; } ``` ### Sending Emails with Attachments Here are different examples of sending emails with attachments: 1. **Send with Buffer attachment:** ```typescript import { Injectable } from '@nestjs/common'; import { MailerService } from '@c1x/nest-mailer'; import * as fs from 'fs'; @Injectable() export class EmailService { constructor(private readonly mailerService: MailerService) {} async sendWithAttachment() { // Read file as buffer const fileBuffer = fs.readFileSync('path/to/file.pdf'); await this.mailerService.sendMail({ to: 'user@example.com', fromAddress: 'noreply@yourapp.com', fromName:"test", subject: 'Document Attached', text: 'Please find the attached document.', attachments: [ { filename: 'document.pdf', content: fileBuffer, contentType: 'application/pdf', } ] }); } } ``` 2. Send with multiple attachments: ```typescript @Injectable() export class EmailService { constructor(private readonly mailerService: MailerService) {} async sendWithMultipleAttachments() { await this.mailerService.sendMail({ to: 'user@example.com', fromAddress: 'noreply@yourapp.com', fromName:"test", subject: 'Multiple Attachments', text: 'Please find the attached files.', attachments: [ { filename: 'report.pdf', content: fs.readFileSync('path/to/report.pdf'), contentType: 'application/pdf', }, { filename: 'image.jpg', content: fs.readFileSync('path/to/image.jpg'), contentType: 'image/jpeg', }, { filename: 'data.csv', content: fs.readFileSync('path/to/data.csv'), contentType: 'text/csv', } ] }); } } ``` 3. Inline images in HTML email: ```typescript @Injectable() export class EmailService { constructor(private readonly mailerService: MailerService) {} async sendWithInlineImages() { await this.mailerService.sendMail({ to: 'user@example.com', fromAddress: 'noreply@yourapp.com', fromName:"test", subject: 'Email with Inline Image', html: ` <h1>Welcome!</h1> <p>Here's our logo:</p> <img src="cid:unique-logo-id" /> `, attachments: [ { filename: 'logo.png', content: fs.readFileSync('path/to/logo.png'), contentType: 'image/png', cid: 'unique-logo-id' // Content ID for referencing in HTML } ] }); } } ``` 4. Send with Base64 attachment: ```typescript @Injectable() export class EmailService { constructor(private readonly mailerService: MailerService) {} async sendWithBase64Attachment() { const base64Content = 'base64_encoded_string'; await this.mailerService.sendMail({ to: 'user@example.com', fromAddress: 'noreply@yourapp.com', fromName:"test", subject: 'Image Attached', html: '<h1>Check out this image!</h1>', attachments: [ { filename: 'image.png', content: base64Content, contentType: 'image/png', } ] }); } } ``` 5. Use the MailerService with templates in your application: ```typescript import { Injectable } from '@nestjs/common'; import { MailerService } from '@c1x/nest-mailer'; @Injectable() export class AppService { constructor(private readonly mailerService: MailerService) {} async sendWelcomeEmail(userEmail: string, userName: string) { await this.mailerService.sendMail({ to: userEmail, fromAddress: 'noreply@yourapp.com', fromName:"test", subject: 'Welcome to Our App!', template: 'welcome', // References welcome.hbs context: { appName: 'YourApp', userName: userName, welcomeMessage: 'We\'re excited to have you on board!' } }); } } ``` ## Best Practices 1. Always use environment variables for sensitive credentials 2. Implement proper error handling 3. Use type-safe interfaces provided by the library 4. Consider implementing a retry mechanism for failed emails 5. Use HTML templates for consistent email styling ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## License MIT ## Support For issues and feature requests, please create an issue in the GitHub repository. <!-- ## Changelog ## [0.0.1] - 2024-12-31 - Initial release - Support for SMTP, AWS SES, and SendGrid providers - Basic email functionality - Environment-based configuration ## [0.0.2] - 2024-12-31 - Initial release - Support for SMTP, AWS SES, and SendGrid providers - Basic email functionality - logic optimized - Environment-based configuration ## [0.0.3] - 2024-12-31 ### Added - Comprehensive attachment examples in documentation - Support for inline images in HTML emails ### Changed - Updated package name to @c1x/nest-mailer ## [0.0.4] - 2024-12-31 ### Added - Comprehensive attachment examples in documentation - Support for inline images in HTML emails ### Changed - Updated package name to @c1x/nest-mailer ## [0.0.5] - 2024-12-31 ### Added - Comprehensive attachment examples in documentation - Support for inline images in HTML emails ### Changed - Updated package name to @c1x/nest-mailer ## [0.0.6] - 2024-12-31 ### Added - Comprehensive attachment examples in documentation - Support for inline images in HTML emails ### Changed - Updated package name to @c1x/nest-mailer ## [0.0.7] - 2024-12-31 ### Added - Comprehensive attachment examples in documentation - Support for inline images in HTML emails - Keywords added ### Changed - Updated package name to @c1x/nest-mailer -->