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 🙏

© 2026 – Pkg Stats / Ryan Hefner

townkrier-termii

v1.0.1-alpha.1

Published

Termii SMS adapter for Townkrier notification system

Readme

townkrier-termii

Termii SMS adapter for the TownKrier notification system.

Features

  • 📱 SMS notifications via Termii API
  • 🌍 Support for multiple countries and regions
  • 🔄 Automatic retry with exponential backoff
  • 📝 Message templates and personalization
  • 🔍 Delivery status tracking
  • 🛡️ Error handling and validation

Installation

npm install townkrier-termii townkrier-core
# or
pnpm add townkrier-termii townkrier-core

Quick Start

import { NotificationManager, NotificationChannel } from 'townkrier-core';
import { createTermiiChannel } from 'townkrier-termii';

// Configure the manager with Termii channel
const manager = new NotificationManager({
  defaultChannel: 'sms-termii',
  channels: [
    {
      name: 'sms-termii',
      enabled: true,
      config: {
        apiKey: process.env.TERMII_API_KEY,
        senderId: 'YourApp', // Your registered sender ID
        channel: 'generic', // or 'dnd', 'whatsapp'
      },
    },
  ],
});

// Register the Termii channel factory
manager.registerFactory('sms-termii', createTermiiChannel);

// Create a notification
class WelcomeSmsNotification extends Notification {
  constructor(private userName: string) {
    super();
  }

  via() {
    return [NotificationChannel.SMS];
  }

  toSms() {
    return {
      to: '+1234567890',
      message: `Welcome ${this.userName}! Thank you for joining our service.`,
    };
  }
}

// Send the notification
const notification = new WelcomeSmsNotification('John');
const recipient = {
  [NotificationChannel.SMS]: {
    phone: '+1234567890',
  },
};

await manager.send(notification, recipient);

Configuration

TermiiConfig

interface TermiiConfig {
  apiKey: string; // Required: Your Termii API key
  senderId: string; // Required: Your registered sender ID (max 11 chars)
  channel?: string; // Optional: Message channel (default: 'generic')
  timeout?: number; // Optional: Request timeout in ms (default: 30000)
  debug?: boolean; // Optional: Enable debug logging (default: false)
}

Channel Types

Termii supports different message channels:

  • generic - Standard SMS (default, most reliable)
  • dnd - For numbers on DND (Do Not Disturb)
  • whatsapp - For WhatsApp Business messages
{
  channel: 'generic', // Change based on your needs
}

Advanced Usage

With Personalization

class OrderConfirmationNotification extends Notification {
  constructor(
    private orderNumber: string,
    private totalAmount: string,
    private estimatedDelivery: string,
  ) {
    super();
  }

  via() {
    return [NotificationChannel.SMS];
  }

  toSms() {
    return {
      to: '+1234567890',
      message: `Order #${this.orderNumber} confirmed! Total: ${this.totalAmount}. Estimated delivery: ${this.estimatedDelivery}`,
    };
  }
}

Multi-Channel with Fallback

class CriticalAlertNotification extends Notification {
  via() {
    // Try SMS first, fallback to email if SMS fails
    return [NotificationChannel.SMS, NotificationChannel.EMAIL];
  }

  toSms() {
    return {
      to: '+1234567890',
      message: 'Critical Alert: Your account requires immediate attention.',
    };
  }

  toEmail() {
    return {
      subject: 'Critical Alert',
      html: '<h1>Critical Alert</h1><p>Your account requires immediate attention.</p>',
    };
  }
}

International Numbers

// Always use E.164 format for international numbers
{
  to: '+44712345678',  // UK
  to: '+12125551234',  // USA
  to: '+234812345678', // Nigeria
  message: 'Your message here',
}

Getting Your API Key

  1. Sign up at termii.com
  2. Navigate to your Dashboard
  3. Go to API Settings
  4. Copy your API Key
  5. Register a Sender ID (this may require verification)

Sender ID Requirements

  • Maximum 11 characters
  • Alphanumeric only
  • Must be approved by Termii
  • Some countries require pre-registration

Error Handling

The adapter includes comprehensive error handling:

import { NotificationFailed } from 'townkrier-core';

// Listen for failures
eventDispatcher.on(NotificationFailed, async (event) => {
  console.error('SMS failed:', event.error.message);
  console.error('Failed channel:', event.failedChannel);

  // Implement custom retry logic or alerts
  if (event.error.message.includes('Invalid number')) {
    // Handle invalid phone numbers
  }
});

Message Length

  • Standard SMS: 160 characters
  • Unicode messages (emojis, etc.): 70 characters
  • Messages longer than these limits are split into multiple parts

Testing

Development Mode

{
  apiKey: process.env.TERMII_API_KEY,
  senderId: 'Test',
  debug: true, // Enable detailed logging
}

Test Numbers

Termii provides test numbers for development. Check their documentation for current test numbers.

Pricing

Termii charges per SMS sent. Pricing varies by:

  • Destination country
  • Message type (SMS vs WhatsApp)
  • Volume discounts

Check Termii Pricing for current rates.

Best Practices

  1. Validate Phone Numbers: Always validate numbers before sending
  2. Keep Messages Concise: Stay under 160 characters when possible
  3. Use Sender ID Wisely: Choose a recognizable sender ID
  4. Handle Errors: Implement proper error handling and logging
  5. Respect Regulations: Follow SMS marketing regulations (TCPA, etc.)
  6. Rate Limiting: Be mindful of rate limits
  7. Store Preferences: Track user SMS preferences and opt-outs

Troubleshooting

"Invalid API Key"

  • Verify your API key is correct
  • Check if the key has necessary permissions
  • Ensure the key hasn't expired

"Invalid Sender ID"

  • Verify sender ID is registered with Termii
  • Check sender ID is maximum 11 characters
  • Ensure sender ID is approved for your account

"Insufficient Balance"

  • Check your Termii account balance
  • Add credits to your account

"Invalid Phone Number"

  • Use E.164 format (+countrycode + number)
  • Remove spaces, dashes, or special characters
  • Verify the number is valid for the destination country

Related Packages

Examples

See the examples directory for complete working examples:

License

MIT

Support

Author

Jeremiah Olisa