UNPKG

@sonatel-os/juf

Version:

The community SDK for Orange Money, SMS, Email & Sonatel APIs on the Orange Developer Platform.

180 lines (177 loc) 6.26 kB
import { authenticationService_default } from "./chunk-QDNKDHVC.js"; import { EMAIL_URI, SMS_URI, buildAuthHeader, validate } from "./chunk-BXTDSY5Z.js"; import { SMS_CHANNEL, fromAxiosError, getApiUrl, logger, requester_default } from "./chunk-4T5F3RH2.js"; // src/communication/communication.structure.js import { object, string, boolean, optional, define } from "superstruct"; var EmailStructure = object({ subject: string(), to: string(), from: string(), body: string(), html: optional(boolean()) }); var DateTimeString = define("DateTimeString", (value) => { return typeof value === "string" && !isNaN(Date.parse(value)); }); var SmsStructure = object({ body: string(), to: string(), confidential: optional(boolean()), scheduledFor: optional(DateTimeString), senderName: string() }); // src/communication/communicationService.js var Communication = class _Communication { /** @private @type {Authentication} */ #authService; /** @private @type {import('axios').AxiosInstance} */ #client; /** @private */ #logger; /** * Creates a Communication instance with injectable dependencies. * * @param {object} deps - Dependencies for the communication service. * @param {Authentication} deps.authService - Authentication service instance. * @param {import('axios').AxiosInstance} deps.client - HTTP client instance. * @param {object} deps.logger - Logger instance with error/warn/info/debug methods. */ constructor({ authService, client, logger: logger2 }) { this.#authService = authService; this.#client = client; this.#logger = logger2; } /** * Factory method to initialize Communication with default dependencies. * @method init * @memberof Service\Communication * @param {object} [deps] - Optional shared dependencies. * @param {Authentication} [deps.authService] - Shared auth instance (avoids duplicate token fetches). * @returns {Communication} An initialized instance of Communication. */ static init({ authService } = {}) { return new _Communication({ authService: authService || authenticationService_default.init(), client: requester_default.bootstrap({ baseURL: getApiUrl() }), logger: logger.child("communication") }); } /** * Sends an email through the Apigee API. * * @async * @method sendEmail * @memberof Service\Communication * @param {object} emailParams - Parameters for the email to be sent. * @param {string} emailParams.subject - The subject of the email. * @param {string} emailParams.to - The email address of the recipient. * @param {string} emailParams.from - The email address of the sender. * @param {string} emailParams.body - The plaintext body of the email. * @param {boolean} [emailParams.html] - Whether the body is HTML (optional). * @returns {Promise<{ id: string, status: string }>} The response from the Apigee API. * @throws {import('../core/errors.js').ValidationError} When input validation fails. * @throws {import('../core/errors.js').ExternalServiceError} When the API request fails. * * @example * communication.sendEmail({ * subject: 'Hello!', * to: 'recipient@example.com', * from: 'sender@example.com', * body: '<p>This is a test email.</p>', * html: true * }); */ async sendEmail({ subject, to, from, body, html }) { validate({ subject, to, from, body, html }, EmailStructure, "sendEmail"); const headers = await this.#getAuthHeaders(); const payload = { subject, from, to, body, ...html && { html } }; return this.#sendRequest(EMAIL_URI, payload, headers); } /** * Sends an SMS through the Apigee API. * * @async * @method sendSMS * @memberof Service\Communication * @param {object} smsParams - Parameters for the SMS to be sent. * @param {string} smsParams.body - The message body of the SMS. * @param {boolean} [smsParams.confidential=true] - Whether the message is confidential. * @param {string} [smsParams.scheduledFor] - Scheduled time (ISO 8601 format). * @param {string} smsParams.senderName - The name of the sender. * @param {string} smsParams.to - The phone number of the recipient. * @returns {Promise<{ id: string, status: string }>} The response from the Apigee API. * @throws {import('../core/errors.js').ValidationError} When input validation fails. * @throws {import('../core/errors.js').ExternalServiceError} When the API request fails. * * @example * communication.sendSMS({ * body: 'This is a test SMS.', * to: '+1234567890', * senderName: 'MyApp' * }); */ async sendSMS({ body, confidential = true, scheduledFor, senderName, to }) { validate({ body, confidential, scheduledFor, senderName, to }, SmsStructure, "sendSMS"); const headers = await this.#getAuthHeaders(); const payload = { body, channel: SMS_CHANNEL, confidential, ...scheduledFor && { scheduledFor }, ...senderName && { senderName }, to }; return this.#sendRequest(SMS_URI, payload, headers); } /** * @private * @returns {Promise<{ Authorization: string }>} Authorization headers. */ async #getAuthHeaders() { const { access_token, token_type } = await this.#authService.debug(); return buildAuthHeader(access_token, token_type); } /** * @private * @param {string} uri - The API endpoint path. * @param {object} payload - The request payload. * @param {object} headers - The request headers. * @returns {Promise<object>} The response data. * @throws {import('../core/errors.js').ExternalServiceError} On request failure. */ async #sendRequest(uri, payload, headers) { try { const { data } = await this.#client.post(uri, payload, { headers }); return data; } catch (error) { this.#logger.error("Communication request failed", { uri, status: error.response?.status }); throw fromAxiosError(error, "Request failed. Please check your input and try again."); } } }; var communicationService_default = Communication; export { EmailStructure, SmsStructure, communicationService_default }; //# sourceMappingURL=chunk-ZWM2VYBB.js.map