Careeroza
Real World Example
Switching SMS Providers Without Code Changes
Indian apps often switch SMS vendors (MSG91, Twilio, Gupshup) for cost or delivery rates. With a token and useFactory, the vendor is chosen from config.
src/notifications/sms.module.ts
import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Msg91Sender } from './msg91.sender';
import { TwilioSender } from './twilio.sender';
import { ConsoleSender } from './console.sender';
export interface SmsSender { send(phone: string, text: string): Promise<void>; }
export const SMS_SENDER = Symbol('SMS_SENDER');
@Module({
providers: [
Msg91Sender,
TwilioSender,
ConsoleSender,
{
provide: SMS_SENDER,
inject: [ConfigService, Msg91Sender, TwilioSender, ConsoleSender],
useFactory: (config: ConfigService, msg91: Msg91Sender, twilio: TwilioSender, dev: ConsoleSender): SmsSender => {
switch (config.get('SMS_VENDOR')) {
case 'msg91': return msg91;
case 'twilio': return twilio;
default: return dev; // local development: print to console
}
},
},
],
exports: [SMS_SENDER],
})
export class SmsModule {}@Injectable()
export class OtpService {
constructor(@Inject(SMS_SENDER) private readonly sms: SmsSender) {}
async sendOtp(phone: string, otp: string) {
await this.sms.send(phone, `${otp} is your ShopEase OTP. Valid for 5 minutes.`);
}
}