UNPKG

@codebucket/whatsapp

Version:

A reusable WhatsApp Business API client with template and non-template support, webhook handling, pluggable storage, and text sanitization

81 lines (80 loc) 3.06 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.sendWhatsApp = sendWhatsApp; exports.handleWhatsAppWebhook = handleWhatsAppWebhook; // src/client.ts const axios_1 = __importDefault(require("axios")); const template_1 = require("./template"); const phoneNumberCache = new Map(); async function getBusinessPhoneNumber(phoneNumberId, accessToken) { if (phoneNumberCache.has(phoneNumberId)) { return phoneNumberCache.get(phoneNumberId); } const token = accessToken || process.env.WABA_TOKEN; const url = `https://graph.facebook.com/v22.0/${phoneNumberId}`; const resp = await axios_1.default.get(url, { params: { access_token: token, fields: 'display_phone_number' } }); const display = resp.data.display_phone_number; phoneNumberCache.set(phoneNumberId, display); return display; } async function sendWhatsApp(opts, store) { // 1) build or pick the payload let payload; let warnings = []; if ('templateName' in opts) { const result = await (0, template_1.createWhatsAppTemplatePayload)({ businessAccountId: opts.businessAccountId, accessToken: opts.accessToken, to: opts.to, templateName: opts.templateName, language: opts.language, variables: opts.variables }); payload = result.payload; warnings = result.warnings; } else { payload = { ...opts.messagePayload }; } // 2) inject messaging_product automatically payload.messaging_product = 'whatsapp'; // 3) send to Graph API const url = `https://graph.facebook.com/v22.0/${opts.senderUserId}/messages`; const resp = await axios_1.default.post(url, payload, { headers: { Authorization: `Bearer ${opts.accessToken}`, 'Content-Type': 'application/json' } }); let senderPhoneNumber = await getBusinessPhoneNumber(opts.senderUserId, opts.accessToken); // 4) persist outgoing if (store) await store.saveOutgoingMessage(opts.senderUserId, { senderUserId: opts.senderUserId, senderPhoneNumber, accessToken: opts.accessToken, to: opts.to, messagePayload: payload }, resp.data); return { response: resp.data, warnings }; } async function handleWhatsAppWebhook(payload, store) { for (const entry of payload.entry) { const accountId = entry.changes[0].value.metadata.phone_number_id; if (store) { for (const msg of entry.changes[0].value.messages || []) { await store.saveIncomingMessage(accountId, msg); } if (store.saveMessageStatus) { for (const st of entry.changes[0].value.statuses || []) { await store.saveMessageStatus(accountId, st); } } } } }