UNPKG

simple-sms-sender

Version:

Simple SMS sender to multiple recipients using Twilio

175 lines (172 loc) 5.93 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { SmsSender: () => SmsSender }); module.exports = __toCommonJS(index_exports); // src/SmsSender.ts var import_twilio = __toESM(require("twilio"), 1); var SmsSender = class { /** Twilio Account SID */ accountSid; /** Twilio client instance */ client; /** Sender's phone number */ fromNumber; /** Logger for logging messages and errors */ logger; /** Twilio SID */ sid; /** Twilio secret */ secret; /** * Creates an instance of SmsSender. * @param accountSid - Twilio Account SID. * @param fromNumber - Sender's phone number. * @param logger - Logger for logging messages and errors. * @param sid - Twilio SID. * @param secret - Twilio secret. */ constructor({ accountSid, fromNumber, logger, sid, secret }) { this.accountSid = accountSid; this.logger = logger || { error: console.error.bind(console), info: console.log.bind(console) }; this.fromNumber = fromNumber; this.sid = sid; this.secret = secret; this.client = (0, import_twilio.default)(this.sid, this.secret, { accountSid: this.accountSid }); } /** * Sends an SMS message to a list of recipients. * @param body - The content of the SMS message. * @param recipients - Array of recipient phone numbers. * @param scheduledTime - Optional ISO 8601 formatted date/time to schedule the message. * @throws Will throw an error if the body or recipients are empty. * @returns A promise that resolves to an array of sent message objects. */ async sendSms({ body, recipients, scheduledTime }) { if (!body || body.length === 0) { throw new Error("No body to send SMS"); } if (!recipients || recipients.length === 0) { throw new Error("No recipients to send SMS"); } if (scheduledTime) { this.validateScheduledTime(scheduledTime); } const sendSmsToNumber = async (phoneNumber) => { const to = phoneNumber?.trim(); if (!to) { this.logger.error("Not a valid phone number to send SMS"); return; } this.logger.info(`Trying to send SMS to number ${phoneNumber}`); try { const message = await this.client.messages.create({ body, to, from: this.fromNumber, ...scheduledTime && { sendAt: new Date(scheduledTime) } }); const { errorCode, errorMessage, status } = message; if (errorCode) { this.logger.error( `There was an error sending SMS to number ${phoneNumber} (${errorCode} - ${errorMessage})` ); } else { this.logger.info( `Sent SMS to number ${phoneNumber} successful (status ${status})` ); } return message; } catch (error) { this.logger.error( `Could not send SMS to number '${phoneNumber}'`, error ); } return; }; return Promise.all(recipients.map(sendSmsToNumber)); } /** * Sends multiple SMS messages. * @param messages - Array of messages to send. * @returns A promise that resolves to an array of sent message objects. */ async sendMultipleSms(messages) { return Promise.all(messages.map((message) => this.sendSms(message))); } /** * Validates the scheduled time format and ensures it's in the future. * @param scheduledTime - ISO 8601 formatted date/time string. * @throws Will throw an error if the format is invalid or time is in the past. */ validateScheduledTime(scheduledTime) { try { const scheduledDate = new Date(scheduledTime); if (isNaN(scheduledDate.getTime())) { throw new Error("Invalid date format"); } const now = /* @__PURE__ */ new Date(); if (scheduledDate <= now) { throw new Error("Scheduled time must be in the future"); } const maxFutureDate = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1e3); if (scheduledDate > maxFutureDate) { throw new Error( "Scheduled time cannot be more than 7 days in the future" ); } } catch (error) { if (error instanceof Error) { throw new Error(`Invalid scheduledTime: ${error.message}`); } throw new Error( "Invalid scheduledTime format. Please use ISO 8601 format (e.g., 2024-01-01T12:00:00Z)" ); } } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { SmsSender });