NestJS Examples

NestJS integration examples using the Metigan SDK. Learn how to send emails, manage contacts, and integrate Metigan into your NestJS applications.

Installation

install.shTerminal
1
2
3
npm install @metigan/nestjs
# or
yarn add @metigan/nestjs

Basic Setup

1. Import the Module

app.module.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
import { Module } from '@nestjs/common';
import { MetiganModule } from '@metigan/nestjs';

@Module({
  imports: [
    MetiganModule.forRoot({
      apiKey: process.env.METIGAN_API_KEY,
    }),
  ],
})
export class AppModule {}

2. Use in Your Service

email.service.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Injectable } from '@nestjs/common';
import { MetiganService } from '@metigan/nestjs';

@Injectable()
export class EmailService {
  constructor(private readonly metigan: MetiganService) {}

  async sendWelcomeEmail(email: string) {
    const result = await this.metigan.email.sendEmail({
      from: 'Sender <sender@example.com>',
      recipients: [email],
      subject: 'Welcome!',
      content: '<h1>Hello!</h1><p>Thank you for signing up.</p>',
    });

    return result;
  }
}

Sending Emails

Basic Email

send-email.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
async sendEmail() {
  const result = await this.metigan.email.sendEmail({
    from: 'sender@example.com',
    recipients: ['recipient@example.com'],
    subject: 'Email Subject',
    content: '<h1>HTML Content</h1><p>This is the email body.</p>',
  });

  if (result.success) {
    console.log('Email sent successfully!');
    console.log(`Emails remaining: ${result.emailsRemaining}`);
  }
}

Email with CC and BCC

send-email-cc.tsTypeScript
1
2
3
4
5
6
7
8
9
const result = await this.metigan.email.sendEmail({
  from: 'company@email.com',
  recipients: ['main@email.com'],
  subject: 'Meeting',
  content: 'Email content',
  cc: ['copy@email.com'],
  bcc: ['hidden-copy@email.com'],
  replyTo: 'reply-here@email.com',
});

Email with Attachments

send-email-attachment.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import * as fs from 'fs';

const fileData = fs.readFileSync('document.pdf');

const result = await this.metigan.email.sendEmail({
  from: 'company@email.com',
  recipients: ['customer@email.com'],
  subject: 'Important Document',
  content: 'Please find the document attached.',
  attachments: [
    {
      buffer: fileData,
      originalname: 'document.pdf',
      mimetype: 'application/pdf',
    },
  ],
});

Email with Template

send-email-template.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
const result = await this.metigan.email.sendEmailWithTemplate(
  'template-123',
  {
    name: 'John Doe',
    company: 'Acme Inc',
  },
  {
    from: 'sender@example.com',
    recipients: ['recipient@example.com'],
  },
);

Contact Management

Create Contact

create-contact.tsTypeScript
1
2
3
4
5
6
7
const contact = await this.metigan.contacts.create({
  email: 'new@email.com',
  firstName: 'Jane',
  lastName: 'Doe',
  audienceId: 'audience-123',
  tags: ['customer', 'newsletter'],
});

Get Contact

get-contact.tsTypeScript
1
2
3
4
5
// By ID
const contact = await this.metigan.contacts.get('contact-456');

// By email
const contact = await this.metigan.contacts.getByEmail('jane@email.com', 'audience-123');

List Contacts

list-contacts.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
const result = await this.metigan.contacts.list({
  audienceId: 'audience-123',
  status: 'subscribed',
  page: 1,
  limit: 50,
});

console.log(`Total contacts: ${result.pagination.total}`);
result.contacts.forEach(contact => {
  console.log(`${contact.email}: ${contact.firstName}`);
});

Update Contact

update-contact.tsTypeScript
1
2
3
4
const updated = await this.metigan.contacts.update('contact-456', {
  firstName: 'Jane Marie',
  tags: ['customer', 'vip'],
});

Manage Subscription

manage-subscription.tsTypeScript
1
2
3
4
5
// Subscribe
await this.metigan.contacts.subscribe('contact-456');

// Unsubscribe
await this.metigan.contacts.unsubscribe('contact-456');

Manage Tags

manage-tags.tsTypeScript
1
2
3
4
5
// Add tags
await this.metigan.contacts.addTags('contact-456', ['vip', 'black-friday']);

// Remove tags
await this.metigan.contacts.removeTags('contact-456', ['test']);

Audience Management

Create Audience

create-audience.tsTypeScript
1
2
3
4
const audience = await this.metigan.audiences.create({
  name: 'Main Newsletter',
  description: 'Main subscriber list',
});

List Audiences

list-audiences.tsTypeScript
1
2
3
4
5
6
7
8
const result = await this.metigan.audiences.list({
  page: 1,
  limit: 10,
});

result.audiences.forEach(audience => {
  console.log(`${audience.name}: ${audience.count} contacts`);
});

Get Audience Statistics

audience-stats.tsTypeScript
1
2
3
4
5
const stats = await this.metigan.audiences.getStats('audience-123');

console.log(`Total: ${stats.total}`);
console.log(`Subscribed: ${stats.subscribed}`);
console.log(`Unsubscribed: ${stats.unsubscribed}`);

Forms

Submit Form

submit-form.tsTypeScript
1
2
3
4
5
6
7
8
9
10
const result = await this.metigan.forms.submit({
  formId: 'form-123',
  data: {
    'field-email': 'user@email.com',
    'field-name': 'John Doe',
    'field-message': 'Hello, I would like more information.',
  },
});

console.log(result.message);

Get Form

get-form.tsTypeScript
1
2
3
const form = await this.metigan.forms.get('form-123');
console.log(form.title);
console.log(form.fields);

Error Handling

error-handling.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { ApiError, ValidationError } from '@metigan/nestjs';

try {
  const result = await this.metigan.email.sendEmail(options);
} catch (error) {
  if (error instanceof ApiError) {
    console.error(`API Error: ${error.statusCode} - ${error.message}`);
  } else if (error instanceof ValidationError) {
    console.error(`Validation Error: ${error.message}`);
    if (error.field) {
      console.error(`Field: ${error.field}`);
    }
  } else {
    console.error(`Unknown error: ${error}`);
  }
}

Async Configuration

async-config.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MetiganModule } from '@metigan/nestjs';

@Module({
  imports: [
    ConfigModule.forRoot(),
    MetiganModule.forRootAsync({
      useFactory: (configService: ConfigService) => ({
        apiKey: configService.get<string>('METIGAN_API_KEY'),
        timeout: configService.get<number>('METIGAN_TIMEOUT', 30000),
        retryCount: configService.get<number>('METIGAN_RETRY_COUNT', 3),
        retryDelay: configService.get<number>('METIGAN_RETRY_DELAY', 2000),
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

Advanced Configuration

advanced-config.tsTypeScript
1
2
3
4
5
6
7
MetiganModule.forRoot({
  apiKey: process.env.METIGAN_API_KEY,
  timeout: 30000,     // Optional, defaults to 30000ms
  retryCount: 3,      // Optional, defaults to 3
  retryDelay: 2000,   // Optional, defaults to 2000ms
  debug: false,       // Optional, defaults to false
})

Controller Example

email.controller.tsTypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Controller, Post, Body } from '@nestjs/common';
import { MetiganService } from '@metigan/nestjs';

@Controller('email')
export class EmailController {
  constructor(private readonly metigan: MetiganService) {}

  @Post('send')
  async sendEmail(@Body() body: { to: string; subject: string; content: string }) {
    const result = await this.metigan.email.sendEmail({
      from: 'noreply@example.com',
      recipients: [body.to],
      subject: body.subject,
      content: body.content,
    });

    return {
      success: result.success,
      message: result.message,
    };
  }
}
Environment Variables

Use environment variables to store your API key securely. Create a .env file with METIGAN_API_KEY=your_api_key