@sorasys/orange-sms-gateway
Version:
A lightweight and intuitive Node.js package for integrating with the Orange SMS API.
149 lines (144 loc) • 4.43 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
OrangeSmsClient: () => OrangeSmsClient
});
module.exports = __toCommonJS(src_exports);
// src/lib/constants.ts
var API_URL = "https://api.orange.com";
// src/lib/validations.ts
var validateConfigs = (config) => {
if (!config) {
throw new Error("Configuration object is required.");
}
if (!config.sender) {
throw new Error('The "sender" field is required.');
}
if (config.sender.startsWith("+")) {
throw new Error(
'The "sender" field must not start with a "+". Use an international format without the "+" sign.'
);
}
if (!config.authHeader) {
throw new Error('The "authHeader" field is required.');
}
if (!config.authHeader.startsWith("Basic ")) {
throw new Error('The "authHeader" field must start with "Basic ".');
}
};
var validateSendSmsParams = (params) => {
if (!params) {
throw new Error("The parameters object is required.");
}
if (!params.phone) {
throw new Error('The "phone" field is required.');
}
if (!params.message) {
throw new Error('The "message" field is required.');
}
};
// src/client/index.ts
var OrangeSmsClient = class {
sender;
authHeader;
token = "";
tokenExpiry = 0;
isAuthenticating = false;
constructor(params) {
validateConfigs(params);
this.sender = params.sender;
this.authHeader = params.authHeader;
}
async send(params) {
try {
validateSendSmsParams(params);
await this.checkAuthTokenExpiry();
const headers = this.createHeaders(this.token);
const body = {
outboundSMSMessageRequest: {
address: `tel:${params.phone}`,
senderAddress: `tel:+${this.sender}`,
outboundSMSTextMessage: {
message: params.message
}
}
};
const phone = encodeURIComponent(`tel:+${this.sender}`);
const response = await fetch(
`${API_URL}/smsmessaging/v1/outbound/${phone}/requests`,
{
method: "POST",
headers,
body: JSON.stringify(body)
}
);
if (!response.ok) {
throw new Error(`Failed to send SMS. HTTP status: ${response.status}`);
}
await response.json();
} catch (error) {
throw new Error(`Failed to send SMS. Reason: ${error.message}`);
}
}
async authenticate() {
if (this.isAuthenticating) return;
this.isAuthenticating = true;
try {
const body = new URLSearchParams();
body.append("grant_type", "client_credentials");
const response = await fetch(`${API_URL}/oauth/v3/token`, {
method: "POST",
headers: this.createHeaders(),
body
});
if (!response.ok) {
throw new Error(
`Authentication failed. HTTP status: ${response.status}`
);
}
const data = await response.json();
this.token = data.access_token;
this.tokenExpiry = Date.now() + Math.floor(data.expires_in * 1e3);
} catch (error) {
throw error;
} finally {
this.isAuthenticating = false;
}
}
async checkAuthTokenExpiry() {
if (this.token && !this.isTokenExpired()) return;
this.token = "";
await this.authenticate();
}
isTokenExpired() {
return Date.now() > this.tokenExpiry;
}
createHeaders(authToken) {
return {
Authorization: authToken ? `Bearer ${authToken}` : this.authHeader,
"Content-Type": authToken ? "application/json" : "application/x-www-form-urlencoded"
};
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
OrangeSmsClient
});