feat(server): first version

This commit is contained in:
2021-10-30 00:30:23 +08:00
commit 7e8985972c
11 changed files with 4224 additions and 0 deletions
+209
View File
@@ -0,0 +1,209 @@
const path = require("path");
const fs = require("fs");
const socket = require("./socket.js");
const db = require("./db.js");
const {
bot,
getDisplayName,
getGroupMsgSpeaker,
getNickName,
} = require("./bot.js");
const {
composeMessageID,
composeMediaFilePath,
composeFilename,
composeCacheFilePath,
fileMD5,
ensureMediaDir,
} = require("./util");
async function processMessage(msg) {
if ([50, 51, 52, 53, 9999].includes(msg.MsgType)) {
return;
}
const peerContact = bot.contacts[msg.getPeerUserName()];
const fromContact = bot.contacts[msg["FromUserName"]];
const toContact = bot.contacts[msg["ToUserName"]];
if (!peerContact || !fromContact || !toContact) {
// TODO: notify self
return;
}
if (
bot.Contact.isPublicContact(peerContact) ||
(bot.Contact.isSpContact(peerContact) &&
peerContact.UserName !== "filehelper")
) {
return;
}
ensureMediaDir(msg);
const msgID = msg["MsgId"];
const msgType = msg["MsgType"];
const m = {
messageID: msgID,
composedID: composeMessageID(msg),
createTimestamp: msg["CreateTime"],
messageType: msgType,
fromID: msg["FromUserName"],
toID: msg["ToUserName"],
fromName: getDisplayName(fromContact),
fromNickName: getNickName(fromContact),
toName: getDisplayName(toContact),
toNickName: getNickName(toContact),
type: "unknown",
content: null,
group: bot.Contact.isRoomContact(peerContact) ? peerContact : null,
speakingGroupMember: null,
filename: null,
displayFilename: msg["FileName"] || "",
isGroupMessage: bot.Contact.isRoomContact(peerContact),
};
if (m.isGroupMessage) {
if (!msg.isSendBySelf) {
m.speakingGroupMember = getGroupMsgSpeaker(msg);
}
}
switch (msgType) {
case bot.CONF.MSGTYPE_TEXT:
// 文本消息
m.type = "text";
m.content = msg["Content"];
break;
case bot.CONF.MSGTYPE_EMOTICON:
case bot.CONF.MSGTYPE_IMAGE: {
const suffix = msgType === bot.CONF.MSGTYPE_IMAGE ? ".jpg" : ".gif";
m.type = "img";
m.content =
`${msgType === bot.CONF.MSGTYPE_IMAGE ? "图片" : "表情"}` +
(msg["FileName"] || "");
if (msg["HasProductId"]) {
m.type = "unknown";
m.content = "【表情贴图】请在手机上查看";
break;
}
const cachePath = composeCacheFilePath(msg, suffix);
// ENHANCE: 提前判断表情是否存在,节约带宽
const res = await bot.getMsgImg(msg.MsgId);
fs.writeFileSync(cachePath, res.data);
const md5 = await fileMD5(cachePath);
m.filename = md5 + suffix;
const filename = composeMediaFilePath(msg, m.filename);
if (fs.existsSync(filename)) {
fs.rmSync(cachePath);
} else {
fs.renameSync(cachePath, filename);
}
break;
}
case bot.CONF.MSGTYPE_VOICE: {
m.type = "voice";
m.content = "【语音消息】";
m.filename = composeFilename(msg, ".mp3");
const { data } = await bot.getVoice(msg.MsgId);
fs.writeFileSync(composeMediaFilePath(msg, m.filename), data);
break;
}
case bot.CONF.MSGTYPE_VIDEO:
case bot.CONF.MSGTYPE_MICROVIDEO: {
m.type = "video";
const suffix = ".mp4";
const cachePath = composeCacheFilePath(msg, suffix);
const res = await bot.getVideo(msg.MsgId);
fs.writeFileSync(cachePath, res.data);
const md5 = await fileMD5(cachePath);
m.filename = md5 + suffix;
const filename = composeMediaFilePath(msg, m.filename);
if (fs.existsSync(filename)) {
fs.rmSync(cachePath);
} else {
fs.renameSync(cachePath, filename);
}
break;
}
case bot.CONF.MSGTYPE_APP:
m.type = "file";
if (msg.AppMsgType === 5) {
m.type = "text";
m.content = "【链接】" + msg["FileName"] + ": " + msg["Url"];
break;
} else if (msg.AppMsgType == 6) {
if (!(msg.FileSize < 10 * 1024 * 1024)) {
// 忽略10M以上的大文件
m.type = "unknown";
m.content = "【文件】" + m.displayFilename;
m.filename = null;
break;
}
const suffix = path.extname(m.displayFilename);
const cachePath = composeCacheFilePath(msg, suffix);
const res = await bot.getDoc(
msg.FromUserName,
msg.MediaId,
msg.FileName
);
fs.writeFileSync(cachePath, res.data);
const md5 = await fileMD5(cachePath);
m.filename = md5 + suffix;
const filename = composeMediaFilePath(msg, m.filename);
if (fs.existsSync(filename)) {
fs.rmSync(cachePath);
} else {
fs.renameSync(cachePath, filename);
}
break;
}
break;
default:
break;
}
if (m.type === "unknown") {
m.content ||= "未知类型的消息,请在手机上查看";
}
const dbMsg = {
messageID: m.composedID,
createTimestamp: m.createTimestamp,
type: m.type,
messageType: m.messageType,
fromName: m.fromName,
fromNickName: m.fromNickName,
toName: m.toName,
toNickName: m.toNickName,
isGroupMessage: m.isGroupMessage,
speakingGroupMemberName:
(m.speakingGroupMember && getDisplayName(m.speakingGroupMember)) || null,
content: m.content,
filename: m.filename,
displayFilename: m.displayFilename,
};
const clientMsg = {
msgID: m.messageID,
composedID: m.composedID,
createTimestamp: m.createTimestamp,
type: m.type,
fromID: m.fromID,
fromName: m.fromName,
fromNickName: m.fromNickName,
toID: m.toID,
toName: m.toName,
toNickName: m.toNickName,
isGroupMessage: m.isGroupMessage,
speakingGroupMemberID:
m.speakingGroupMember && m.speakingGroupMember.UserName,
speakingGroupMemberName:
(m.speakingGroupMember && getDisplayName(m.speakingGroupMember)) || null,
content: m.content,
filename: m.filename,
displayFilename: m.displayFilename,
};
await db.pushMessage(dbMsg);
socket.pushMessage(clientMsg);
}
module.exports = {
processMessage,
};