-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create methos, class and channel for use twilio channel BREAKING CHANGE: project structure
- Loading branch information
1 parent
7c34099
commit 7c0a8d3
Showing
12 changed files
with
495 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './twilio.channel'; | ||
export * from './twilio-channel.message'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import { TwilioChannelModuleOptions } from '../interfaces'; | ||
import { TwilioChannelException } from '../exceptions'; | ||
|
||
/** | ||
* Service name message | ||
* @class TwilioChannelMessage | ||
*/ | ||
export class TwilioChannelMessage { | ||
/** | ||
* @property | ||
* @private | ||
*/ | ||
private accountSid: string; | ||
|
||
/** | ||
* @property | ||
* @private | ||
*/ | ||
private authToken: string; | ||
|
||
/** | ||
* @property | ||
* @private | ||
*/ | ||
private sender: string; | ||
|
||
/** | ||
* @property | ||
* @private | ||
*/ | ||
private message: string; | ||
|
||
/** | ||
* @property | ||
* @private | ||
*/ | ||
private toPhoneNumber: string; | ||
|
||
/** | ||
* @constructor | ||
* @param {TwilioChannelModuleOptions} options | ||
*/ | ||
constructor(options?: TwilioChannelModuleOptions) { | ||
this.accountSid = options?.twilioAccountSid; | ||
this.authToken = options?.twilioAuthToken; | ||
this.sender = options?.twilioSender; | ||
} | ||
|
||
/** | ||
* @method | ||
*/ | ||
get getAccountSid() { | ||
return this.accountSid; | ||
} | ||
|
||
/** | ||
* @method | ||
* @param sid | ||
*/ | ||
setAccountSid(sid: string) { | ||
this.accountSid = sid; | ||
|
||
return this; | ||
} | ||
|
||
/** | ||
* @method | ||
*/ | ||
get getAccountToken() { | ||
return this.authToken; | ||
} | ||
|
||
/** | ||
* @method | ||
* @param token | ||
*/ | ||
setAccountToken(token: string) { | ||
this.authToken = token; | ||
|
||
return this; | ||
} | ||
|
||
/** | ||
* @method | ||
*/ | ||
get getSender() { | ||
return this.sender; | ||
} | ||
|
||
/** | ||
* @method | ||
* @param sender | ||
*/ | ||
setSender(sender: string) { | ||
this.sender = sender; | ||
|
||
return this; | ||
} | ||
|
||
/** | ||
* @method | ||
*/ | ||
get getToPhoneNumber() { | ||
return this.toPhoneNumber; | ||
} | ||
|
||
/** | ||
* @method | ||
* @param toPhoneNumber | ||
*/ | ||
setToPhoneNumber(toPhoneNumber: string) { | ||
if (!toPhoneNumber.startsWith('+')) { | ||
throw new TwilioChannelException('Your phone number must start with +.'); | ||
} | ||
|
||
this.toPhoneNumber = toPhoneNumber; | ||
|
||
return this; | ||
} | ||
|
||
/** | ||
* @method | ||
*/ | ||
get getMessage() { | ||
return this.message; | ||
} | ||
|
||
/** | ||
* @method | ||
* @param message | ||
*/ | ||
setMessage(message: string) { | ||
this.message = message; | ||
|
||
return this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import { Inject, Injectable, Optional } from '@nestjs/common'; | ||
import { INestjsNotificationChannel } from '@sinuos/nestjs-notification'; | ||
import { Twilio } from 'twilio'; | ||
import { TWILIO_CHANNEL_OPTIONS } from '../constants'; | ||
import { ITwilioChannel, TwilioChannelModuleOptions } from '../interfaces'; | ||
import { TwilioChannelException } from '../exceptions'; | ||
|
||
@Injectable() | ||
export class TwilioChannel implements INestjsNotificationChannel { | ||
/** | ||
* @property | ||
* @private | ||
*/ | ||
private readonly accountSid = process.env.TWILIO_ACCOUNT_SID; | ||
|
||
/** | ||
* @property | ||
* @private | ||
*/ | ||
private readonly authToken = process.env.TWILIO_AUTH_TOKEN; | ||
|
||
/** | ||
* @property | ||
* @private | ||
*/ | ||
private readonly sender = process.env.TWILIO_SENDER; | ||
|
||
/** | ||
* Twilio channel constructor. | ||
* @constructor | ||
* @param {TwilioChannelModuleOptions} options | ||
*/ | ||
constructor( | ||
@Optional() | ||
@Inject(TWILIO_CHANNEL_OPTIONS) | ||
options: TwilioChannelModuleOptions, | ||
) { | ||
if (options?.twilioAccountSid) { | ||
this.accountSid = options.twilioAccountSid; | ||
} | ||
|
||
if (options?.twilioAuthToken) { | ||
this.authToken = options.twilioAuthToken; | ||
} | ||
|
||
if (options?.twilioSender) { | ||
this.sender = options.twilioSender; | ||
} | ||
} | ||
|
||
/** | ||
* Send notify action | ||
* @public | ||
* @param {ITwilioChannel} notification | ||
* @return Promise<AxiosResponse<any>> | ||
*/ | ||
public async send(notification: ITwilioChannel): Promise<any> { | ||
// Validator notification requirements. | ||
this.validator(notification); | ||
|
||
// get message content. | ||
const message = TwilioChannel.getData(notification); | ||
|
||
// twilio username. | ||
const username = this.accountSid ?? message.getAccountSid; | ||
|
||
// twilio password | ||
const password = this.authToken ?? message.getAccountToken; | ||
|
||
// sender | ||
const sender = this.sender || message.getSender; | ||
|
||
/** @const twilioClient - Init twilio client */ | ||
const twilioClient = new Twilio(username, password); | ||
|
||
// return twilio message instance | ||
try { | ||
return await twilioClient.messages.create({ | ||
body: message.getMessage, | ||
to: message.getToPhoneNumber, | ||
from: sender, | ||
}); | ||
} catch (e) { | ||
throw new TwilioChannelException(e.message); | ||
} | ||
} | ||
|
||
/** | ||
* Get data. | ||
* @method | ||
* @param {ITwilioChannel} notification | ||
* @private | ||
*/ | ||
private static getData(notification: ITwilioChannel) { | ||
return TwilioChannel.getChannelData(notification); | ||
} | ||
|
||
/** | ||
* Validator. | ||
* @method | ||
* @param {ITwilioChannel} notification | ||
* @private | ||
*/ | ||
private validator(notification: ITwilioChannel) { | ||
const message = TwilioChannel.getData(notification); | ||
|
||
/** Account sid is empty */ | ||
if (!this.accountSid && !message.getAccountSid) { | ||
throw new TwilioChannelException('Account sid is required'); | ||
} | ||
|
||
/** Auth token is empty */ | ||
if (!this.authToken && !message.getAccountToken) { | ||
throw new TwilioChannelException('Account token is required'); | ||
} | ||
|
||
/** Sender is empty */ | ||
if (!this.sender && !message.getSender) { | ||
throw new TwilioChannelException('Sender is required'); | ||
} | ||
|
||
/** Phone number is empty */ | ||
if (!message.getToPhoneNumber) { | ||
throw new TwilioChannelException('To phone number is required'); | ||
} | ||
|
||
/** Message is empty */ | ||
if (!message.getMessage) { | ||
throw new TwilioChannelException('Message is required'); | ||
} | ||
} | ||
|
||
/** | ||
* Get the data for the notification. | ||
* @method | ||
* @param notification | ||
*/ | ||
private static getChannelData(notification: ITwilioChannel) { | ||
if (typeof notification.toTwilio === 'function') { | ||
return notification.toTwilio(); | ||
} | ||
|
||
throw new TwilioChannelException( | ||
'Notification is missing toTwilio method.', | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './twilio.constant'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const TWILIO_CHANNEL_OPTIONS = 'TWILIO_CHANNEL_OPTIONS'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './twilio-channel.exception'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/** | ||
* @class TwilioChannelException | ||
* @extends Error | ||
*/ | ||
export class TwilioChannelException extends Error { | ||
/** | ||
* @constructor | ||
* @param message | ||
*/ | ||
constructor(message: string) { | ||
super(message); | ||
|
||
this.name = 'TwilioChannelException'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './bootstrap'; | ||
export * from './interfaces'; | ||
export * from './twilio-channel.module'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './twilio-channel-module.interface'; | ||
export * from './twilio-channel.interface'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { ModuleMetadata, Provider, Type } from '@nestjs/common'; | ||
|
||
/** | ||
* @interface TwilioChannelModuleOptionsFactory | ||
* @property createTwilioChannelOptions() | ||
*/ | ||
export interface TwilioChannelModuleOptionsFactory { | ||
createTwilioChannelOptions(): | ||
| Promise<TwilioChannelModuleOptions> | ||
| TwilioChannelModuleOptions; | ||
} | ||
|
||
/** | ||
* @interface TwilioChannelModuleAsyncOptions | ||
* @extends {Pick<ModuleMetadata, 'imports'>} | ||
* @property useExisting | ||
* @property useClass | ||
* @property useFactory | ||
* @property inject | ||
* @property extraProviders | ||
*/ | ||
export interface TwilioChannelModuleAsyncOptions | ||
extends Pick<ModuleMetadata, 'imports'> { | ||
useExisting?: Type<TwilioChannelModuleOptionsFactory>; | ||
useClass?: Type<TwilioChannelModuleOptionsFactory>; | ||
useFactory?: ( | ||
...args: any[] | ||
) => Promise<TwilioChannelModuleOptions> | TwilioChannelModuleOptions; | ||
inject?: any[]; | ||
extraProviders?: Provider[]; | ||
} | ||
|
||
/** | ||
* @interface TwilioChannelModuleOptions | ||
* @property {string} twilioAccountSid | ||
* @property {string} twilioAuthToken | ||
*/ | ||
export interface TwilioChannelModuleOptions { | ||
twilioAccountSid?: string; | ||
twilioAuthToken?: string; | ||
twilioSender?: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { NestJsNotification } from '@sinuos/nestjs-notification'; | ||
|
||
/** | ||
* Twilio channel model | ||
* @interface ITwilioChannel | ||
* @extends NestJsNotification | ||
*/ | ||
export interface ITwilioChannel extends NestJsNotification { | ||
/** | ||
* Get representation of the notification. | ||
* @property | ||
* @returns {any} | ||
*/ | ||
toTwilio?(): any; | ||
} |
Oops, something went wrong.