feat:完成商业号模板消息解析

main
LiaoYijun 8 months ago
parent 1525af2415
commit 3dc5ab72da

@ -88,187 +88,152 @@ const createWhatsApp = async phone => {
store?.bind(waSocket.ev);
const handleMessagesUpsert = async upsert => {
console.info('messages.upsert: ', JSON.stringify(upsert, undefined, 2));
const parseTextMessage = original => {
const text = original.message?.conversation || original.message?.extendedTextMessage?.text;
return {
type: 'text',
text: {
body: text,
},
};
};
if (upsert.type === 'notify') {
for (const msg of upsert.messages) {
// 没有类型的消息,先忽略
if (!msg.message) {
console.info('!msg.message, ignored.');
continue;
}
if (isJidStatusBroadcast(msg.key.remoteJid)) {
console.info('isJidStatusBroadcast, ignored.');
continue;
}
if (isJidNewsletter(msg.key.remoteJid)) {
console.info('isJidNewsletter, ignored.');
continue;
}
const messageType = Object.keys(msg.message)[0];
// 如果是群发(xxx@broadcast)participant 是发送人,不然则是 remoteJid
const remoteNo = isJidBroadcast(msg.key.remoteJid) ? decodeJid(msg.key.participant) : decodeJid(msg.key.remoteJid);
const externalId = externalIdCache.get(msg.key.id);
const isPersonal = isJidPersonal(msg.key.remoteJid);
const conversationType = isPersonal ? 'individual' : 'group';
const isGroup = isJidGroup(msg.key.remoteJid);
let groupSubject = groupSubjectCache.get(msg.key.remoteJid);
if (isGroup && groupSubject === undefined) {
const groupMetadata = await waSocket.groupMetadata(msg.key.remoteJid);
groupSubject = groupMetadata.subject;
groupSubjectCache.set(msg.key.remoteJid, groupMetadata.subject)
}
const emitEventName = msg.key.fromMe ? 'message:updated' : 'message:received';
const msgDirection = msg.key.fromMe ? 'outbound' : 'inbound';
const msgFrom = msg.key.fromMe ? whatsAppNo : remoteNo;
const msgTo = msg.key.fromMe ? remoteNo : whatsAppNo;
const msgStatus = msg.status === undefined ? '' : formatStatus(msg.status);
if (msg.message?.conversation || msg.message?.extendedTextMessage?.text) {
const text = msg.message?.conversation || msg.message?.extendedTextMessage?.text;
waEmitter.emit(emitEventName, {
id: msg.key.id,
externalId,
status: msgStatus,
direction: msgDirection,
from: msgFrom,
to: msgTo,
type: 'text',
text: {
body: text,
},
conversation: {
type: conversationType,
name: groupSubject,
},
customerProfile: {
id: decodeJid(msg.key.participant),
name: msg.pushName,
},
whatsAppNo,
fromMe: msg.key.fromMe,
eventSource: serverConfig.name + '.messages.upsert.notify',
updateTime: formatTimestamp(msg.messageTimestamp),
});
} else if (messageType === 'imageMessage') {
const imageMessage = msg.message.imageMessage;
const fileExtension = getFileExtension(imageMessage.mimetype);
const imageBuffer = await downloadMediaMessage(
msg, 'buffer', {}, { logger, reuploadRequest: waSocket.updateMediaMessage, },
);
const imageFilename = './temp/image_' + whatsAppNo + '_' + msg.key.id + fileExtension;
await writeFile(imageFilename, imageBuffer);
waEmitter.emit(emitEventName, {
id: msg.key.id,
externalId,
status: msgStatus,
direction: msgDirection,
from: msgFrom,
to: msgTo,
type: 'image',
image: {
mimetype: imageMessage.mimetype,
sha256: uint8ArrayToBase64(imageMessage.fileSha256),
caption: imageMessage.caption,
filePath: imageFilename,
link_original: imageMessage.url,
},
conversation: {
type: conversationType,
name: groupSubject,
},
customerProfile: {
id: decodeJid(msg.key.participant),
name: msg.pushName,
},
whatsAppNo,
fromMe: msg.key.fromMe,
eventSource: serverConfig.name + '.messages.upsert.notify',
updateTime: formatTimestamp(msg.messageTimestamp),
});
}
const parseImageMessage = async original => {
const imageMessage = original.message.imageMessage;
const fileExtension = getFileExtension(imageMessage.mimetype);
const imageBuffer = await downloadMediaMessage(
original, 'buffer', {}, { logger, reuploadRequest: waSocket.updateMediaMessage, },
);
const imageFilename = './temp/image_' + whatsAppNo + '_' + original.key.id + fileExtension;
await writeFile(imageFilename, imageBuffer);
return {
type: 'image',
image: {
mimetype: imageMessage.mimetype,
sha256: uint8ArrayToBase64(imageMessage.fileSha256),
caption: imageMessage.caption,
filePath: imageFilename,
link_original: imageMessage.url,
},
};
};
const parseTemplateMessage = original => {
if (original.message.templateMessage.hydratedTemplate) {
const text = original.message.templateMessage?.hydratedTemplate?.hydratedContentText;
return {
type: 'text',
text: {
body: text,
},
}
} else if (upsert.type === 'append') {
for (const msg of upsert.messages) {
if (msg.message?.conversation || msg.message?.extendedTextMessage?.text) {
const text = msg.message?.conversation || msg.message?.extendedTextMessage?.text;
// 如果是群发(xxx@broadcast)participant 是发送人,不然则是 remoteJid
const remoteNo = isJidBroadcast(msg.key.remoteJid) ? decodeJid(msg.key.participant) : decodeJid(msg.key.remoteJid);
const externalId = externalIdCache.get(msg.key.id);
const isPersonal = isJidPersonal(msg.key.remoteJid);
const conversationType = isPersonal ? 'individual' : 'group';
const emitEventName = msg.key.fromMe ? 'message:updated' : 'message:received';
const msgDirection = msg.key.fromMe ? 'outbound' : 'inbound';
const msgFrom = msg.key.fromMe ? whatsAppNo : remoteNo;
const msgTo = msg.key.fromMe ? remoteNo : whatsAppNo;
const msgStatus = msg.status === undefined ? '' : formatStatus(msg.status);
waEmitter.emit(emitEventName, {
id: msg.key.id,
externalId,
status: msgStatus,
direction: msgDirection,
from: msgFrom,
to: msgTo,
type: 'text',
text: {
body: text,
},
conversation: {
type: conversationType,
},
customerProfile: {
id: decodeJid(msg.participant),
name: msg.pushName,
},
whatsAppNo,
fromMe: msg.key.fromMe,
eventSource: serverConfig.name + '.messages.upsert.append',
updateTime: formatTimestamp(msg.messageTimestamp),
});
}
} else if (original.message.templateMessage.interactiveMessageTemplate) {
const text = original.message.templateMessage.interactiveMessageTemplate?.body?.text;
return {
type: 'text',
text: {
body: text,
},
}
}
}
};
const handleTemplateMessage = async msgObj => {
const text = msgObj.message.templateMessage?.hydratedTemplate?.hydratedContentText;
const getMessageParser = (original) => {
waEmitter.emit(emitEventName, {
id: msgObj.key.id,
externalId,
status: msgStatus,
direction: msgDirection,
from: msgFrom,
to: msgTo,
type: 'text',
text: {
body: text,
},
conversation: {
type: conversationType,
name: groupSubject,
},
customerProfile: {
id: decodeJid(msgObj.key.remoteJid),
name: msgObj.verifiedBizName || msgObj.pushName,
},
whatsAppNo,
fromMe: msgObj.key.fromMe,
eventSource: serverConfig.name + '.messages.upsert.notify',
updateTime: formatTimestamp(msgObj.messageTimestamp),
});
if (original.message?.conversation || original.message?.extendedTextMessage?.text) return parseTextMessage;
if (original.message?.imageMessage) return parseImageMessage;
if (original.message?.templateMessage) return parseTemplateMessage;
return null;
};
const getEventSource = (upsert) => {
if (upsert.type === 'notify') {
return serverConfig.name + '.messages.upsert.notify';
} else if (upsert.type === 'append') {
return serverConfig.name + '.messages.upsert.append';
} else {
return serverConfig.name + '.messages.upsert.unknown';
}
};
const handleMessagesUpsert = async upsert => {
console.info('messages.upsert: ', JSON.stringify(upsert, undefined, 2));
for (const msg of upsert.messages) {
// 没有类型的消息,先忽略
if (!msg.message) {
console.info('!msg.message, ignored.');
continue;
}
if (isJidStatusBroadcast(msg.key.remoteJid)) {
console.info('isJidStatusBroadcast, ignored.');
continue;
}
if (isJidNewsletter(msg.key.remoteJid)) {
console.info('isJidNewsletter, ignored.');
continue;
}
// 如果是群发(xxx@broadcast)participant 是发送人,不然则是 remoteJid
const remoteNo = isJidBroadcast(msg.key.remoteJid) ? decodeJid(msg.key.participant) : decodeJid(msg.key.remoteJid);
const externalId = externalIdCache.get(msg.key.id);
const isPersonal = isJidPersonal(msg.key.remoteJid);
const conversationType = isPersonal ? 'individual' : 'group';
const isGroup = isJidGroup(msg.key.remoteJid);
let groupSubject = groupSubjectCache.get(msg.key.remoteJid);
if (isGroup && groupSubject === undefined) {
const groupMetadata = await waSocket.groupMetadata(msg.key.remoteJid);
groupSubject = groupMetadata.subject;
groupSubjectCache.set(msg.key.remoteJid, groupMetadata.subject)
}
const emitEventName = msg.key.fromMe ? 'message:updated' : 'message:received';
const msgEventSource = getEventSource(upsert);
const msgDirection = msg.key.fromMe ? 'outbound' : 'inbound';
const msgFrom = msg.key.fromMe ? whatsAppNo : remoteNo;
const msgTo = msg.key.fromMe ? remoteNo : whatsAppNo;
const msgStatus = msg.status === undefined ? '' : formatStatus(msg.status);
const standardMessage = {
id: msg.key.id,
externalId,
status: msgStatus,
direction: msgDirection,
from: msgFrom,
to: msgTo,
conversation: {
type: conversationType,
name: groupSubject,
},
customerProfile: {
id: isGroup ? decodeJid(msg.key.participant) : decodeJid(msg.key.remoteJid),
// 商业号使用 verifiedBizName个人使用 pushName
name: msg.verifiedBizName || msg.pushName,
},
whatsAppNo,
fromMe: msg.key.fromMe,
eventSource: msgEventSource,
updateTime: formatTimestamp(msg.messageTimestamp),
}
const messageParser = getMessageParser(msg);
if (messageParser) {
const parsedMessage = await messageParser(msg);
const mergedMessage = Object.assign({}, standardMessage, parsedMessage);
waEmitter.emit(emitEventName, mergedMessage);
} else {
console.info('不支持该消息类型:', msg);
}
}
}
const handleMessagesUpdate = async messageUpdate => {
console.info('messages.update: ', JSON.stringify(messageUpdate, undefined, 2));
@ -383,7 +348,6 @@ const createWhatsApp = async phone => {
// 第一次一分钟,后面是 20 秒更新一次
if (qrCode === null) {
qrCode = qr;
console.info('QR Code: ' + qrCode);
waEmitter.emit('creds:update', {
id: generateId(),
qr, whatsAppNo,

Loading…
Cancel
Save