mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
feat: new message logging using raw msg object
This commit is contained in:
@@ -2,6 +2,7 @@ import log4js, { Configuration } from 'log4js';
|
||||
import { truncateString } from '@/common/utils/helper';
|
||||
import path from 'node:path';
|
||||
import chalk from 'chalk';
|
||||
import { AtType, ChatType, ElementType, ElementWrapper, RawMessage, SelfInfo } from '@/core';
|
||||
|
||||
export enum LogLevel {
|
||||
DEBUG = 'debug',
|
||||
@@ -135,4 +136,104 @@ export class LogWrapper {
|
||||
logFatal(...args: any[]) {
|
||||
this._log(LogLevel.FATAL, ...args);
|
||||
}
|
||||
|
||||
logMessage(msg: RawMessage, selfInfo: SelfInfo) {
|
||||
const isSelfSent = msg.senderUin === selfInfo.uin;
|
||||
this.log(`${
|
||||
isSelfSent ? '发送 ->' : '接收 <-'
|
||||
} ${rawMessageToText(msg)}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function rawMessageToText(msg: RawMessage, recursiveLevel = 0): string {
|
||||
if (recursiveLevel > 2) {
|
||||
return '...';
|
||||
}
|
||||
|
||||
const tokens: string[] = [];
|
||||
|
||||
if (msg.chatType == ChatType.friend) {
|
||||
tokens.push(`私聊 (${msg.peerUin})`);
|
||||
} else if (msg.chatType == ChatType.group) {
|
||||
tokens.push(`群聊 (群 ${msg.peerUin} 的 ${msg.senderUin})`);
|
||||
} else if (msg.chatType == ChatType.chatDevice) {
|
||||
tokens.push('移动设备');
|
||||
} else /* temp */ {
|
||||
tokens.push(`临时消息 (${msg.peerUin})`);
|
||||
}
|
||||
|
||||
// message content
|
||||
|
||||
function msgElementToText(element: ElementWrapper) {
|
||||
if (element.textElement) {
|
||||
if (element.textElement.atType === AtType.notAt) {
|
||||
return element.textElement.content;
|
||||
} else if (element.textElement.atType === AtType.atAll) {
|
||||
return `@全体成员`;
|
||||
} else if (element.textElement.atType === AtType.atUser) {
|
||||
return `${element.textElement.content} (${element.textElement.atUid})`;
|
||||
}
|
||||
}
|
||||
|
||||
if (element.replyElement) {
|
||||
const recordMsgOrNull = msg.records.find(
|
||||
record => element.replyElement!.sourceMsgIdInRecords === record.msgId
|
||||
);
|
||||
return `[回复消息 ${
|
||||
recordMsgOrNull &&
|
||||
recordMsgOrNull.peerUin != '284840486' // 非转发消息; 否则定位不到
|
||||
?
|
||||
rawMessageToText(recordMsgOrNull, recursiveLevel + 1) :
|
||||
`未找到消息记录 (MsgId = ${element.replyElement.sourceMsgIdInRecords})`
|
||||
}]`;
|
||||
}
|
||||
|
||||
if (element.picElement) {
|
||||
return `[图片 ${element.picElement.fileName}]`;
|
||||
}
|
||||
|
||||
if (element.fileElement) {
|
||||
return `[文件 ${element.fileElement.fileName}]`;
|
||||
}
|
||||
|
||||
if (element.videoElement) {
|
||||
return `[视频 ${element.videoElement.fileName}]`;
|
||||
}
|
||||
|
||||
if (element.pttElement) {
|
||||
return `[语音 ${element.pttElement.duration}s]`;
|
||||
}
|
||||
|
||||
if (element.arkElement) {
|
||||
return `[卡片消息 ${element.arkElement.bytesData}]`;
|
||||
}
|
||||
|
||||
if (element.faceElement) {
|
||||
return `[表情 ${element.faceElement.faceText ?? ''}]`;
|
||||
}
|
||||
|
||||
if (element.marketFaceElement) {
|
||||
return `[商城表情 ${element.marketFaceElement.faceName}]`;
|
||||
}
|
||||
|
||||
if (element.markdownElement) {
|
||||
return `[Markdown ${element.markdownElement.content}]`;
|
||||
}
|
||||
|
||||
if (element.multiForwardMsgElement) {
|
||||
return `[转发消息]`;
|
||||
}
|
||||
|
||||
if (element.elementType === ElementType.GreyTip) {
|
||||
return `[灰条消息]`; // TODO: resolve the text
|
||||
}
|
||||
|
||||
return `[未实现 (ElementType = ${element.elementType})]`;
|
||||
}
|
||||
|
||||
for (const element of msg.elements) {
|
||||
tokens.push(msgElementToText(element));
|
||||
}
|
||||
|
||||
return tokens.join(' ');
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ import fs from 'node:fs';
|
||||
import { InstanceContext } from './wrapper';
|
||||
import { proxiedListenerOf } from '@/common/utils/proxy-handler';
|
||||
import { GroupListener, MsgListener, ProfileListener } from './listeners';
|
||||
import { GroupMember, SelfInfo, SelfStatusInfo } from './entities';
|
||||
import { GroupMember, SelfInfo } from './entities';
|
||||
import { LegacyNTEventWrapper } from '@/common/framework/event-legacy';
|
||||
import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from './apis';
|
||||
import os from 'node:os';
|
||||
@@ -90,8 +90,8 @@ export class NapCatCore {
|
||||
// Renamed from 'InitDataListener'
|
||||
async initNapCatCoreListeners() {
|
||||
const msgListener = new MsgListener();
|
||||
msgListener.onRecvMsg = (msg) => {
|
||||
//console.log('RecvMsg', msg);
|
||||
msgListener.onRecvMsg = (msgs) => {
|
||||
msgs.forEach(msg => this.context.logger.logMessage(msg, this.selfInfo));
|
||||
};
|
||||
//await sleep(2500);
|
||||
this.context.session.getMsgService().addKernelMsgListener(
|
||||
@@ -104,7 +104,7 @@ export class NapCatCore {
|
||||
Object.assign(this.selfInfo, profile);
|
||||
}
|
||||
};
|
||||
profileListener.onSelfStatusChanged = (Info: SelfStatusInfo) => {
|
||||
profileListener.onSelfStatusChanged = (/* Info: SelfStatusInfo */) => {
|
||||
// if (Info.status == 20) {
|
||||
// log("账号状态变更为离线")
|
||||
// }
|
||||
@@ -128,12 +128,12 @@ export class NapCatCore {
|
||||
// 获取群成员
|
||||
}
|
||||
const sceneId = this.context.session.getGroupService().createMemberListScene(g.groupCode, 'groupMemberList_MainWindow');
|
||||
this.context.session.getGroupService().getNextMemberList(sceneId!, undefined, 3000).then(r => {
|
||||
this.context.session.getGroupService().getNextMemberList(sceneId!, undefined, 3000).then( /* r => {
|
||||
// console.log(`get group ${g.groupCode} members`, r);
|
||||
// r.result.infos.forEach(member => {
|
||||
// });
|
||||
// groupMembers.set(g.groupCode, r.result.infos);
|
||||
});
|
||||
} */);
|
||||
});
|
||||
};
|
||||
groupListener.onMemberListChange = (arg) => {
|
||||
|
@@ -1,86 +0,0 @@
|
||||
import { Group, NapCatCore } from '@/core';
|
||||
import { OB11Message } from '@/onebot/types';
|
||||
import chalk from 'chalk';
|
||||
|
||||
const spSegColor = chalk.blue;// for special segment
|
||||
const spColor = chalk.cyan;// for special
|
||||
|
||||
// todo: 应该放到core去用RawMessage解析打印
|
||||
export async function logOB11Message(coreContext: NapCatCore, ob11Message: OB11Message) {
|
||||
const isSelfSent = ob11Message.sender.user_id.toString() === coreContext.selfInfo.uin;
|
||||
let prefix = '';
|
||||
let group: Group | undefined;
|
||||
if (isSelfSent) {
|
||||
prefix = '发送消息 ';
|
||||
if (ob11Message.message_type === 'private') {
|
||||
prefix += '给私聊 ';
|
||||
prefix += `${ob11Message.target_id}`;
|
||||
} else {
|
||||
prefix += '给群聊 ';
|
||||
}
|
||||
}
|
||||
if (ob11Message.message_type === 'group') {
|
||||
if (ob11Message.group_id == 284840486) {
|
||||
// group = await coreContext.ApiContext.GroupApi.getGroup(ob11Message.group_id!.toString());
|
||||
prefix += '转发消息[外部来源] ';
|
||||
} else {
|
||||
group = await coreContext.apis.GroupApi.getGroup(ob11Message.group_id!.toString());
|
||||
prefix += `群[${group?.groupName}(${ob11Message.group_id})] `;
|
||||
}
|
||||
}
|
||||
let msgChain: string;
|
||||
if (Array.isArray(ob11Message.message)) {
|
||||
const msgParts = [];
|
||||
for (const segment of ob11Message.message) {
|
||||
if (segment.type === 'text') {
|
||||
msgParts.push(segment.data.text);
|
||||
} else if (segment.type === 'at') {
|
||||
const groupMember = await coreContext.apis.GroupApi.getGroupMember(ob11Message.group_id!, segment.data.qq!);
|
||||
msgParts.push(spSegColor(`[@${groupMember?.cardName || groupMember?.nick}(${segment.data.qq})]`));
|
||||
} else if (segment.type === 'reply') {
|
||||
msgParts.push(spSegColor(`[回复消息|id:${segment.data.id}]`));
|
||||
} else if (segment.type === 'image') {
|
||||
msgParts.push(spSegColor(`[图片|${segment.data.url}]`));
|
||||
} else if (segment.type === 'face') {
|
||||
msgParts.push(spSegColor(`[表情|id:${segment.data.id}]`));
|
||||
} else if (segment.type === 'mface') {
|
||||
// @ts-expect-error 商城表情 url
|
||||
msgParts.push(spSegColor(`[商城表情|${segment.data.url}]`));
|
||||
} else if (segment.type === 'record') {
|
||||
msgParts.push(spSegColor(`[语音|${segment.data.file}]`));
|
||||
} else if (segment.type === 'file') {
|
||||
msgParts.push(spSegColor(`[文件|${segment.data.file}]`));
|
||||
} else if (segment.type === 'json') {
|
||||
msgParts.push(spSegColor(`[json|${JSON.stringify(segment.data)}]`));
|
||||
} else if (segment.type === 'markdown') {
|
||||
msgParts.push(spSegColor(`[markdown|${segment.data.content}]`));
|
||||
} else if (segment.type === 'video') {
|
||||
msgParts.push(spSegColor(`[视频|${segment.data.url}]`));
|
||||
} else if (segment.type === 'forward') {
|
||||
msgParts.push(spSegColor(`[转发|${segment.data.id}|消息开始]`));
|
||||
segment.data.content.forEach((msg) => {
|
||||
logOB11Message(coreContext, msg);
|
||||
});
|
||||
msgParts.push(spSegColor(`[转发|${segment.data.id}|消息结束]`));
|
||||
} else {
|
||||
msgParts.push(spSegColor(`[未实现|${JSON.stringify(segment)}]`));
|
||||
}
|
||||
}
|
||||
msgChain = msgParts.join(' ');
|
||||
} else {
|
||||
msgChain = ob11Message.message;
|
||||
}
|
||||
let msgString = `${prefix}${ob11Message.sender.nickname}(${ob11Message.sender.user_id}): ${msgChain}`;
|
||||
if (isSelfSent) {
|
||||
msgString = `${prefix}: ${msgChain}`;
|
||||
}
|
||||
coreContext.context.logger.log(msgString);
|
||||
}
|
||||
|
||||
export async function logOB11Notice(coreContext: NapCatCore, ob11Notice: any) {
|
||||
coreContext.context.logger.log(spColor('[Notice]'), ob11Notice);
|
||||
}
|
||||
|
||||
export async function logOB11Request(coreContext: NapCatCore, ob11Request: any) {
|
||||
coreContext.context.logger.log(spColor('[Request]'), ob11Request);
|
||||
}
|
@@ -25,7 +25,6 @@ import { WebUiDataRuntime } from '@/webui/src/helper/Data';
|
||||
import { OB11InputStatusEvent } from '@/onebot/event/notice/OB11InputStatusEvent';
|
||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||
import { OB11Constructor } from '@/onebot/helper/data';
|
||||
import { logOB11Message } from '@/onebot/helper/log';
|
||||
import { proxiedListenerOf } from '@/common/utils/proxy-handler';
|
||||
import { OB11FriendRequestEvent } from '@/onebot/event/request/OB11FriendRequest';
|
||||
import { OB11GroupAdminNoticeEvent } from '@/onebot/event/notice/OB11GroupAdminNoticeEvent';
|
||||
@@ -252,7 +251,7 @@ export class NapCatOneBot11Adapter {
|
||||
|
||||
for (const msg of msgList.filter(e => e.senderUin == this.core.selfInfo.uin)) {
|
||||
// console.log(msg);
|
||||
if (!!msgIdSend.get(msg.msgId)) continue;
|
||||
if (msgIdSend.get(msg.msgId)) continue;
|
||||
msgIdSend.put(msg.msgId, true);
|
||||
if (msg.sendStatus == 2) {
|
||||
// 完成后再post
|
||||
@@ -267,7 +266,7 @@ export class NapCatOneBot11Adapter {
|
||||
}, msg.msgId);
|
||||
this.emitMsg(msg);
|
||||
} else {
|
||||
logOB11Message(this.core, ob11Msg);
|
||||
// logOB11Message(this.core, ob11Msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -426,9 +425,9 @@ export class NapCatOneBot11Adapter {
|
||||
|
||||
private async emitMsg(message: RawMessage) {
|
||||
const { debug, reportSelfMessage, messagePostFormat } = this.configLoader.configData;
|
||||
this.context.logger.logDebug('收到新消息', message);
|
||||
this.context.logger.logDebug('收到新消息 RawMessage', message);
|
||||
OB11Constructor.message(this.core, message, messagePostFormat).then((ob11Msg) => {
|
||||
this.context.logger.logDebug('收到消息: ', ob11Msg);
|
||||
this.context.logger.logDebug('转化为 OB11Message', ob11Msg);
|
||||
if (debug) {
|
||||
ob11Msg.raw = message;
|
||||
} else {
|
||||
@@ -436,8 +435,8 @@ export class NapCatOneBot11Adapter {
|
||||
return;
|
||||
}
|
||||
}
|
||||
logOB11Message(this.core, ob11Msg)
|
||||
.catch(e => this.context.logger.logError('logMessage error: ', e));
|
||||
// logOB11Message(this.core, ob11Msg)
|
||||
// .catch(e => this.context.logger.logError('logMessage error: ', e));
|
||||
const isSelfMsg = ob11Msg.user_id.toString() == this.core.selfInfo.uin;
|
||||
if (isSelfMsg && !reportSelfMessage) {
|
||||
return;
|
||||
|
Reference in New Issue
Block a user