diff --git a/src/onebot11/action/go-cqhttp/SendForwardMsg.ts b/src/onebot11/action/go-cqhttp/SendForwardMsg.ts index a2c2ce34..f866816e 100644 --- a/src/onebot11/action/go-cqhttp/SendForwardMsg.ts +++ b/src/onebot11/action/go-cqhttp/SendForwardMsg.ts @@ -1,4 +1,4 @@ -import SendMsg, { convertMessage2List } from '../msg/SendMsg'; +import SendMsg, { normalize } from '../msg/SendMsg'; import { OB11PostSendMsg } from '../../types'; import { ActionName } from '../types'; @@ -6,7 +6,7 @@ export class GoCQHTTPSendForwardMsg extends SendMsg { actionName = ActionName.GoCQHTTP_SendForwardMsg; protected async check(payload: OB11PostSendMsg) { - if (payload.messages) payload.message = convertMessage2List(payload.messages); + if (payload.messages) payload.message = normalize(payload.messages); return super.check(payload); } } @@ -17,4 +17,4 @@ export class GoCQHTTPSendPrivateForwardMsg extends GoCQHTTPSendForwardMsg { export class GoCQHTTPSendGroupForwardMsg extends GoCQHTTPSendForwardMsg { actionName = ActionName.GoCQHTTP_SendGroupForwardMsg; -} \ No newline at end of file +} diff --git a/src/onebot11/action/msg/SendMsg/check-send-message.ts b/src/onebot11/action/msg/SendMsg/check-send-message.ts new file mode 100644 index 00000000..299f41dc --- /dev/null +++ b/src/onebot11/action/msg/SendMsg/check-send-message.ts @@ -0,0 +1,36 @@ +import { OB11MessageData } from '@/onebot11/types'; + +function checkSendMessage(sendMsgList: OB11MessageData[]) { + function checkUri(uri: string): boolean { + const pattern = /^(file:\/\/|http:\/\/|https:\/\/|base64:\/\/)/; + return pattern.test(uri); + } + + for (const msg of sendMsgList) { + if (msg['type'] && msg['data']) { + const type = msg['type']; + const data = msg['data']; + if (type === 'text' && !data['text']) { + return 400; + } else if (['image', 'voice', 'record'].includes(type)) { + if (!data['file']) { + return 400; + } else { + if (checkUri(data['file'])) { + return 200; + } else { + return 400; + } + } + + } else if (type === 'at' && !data['qq']) { + return 400; + } else if (type === 'reply' && !data['id']) { + return 400; + } + } else { + return 400; + } + } + return 200; +} diff --git a/src/onebot11/action/msg/SendMsg/handle-forward-node.ts b/src/onebot11/action/msg/SendMsg/handle-forward-node.ts new file mode 100644 index 00000000..3fb13064 --- /dev/null +++ b/src/onebot11/action/msg/SendMsg/handle-forward-node.ts @@ -0,0 +1,163 @@ +import { ChatType, ElementType, Group, NTQQMsgApi, Peer, RawMessage, SendMessageElement } from '@/core'; +import { OB11MessageNode } from '@/onebot11/types'; +import { selfInfo } from '@/core/data'; +import { dbUtil } from '@/core/utils/db'; +import createSendElements from '@/onebot11/action/msg/SendMsg/create-send-elements'; +import { logDebug, logError } from '@/common/utils/log'; +import { sleep } from '@/common/utils/helper'; +import fs from 'node:fs'; +import { normalize, sendMsg } from '@/onebot11/action/msg/SendMsg/index'; + +async function cloneMsg(msg: RawMessage): Promise { + const selfPeer = { + chatType: ChatType.friend, + peerUid: selfInfo.uid + }; + + logDebug('克隆的目标消息', msg); + + const sendElements: SendMessageElement[] = []; + + for (const element of msg.elements) { + sendElements.push(element as SendMessageElement); + } + + if (sendElements.length === 0) { + logDebug('需要clone的消息无法解析,将会忽略掉', msg); + } + + logDebug('克隆消息', sendElements); + + try { + const nodeMsg = await NTQQMsgApi.sendMsg(selfPeer, sendElements, true); + await sleep(500); // 防止风控 + return nodeMsg; + } catch (e) { + logError(e, '克隆转发消息失败,将忽略本条消息', msg); + } +} + +export async function handleForwardNode(destPeer: Peer, messageNodes: OB11MessageNode[], group: Group | undefined): Promise { + const selfPeer = { + chatType: ChatType.friend, + peerUid: selfInfo.uid + }; + let nodeMsgIds: string[] = []; + + // 先判断一遍是不是id和自定义混用 + const needClone = + messageNodes.filter(node => node.data.id).length && + messageNodes.filter(node => !node.data.id).length; + + for (const messageNode of messageNodes) { + // 一个node表示一个人的消息 + const nodeId = messageNode.data.id; + // 有nodeId表示一个子转发消息卡片 + if (nodeId) { + const nodeMsg = await dbUtil.getMsgByShortId(parseInt(nodeId)); + if (!needClone) { + nodeMsgIds.push(nodeMsg!.msgId); + } else { + if (nodeMsg!.peerUid !== selfInfo.uid) { + // need cloning + const clonedMsg = await cloneMsg(nodeMsg!); + if (clonedMsg) { + nodeMsgIds.push(clonedMsg.msgId); + } + } + } + } else { + // 自定义的消息 + // 提取消息段,发给自己生成消息id + try { + const { sendElements, deleteAfterSentFiles } = await createSendElements(normalize(messageNode.data.content), group); + logDebug('开始生成转发节点', sendElements); + const sendElementsSplit: SendMessageElement[][] = []; + let splitIndex = 0; + for (const sendElement of sendElements) { + if (!sendElementsSplit[splitIndex]) { + sendElementsSplit[splitIndex] = []; + } + + if (sendElement.elementType === ElementType.FILE || sendElement.elementType === ElementType.VIDEO) { + if (sendElementsSplit[splitIndex].length > 0) { + splitIndex++; + } + sendElementsSplit[splitIndex] = [sendElement]; + splitIndex++; + } else { + sendElementsSplit[splitIndex].push(sendElement); + } + logDebug(sendElementsSplit); + } + // log("分割后的转发节点", sendElementsSplit) + const MsgNodeList: Promise[] = []; + for (const sendElementsSplitElement of sendElementsSplit) { + MsgNodeList.push(sendMsg(selfPeer, sendElementsSplitElement, [], true)); + await sleep(Math.trunc(sendElementsSplit.length / 10) * 100); + //await sleep(10); + } + for (const msgNode of MsgNodeList) { + const result = await msgNode; + nodeMsgIds.push(result.msgId); + logDebug('转发节点生成成功', result.msgId); + } + deleteAfterSentFiles.map(f => fs.unlink(f, () => { + })); + + } catch (e) { + logDebug('生成转发消息节点失败', e); + } + } + } + + // 检查srcPeer是否一致,不一致则需要克隆成自己的消息, 让所有srcPeer都变成自己的,使其保持一致才能够转发 + const nodeMsgArray: Array = []; + let srcPeer: Peer | undefined = undefined; + let needSendSelf = false; + for (const msgId of nodeMsgIds) { + const nodeMsg = await dbUtil.getMsgByLongId(msgId); + if (nodeMsg) { + nodeMsgArray.push(nodeMsg); + if (!srcPeer) { + srcPeer = { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid }; + } else if (srcPeer.peerUid !== nodeMsg.peerUid) { + needSendSelf = true; + srcPeer = selfPeer; + } + } + } + logDebug('nodeMsgArray', nodeMsgArray); + nodeMsgIds = nodeMsgArray.map(msg => msg.msgId); + if (needSendSelf) { + logDebug('需要克隆转发消息'); + for (const [index, msg] of nodeMsgArray.entries()) { + if (msg.peerUid !== selfInfo.uid) { + const clonedMsg = await cloneMsg(msg); + if (clonedMsg) { + nodeMsgIds[index] = clonedMsg.msgId; + } + } + } + } + // elements之间用换行符分隔 + // let _sendForwardElements: SendMessageElement[] = [] + // for(let i = 0; i < sendForwardElements.length; i++){ + // _sendForwardElements.push(sendForwardElements[i]) + // _sendForwardElements.push(SendMsgElementConstructor.text("\n\n")) + // } + // const nodeMsg = await NTQQApi.sendMsg(selfPeer, _sendForwardElements, true); + // nodeIds.push(nodeMsg.msgId) + // await sleep(500); + // 开发转发 + if (nodeMsgIds.length === 0) { + throw Error('转发消息失败,生成节点为空'); + } + try { + logDebug('开发转发', srcPeer, destPeer, nodeMsgIds); + return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, nodeMsgIds); + } catch (e) { + logError('forward failed', e); + return null; + } +} diff --git a/src/onebot11/action/msg/SendMsg/index.ts b/src/onebot11/action/msg/SendMsg/index.ts index 18cf2e0f..1f51ee7d 100644 --- a/src/onebot11/action/msg/SendMsg/index.ts +++ b/src/onebot11/action/msg/SendMsg/index.ts @@ -1,6 +1,5 @@ import BaseAction from '@/onebot11/action/BaseAction'; import { - OB11MessageCustomMusic, OB11MessageData, OB11MessageDataType, OB11MessageMixType, @@ -8,88 +7,32 @@ import { OB11PostSendMsg } from '@/onebot11/types'; import { ActionName, BaseCheckResult } from '@/onebot11/action/types'; -import { getFriend, getGroup, getUidByUin, selfInfo } from '@/core/data'; +import { getFriend, getGroup, getUidByUin } from '@/core/data'; import { dbUtil } from '@/core/utils/db'; -import { - ChatType, - CustomMusicSignPostData, - ElementType, - Group, - IdMusicSignPostData, - NTQQMsgApi, - Peer, - RawMessage, - SendArkElement, - SendMessageElement, - SendMsgElementConstructor -} from '@/core'; +import { ChatType, Group, NTQQMsgApi, Peer, SendMessageElement, } from '@/core'; import fs from 'node:fs'; -import { logDebug, logError } from '@/common/utils/log'; -import { sleep } from '@/common/utils/helper'; -import { ob11Config } from '@/onebot11/config'; -import { RequestUtil } from '@/common/utils/request'; +import { logDebug } from '@/common/utils/log'; import { decodeCQCode } from '@/onebot11/cqcode'; import createSendElements from './create-send-elements'; +import { handleForwardNode } from '@/onebot11/action/msg/SendMsg/handle-forward-node'; const ALLOW_SEND_TEMP_MSG = false; -function checkSendMessage(sendMsgList: OB11MessageData[]) { - function checkUri(uri: string): boolean { - const pattern = /^(file:\/\/|http:\/\/|https:\/\/|base64:\/\/)/; - return pattern.test(uri); - } - - for (const msg of sendMsgList) { - if (msg['type'] && msg['data']) { - const type = msg['type']; - const data = msg['data']; - if (type === 'text' && !data['text']) { - return 400; - } else if (['image', 'voice', 'record'].includes(type)) { - if (!data['file']) { - return 400; - } else { - if (checkUri(data['file'])) { - return 200; - } else { - return 400; - } - } - - } else if (type === 'at' && !data['qq']) { - return 400; - } else if (type === 'reply' && !data['id']) { - return 400; - } - } else { - return 400; - } - } - return 200; -} - export interface ReturnDataType { message_id: number; } -export function convertMessage2List(message: OB11MessageMixType, autoEscape = false) { - if (typeof message === 'string') { - if (autoEscape === true) { - message = [{ - type: OB11MessageDataType.text, - data: { - text: message - } - }]; - } else { - message = decodeCQCode(message.toString()); - } - } else if (!Array.isArray(message)) { - message = [message]; - } - return message; +// Normalizes a mixed type (CQCode/a single segment/segment array) into a segment array. +export function normalize(message: OB11MessageMixType, autoEscape = false): OB11MessageData[] { + return typeof message === 'string' ? ( + autoEscape ? + [{ type: OB11MessageDataType.text, data: { text: message } }] : + decodeCQCode(message) + ) : Array.isArray(message) ? message : [message]; } +export { createSendElements }; + export async function sendMsg(peer: Peer, sendElements: SendMessageElement[], deleteAfterSentFiles: string[], waitComplete = true) { if (!sendElements.length) { throw ('消息体无法解析, 请检查是否发送了不支持的消息类型'); @@ -101,288 +44,112 @@ export async function sendMsg(peer: Peer, sendElements: SendMessageElement[], de logDebug('发送消息id获取失败', e); returnMsg.id = 0; } - // log('消息发送结果', returnMsg); deleteAfterSentFiles.map(f => fs.unlink(f, () => { })); return returnMsg; } +async function createContext(payload: OB11PostSendMsg): Promise<{ + peer: Peer, group?: Group +}> { + // This function determines the type of message by the existence of user_id / group_id, + // not message_type. + // This redundant design of Ob11 here should be blamed. + + if (payload.user_id) { // take this as a private message + const friend = await getFriend(payload.user_id.toString()); + if (!friend) { + if (ALLOW_SEND_TEMP_MSG) { + const tempUid = getUidByUin(payload.user_id.toString()); + if (tempUid) return { + peer: { + chatType: ChatType.temp, + peerUid: tempUid + }, + }; + } + throw `找不到私聊对象 ${payload.user_id}`; + } + return { + peer: { + chatType: ChatType.friend, + peerUid: friend.uid + }, + }; + } else if (payload.group_id) { // take this as a group message + const group = (await getGroup(payload.group_id))!; // checked before + return { + peer: { + chatType: ChatType.group, + peerUid: group.groupCode + }, + group: group, + }; + } + throw '请指定 group_id 或 user_id'; +} + +function getSpecialMsgNum(payload: OB11PostSendMsg, msgType: OB11MessageDataType): number { + if (Array.isArray(payload.message)) { + return payload.message.filter(msg => msg.type == msgType).length; + } + return 0; +} + export class SendMsg extends BaseAction { actionName = ActionName.SendMsg; protected async check(payload: OB11PostSendMsg): Promise { - const messages = convertMessage2List(payload.message); - const fmNum = this.getSpecialMsgNum(payload, OB11MessageDataType.node); - if (fmNum && fmNum != messages.length) { - return { - valid: false, - message: '转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素' - }; + const messages = normalize(payload.message); + if (getSpecialMsgNum(payload, OB11MessageDataType.node) != messages.length) { + return { valid: false, message: '转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素' }; } if (payload.message_type !== 'private' && payload.group_id && !(await getGroup(payload.group_id))) { - return { - valid: false, - message: `群${payload.group_id}不存在` - }; + return { valid: false, message: `群${payload.group_id}不存在` }; } if (payload.user_id && payload.message_type !== 'group') { if (!(await getFriend(payload.user_id))) { - if (!ALLOW_SEND_TEMP_MSG - && !(await dbUtil.getUidByTempUin(payload.user_id.toString())) + if ( + !ALLOW_SEND_TEMP_MSG && + !(await dbUtil.getUidByTempUin(payload.user_id)) ) { - return { - valid: false, - message: '不能发送临时消息' - }; + return { valid: false, message: '不能发送临时消息' }; } } } - return { - valid: true, - }; + return { valid: true, }; } protected async _handle(payload: OB11PostSendMsg): Promise<{ message_id: number }> { + const { peer, group } = await createContext(payload); - const peer: Peer = { - chatType: ChatType.friend, - peerUid: '' - }; - let isTempMsg = false; - let group: Group | undefined = undefined; - const genGroupPeer = async () => { - if (payload.group_id) { - group = await getGroup(payload.group_id.toString()); - if (group) { - peer.chatType = ChatType.group; - // peer.name = group.name - peer.peerUid = group.groupCode; - } + const messages = normalize( + payload.message, + payload.auto_escape === true || payload.auto_escape === 'true' + ); - } - }; - - const genFriendPeer = async () => { - if (!payload.user_id) { - return; - } - const friend = await getFriend(payload.user_id.toString()); - if (friend) { - // peer.name = friend.nickName - peer.peerUid = friend.uid; + if (getSpecialMsgNum(payload, OB11MessageDataType.node)) { + const returnMsg = await handleForwardNode(peer, messages as OB11MessageNode[], group); + if (returnMsg) { + const msgShortId = await dbUtil.addMsg(returnMsg!, false); + return { message_id: msgShortId }; } else { - peer.chatType = ChatType.temp; - const tempUserUid = getUidByUin(payload.user_id.toString()); - if (!tempUserUid) { - throw (`找不到私聊对象${payload.user_id}`); - } - // peer.name = tempUser.nickName - isTempMsg = true; - peer.peerUid = tempUserUid; - } - }; - if (payload?.group_id && payload.message_type === 'group') { - await genGroupPeer(); - - } else if (payload?.user_id) { - await genFriendPeer(); - } else if (payload.group_id) { - await genGroupPeer(); - } else { - throw ('发送消息参数错误, 请指定group_id或user_id'); - } - const messages = convertMessage2List(payload.message, payload.auto_escape === true || payload.auto_escape === 'true'); - if (this.getSpecialMsgNum(payload, OB11MessageDataType.node)) { - try { - const returnMsg = await this.handleForwardNode(peer, messages as OB11MessageNode[], group); - if (returnMsg) { - const msgShortId = await dbUtil.addMsg(returnMsg!, false); - return { message_id: msgShortId }; - } else { - throw Error('发送转发消息失败'); - } - } catch (e: any) { - throw Error('发送转发消息失败 ' + e.toString()); + throw Error('发送转发消息失败'); } } else { - if (this.getSpecialMsgNum(payload, OB11MessageDataType.music)) { - const music: OB11MessageCustomMusic = messages[0] as OB11MessageCustomMusic; - // if (music) { - // } - } + // if (getSpecialMsgNum(payload, OB11MessageDataType.music)) { + // const music: OB11MessageCustomMusic = messages[0] as OB11MessageCustomMusic; + // if (music) { + // } + // } } // log("send msg:", peer, sendElements) const { sendElements, deleteAfterSentFiles } = await createSendElements(messages, group); const returnMsg = await sendMsg(peer, sendElements, deleteAfterSentFiles); - deleteAfterSentFiles.map(f => fs.unlink(f, () => { - })); + deleteAfterSentFiles.forEach(f => fs.unlinkSync(f)); - const res = { message_id: returnMsg.id! }; - // console.log(res); - return res; + return { message_id: returnMsg.id! }; } - - - private getSpecialMsgNum(payload: OB11PostSendMsg, msgType: OB11MessageDataType): number { - if (Array.isArray(payload.message)) { - return payload.message.filter(msg => msg.type == msgType).length; - } - return 0; - } - - private async cloneMsg(msg: RawMessage): Promise { - logDebug('克隆的目标消息', msg); - const sendElements: SendMessageElement[] = []; - for (const ele of msg.elements) { - sendElements.push(ele as SendMessageElement); - // Object.keys(ele).forEach((eleKey) => { - // if (eleKey.endsWith("Element")) { - // } - - } - if (sendElements.length === 0) { - logDebug('需要clone的消息无法解析,将会忽略掉', msg); - } - logDebug('克隆消息', sendElements); - try { - const nodeMsg = await NTQQMsgApi.sendMsg({ - chatType: ChatType.friend, - peerUid: selfInfo.uid - }, sendElements, true); - await sleep(500); - return nodeMsg; - } catch (e) { - logError(e, '克隆转发消息失败,将忽略本条消息', msg); - } - - } - - // 返回一个合并转发的消息id - private async handleForwardNode(destPeer: Peer, messageNodes: OB11MessageNode[], group: Group | undefined): Promise { - - const selfPeer = { - chatType: ChatType.friend, - peerUid: selfInfo.uid - }; - let nodeMsgIds: string[] = []; - // 先判断一遍是不是id和自定义混用 - const needClone = messageNodes.filter(node => node.data.id).length && messageNodes.filter(node => !node.data.id).length; - for (const messageNode of messageNodes) { - // 一个node表示一个人的消息 - const nodeId = messageNode.data.id; - // 有nodeId表示一个子转发消息卡片 - if (nodeId) { - const nodeMsg = await dbUtil.getMsgByShortId(parseInt(nodeId)); - if (!needClone) { - nodeMsgIds.push(nodeMsg!.msgId); - } else { - if (nodeMsg!.peerUid !== selfInfo.uid) { - const cloneMsg = await this.cloneMsg(nodeMsg!); - if (cloneMsg) { - nodeMsgIds.push(cloneMsg.msgId); - } - } - } - } else { - // 自定义的消息 - // 提取消息段,发给自己生成消息id - try { - const { - sendElements, - deleteAfterSentFiles - } = await createSendElements(convertMessage2List(messageNode.data.content), group); - logDebug('开始生成转发节点', sendElements); - const sendElementsSplit: SendMessageElement[][] = []; - let splitIndex = 0; - for (const ele of sendElements) { - if (!sendElementsSplit[splitIndex]) { - sendElementsSplit[splitIndex] = []; - } - - if (ele.elementType === ElementType.FILE || ele.elementType === ElementType.VIDEO) { - if (sendElementsSplit[splitIndex].length > 0) { - splitIndex++; - } - sendElementsSplit[splitIndex] = [ele]; - splitIndex++; - } else { - sendElementsSplit[splitIndex].push(ele); - } - logDebug(sendElementsSplit); - } - // log("分割后的转发节点", sendElementsSplit) - const MsgNodeList: Promise[] = []; - for (const eles of sendElementsSplit) { - MsgNodeList.push(sendMsg(selfPeer, eles, [], true)); - await sleep(Math.trunc(sendElementsSplit.length / 10) * 100); - //await sleep(10); - } - for (const msgNode of MsgNodeList) { - const result = await msgNode; - nodeMsgIds.push(result.msgId); - logDebug('转发节点生成成功', result.msgId); - } - deleteAfterSentFiles.map(f => fs.unlink(f, () => { - })); - - } catch (e) { - logDebug('生成转发消息节点失败', e); - } - } - } - - // 检查srcPeer是否一致,不一致则需要克隆成自己的消息, 让所有srcPeer都变成自己的,使其保持一致才能够转发 - const nodeMsgArray: Array = []; - let srcPeer: Peer | undefined = undefined; - let needSendSelf = false; - for (const [index, msgId] of nodeMsgIds.entries()) { - const nodeMsg = await dbUtil.getMsgByLongId(msgId); - if (nodeMsg) { - nodeMsgArray.push(nodeMsg); - if (!srcPeer) { - srcPeer = { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid }; - } else if (srcPeer.peerUid !== nodeMsg.peerUid) { - needSendSelf = true; - srcPeer = selfPeer; - } - } - } - logDebug('nodeMsgArray', nodeMsgArray); - nodeMsgIds = nodeMsgArray.map(msg => msg.msgId); - if (needSendSelf) { - logDebug('需要克隆转发消息'); - for (const [index, msg] of nodeMsgArray.entries()) { - if (msg.peerUid !== selfInfo.uid) { - const cloneMsg = await this.cloneMsg(msg); - if (cloneMsg) { - nodeMsgIds[index] = cloneMsg.msgId; - } - } - } - } - // elements之间用换行符分隔 - // let _sendForwardElements: SendMessageElement[] = [] - // for(let i = 0; i < sendForwardElements.length; i++){ - // _sendForwardElements.push(sendForwardElements[i]) - // _sendForwardElements.push(SendMsgElementConstructor.text("\n\n")) - // } - // const nodeMsg = await NTQQApi.sendMsg(selfPeer, _sendForwardElements, true); - // nodeIds.push(nodeMsg.msgId) - // await sleep(500); - // 开发转发 - if (nodeMsgIds.length === 0) { - throw Error('转发消息失败,生成节点为空'); - } - try { - logDebug('开发转发', srcPeer, destPeer, nodeMsgIds); - return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, nodeMsgIds); - } catch (e) { - logError('forward failed', e); - return null; - } - } - - } export default SendMsg; diff --git a/src/onebot11/server/postOB11Event.ts b/src/onebot11/server/postOB11Event.ts index 3c2acd22..1c1f1677 100644 --- a/src/onebot11/server/postOB11Event.ts +++ b/src/onebot11/server/postOB11Event.ts @@ -3,11 +3,11 @@ import { OB11BaseMetaEvent } from '../event/meta/OB11BaseMetaEvent'; import { OB11BaseNoticeEvent } from '../event/notice/OB11BaseNoticeEvent'; import { WebSocket as WebSocketClass } from 'ws'; import { wsReply } from './ws/reply'; -import { log, logDebug, logError } from '@/common/utils/log'; +import { logDebug, logError } from '@/common/utils/log'; import { ob11Config } from '@/onebot11/config'; import crypto from 'crypto'; import { ChatType, Group, GroupRequestOperateTypes, Peer } from '@/core/entities'; -import { convertMessage2List, sendMsg } from '../action/msg/SendMsg'; +import { normalize, sendMsg } from '../action/msg/SendMsg'; import { OB11FriendRequestEvent } from '../event/request/OB11FriendRequest'; import { OB11GroupRequestEvent } from '../event/request/OB11GroupRequest'; import { isNull } from '@/common/utils/helper'; @@ -139,7 +139,7 @@ export function postOB11Event(msg: PostEventType, reportSelf = false, postWs = t } as OB11MessageAt); } } - replyMessage = replyMessage.concat(convertMessage2List(reply, resJson.auto_escape)); + replyMessage = replyMessage.concat(normalize(reply, resJson.auto_escape)); const { sendElements, deleteAfterSentFiles } = await createSendElements(replyMessage, group); sendMsg(peer, sendElements, deleteAfterSentFiles, false).then(); } else if (resJson.delete) { diff --git a/src/onebot11/types/entity.ts b/src/onebot11/types/entity.ts new file mode 100644 index 00000000..32df147a --- /dev/null +++ b/src/onebot11/types/entity.ts @@ -0,0 +1,63 @@ +export interface OB11User { + user_id: number; + nickname: string; + remark?: string; + sex?: OB11UserSex; + level?: number; + age?: number; + qid?: string; + login_days?: number; +} + +export enum OB11UserSex { + male = 'male', + female = 'female', + unknown = 'unknown' +} + +export enum OB11GroupMemberRole { + owner = 'owner', + admin = 'admin', + member = 'member', +} + +export interface OB11GroupMember { + group_id: number + user_id: number + nickname: string + card?: string + sex?: OB11UserSex + age?: number + join_time?: number + last_sent_time?: number + level?: number + qq_level?: number + role?: OB11GroupMemberRole + title?: string + area?: string + unfriendly?: boolean + title_expire_time?: number + card_changeable?: boolean + // 以下为gocq字段 + shut_up_timestamp?: number + // 以下为扩展字段 + is_robot?: boolean + qage?: number +} + +export interface OB11Group { + group_id: number + group_name: string + member_count?: number + max_member_count?: number +} + +export interface OB11Sender { + user_id: number, + nickname: string, + sex?: OB11UserSex, + age?: number, + card?: string, // 群名片 + level?: string, // 群等级 + role?: OB11GroupMemberRole +} diff --git a/src/onebot11/types/index.ts b/src/onebot11/types/index.ts new file mode 100644 index 00000000..e640c90d --- /dev/null +++ b/src/onebot11/types/index.ts @@ -0,0 +1,3 @@ +export * from './entity'; +export * from './message'; +export * from './meta'; diff --git a/src/onebot11/types.ts b/src/onebot11/types/message.ts similarity index 72% rename from src/onebot11/types.ts rename to src/onebot11/types/message.ts index 679bada6..8b709975 100644 --- a/src/onebot11/types.ts +++ b/src/onebot11/types/message.ts @@ -1,71 +1,6 @@ -import { PicSubType, RawMessage } from '@/core'; -import { EventType } from './event/OB11BaseEvent'; -import { CustomMusicSignPostData, IdMusicSignPostData } from '@/core/apis/sign'; -import { stat } from '@/core/data'; - -export interface OB11User { - user_id: number; - nickname: string; - remark?: string; - sex?: OB11UserSex; - level?: number; - age?: number; - qid?: string; - login_days?: number; -} - -export enum OB11UserSex { - male = 'male', - female = 'female', - unknown = 'unknown' -} - -export enum OB11GroupMemberRole { - owner = 'owner', - admin = 'admin', - member = 'member', -} - -export interface OB11GroupMember { - group_id: number - user_id: number - nickname: string - card?: string - sex?: OB11UserSex - age?: number - join_time?: number - last_sent_time?: number - level?: number - qq_level?: number - role?: OB11GroupMemberRole - title?: string - area?: string - unfriendly?: boolean - title_expire_time?: number - card_changeable?: boolean - // 以下为gocq字段 - shut_up_timestamp?: number - // 以下为扩展字段 - is_robot?: boolean - qage?: number -} - -export interface OB11Group { - group_id: number - group_name: string - member_count?: number - max_member_count?: number -} - -interface OB11Sender { - user_id: number, - nickname: string, - sex?: OB11UserSex, - age?: number, - card?: string, // 群名片 - level?: string, // 群等级 - role?: OB11GroupMemberRole -} +import { OB11Sender } from './entity'; +import { EventType } from '@/onebot11/event/OB11BaseEvent'; +import { CustomMusicSignPostData, IdMusicSignPostData, PicSubType, RawMessage } from '@/core'; export enum OB11MessageType { private = 'private', @@ -256,17 +191,3 @@ export interface OB11PostSendMsg { messages?: OB11MessageMixType; // 兼容 go-cqhttp auto_escape?: boolean | string } - -export interface OB11Version { - app_name: string - app_version: string - protocol_version: 'v11' -} - - -export interface OB11Status { - online: boolean | null, - good: boolean, - stat: typeof stat -} - diff --git a/src/onebot11/types/meta.ts b/src/onebot11/types/meta.ts new file mode 100644 index 00000000..768dde54 --- /dev/null +++ b/src/onebot11/types/meta.ts @@ -0,0 +1,13 @@ +import { stat } from '@/core/data'; + +export interface OB11Version { + app_name: string + app_version: string + protocol_version: 'v11' +} + +export interface OB11Status { + online: boolean | null, + good: boolean, + stat: typeof stat +}