> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendpost.io/llms.txt
> Use this file to discover all available pages before exploring further.

# NestJS Quickstart

> Learn how to send emails with SendPost in your NestJS application using modules, services, and dependency injection

## Prerequisites

To get the most out of this guide, you'll need to:

* [**Create a SendPost Account**](https://app.sendpost.io/register)
* [**NestJS 9+**](https://nestjs.com/)
* [**Node.js 16+**](https://nodejs.org/)
* A **Sub-Account API Key** from your SendPost dashboard

<Info>
  You can find your API keys in your [SendPost Dashboard](https://app.sendpost.io). Make sure to use your Sub-Account API Key for sending emails.
</Info>

## 1. Install Dependencies

```shellscript npm theme={null}
npm install sendpost-js-sdk
npm install --save-dev @types/node
```

## 2. Create Email Module

Create `src/email/email.module.ts`:

```typescript TypeScript theme={null}
import { Module } from '@nestjs/common';
import { EmailService } from './email.service';

@Module({
  providers: [EmailService],
  exports: [EmailService],
})
export class EmailModule {}
```

## 3. Create Email Service

Create `src/email/email.service.ts`:

```typescript TypeScript theme={null}
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`:

```env theme={null}
SENDPOST_API_KEY=your_sub_account_api_key
SENDPOST_FROM_EMAIL=hello@playwithsendpost.io
SENDPOST_FROM_NAME=SendPost
```

Update `app.module.ts`:

```typescript TypeScript theme={null}
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

Create `src/email/email.controller.ts`:

```typescript TypeScript theme={null}
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 to `email.service.ts`:

```typescript TypeScript theme={null}
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 TypeScript theme={null}
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 TypeScript theme={null}
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:

```bash theme={null}
npm install @nestjs/bull bull
```

Create email queue:

```typescript TypeScript theme={null}
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 {}
```

Create processor:

```typescript TypeScript theme={null}
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);
  }
}
```

<Warning>
  Make sure your sender email domain is verified in your SendPost account before sending emails.
</Warning>

## 9. Next Steps

Explore more examples and use cases:

<Columns cols={3}>
  <Card title="NestJS Documentation" icon="nestjs" href="https://docs.nestjs.com/">
    Learn more about NestJS framework
  </Card>

  <Card title="SendPost JavaScript SDK" icon="npm" href="https://www.npmjs.com/package/sendpost-js-sdk">
    View the official SDK package on npm
  </Card>

  <Card title="Quickstart Example" icon="github" href="https://github.com/sendpost/sendpost-nestjs-example">
    View a complete working example on GitHub
  </Card>
</Columns>
