Integrating AWS Pinpoint with a NestJS Backend to Send Phone Verification Codes

Gedion DanielGedion Daniel
4 min read

As a developer, I’m always looking for ways to make my applications more secure and user-friendly. One of the ways to do this is by adding phone verification to ensure that users are who they say they are. In one of my recent projects, I decided to integrate AWS Pinpoint with my NestJS backend to send SMS verification codes to users' phones.

If you're working on a similar project, or just curious, I’ll walk you through how I managed to set this up. I’ll keep things simple and personal, so don’t worry if you’re new to this!


What is AWS Pinpoint?

AWS Pinpoint is a service by Amazon Web Services that allows you to send messages to users via multiple channels, including SMS, email, and push notifications. For this particular project, I used it to send SMS verification codes.

Why Use AWS Pinpoint?

There are several reasons why AWS Pinpoint is a good choice for sending phone verifications:

  • It’s scalable.

  • It supports global SMS delivery.

  • It’s easy to integrate with other AWS services.

Setting Up AWS Pinpoint

Before diving into the integration with NestJS, I had to configure AWS Pinpoint. Here’s how I set it up:

  1. Create an AWS Account: If you don’t already have one, you’ll need to sign up for AWS.

  2. Set Up an SMS Messaging Project:

    • Go to the AWS Pinpoint console.

    • Create a new project for SMS messaging.

    • Enable SMS in the project settings and set up your default sender ID and message type (transactional messages for verification codes).

  3. Obtain AWS Credentials: You’ll need your Access Key and Secret Key to authenticate AWS requests from your NestJS application.

Installing AWS SDK in NestJS

Once AWS Pinpoint was ready, the next step was integrating it into my NestJS backend. I installed the AWS SDK in my NestJS project:

bashCopy codenpm install @aws-sdk/client-pinpoint

This package allows me to interact with AWS Pinpoint directly from my backend.

Writing the NestJS Service to Send SMS

With the AWS SDK installed, I wrote a service in NestJS to handle the sending of SMS verification codes. Here's a simplified version of how I did it:

typescriptCopy codeimport { Injectable } from '@nestjs/common';
import { PinpointClient, SendMessagesCommand } from '@aws-sdk/client-pinpoint';

@Injectable()
export class SmsService {
  private pinpointClient: PinpointClient;

  constructor() {
    this.pinpointClient = new PinpointClient({ region: 'your-region' });
  }

  async sendSmsVerification(phoneNumber: string, code: string): Promise<void> {
    const params = {
      ApplicationId: 'your-pinpoint-app-id',
      MessageRequest: {
        Addresses: {
          [phoneNumber]: {
            ChannelType: 'SMS',
          },
        },
        MessageConfiguration: {
          SMSMessage: {
            Body: `Your verification code is ${code}`,
            MessageType: 'TRANSACTIONAL',
          },
        },
      },
    };

    const command = new SendMessagesCommand(params);
    await this.pinpointClient.send(command);
  }
}

How It Works:

  • The PinpointClient is initialized with the correct AWS region.

  • The sendSmsVerification method sends an SMS to the provided phone number with a verification code.

  • I used AWS Pinpoint's SendMessagesCommand to send the SMS. The body of the message contains the verification code, and the message type is set to TRANSACTIONAL.

Calling the Service from the Controller

Next, I set up a controller to handle the API request from the frontend, where a user would input their phone number to receive the verification code:

typescriptCopy codeimport { Controller, Post, Body } from '@nestjs/common';
import { SmsService } from './sms.service';

@Controller('auth')
export class AuthController {
  constructor(private readonly smsService: SmsService) {}

  @Post('send-verification')
  async sendVerificationCode(@Body('phoneNumber') phoneNumber: string) {
    const verificationCode = this.generateVerificationCode();
    await this.smsService.sendSmsVerification(phoneNumber, verificationCode);
    return { message: 'Verification code sent' };
  }

  private generateVerificationCode(): string {
    return Math.floor(100000 + Math.random() * 900000).toString(); // 6-digit code
  }
}

How It Works:

  • The AuthController listens for a POST request to the /auth/send-verification endpoint.

  • It calls the SmsService to send the SMS to the user's phone number with a randomly generated 6-digit verification code.

Testing the Integration

Once everything was set up, I tested the flow by calling the endpoint from Postman (or you could do it from your frontend). It worked perfectly — the phone number received the SMS with the verification code!

0
Subscribe to my newsletter

Read articles from Gedion Daniel directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Gedion Daniel
Gedion Daniel

I am a Software Developer from Italy.