townkrier-termii
v1.0.1-alpha.1
Published
Termii SMS adapter for Townkrier notification system
Maintainers
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-coreQuick 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
- Sign up at termii.com
- Navigate to your Dashboard
- Go to API Settings
- Copy your API Key
- 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
- Validate Phone Numbers: Always validate numbers before sending
- Keep Messages Concise: Stay under 160 characters when possible
- Use Sender ID Wisely: Choose a recognizable sender ID
- Handle Errors: Implement proper error handling and logging
- Respect Regulations: Follow SMS marketing regulations (TCPA, etc.)
- Rate Limiting: Be mindful of rate limits
- 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
- townkrier-core - Core notification system
- townkrier-resend - Email provider
- townkrier-fcm - Push notifications provider
- townkrier-queue - Queue system for background processing
- townkrier-dashboard - Monitoring dashboard
Examples
See the examples directory for complete working examples:
- Complete Example - Full multi-channel setup
- SMS Specific Examples - SMS notification examples
License
MIT
Support
Author
Jeremiah Olisa
