Nest.JS | Providers -> Twilio.

To send an SMS in Nest.js using Twilio, you’ll first need to install the Twilio npm package by running npm install twilio. Then, you can use the Twilio client in your Nest.js code to send an SMS.

Here’s an example of how you can create a Twilio module for Nest.js:

  1. Create a new folder called providers/twilio in the src directory of your Nest.js project.
  2. Inside the twilio folder, create a new file called twilio.module.ts. This file will be used to define the Twilio module.
  3. In twilio.module.ts, import the Module class from the @nestjs/common module and the TwilioService class that you will create next.
import { Module } from '@nestjs/common';
import { TwilioService } from './twilio.service';

@Module({
  providers: [TwilioService],
  exports: [TwilioService],
})
export class TwilioModule {}

4. Create a new file called twilio.service.ts inside the twilio folder. This file will be used to define the Twilio service.

5. In twilio.service.ts, import the Injectable decorator from the @nestjs/common module and the Twilio client from the twilio npm package.

import { Module } from '@nestjs/common';
import { TwilioService } from './twilio.service';

@Module({
  providers: [TwilioService],
  exports: [TwilioService],
})
export class TwilioModule {}
4. Create a new file called twilio.service.ts inside the twilio folder. This file will be used to define the Twilio service.

5. In twilio.service.ts, import the Injectable decorator from the @nestjs/common module and the Twilio client from the twilio npm package.

import PQueue from 'p-queue';
import pRetry from 'p-retry';
import twilio from 'twilio';
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { MessageListInstanceCreateOptions } from 'twilio/lib/rest/api/v2010/account/message';
import TwilioClient from 'twilio/lib/rest/Twilio';

@Injectable()
export default class TwilioService {
  client: TwilioClient;

  logger = new Logger(TwilioService.name);

  private queue = new PQueue({ concurrency: 1 });

  constructor(private configService: ConfigService) {
    const twilioAccountSid = this.configService.get<string>(
      'twilio.accountSid',
    );
    const twilioAuthToken = this.configService.get<string>(
      'twilio.authToken',
    );

    if (!twilioAccountSid || !twilioAuthToken) {
      throw new Error('Twilio account SID/auth token not found');
    }

    this.client = twilio(
      twilioAccountSid,
      twilioAuthToken,
    );
  }

  private async sendSms(options: MessageListInstanceCreateOptions) {
    return this.client.messages.create(options);
  }

  send(options: MessageListInstanceCreateOptions) {
    return this.queue
      .add(() => pRetry(() => this.sendSms(options), {
        onFailedAttempt: (error) => {
          this.logger.debug(
            `SMS to ${options.to} failed, retrying (${error.retriesLeft} attempts left)`,
            error,
          );
        },
        retries: this.configService.get<number>('twilio.retries') ?? 3,
      }));
  }
}

p-queueis a npm package (short for Node Package Manager) that provides a lightweight and fast priority queue implementation for JavaScript. It allows you to add items to the queue with a priority value, and then retrieve items in order of their priority. This can be useful in a variety of situations where you need to keep track of items that have different levels of importance or urgency.

p-retry is a npm package for handling retries of promises. It allows you to easily retry a promise-returning function when it fails, with exponential backoff and customizable retry conditions. The package provides a retry() function that takes a promise-returning function as its first argument and returns a new promise that will be retried according to the provided options. The returned promise will resolve or reject with the result of the original promise once the retries have been exhausted.