feat(wai): 存储多媒体消息的文件

dev/supplier-email-drawer
Lei OT 9 months ago
parent 3e5599b155
commit 277864bcc6

@ -10,7 +10,7 @@ const { updateConnection, addCurrentConnection, resetConnection, getConnection }
const { getOutboundMessage, upsertOutboundMessage } = require('../../services/outbound_messages.service');
const { objectMapper, pick } = require('../../utils/commons.util');
const { logger, getUserLogger } = require('../../utils/logger.util');
const { DbData } = require('../../helper/wai.msg.helper');
const { DbData, waiContentToDB, uploadMediaFile } = require('../../helper/wai.msg.helper');
const connectionEventNames = ['connection:connect', 'connection:open', 'connection:close'];
const messageEventNames = ['message:received', 'message:updated'];
@ -169,15 +169,18 @@ const setupMessageHandler = () => {
upsertFields.evt_id = webhookBody.id;
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 waiContentFieldsToDB = waiContentToDB(messageData);
if (['image', 'sticker', 'audio', 'video', 'document'].includes(waiMessage.type)) {
// 存储文件
const filePath = messageData[messageData.type].filename;
const webLink = await uploadMediaFile(filePath);
waiContentFieldsToDB.link = webLink;
}
const msgRow = await upsertOutboundMessage(
{ ...timeFields, ...upsertFields, ...pusher, ...contentFields, ...record, ...typeField, message_origin: savedMsg?.message_origin || JSON.stringify(messageData) },
{ ...timeFields, ...upsertFields, ...pusher, ...waiContentFieldsToDB, ...record, ...typeField, message_origin: savedMsg?.message_origin || JSON.stringify(messageData) },
targetUpsert,
);
// console.log('upsert=========================', upsert);
// 把内容加上, 否则前端没显示
await callWebhook(webhookBodyFill(webhookBody, msgRow));
} catch (error) {

@ -22,7 +22,16 @@ const mediaMsg = {
// seconds?: number; // audio
// isAnimated?: boolean; // sticker
// jpegThumbnail?: string; // image, video
imageUrl: msgcontent[msgtype].link, // 25.01.01 版本, 后续更改payload格式 todo:
};
},
waiContentToDB: msg => {
const { type } = msg;
return {
IVADS_link_original: msg[type].link_original,
IVADS_caption: msg[type].caption || '',
IVADS_filename: msg[type].filename || '',
IVADS_mime_type: msg[type].mimetype || '',
IVADS_sha256: msg[type].sha256 || '',
};
},
dataToDB: msg => {
@ -65,10 +74,12 @@ const waiMsgTypeMapped = {
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 } } : {}),
}),
waiContentToDB: msg => {
return { text_body: msg.text.body };
},
dataToDB: msg => {
const { msgcontent } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
@ -146,6 +157,13 @@ const waiMsgTypeMapped = {
key: msg.msgcontent.context.message_id,
},
}),
waiContentToDB: msg => {
return {
// todo:
reaction_message_id: '',
reaction_emoji: '',
};
},
dataToDB: msg => {
const { msgtype, msgcontent, ...body } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
@ -173,6 +191,10 @@ const waiMsgTypeMapped = {
externalId: msg.actionId,
// location: { degreesLatitude: msg.latitude, degreesLongitude: msg.longitude }, // todo:
}),
waiContentToDB: msg => {
// todo:
return {};
},
dataToDB: msg => {
const { msgtype, msgcontent, ...body } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
@ -204,6 +226,11 @@ const waiMsgTypeMapped = {
externalId: msg.actionId,
// contacts: { displayName: '', contacts: msg.contacts }, // todo:
}),
waiContentToDB: msg => {
return {
contacts: JSON.stringify(msg.contacts),
};
},
dataToDB: msg => {
const { msgtype, msgcontent, ...body } = msg;
const record = pick(msg, ['actionId', 'msgtype', 'externalId', 'from', 'to']);
@ -268,6 +295,15 @@ const ctxToDB = ctxContent => {
return msgReady;
};
/**
* wai Event Msg data to DB
*/
const waiContentToDB = waiMsg => {
const { waiContentToDB } = waiMsgTypeMapped[waiMsg.type];
const msgReady = waiContentToDB(waiMsg);
return msgReady;
};
/**
* Parse DB Data to UI/API/Webhook
*/
@ -277,8 +313,47 @@ const DbData = row => {
return msgReady;
};
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
const PROJECT_ROOT = process.cwd();
/**
* Upload Media File
* * https://p9axztuwd7x8a7.mycht.cn/whatsapp_server/WAFileUpload
* @param {*} filePath
*/
async function uploadMediaFile(filePath) {
const url = 'https://p9axztuwd7x8a7.mycht.cn/whatsapp_server/WAFileUpload';
try {
const pathObject = path.parse(filePath);
const filename = 'wai_' + pathObject.name.replace(/\s/g, '-') + `_${Date.now()}` + pathObject.ext;
const _filePath = path.join(PROJECT_ROOT, filePath);
const formData = new FormData();
formData.append('file', fs.createReadStream(_filePath), filename);
const response = await axios.post(url, formData, {
headers: formData.getHeaders(),
maxBodyLength: Infinity,
maxContentLength: Infinity,
});
const { result, errcode, errmsg } = response.data;
if (errcode !== 0) {
throw new Error(`Upload media file failed: ${errmsg}. ${filePath}`);
}
return errcode === 0 ? result.file_url : '';
} catch (error) {
console.error('Upload failed:', error);
// throw error;
return '';
}
}
module.exports = {
ctxToSendBuilder,
ctxToDB,
waiContentToDB,
DbData,
uploadMediaFile,
};

Loading…
Cancel
Save