Prerequisites
To get the most out of this guide, you’ll need to:- Create a SendPost Account
- NestJS 9+
- Node.js 16+
- A Sub-Account API Key from your SendPost dashboard
You can find your API keys in your SendPost Dashboard. Make sure to use your Sub-Account API Key for sending emails.
1. Install Dependencies
npm
npm install sendpost-js-sdk
npm install --save-dev @types/node
2. Create Email Module
Createsrc/email/email.module.ts:
TypeScript
import { Module } from '@nestjs/common';
import { EmailService } from './email.service';
@Module({
providers: [EmailService],
exports: [EmailService],
})
export class EmailModule {}
3. Create Email Service
Createsrc/email/email.service.ts:
TypeScript
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import sendpost from 'sendpost-js-sdk';
const emailApi = new sendpost.EmailApi();
@Injectable()
export class EmailService {
private readonly apiKey: string;
private readonly fromEmail: string;
private readonly fromName: string;
constructor(private configService: ConfigService) {
this.apiKey = this.configService.get<string>('SENDPOST_API_KEY') || '';
this.fromEmail = this.configService.get<string>('SENDPOST_FROM_EMAIL') || 'hello@playwithsendpost.io';
this.fromName = this.configService.get<string>('SENDPOST_FROM_NAME') || 'SendPost';
}
async sendEmail({
to,
subject,
htmlBody,
textBody,
from,
groups,
trackOpens = true,
trackClicks = true,
customFields,
}: {
to: string | Array<{ email: string; name?: string; customFields?: Record<string, any> }>;
subject: string;
htmlBody: string;
textBody?: string;
from?: { email: string; name?: string };
groups?: string[];
trackOpens?: boolean;
trackClicks?: boolean;
customFields?: Record<string, any>;
}) {
try {
const emailMessage = new sendpost.EmailMessage();
emailMessage.from = from || {
email: this.fromEmail,
name: this.fromName,
};
// Handle single email or array of recipients
if (typeof to === 'string') {
emailMessage.to = [{ email: to }];
} else {
emailMessage.to = to.map(recipient => {
if (typeof recipient === 'string') {
return { email: recipient };
}
return {
email: recipient.email,
name: recipient.name,
customFields: recipient.customFields || customFields,
};
});
}
emailMessage.subject = subject;
emailMessage.htmlBody = htmlBody;
emailMessage.textBody = textBody || htmlBody.replace(/<[^>]*>/g, '');
emailMessage.trackOpens = trackOpens;
emailMessage.trackClicks = trackClicks;
if (groups) {
emailMessage.groups = groups;
}
const response = await emailApi.sendEmail(this.apiKey, { emailMessage });
return {
success: true,
messageId: response.messageId,
data: response,
};
} catch (error: any) {
console.error('SendPost error:', error);
return {
success: false,
error: error.message || 'Failed to send email',
details: error,
};
}
}
}
4. Configure Environment Variables
Create.env:
SENDPOST_API_KEY=your_sub_account_api_key
SENDPOST_FROM_EMAIL=hello@playwithsendpost.io
SENDPOST_FROM_NAME=SendPost
app.module.ts:
TypeScript
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { EmailModule } from './email/email.module';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
EmailModule,
],
})
export class AppModule {}
5. Create Email Controller
Createsrc/email/email.controller.ts:
TypeScript
import { Controller, Post, Body, HttpCode, HttpStatus } from '@nestjs/common';
import { EmailService } from './email.service';
@Controller('email')
export class EmailController {
constructor(private readonly emailService: EmailService) {}
@Post('send')
@HttpCode(HttpStatus.OK)
async sendEmail(@Body() body: {
to: string;
subject: string;
htmlBody: string;
textBody?: string;
}) {
const result = await this.emailService.sendEmail({
to: body.to,
subject: body.subject,
htmlBody: body.htmlBody,
textBody: body.textBody,
});
if (!result.success) {
throw new Error(result.error);
}
return {
success: true,
messageId: result.messageId,
};
}
}
6. Common Use Cases
Welcome Email Service Method
Add toemail.service.ts:
TypeScript
async sendWelcomeEmail(email: string, firstName: string) {
return this.sendEmail({
to: {
email,
name: firstName,
customFields: { firstName },
},
subject: 'Welcome {{firstName}}!',
htmlBody: `
<h1>Welcome, {{firstName}}!</h1>
<p>Thank you for joining us. We're excited to have you on board.</p>
<p>Get started by exploring our features:</p>
<ul>
<li>Feature 1</li>
<li>Feature 2</li>
<li>Feature 3</li>
</ul>
<p>If you have any questions, just reply to this email.</p>
<p><a href="{{unsubscribe}}">Unsubscribe</a></p>
`,
textBody: `
Welcome, {{firstName}}!
Thank you for joining us. We're excited to have you on board.
Get started by exploring our features:
- Feature 1
- Feature 2
- Feature 3
If you have any questions, just reply to this email.
Unsubscribe: {{unsubscribe}}
`,
groups: ['welcome'],
});
}
Password Reset Email
TypeScript
async sendPasswordResetEmail(email: string, resetToken: string, firstName: string) {
const appUrl = this.configService.get<string>('APP_URL') || 'https://yourapp.com';
const resetUrl = `${appUrl}/reset-password?token=${resetToken}`;
return this.sendEmail({
to: {
email,
name: firstName,
customFields: {
firstName,
resetUrl,
},
},
subject: 'Reset Your Password',
htmlBody: `
<h2>Hello {{firstName}},</h2>
<p>We received a request to reset your password. Click the button below:</p>
<p>
<a href="{{resetUrl}}" style="background-color: #5750EC; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">
Reset Password
</a>
</p>
<p>Or copy and paste this link: {{resetUrl}}</p>
<p>This link will expire in 1 hour.</p>
`,
groups: ['password-reset'],
trackClicks: true,
});
}
7. Using in Other Services
TypeScript
import { Injectable } from '@nestjs/common';
import { EmailService } from '../email/email.service';
@Injectable()
export class UserService {
constructor(private readonly emailService: EmailService) {}
async createUser(userData: CreateUserDto) {
// Create user logic
const user = await this.userRepository.create(userData);
// Send welcome email
await this.emailService.sendWelcomeEmail(user.email, user.firstName);
return user;
}
}
8. Using with Queues (Bull)
Install Bull:npm install @nestjs/bull bull
TypeScript
import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { EmailProcessor } from './email.processor';
@Module({
imports: [
BullModule.registerQueue({
name: 'email',
}),
],
providers: [EmailProcessor],
})
export class EmailQueueModule {}
TypeScript
import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';
import { EmailService } from '../email.service';
@Processor('email')
export class EmailProcessor {
constructor(private readonly emailService: EmailService) {}
@Process('welcome')
async handleWelcomeEmail(job: Job) {
const { email, firstName } = job.data;
return this.emailService.sendWelcomeEmail(email, firstName);
}
}
Make sure your sender email domain is verified in your SendPost account before sending emails.
9. Next Steps
Explore more examples and use cases:NestJS Documentation
Learn more about NestJS framework
SendPost JavaScript SDK
View the official SDK package on npm
Quickstart Example
View a complete working example on GitHub