Spaces:
Sleeping
Sleeping
| const crypto = require('crypto'); | |
| function constantTimeEquals(left, right) { | |
| const leftBuffer = Buffer.from(left || '', 'utf8'); | |
| const rightBuffer = Buffer.from(right || '', 'utf8'); | |
| if (leftBuffer.length !== rightBuffer.length) { | |
| return false; | |
| } | |
| return crypto.timingSafeEqual(leftBuffer, rightBuffer); | |
| } | |
| function isValidWebhookVerification({ mode, verifyToken, expectedVerifyToken }) { | |
| return ( | |
| mode === 'subscribe' && | |
| Boolean(expectedVerifyToken) && | |
| constantTimeEquals(verifyToken, expectedVerifyToken) | |
| ); | |
| } | |
| function isValidMetaSignature({ rawBody, signature, appSecret }) { | |
| if (!rawBody || !signature || !appSecret) { | |
| return false; | |
| } | |
| const expectedSignature = `sha256=${crypto | |
| .createHmac('sha256', appSecret) | |
| .update(rawBody) | |
| .digest('hex')}`; | |
| return constantTimeEquals(signature, expectedSignature); | |
| } | |
| function extractIncomingWhatsAppMessages(payload) { | |
| if (payload?.object !== 'whatsapp_business_account') { | |
| return []; | |
| } | |
| const messages = []; | |
| for (const entry of payload.entry || []) { | |
| for (const change of entry.changes || []) { | |
| const value = change.value || {}; | |
| for (const message of value.messages || []) { | |
| messages.push({ | |
| id: message.id || null, | |
| from: message.from || null, | |
| type: message.type || 'unknown', | |
| text: message.type === 'text' ? message.text?.body?.trim() || '' : '', | |
| }); | |
| } | |
| } | |
| } | |
| return messages.filter((message) => Boolean(message.from)); | |
| } | |
| module.exports = { | |
| extractIncomingWhatsAppMessages, | |
| isValidMetaSignature, | |
| isValidWebhookVerification, | |
| }; | |