npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

termii-nestjs

v5.0.0

Published

A NestJS SDK for Termii API

Downloads

50

Readme

Termii NestJS SDK

npm version License: MIT

A robust, well-structured, and fully-typed NestJS SDK for interacting with the Termii API. This library simplifies sending SMS and WhatsApp messages with a developer-friendly API.

Features

  • ✅ Easy integration with any NestJS application
  • ✅ Static (forRoot) and async (forRootAsync) module configuration
  • ✅ Strongly-typed DTOs for both requests and responses
  • Full Termii API Coverage:
    • Messaging: Send SMS & WhatsApp messages, manage Sender IDs, and Phone Books.
    • Token: Send, verify, and generate OTPs via SMS, Voice, and Email.
    • Insights: Check account balance, search history, and perform number lookups.

Installation

npm install termii-nestjs

or

yarn add termii-nestjs

This library has peer dependencies on several NestJS packages. If they are not already installed in your project, you will need to add them:

npm install @nestjs/common @nestjs/core reflect-metadata

Getting Started

1. Import the Module

Import TermiiModule into your root AppModule.

Static Configuration (forRoot)

This method is suitable for simple configurations where credentials are not loaded dynamically.

// src/app.module.ts
import { Module } from '@nestjs/common';
import { TermiiModule } from 'termii-nestjs';

@Module({
  imports: [
    TermiiModule.forRoot({
      apiKey: 'YOUR_TERMII_API_KEY',
      // baseUrl: 'https://api.ng.termii.com' // Optional: Override base URL
    }),
  ],
})
export class AppModule {}

Async Configuration (forRootAsync)

This is the recommended approach, especially when using @nestjs/config to manage environment variables.

// src/app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TermiiModule } from 'termii-nestjs';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TermiiModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        apiKey: configService.get<string>('TERMII_API_KEY'),
        // baseUrl: 'https://api.ng.termii.com' // Optional: Override base URL
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

2. Inject and Use TermiiService

You can now inject TermiiService into any of your services or controllers. The service is namespaced to provide easy access to different parts of the Termii API:

  • termiiService.messaging
  • termiiService.token
  • termiiService.insight

Below are examples for each service.

Messaging API

The messaging service handles sending messages and managing related resources like Sender IDs and Phone Books.

Example: Sending an SMS

import { Injectable, Logger } from '@nestjs/common';
import { TermiiService, TermiiSendMessageRequest } from 'termii-nestjs';

@Injectable()
export class NotificationService {
  private readonly logger = new Logger(NotificationService.name);

  constructor(private readonly termiiService: TermiiService) {}

  async sendWelcomeMessage(phoneNumber: string) {
    const payload: TermiiSendMessageRequest = {
      to: phoneNumber,
      from: 'YourSenderID', // This will be the sender ID displayed on the recipient's device
      sms: 'Hi there, welcome to our service!',
      channel: 'generic', // Use 'generic' for SMS, 'dnd' to bypass DND, or 'whatsapp'
    };
    try {
      const response = await this.termiiService.messaging.sendMessage(payload);
      this.logger.log(`Message sent. Message ID: ${response.message_id}`);
    } catch (error) {
      this.logger.error(
        'Failed to send SMS',
        error.response?.data || error.message
      );
    }
  }
}

Example: Requesting a Sender ID

import { Injectable, Logger } from '@nestjs/common';
import { TermiiService, TermiiRequestSenderIdRequest } from 'termii-nestjs';

@Injectable()
export class OnboardingService {
  private readonly logger = new Logger(OnboardingService.name);

  constructor(private readonly termiiService: TermiiService) {}

  async requestNewSenderId() {
    const payload: TermiiRequestSenderIdRequest = {
      sender_id: 'NewBrand',
      usecase:
        'We will use this to send transaction notifications to our customers.',
      company: 'My Awesome Company',
    };
    try {
      const response = await this.termiiService.messaging.requestSenderId(
        payload
      );
      this.logger.log(`Sender ID request successful: ${response.message}`);
    } catch (error) {
      this.logger.error(
        'Failed to request Sender ID',
        error.response?.data || error.message
      );
    }
  }
}

Token API

The token service is used for sending and verifying One-Time Passwords (OTPs) through various channels.

Example: Sending an OTP via SMS

import { Injectable, Logger } from '@nestjs/common';
import { TermiiService, TermiiSendTokenRequest } from 'termii-nestjs';

@Injectable()
export class AuthService {
  private readonly logger = new Logger(AuthService.name);

  constructor(private readonly termiiService: TermiiService) {}

  async sendLoginOtp(phoneNumber: string) {
    const payload: TermiiSendTokenRequest = {
      message_type: 'NUMERIC',
      to: phoneNumber,
      from: 'YourSenderID',
      channel: 'generic',
      pin_attempts: 3,
      pin_time_to_live: 5, // In minutes
      pin_length: 6,
      pin_placeholder: '< 1234 >',
      message_text: 'Your login code is < 1234 >. It will expire in 5 minutes.',
    };
    try {
      const response = await this.termiiService.token.sendToken(payload);
      this.logger.log(`OTP sent. Pin ID: ${response.pinId}`);
      return response.pinId; // Return pinId to be used for verification
    } catch (error) {
      this.logger.error(
        'Failed to send OTP',
        error.response?.data || error.message
      );
    }
  }
}

Example: Verifying an OTP

import { Injectable, Logger } from '@nestjs/common';
import { TermiiService, TermiiVerifyTokenRequest } from 'termii-nestjs';

@Injectable()
export class AuthService {
  private readonly logger = new Logger(AuthService.name);

  constructor(private readonly termiiService: TermiiService) {}

  async verifyLoginOtp(pinId: string, pin: string) {
    const payload: TermiiVerifyTokenRequest = { pin_id: pinId, pin: pin };
    try {
      const response = await this.termiiService.token.verifyToken(payload);
      if (response.verified) {
        this.logger.log(`OTP verification successful for ${response.msisdn}`);
        return true;
      }
      this.logger.warn(`OTP verification failed for pinId: ${pinId}`);
      return false;
    } catch (error) {
      this.logger.error(
        'Failed to verify OTP',
        error.response?.data || error.message
      );
      return false;
    }
  }
}

Insight API

The insight service provides tools for checking your account status and looking up information about phone numbers.

Example: Checking Your Balance

import { Injectable, Logger } from '@nestjs/common';
import { TermiiService } from 'termii-nestjs';

@Injectable()
export class AdminService {
  private readonly logger = new Logger(AdminService.name);

  constructor(private readonly termiiService: TermiiService) {}

  async checkAccountBalance() {
    try {
      const response = await this.termiiService.insight.getBalance();
      this.logger.log(
        `Account balance: ${response.balance} ${response.currency}`
      );
    } catch (error) {
      this.logger.error(
        'Failed to fetch balance',
        error.response?.data || error.message
      );
    }
  }
}

Example: Checking DND Status of a Phone Number

import { Injectable, Logger } from '@nestjs/common';
import { TermiiService } from 'termii-nestjs';

@Injectable()
export class CustomerSupportService {
  private readonly logger = new Logger(CustomerSupportService.name);

  constructor(private readonly termiiService: TermiiService) {}

  async checkDndStatus(phoneNumber: string) {
    try {
      // The search method checks the DND status of a number
      const response = await this.termiiService.insight.search(phoneNumber);

      this.logger.log(`DND status for ${response.number}:`, {
        dndActive: response.dnd_active,
        network: response.network_code,
      });
    } catch (error) {
      this.logger.error(
        `Failed to check DND status for ${phoneNumber}`,
        error.response?.data || error.message
      );
    }
  }
}

License

This project is licensed under the MIT License.