diff --git a/wai-server/core/handler/whatsappHandler.js b/wai-server/core/handler/whatsappHandler.js index 0bf48bd..6ee4c6d 100644 --- a/wai-server/core/handler/whatsappHandler.js +++ b/wai-server/core/handler/whatsappHandler.js @@ -23,6 +23,43 @@ const eventTypeMapped = { }; const timeField = { saved: 'createTime', pending: 'createTime', sent: 'sendTime', delivered: 'deliverTime', read: 'readTime', failed: 'updateTime' }; const statusMapped = { saved: 'accepted', pending: 'accepted', sent: 'sent', delivered: 'delivered', read: 'read', failed: 'failed' }; +function getCorrectOrderStatus(currentStatus, newStatus) { + const statusOrder = ['accepted', 'failed', 'sent', 'delivered', 'read']; + if (!currentStatus || typeof currentStatus !== 'string') { + currentStatus = null; // default 'pending' + } + if (!newStatus || typeof newStatus !== 'string') { + return currentStatus; + } + if (!statusOrder.includes(newStatus)) { + // console.warn(`Unknown status: ${newStatus}`); + return currentStatus; + } + if (!currentStatus) { + return newStatus; + } + if (!statusOrder.includes(currentStatus)) { + // console.warn(`Unknown status: ${currentStatus}`); + return newStatus; + } + const currentIndex = statusOrder.indexOf(currentStatus); + const newIndex = statusOrder.indexOf(newStatus); + if (newIndex > currentIndex) { + return newStatus; + } else if (newIndex === currentIndex) { + return currentStatus; + } else { + // Optionally handle cases where the new status is "behind" the current one + // Options: + // 1. Ignore the new status (most common): + return currentStatus; + // 2. Allow "downgrades" (use with caution, may indicate errors): + // return newStatus; + // 3. Throw an error or log a warning: + // console.error(`Invalid status transition: ${currentStatus} -> ${newStatus}`); + // return currentStatus; // Or throw an error + } +} const directionField = { 'message:received': 'inbound', 'message:updated': 'outbound' }; const directionPrefix = { inbound: 'in_', outbound: 'out_' }; const directionIdUserPrefix = { inbound: 'to', outbound: 'from' }; @@ -58,9 +95,9 @@ const webhookBodyBuilder = (messageData, messageType) => { return message; }; -const webhookBodyFill = (webhookBody, messageData) => { - const DBDataObj = DbData(messageData); - Object.assign(webhookBody.waiMessage, DBDataObj); +const webhookBodyFill = (webhookBody, savedData) => { + const DBDataObj = DbData(savedData); + Object.assign(webhookBody.waiMessage, DBDataObj, pick(savedData, ['status'])); return webhookBody; }; @@ -172,17 +209,22 @@ const setupMessageHandler = async () => { const pusher = { customerProfile_id: waiMessage.customerProfile?.id || '', customerProfile_name: waiMessage.customerProfile?.name || '' }; const record = objectMapper(waiMessage, { from: 'from', to: 'to', status: 'msg_status', type: 'msgtype' }, false); const waiContentFieldsToDB = messageData.type ? waiContentToDB(messageData) : {}; - if (isEmpty(savedMsg.IVADS_link) && ['image', 'sticker', 'audio', 'video', 'document'].includes(waiMessage.type)) { + const upsertMsgOrigin = !isEmpty(omitEmpty(waiContentFieldsToDB)) || isEmpty(savedMsg); + const msgOrigin = upsertMsgOrigin ? { message_origin: JSON.stringify(messageData) } : {}; + if (isEmpty(savedMsg.IVADS_link) && ['image', 'sticker', 'audio', 'video', 'document'].includes(messageData.type)) { // 存储文件 const filePath = messageData[messageData.type].filePath; const webLink = await uploadMediaFile(filePath); waiContentFieldsToDB.IVADS_link = webLink; } + const currenctStatus = getCorrectOrderStatus(savedMsg.msg_status, messageData.status); + record.msg_status = currenctStatus; + delete upsertFields.status; const readyUpsert = omitEmpty({ ...timeFields, ...pusher, ...waiContentFieldsToDB, ...record }); - const msgRow = await upsertOutboundMessage({ ...upsertFields, ...readyUpsert, ...typeField, message_origin: savedMsg?.message_origin || JSON.stringify(messageData) }, targetUpsert); + const msgRow = await upsertOutboundMessage({ ...upsertFields, ...readyUpsert, ...typeField, ...msgOrigin }, targetUpsert); // 把内容加上, 否则前端没显示 - await callWebhook(webhookBodyFill(webhookBody, msgRow)); + await callWebhook(webhookBodyFill(webhookBody, { ...msgRow, status: msgRow.msg_status })); } catch (error) { logger.error({ messageData, error }, 'error call webhook'); }