import { Department } from "../interfaces/department"; import { Recipient } from "../interfaces/reciptient"; import { MessageOptions } from "../interfaces/message-options"; import { injectable } from "inversify"; import { SmsHandler } from "./handlers/sms.handler"; import "reflect-metadata"; @injectable() export class SmsDepartment implements Department { private supportedTypes = ["reminder", "custom-reminder", "match"]; private supportedSubtypes = ["partly-payment", "rent", "loan", "none"]; constructor(private _smsHandler: SmsHandler) {} public async send( recipients: Recipient[], messageOptions: MessageOptions ): Promise { this.validateMessageOptions(messageOptions); if (!recipients || recipients.length <= 0) { throw `recipients array empty`; } return await this.delegateSendRequests(recipients, messageOptions); } private async delegateSendRequests( recipients: Recipient[], messageOptions: MessageOptions ) { const promiseArr: Promise[] = []; for (let recipient of recipients) { if ( recipient.mediumOverrides && recipient.mediumOverrides.sms === false ) { continue; } promiseArr.push(this._smsHandler.send(recipient, messageOptions)); } try { const results = await Promise.all(promiseArr.map(this.reflect)); const successes = results.filter(x => x.status === "resolved"); if (successes.length <= 0) { throw `none of the sms requests was a success`; } return true; } catch (e) { throw `something went wrong when trying to send sms requests: ${e}`; } } private validateMessageOptions(messageOptions: MessageOptions) { if (!this.isTypeSupported(messageOptions.type)) { throw `type "${messageOptions.type}" not supported`; } if (!this.isSubtypeSupported(messageOptions.subtype)) { throw `subtype "${messageOptions.subtype}" not supported`; } } private isTypeSupported(type: any) { return this.supportedTypes.indexOf(type) >= 0; } private isSubtypeSupported(subtype: any) { return this.supportedSubtypes.indexOf(subtype) >= 0; } private reflect(promise: Promise) { return promise.then( res => { return { result: res, status: "resolved" }; }, err => { return { error: err, status: "rejected" }; } ); } }