UNPKG

ws-cloud-api

Version:

WhatsApp Cloud API for NodeJS

360 lines (355 loc) 7.64 kB
'use strict'; const media = require('../media.cjs'); const index = require('../index.cjs'); async function sendRequest({ id, body, path, query, method, config }) { const apiVersion = typeof process !== "undefined" ? process.env.WS_CA_VERSION ?? config?.apiVersion ?? "20.0" : config?.apiVersion ?? "20.0"; const phoneNumberId = typeof process !== "undefined" ? process.env.WS_PHONE_NUMBER_ID ?? config?.phoneNumberId : config?.phoneNumberId; const businessId = typeof process !== "undefined" ? process.env.WS_BUSINESS_ID ?? config?.businessId : config?.businessId; const token = typeof process !== "undefined" ? process.env.WS_TOKEN ?? config?.token : config?.token; const requestId = id === "phoneNumberId" ? phoneNumberId : businessId; if (requestId === void 0) { return { success: false, error: "Missing request ID" }; } if (token === void 0) { return { success: false, error: "Missing token" }; } try { const response = await fetch( `https://graph.facebook.com/v${apiVersion}/${requestId}/${path}${query !== void 0 ? `?${query}` : ""}`, { method, headers: { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" }, body } ); if (!response.ok) { return { success: false, error: response }; } return { success: true, response: await response.json() }; } catch (error) { console.error("Fetch failed:", error); return { success: false, error }; } } async function sendMessageRequest({ to, body, config }) { const postBody = JSON.stringify({ messaging_product: "whatsapp", to, ...body }); const requestResponse = await sendRequest({ id: "phoneNumberId", body: postBody, path: "messages", method: "POST", config }); if (!requestResponse.success) { console.error(`Failed to send ${body.type} message`); console.error(JSON.stringify(await requestResponse.error, null, 2)); } return requestResponse; } async function sendText({ to, message, previewUrl, config }) { return await sendMessageRequest({ to, body: { type: index.MessageTypes.Text, [index.MessageTypes.Text]: { preview_url: previewUrl, body: message } }, config }); } async function sendSimpleMedia({ to, type, link, filename, caption, config }) { return await sendMessageRequest({ to, // FIXME: Typescript not identifying the type // @ts-expect-error Typescript not identifying the type body: { type, [type]: { link, filename, caption } }, config }); } async function sendImage({ to, link, config }) { return await sendSimpleMedia({ to, type: index.MessageTypes.Image, link, config }); } async function sendVideo({ to, link, config }) { return await sendSimpleMedia({ to, type: index.MessageTypes.Video, link, config }); } async function sendDocument({ to, link, filename, caption, config }) { return await sendSimpleMedia({ to, type: index.MessageTypes.Document, link, filename, caption, config }); } async function sendAudio({ to, link, config }) { return await sendSimpleMedia({ to, type: index.MessageTypes.Audio, link, config }); } async function sendFile({ to, file, config }) { try { const mediaId = await media.uploadMedia({ media: file, config }); const mimeType = file.type.split("/")[0]; const type = mimeType === "text" || mimeType === "application" ? index.MessageTypes.Document : mimeType; return await sendMessageRequest({ to, // FIXME: Typescript not identifying the type // @ts-expect-error Typescript not identifying the type body: { type, [type]: { id: mediaId } }, config }); } catch (error) { console.error("Failed to send file"); console.error(error); return { success: false, error }; } } function generateInteractiveBody(input) { return { type: index.MessageTypes.Interactive, interactive: input }; } async function sendButtonMessage({ to, message, config }) { const body = { type: index.InteractiveTypes.Button, body: { text: message.text }, action: { buttons: [] } }; for (let i = 0; i < message.buttons.length; i++) { body.action.buttons.push({ type: "reply", reply: message.buttons[i] }); } return await sendMessageRequest({ to, body: generateInteractiveBody(body), config }); } async function sendCTAButtonMessage({ to, message, config }) { const body = { type: index.InteractiveTypes.CTAButton, body: { text: message.text }, action: { name: index.InteractiveTypes.CTAButton, parameters: { display_text: message.buttonText, url: message.url } } }; return await sendMessageRequest({ to, body: generateInteractiveBody(body), config }); } async function sendInteractiveListMessage({ to, list, config }) { const body = { type: index.InteractiveTypes.List, body: { text: list.text }, action: { button: list.buttonText, sections: [ { title: list.buttonText, rows: [] } ] } }; for (let i = 0; i < list.list.length; i++) { body.action.sections[0].rows.push({ id: list.list[i].description, ...list.list[i] }); } return await sendMessageRequest({ to, body: generateInteractiveBody(body), config }); } async function sendInteractiveSectionListMessage({ to, list, config }) { const body = { type: index.InteractiveTypes.List, body: { text: list.text }, action: { button: list.buttonText, sections: [] } }; for (let i = 0; i < list.sections.length; i++) { body.action.sections.push({ title: list.sections[i].sectionTitle, rows: [] }); for (let j = 0; j < list.sections[i].list.length; j++) { body.action.sections[i].rows.push({ id: list.sections[i].list[j].description, ...list.sections[i].list[j] }); } } return await sendMessageRequest({ to, body: generateInteractiveBody(body), config }); } async function sendFlowMessage({ to, flow, draft, config }) { const body = { type: index.InteractiveTypes.Flow, body: { text: flow.text }, action: { name: "flow", parameters: { mode: draft === true ? "draft" : "published", flow_message_version: "3", flow_action: "navigate", flow_token: flow.token, flow_id: flow.id, flow_cta: flow.ctaText, flow_action_payload: { screen: flow.defaultScreen } } } }; return await sendMessageRequest({ to, body: generateInteractiveBody(body), config }); } exports.sendAudio = sendAudio; exports.sendButtonMessage = sendButtonMessage; exports.sendCTAButtonMessage = sendCTAButtonMessage; exports.sendDocument = sendDocument; exports.sendFile = sendFile; exports.sendFlowMessage = sendFlowMessage; exports.sendImage = sendImage; exports.sendInteractiveListMessage = sendInteractiveListMessage; exports.sendInteractiveSectionListMessage = sendInteractiveSectionListMessage; exports.sendMessageRequest = sendMessageRequest; exports.sendRequest = sendRequest; exports.sendText = sendText; exports.sendVideo = sendVideo;