|
|
|
@ -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');
|
|
|
|
|
}
|
|
|
|
|