UNPKG

@brighthustle/adonisjs-whatsapp

Version:

Connect your WhatsApp Cloud API with AdonisJS

397 lines (396 loc) 15.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const axios_1 = __importDefault(require("axios")); const Helpers_1 = __importDefault(require("./Helpers")); const enum_1 = require("./types/enum"); class WhatsAppClient { constructor(config, db) { this.config = config; this.db = db; this.headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + this.config.config?.accessToken, }; this.mandatory = { messaging_product: 'whatsapp', recipient_type: 'individual', }; } async send(data, parse = true) { let { timeout, phoneNumberId, graphUrl, graphVersion } = this.config.config; let headers = this.headers; let apiProvider = null; let url = `${graphUrl}/${graphVersion}/${phoneNumberId}/messages`; if (!this.config.db) { this.validateApiProvider(this.config.config.apiProvider); apiProvider = this.config.config.apiProvider; headers = this.getHeaders(apiProvider, this.config.config.accessToken); } if (this.config.db) { if (!data.from) { throw new Error('From (id for whatsapp db) is required as db config is enabled.'); } if (!this.connection) { this.db.connection(this.config.db.connectionName); } const waResponse = await this.db .query() .select('*') .from(this.config.db.tableName) .where('id', data.from) .first(); if (waResponse) { phoneNumberId = waResponse.phone_number_id; apiProvider = waResponse.api_provider; graphVersion = waResponse.graph_version ?? graphVersion; graphUrl = waResponse.graph_url ?? graphUrl; headers = this.getHeaders(apiProvider, waResponse.access_token); } else { throw new Error('Incorrect Phone Number ID'); } } if (apiProvider === enum_1.ApiProvider.MAG91_API) { if (data.type === 'text') { url = `${graphUrl}/${graphVersion}/whatsapp/whatsapp-outbound-message/?integrated_number=${phoneNumberId}&recipient_number=${data.to}&content_type=text&text=${data.text.body}`; } else if (data.type === 'template') { data = Helpers_1.default.transformToMsg91SendTemplate(phoneNumberId, data.template.name, data.template.language.code, data.template.components, data.to); url = `${graphUrl}/${graphVersion}/whatsapp/whatsapp-outbound-message/bulk/`; } else { throw new Error('Not implemented in msg 91 apis'); } } else { url = `${graphUrl}/${graphVersion}/${phoneNumberId}/messages`; data = { ...this.mandatory, ...data }; } const response = await (0, axios_1.default)({ validateStatus: (status) => status <= 999, method: 'POST', url: url, timeout, headers: headers, data: data, responseType: 'json', }); if ('error' in response.data) { throw new Error(response.data.error?.error_data?.details || response.data.error?.message); } return parse ? apiProvider === enum_1.ApiProvider.CLOUD_API ? this.parse(response.data) : this.parseMsg91(response.data, data.from) : response.data; } async media(media, from) { let { timeout, graphUrl, graphVersion } = this.config.config; let dbHeaders = null; if (this.config.db) { if (!from) { throw new Error('From (id for whatsapp db) is required as db config is enabled.'); } if (!this.connection) { this.db.connection(this.config.db.connectionName); } const waResponse = await this.db .query() .select('*') .from(this.config.db.tableName) .where('id', from) .first(); if (waResponse) { graphVersion = waResponse.graph_version ?? graphVersion; dbHeaders = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + waResponse.access_token, }; } else { throw new Error('Incorrect Phone Number ID'); } } const response = await (0, axios_1.default)({ validateStatus: (status) => status <= 999, method: 'GET', url: `${graphUrl}/${graphVersion}/${media}`, timeout, headers: dbHeaders ?? this.headers, responseType: 'json', }); if ('error' in response.data) { throw new Error(response.data.error?.error_data?.details || response.data.error?.message); } return response.data; } async upload(form, from) { let { timeout, phoneNumberId, graphUrl, graphVersion } = this.config.config; let dbHeaders = null; if (this.config.db) { if (!from) { throw new Error('From (id for whatsapp db) is required as db config is enabled.'); } if (!this.connection) { this.db.connection(this.config.db.connectionName); } const waResponse = await this.db .query() .select('*') .from(this.config.db.tableName) .where('id', from) .first(); if (waResponse) { graphVersion = waResponse.graph_version ?? graphVersion; phoneNumberId = waResponse.phone_number_id; dbHeaders = { ...form.getHeaders(), 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + waResponse.access_token, }; } else { throw new Error('Incorrect Phone Number ID'); } } const response = await (0, axios_1.default)({ validateStatus: (status) => status <= 999, method: 'POST', url: `${graphUrl}/${graphVersion}/${phoneNumberId}/media`, timeout, headers: dbHeaders ?? { ...form.getHeaders(), ...this.headers }, data: form, responseType: 'json', }); if ('error' in response.data) { throw new Error(response.data.error?.error_data?.details || response.data.error?.message); } return response.data; } async createTemplate(data) { let { timeout, whatsappBusinessId, graphUrl, graphVersion } = this.config.config; let headers = this.headers; let apiProvider = 'cloud-api'; if (!this.config.db) { this.validateApiProvider(this.config.config.apiProvider); apiProvider = this.config.config.apiProvider; } if (this.config.db) { if (!data.from) { throw new Error('From (id for whatsapp db) is required as db config is enabled.'); } if (!this.connection) { this.db.connection(this.config.db.connectionName); } const waResponse = await this.db .query() .select('*') .from(this.config.db.tableName) .where('id', data.from) .first(); if (waResponse) { graphVersion = waResponse.graph_version ?? graphVersion; apiProvider = waResponse.api_provider; whatsappBusinessId = waResponse.whatsapp_business_id; if (apiProvider === enum_1.ApiProvider.CLOUD_API) { headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + waResponse.access_token, }; } if (apiProvider === enum_1.ApiProvider.MAG91_API) { headers = { 'Content-Type': 'application/json', 'authkey': waResponse.access_token, }; } } else { throw new Error('Incorrect Phone Number ID'); } } const response = await (0, axios_1.default)({ validateStatus: (status) => status <= 999, method: 'POST', url: `${graphUrl}/${graphVersion}/${whatsappBusinessId}/message_templates`, timeout, headers: headers, data: data, responseType: 'json', }); if ('error' in response.data) { throw new Error(response.data.error?.error_data?.details || response.data.error?.message); } return response.data; } async getTemplates(options, from) { let { timeout, whatsappBusinessId, graphUrl, graphVersion } = this.config.config; let dbHeaders = null; if (this.config.db) { if (!from) { throw new Error('From (id for whatsapp db) is required as db config is enabled.'); } if (!this.connection) { this.db.connection(this.config.db.connectionName); } const waResponse = await this.db .query() .select('*') .from(this.config.db.tableName) .where('id', from) .first(); if (waResponse) { graphVersion = waResponse.graph_version ?? graphVersion; whatsappBusinessId = waResponse.whatsapp_business_id; dbHeaders = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + waResponse.access_token, }; } else { throw new Error('Incorrect Phone Number ID'); } } let qs = ''; if (options) { if (options.fields && options.fields.length > 0) { qs += qs.length > 0 ? '&' : '?'; qs += `fields=${options.fields.join(',')}`; } if (options.limit) { qs += qs.length > 0 ? '&' : '?'; qs += `limit=${options.limit}`; } } const response = await (0, axios_1.default)({ validateStatus: (status) => status <= 999, method: 'GET', url: `${graphUrl}/${graphVersion}/${whatsappBusinessId}/message_templates${qs}`, timeout, headers: dbHeaders ?? this.headers, responseType: 'json', }); if ('error' in response.data) { throw new Error(response.data.error?.error_data?.details || response.data.error?.message); } return response.data; } async deleteTemplate(name, from) { let { timeout, graphUrl, graphVersion, whatsappBusinessId } = this.config.config; let dbHeaders = null; if (this.config.db) { if (!from) { throw new Error('From (id for whatsapp db) is required as db config is enabled.'); } if (!this.connection) { this.db.connection(this.config.db.connectionName); } const waResponse = await this.db .query() .select('*') .from(this.config.db.tableName) .where('id', from) .first(); if (waResponse) { graphVersion = waResponse.graph_version ?? graphVersion; whatsappBusinessId = waResponse.whatsapp_business_id; dbHeaders = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + waResponse.access_token, }; } else { throw new Error('Incorrect Phone Number ID'); } } const response = await (0, axios_1.default)({ validateStatus: (status) => status <= 999, method: 'DELETE', url: `${graphUrl}/${graphVersion}/${whatsappBusinessId}/message_templates?name=${name}`, timeout, headers: dbHeaders ?? this.headers, responseType: 'json', }); if ('error' in response.data) { throw new Error(response.data.error?.error_data?.details || response.data.error?.message); } return response.data; } async download(url, from) { let dbHeaders = null; if (this.config.db) { if (!from) { throw new Error('From (id for whatsapp db) is required as db config is enabled.'); } if (!this.connection) { this.db.connection(this.config.db.connectionName); } const waResponse = await this.db .query() .select('*') .from(this.config.db.tableName) .where('id', from) .first(); if (waResponse) { dbHeaders = { Authorization: 'Bearer ' + waResponse.access_token, }; } else { throw new Error('Incorrect Phone Number ID'); } } const response = await (0, axios_1.default)({ validateStatus: (status) => status <= 999, method: 'GET', url: url, headers: dbHeaders ?? { Authorization: 'Bearer ' + this.config.config.accessToken }, responseType: 'arraybuffer', }); if ('error' in response.data) { throw new Error(response.data.error?.error_data?.details || response.data.error?.message); } return response.data; } parse(data) { return { input: Number(data.contacts[0].input), phone: data.contacts[0].wa_id, wamid: data.messages[0].id, }; } parseMsg91(data, from) { return { input: 0, phone: from, wamid: data.request_id, }; } /** * Validates if the provided apiProvider is one of the allowed values. * @param apiProvider - The apiProvider to validate. * @throws {Error} - Throws an error if apiProvider is not valid. */ validateApiProvider(apiProvider) { if (!apiProvider) { throw new Error('API provider is required: cloud-api | msg91.'); } if (!Object.values(enum_1.ApiProvider).includes(apiProvider)) { throw new Error(`Invalid API provider. Expected one of: ${Object.values(enum_1.ApiProvider).join(', ')}.`); } } getHeaders(apiProvider, accessToken) { const headers = { 'Content-Type': 'application/json' }; if (apiProvider === enum_1.ApiProvider.CLOUD_API) { headers['Authorization'] = 'Bearer ' + accessToken; } else if (apiProvider === enum_1.ApiProvider.MAG91_API) { headers['authkey'] = accessToken; } return headers; } } exports.default = WhatsAppClient;