fix(wai): 读取数据库数据发webhook

dev/supplier-email-drawer
Lei OT 9 months ago
parent 703e028a5d
commit d5763ba820

@ -3,11 +3,12 @@
const generateId = require('../../utils/generateId.util');
const { sessionStore } = require('../../core');
const { objectMapper, pick } = require('../../utils/commons.util');
const { ctxToSendBuilder, ctxToDB } = require('./apiPayloadHelper');
const { createOutboundMessage } = require('../../services/outbound_messages.service');
// const { ctxToSendBuilder, ctxToDB } = require('./apiPayloadHelper');
const { createOutboundMessage, getOutboundMessage } = require('../../services/outbound_messages.service');
const waEmitter = require('../../core/emitter');
const logger = require('../../utils/logger.util');
const { ctxToSendBuilder, ctxToDB, DbData } = require('../../helper/wai.msg.helper');
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

@ -10,6 +10,7 @@ const { sessionStore } = require('..');
const { getOutboundMessage, upsertOutboundMessage } = require('../../services/outbound_messages.service');
const logger = require('../../utils/logger.util');
const { DbData, } = require('../../helper/wai.msg.helper');
const connectionEventNames = ['connection:connect', 'connection:open', 'connection:close'];
const messageEventNames = ['message:received', 'message:updated'];
@ -19,7 +20,7 @@ const eventTypeMapped = {
'message:updated': 'wai.message.updated',
'creds:update': 'wai.creds.update',
};
const timeField = { saved: 'createTime', pending: 'createTime', sent: 'sendTime', delivered: 'deliverTime', read: 'readTime' };
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' };
const directionField = { 'message:received': 'inbound', 'message:updated': 'outbound' };
const directionPrefix = { inbound: 'in_', outbound: 'out_' };
@ -53,9 +54,8 @@ const webhookBodyBuilder = (messageData, messageType) => {
};
const webhookBodyFill = (webhookBody, messageData) => {
const { type } = messageData;
const messageObj = { [type]: messageData };
Object.assign(webhookBody.waiMessage, messageObj);
const DBDataObj = DbData(messageData);
Object.assign(webhookBody.waiMessage, DBDataObj);
return webhookBody;
};
@ -150,8 +150,9 @@ const setupMessageHandler = () => {
const savedMsg = await getOutboundMessage(targetUpsert);
const bixFields = pick(savedMsg, ['actionId', 'externalId']);
logger.info('message evt\n', eventName, messageData, savedMsg);
const typeField = { msgtype: messageData?.type || savedMsg?.msgtype || 'text' }; // fix: type 空
const webhookBody = webhookBodyBuilder({ ...messageData, ...bixFields }, eventName);
const webhookBody = webhookBodyBuilder({ ...messageData, ...bixFields, ...typeField }, eventName);
const { waiMessage } = webhookBody;
const timeFields = pick(waiMessage, [...Object.values(timeField), 'createTime', 'updateTime']);
@ -160,9 +161,11 @@ const setupMessageHandler = () => {
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 contentFields = waiMessage.type === 'text' ? { text_body: waiMessage.text.body } : {};
// const contentFieldsToDB =
// todo: 现在只能收text 消息, 后续再加其他类型
const msgRow = await upsertOutboundMessage(
{ ...timeFields, ...upsertFields, ...pusher, ...contentFields, ...record, message_origin: savedMsg?.message_origin || JSON.stringify(messageData) },
{ ...timeFields, ...upsertFields, ...pusher, ...contentFields, ...record, ...typeField, message_origin: savedMsg?.message_origin || JSON.stringify(messageData) },
targetUpsert,
);
// console.log('upsert=========================', upsert);

@ -0,0 +1,273 @@
/**
*
*/
'use strict';
const { objectMapper, pick } = require('../utils/commons.util');
const mediaMsg = {
contentToSend: msg => {
const { msgtype, msgcontent, ...body } = msg;
return {
// ...body,
to: body.to,
externalId: body.actionId,
// type WAMediaUpload = Buffer | WAMediaPayloadStream | WAMediaPayloadURL;
[msgtype]: {
url: msgcontent[msgtype].link,
},
...(msgcontent[msgtype].caption ? { caption: msgcontent[msgtype].caption } : {}), // image, video, document
// mimetype: 'audio/mp4',
...(msgtype === 'document' ? { filename: msgcontent[msgtype].filename } : {}), // document
...(msgcontent.context ? { quoted: { key: msgcontent.context.message_id } } : {}),
// seconds?: number; // audio
// isAnimated?: boolean; // sticker
// jpegThumbnail?: string; // image, video
imageUrl: msgcontent[msgtype].link, // 25.01.01 版本, 后续更改payload格式 todo:
};
},
dataToDB: msg => {
const { msgtype, msgcontent, ...body } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
return {
direction: 'outbound',
msg_status: 'ready',
createTime: Date.now(),
id: msg.actionId,
...record,
IVADS_link: msgcontent[msgtype].link,
IVADS_caption: msgcontent[msgtype].caption || '',
IVADS_filename: msgcontent[msgtype].filename || '',
...(msgcontent.context
? {
context_id: msgcontent.context.message_id,
context_from: msgcontent.message_origin.from,
}
: {}),
message_origin: JSON.stringify(msg),
};
},
DbData: row => ({
[row.msgtype]: {
link: row.IVADS_link,
caption: row.IVADS_caption,
filename: row.IVADS_filename,
},
...(row.context_id ? { context: { message_id: row.context_id, from: row.context_from } } : {}),
}),
};
const waiMsgTypeMapped = {
text: {
type: 'text',
contentToSend: msg => ({
// ...msg,
to: msg.to,
externalId: msg.actionId,
text: msg.msgcontent.body,
content: msg.msgcontent.body, // 25.01.01 版本, 后续更改payload格式 todo:
// linkPreview: true, // {}
...(msg.msgcontent.context ? { quoted: { key: msg.msgcontent.context.message_id } } : {}),
}),
dataToDB: msg => {
const { msgcontent } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
return {
direction: 'outbound',
msg_status: 'ready',
createTime: Date.now(),
id: msg.actionId,
...record,
text_body: msgcontent.body,
text_preview_url: msgcontent.preview_url,
...(msgcontent.context
? {
context_id: msgcontent.context.message_id,
context_from: msgcontent.message_origin.from,
}
: {}),
message_origin: JSON.stringify(msg),
};
},
DbData: row => ({
text: { body: row.text_body, preview_url: row.text_preview_url },
...(row.context_id ? { context: { message_id: row.context_id, from: row.context_from } } : {}),
}),
},
image: {
type: 'image',
contentToSend: msg => ({
...mediaMsg.contentToSend({ ...msg }),
}),
dataToDB: msg => mediaMsg.dataToDB(msg),
DbData: msg => mediaMsg.DbData(msg),
},
sticker: {
type: 'sticker',
contentToSend: msg => ({
...mediaMsg.contentToSend({ ...msg }),
}),
dataToDB: msg => mediaMsg.dataToDB(msg),
DbData: msg => mediaMsg.DbData(msg),
},
audio: {
type: 'audio',
contentToSend: msg => ({
...mediaMsg.contentToSend({ ...msg }),
}),
dataToDB: msg => mediaMsg.dataToDB(msg),
DbData: msg => mediaMsg.DbData(msg),
},
video: {
type: 'video', // todo: gif
contentToSend: msg => ({
...mediaMsg.contentToSend({ ...msg }),
}),
dataToDB: msg => mediaMsg.dataToDB(msg),
DbData: msg => mediaMsg.DbData(msg),
},
document: {
type: 'document',
contentToSend: msg => ({
...mediaMsg.contentToSend({ ...msg }),
}),
dataToDB: msg => mediaMsg.dataToDB(msg),
DbData: msg => mediaMsg.DbData(msg),
},
react: {
type: 'react',
contentToSend: msg => ({
// ...msg,
to: msg.to,
externalId: msg.actionId,
react: {
text: msg.msgcontent.body, // emoji | use an empty string to remove the reaction
key: msg.msgcontent.context.message_id,
},
}),
dataToDB: msg => {
const { msgtype, msgcontent, ...body } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
return {
direction: 'outbound',
msg_status: 'ready',
createTime: Date.now(),
id: msg.actionId,
...record,
reaction_message_id: '',
reaction_emoji: '',
message_origin: JSON.stringify(msg),
};
},
DbData: row => ({
reaction: { emoji: row.reaction_emoji, message_id: row.reaction_message_id },
}),
},
location: {
type: 'location',
contentToSend: msg => ({
// ...msg,
to: msg.to,
externalId: msg.actionId,
// location: { degreesLatitude: msg.latitude, degreesLongitude: msg.longitude }, // todo:
}),
dataToDB: msg => {
const { msgtype, msgcontent, ...body } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
return {
direction: 'outbound',
msg_status: 'ready',
createTime: Date.now(),
id: msg.actionId,
...record,
message_origin: JSON.stringify(msg),
};
},
DbData: row => ({
location: {
latitude: row.location_latitude,
longitude: row.location_longitude,
name: row.location_name,
address: row.location_address,
url: row.location_url,
},
}),
},
contacts: {
type: 'contacts',
contentToSend: msg => ({
// ...msg,
to: msg.to,
externalId: msg.actionId,
// contacts: { displayName: '', contacts: msg.contacts }, // todo:
}),
dataToDB: msg => {
const { msgtype, msgcontent, ...body } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
return {
direction: 'outbound',
msg_status: 'ready',
createTime: Date.now(),
id: msg.actionId,
...record,
contacts: JSON.stringify(msg.contacts),
message_origin: JSON.stringify(msg),
};
},
DbData: row => ({
contacts: JSON.parse(row.contacts),
}),
},
template: {
type: 'template',
contentToSend: msg => ({
// ...msg,
to: msg.to,
externalId: msg.actionId,
// msgcontent: {
// ...msg.template,
// components: [
// ...msg.template.components.filter(com => !['footer', 'buttons'].includes(com.type.toLowerCase())),
// ],
// },
}),
dataToDB: msg => {
const { msgtype, msgcontent, ...body } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
return {
direction: 'outbound',
msg_status: 'ready',
createTime: Date.now(),
id: msg.actionId,
...record,
message_origin: JSON.stringify(msg),
};
},
},
};
/**
* API Payload to Send
*/
exports.ctxToSendBuilder = ctxContent => {
const { contentToSend } = waiMsgTypeMapped[ctxContent.msgtype];
const msgReady = contentToSend(ctxContent);
return msgReady;
};
/**
* API Payload to DB
*/
exports.ctxToDB = ctxContent => {
const { dataToDB } = waiMsgTypeMapped[ctxContent.msgtype];
const msgReady = dataToDB(ctxContent);
return msgReady;
};
/**
* Parse DB Data to UI/API/Webhook
*/
exports.DbData = row => {
const { DbData } = waiMsgTypeMapped[row.msgtype];
const msgReady = DbData(row);
return msgReady;
};

@ -18,7 +18,8 @@ const getOutboundMessage = async msg => {
};
const createOutboundMessage = async (data) => {
return await OutboundModelModel.create(data);
const r = await OutboundModelModel.create(data);
return r;
}
/**

Loading…
Cancel
Save