ws-cloud-api
Version:
WhatsApp Cloud API for NodeJS
142 lines (139 loc) • 3.82 kB
JavaScript
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 };