nestjs-afromessage-unofficial
v0.1.0
Published
Unofficial NestJS module for the AfroMessage SMS/OTP API
Maintainers
Readme
nestjs-afromessage
Note: This is an unofficial, community-maintained NestJS module for the AfroMessage API. It is not formally affiliated with or endorsed by AfroMessage.
A NestJS wrapper around afromessage-ts — gives you a fully injectable AfroMessageService with support for forRoot and forRootAsync (works with @nestjs/config).
Installation
pnpm add nestjs-afromessage-unofficial
Setup
Simple (forRoot)
import { AfroMessageModule } from 'nestjs-afromessage-unofficial';
@Module({
imports: [
AfroMessageModule.forRoot({
apiKey: process.env.AFRO_API_KEY!,
}),
],
})
export class AppModule {}With ConfigService (recommended)
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AfroMessageModule } from 'nestjs-afromessage-unofficial';
@Module({
imports: [
ConfigModule.forRoot(),
AfroMessageModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (cfg: ConfigService) => ({
apiKey: cfg.getOrThrow('AFRO_API_KEY'),
}),
}),
],
})
export class AppModule {}Usage
Inject AfroMessageService into any provider. It exposes the same API as AfroMessageClient from afromessage-ts.
import { Injectable } from '@nestjs/common';
import { AfroMessageService } from 'nestjs-afromessage-unofficial';
@Injectable()
export class AuthService {
constructor(private readonly afro: AfroMessageService) {}
}API
SMS
afro.sms.send(options)
Send a plain SMS message.
const result = await this.afro.sms.send({
to: '+251912345678',
message: 'Hello from AfroMessage!',
});
if (result.acknowledge === 'Success') {
console.log('Sent:', result.response);
}| Option | Type | Required | Description |
| --------- | ------ | -------- | ---------------------- |
| to | string | ✅ | Recipient phone number |
| message | string | ✅ | SMS body text |
OTP
afro.otp.challenge(options)
Send an OTP code to a phone number.
const result = await this.afro.otp.challenge({
to: '+251912345678',
codeLength: 6,
ttl: 300,
});
if (result.acknowledge === 'Success') {
console.log('OTP sent');
}| Option | Type | Required | Description |
| ------------ | ------ | -------- | --------------------------------- |
| to | string | ✅ | Recipient phone number |
| codeLength | number | ✅ | Length of the OTP code (e.g. 4–8) |
| ttl | number | ✅ | Code expiry in seconds |
afro.otp.verify(options)
Verify a code the user submitted.
const result = await this.afro.otp.verify({
to: '+251912345678',
code: userInputCode,
});
if (result.acknowledge === 'Success' && result.response === 'Verified') {
// phone number verified
}| Option | Type | Required | Description |
| ------ | ------ | -------- | -------------------------------- |
| to | string | ✅ | Phone number the OTP was sent to |
| code | string | ✅ | Code entered by the user |
Error Handling
AfroMessageService throws the same typed errors as afromessage-ts. Import them directly from the base SDK:
import {
AfroAuthError,
AfroRateLimitError,
AfroValidationError,
AfroMessageError,
} from 'nestjs-afromessage-unofficial';
try {
await this.afro.sms.send({ to: '+251912345678', message: 'Hi' });
} catch (err) {
if (err instanceof AfroValidationError) {
// bad input — fix before retrying
} else if (err instanceof AfroAuthError) {
// invalid API key
} else if (err instanceof AfroRateLimitError) {
// slow down — you're being rate limited
} else if (err instanceof AfroMessageError) {
console.error(err.statusCode, err.raw);
}
}Configuration
| Option | Type | Default | Description |
| --------- | ------ | ----------------------------- | ------------------------ |
| apiKey | string | required | Your AfroMessage API key |
| baseUrl | string | https://api.afromessage.com | Override for testing |
| retries | number | 3 | Max retries on 429/5xx |
License
MIT
