UNPKG

ws-cloud-api

Version:

WhatsApp Cloud API for NodeJS

142 lines (139 loc) 3.82 kB
import { getMediaUrl, getMedia } from './media.mjs'; import 'cross-fetch'; function verifyWebhook(input) { if (input["hub.mode"] !== "subscribe" || input["hub.verify_token"] !== process.env.WS_VERIFY_TOKEN) { return { statusCode: 401 }; } return { statusCode: 200, body: input["hub.challenge"] }; } async function handleWebhook(input) { if (input.object === void 0) { return; } if (input.entry[0].changes[0].value.metadata.phone_number_id !== process.env.WS_PHONE_NUMBER_ID) { return; } const webhookValue = input.entry[0].changes[0].value; if ("statuses" in webhookValue) { return { type: "statusUpdate", messageId: webhookValue.statuses[0].id, userId: webhookValue.statuses[0].recipient_id, status: webhookValue.statuses[0].status }; } const messageObject = webhookValue.messages[0]; if (messageObject.type === "reaction") { return { type: "reaction", from: messageObject.from, id: messageObject.reaction.message_id, emoji: messageObject.reaction.emoji }; } if (messageObject.type === "interactive" && messageObject.interactive.type === "nfm_reply") { return { type: "flowReply", from: messageObject.from, id: messageObject.id, data: JSON.parse(messageObject.interactive.nfm_reply.response_json) }; } if (["image", "video", "document", "sticker", "audio"].includes(messageObject.type)) { const media = { id: "", caption: "", mimeType: "" }; switch (messageObject.type) { case "image": media.id = messageObject.image.id; media.caption = messageObject.image.caption; media.mimeType = messageObject.image.mime_type; break; case "video": media.id = messageObject.video.id; media.caption = messageObject.video.caption; media.mimeType = messageObject.video.mime_type; break; case "document": media.id = messageObject.document.id; media.caption = messageObject.document.caption; media.mimeType = messageObject.document.mime_type; break; case "sticker": media.id = messageObject.sticker.id; media.mimeType = messageObject.sticker.mime_type; break; case "audio": media.id = messageObject.audio.id; media.mimeType = messageObject.audio.mime_type; break; } const mediaUrl = await getMediaUrl({ mediaId: media.id }); const mediaBlob = await getMedia({ mediaUrl }); return { type: "media", from: messageObject.from, id: messageObject.id, blob: mediaBlob, mimeType: media.mimeType, message: media.caption, source: "user" }; } return { type: "message", from: messageObject.from, ...getMessageText(messageObject) }; } function getMessageText(message) { const id = message.id; switch (message.type) { case "text": return { id, message: message.text.body, source: "user" }; case "interactive": if (message.interactive.type === "nfm_reply") { return { id, message: "Flow message", source: "flow" }; } if (message.interactive.type === "list_reply") { return { id, message: message.interactive.list_reply.id, source: "list" }; } return { id, message: message.interactive.button_reply.id, source: "button" }; case "button": return { id, message: message.button.payload, source: "button" }; default: return { id, message: "Unsupported message type", source: "user" }; } } export { handleWebhook, verifyWebhook };