UNPKG

@sorasys/orange-sms-gateway

Version:

A lightweight and intuitive Node.js package for integrating with the Orange SMS API.

122 lines (119 loc) 3.4 kB
// 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" }; } }; export { OrangeSmsClient };