From 5990e0c2ebd10e13e07087b2d82f3665a9755b2f Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Fri, 9 Aug 2024 20:35:03 +0800 Subject: [PATCH] chore: run eslint --fix in onebot module --- src/onebot/action/BaseAction.ts | 100 +- src/onebot/action/OB11Response.ts | 46 +- src/onebot/action/extends/CreateCollection.ts | 32 +- src/onebot/action/extends/FetchCustomFace.ts | 20 +- src/onebot/action/extends/FetchEmojioLike.ts | 40 +- .../action/extends/GetCollectionList.ts | 24 +- .../action/extends/GetFriendWithCategory.ts | 16 +- .../action/extends/GetGroupAddRequest.ts | 32 +- src/onebot/action/extends/GetProfileLike.ts | 18 +- src/onebot/action/extends/GetRobotUinRange.ts | 10 +- src/onebot/action/extends/OCRImage.ts | 58 +- src/onebot/action/extends/SetGroupHeader.ts | 82 +- src/onebot/action/extends/SetLongNick.ts | 24 +- src/onebot/action/extends/SetOnlineStatus.ts | 32 +- src/onebot/action/extends/SetQQAvatar.ts | 80 +- src/onebot/action/extends/SetSelfProfile.ts | 40 +- .../action/extends/TranslateEnWordToZn.ts | 34 +- src/onebot/action/extends/sharePeer.ts | 54 +- src/onebot/action/file/DelGroupFile.ts | 24 +- src/onebot/action/file/DelGroupFileFolder.ts | 24 +- src/onebot/action/file/GetFile.ts | 336 ++--- src/onebot/action/file/GetGroupFileCount.ts | 24 +- src/onebot/action/file/GetGroupFileList.ts | 40 +- src/onebot/action/file/GetImage.ts | 2 +- src/onebot/action/file/GetRecord.ts | 10 +- src/onebot/action/file/SetGroupFileFolder.ts | 24 +- src/onebot/action/go-cqhttp/DownloadFile.ts | 120 +- src/onebot/action/go-cqhttp/GetForwardMsg.ts | 66 +- .../action/go-cqhttp/GetFriendMsgHistory.ts | 74 +- .../action/go-cqhttp/GetGroupHonorInfo.ts | 28 +- .../action/go-cqhttp/GetGroupMsgHistory.ts | 66 +- .../action/go-cqhttp/GetOnlineClient.ts | 22 +- .../action/go-cqhttp/GetStrangerInfo.ts | 54 +- src/onebot/action/go-cqhttp/QuickAction.ts | 10 +- src/onebot/action/go-cqhttp/SendForwardMsg.ts | 14 +- .../action/go-cqhttp/SendGroupNotice.ts | 94 +- .../action/go-cqhttp/UploadGroupFile.ts | 46 +- .../action/go-cqhttp/UploadPrivareFile.ts | 70 +- src/onebot/action/group/DelEssenceMsg.ts | 34 +- src/onebot/action/group/GetGroupEssence.ts | 30 +- src/onebot/action/group/GetGroupInfo.ts | 30 +- src/onebot/action/group/GetGroupList.ts | 22 +- src/onebot/action/group/GetGroupMemberInfo.ts | 122 +- src/onebot/action/group/GetGroupMemberList.ts | 168 +-- src/onebot/action/group/GetGroupNotice.ts | 62 +- src/onebot/action/group/GetGroupSystemMsg.ts | 72 +- src/onebot/action/group/GetGuildList.ts | 8 +- src/onebot/action/group/SendGroupMsg.ts | 14 +- src/onebot/action/group/SetEssenceMsg.ts | 34 +- src/onebot/action/group/SetGroupAddRequest.ts | 38 +- src/onebot/action/group/SetGroupAdmin.ts | 34 +- src/onebot/action/group/SetGroupBan.ts | 36 +- src/onebot/action/group/SetGroupCard.ts | 28 +- src/onebot/action/group/SetGroupKick.ts | 36 +- src/onebot/action/group/SetGroupLeave.ts | 26 +- src/onebot/action/group/SetGroupName.ts | 26 +- src/onebot/action/group/SetGroupWholeBan.ts | 28 +- src/onebot/action/index.ts | 184 +-- src/onebot/action/msg/DeleteMsg.ts | 70 +- src/onebot/action/msg/ForwardSingleMsg.ts | 72 +- src/onebot/action/msg/GetMsg.ts | 60 +- src/onebot/action/msg/MarkMsgAsRead.ts | 84 +- .../action/msg/SendMsg/check-send-message.ts | 62 +- .../msg/SendMsg/create-send-elements.ts | 345 ++--- .../action/msg/SendMsg/handle-forward-node.ts | 208 +-- src/onebot/action/msg/SendMsg/index.ts | 250 ++-- src/onebot/action/msg/SendPrivateMsg.ts | 12 +- src/onebot/action/msg/SetMsgEmojiLike.ts | 44 +- src/onebot/action/system/CanSendImage.ts | 2 +- src/onebot/action/system/CanSendRecord.ts | 12 +- src/onebot/action/system/GetLoginInfo.ts | 8 +- src/onebot/action/system/GetStatus.ts | 16 +- src/onebot/action/system/GetVersionInfo.ts | 16 +- src/onebot/action/user/GetCookies.ts | 112 +- src/onebot/action/user/GetFriendList.ts | 22 +- src/onebot/action/user/GetRecentContact.ts | 80 +- src/onebot/action/user/SendLike.ts | 46 +- src/onebot/action/user/SetFriendAddRequest.ts | 30 +- src/onebot/event/OB11BaseEvent.ts | 6 +- .../event/message/OB11BaseMessageEvent.ts | 2 +- src/onebot/event/meta/OB11BaseMetaEvent.ts | 4 +- src/onebot/event/meta/OB11HeartbeatEvent.ts | 22 +- src/onebot/event/meta/OB11LifeCycleEvent.ts | 12 +- .../event/notice/OB11BaseNoticeEvent.ts | 2 +- .../event/notice/OB11FriendAddNoticeEvent.ts | 12 +- .../notice/OB11FriendRecallNoticeEvent.ts | 16 +- .../event/notice/OB11GroupAdminNoticeEvent.ts | 4 +- src/onebot/event/notice/OB11GroupBanEvent.ts | 24 +- src/onebot/event/notice/OB11GroupCardEvent.ts | 20 +- .../event/notice/OB11GroupDecreaseEvent.ts | 20 +- .../event/notice/OB11GroupEssenceEvent.ts | 20 +- .../event/notice/OB11GroupIncreaseEvent.ts | 20 +- .../event/notice/OB11GroupNoticeEvent.ts | 4 +- .../notice/OB11GroupRecallNoticeEvent.ts | 20 +- .../event/notice/OB11GroupTitleEvent.ts | 18 +- .../notice/OB11GroupUploadNoticeEvent.ts | 16 +- .../event/notice/OB11InputStatusEvent.ts | 22 +- .../event/notice/OB11MsgEmojiLikeEvent.ts | 20 +- src/onebot/event/notice/OB11PokeEvent.ts | 44 +- src/onebot/event/request/OB11FriendRequest.ts | 10 +- src/onebot/event/request/OB11GroupRequest.ts | 10 +- src/onebot/helper/config.ts | 66 +- src/onebot/helper/cqcode.ts | 114 +- src/onebot/helper/data.ts | 1282 +++++++++-------- src/onebot/helper/msg.ts | 732 +++++----- src/onebot/server/http.ts | 64 +- src/onebot/server/postOB11Event.ts | 244 ++-- src/onebot/server/ws/ReverseWebsocket.ts | 204 +-- src/onebot/server/ws/WebsocketServer.ts | 108 +- src/onebot/server/ws/reply.ts | 26 +- 110 files changed, 3832 insertions(+), 3829 deletions(-) diff --git a/src/onebot/action/BaseAction.ts b/src/onebot/action/BaseAction.ts index 30acb3e6..c2d33551 100644 --- a/src/onebot/action/BaseAction.ts +++ b/src/onebot/action/BaseAction.ts @@ -5,64 +5,64 @@ import Ajv, { ErrorObject, ValidateFunction } from 'ajv'; import { NapCatCore } from '@/core'; class BaseAction { - actionName: ActionName = ActionName.Unknown; - CoreContext: NapCatCore; - private validate: undefined | ValidateFunction = undefined; - PayloadSchema: any = undefined; - constructor(context: NapCatCore) { + actionName: ActionName = ActionName.Unknown; + CoreContext: NapCatCore; + private validate: undefined | ValidateFunction = undefined; + PayloadSchema: any = undefined; + constructor(context: NapCatCore) { //注入上下文 - this.CoreContext = context; - } - protected async check(payload: PayloadType): Promise { - if (this.PayloadSchema) { - this.validate = new Ajv({ allowUnionTypes: true }).compile(this.PayloadSchema); + this.CoreContext = context; } - if (this.validate && !this.validate(payload)) { - const errors = this.validate.errors as ErrorObject[]; - const errorMessages: string[] = errors.map((e) => { - return `Key: ${e.instancePath.split('/').slice(1).join('.')}, Message: ${e.message}`; - }); - return { - valid: false, - message: errorMessages.join('\n') as string || '未知错误' - }; + protected async check(payload: PayloadType): Promise { + if (this.PayloadSchema) { + this.validate = new Ajv({ allowUnionTypes: true }).compile(this.PayloadSchema); + } + if (this.validate && !this.validate(payload)) { + const errors = this.validate.errors as ErrorObject[]; + const errorMessages: string[] = errors.map((e) => { + return `Key: ${e.instancePath.split('/').slice(1).join('.')}, Message: ${e.message}`; + }); + return { + valid: false, + message: errorMessages.join('\n') as string || '未知错误' + }; + } + return { + valid: true + }; } - return { - valid: true - }; - } - public async handle(payload: PayloadType): Promise> { - const result = await this.check(payload); - if (!result.valid) { - return OB11Response.error(result.message, 400); + public async handle(payload: PayloadType): Promise> { + const result = await this.check(payload); + if (!result.valid) { + return OB11Response.error(result.message, 400); + } + try { + const resData = await this._handle(payload); + return OB11Response.ok(resData); + } catch (e: any) { + this.CoreContext.context.logger.logError('发生错误', e); + return OB11Response.error(e?.toString() || e?.stack?.toString() || '未知错误,可能操作超时', 200); + } } - try { - const resData = await this._handle(payload); - return OB11Response.ok(resData); - } catch (e: any) { - this.CoreContext.context.logger.logError('发生错误', e); - return OB11Response.error(e?.toString() || e?.stack?.toString() || '未知错误,可能操作超时', 200); - } - } - public async websocketHandle(payload: PayloadType, echo: any): Promise> { - const result = await this.check(payload); - if (!result.valid) { - return OB11Response.error(result.message, 1400); + public async websocketHandle(payload: PayloadType, echo: any): Promise> { + const result = await this.check(payload); + if (!result.valid) { + return OB11Response.error(result.message, 1400); + } + try { + const resData = await this._handle(payload); + return OB11Response.ok(resData, echo); + } catch (e: any) { + this.CoreContext.context.logger.logError('发生错误', e); + return OB11Response.error(e.stack?.toString() || e.toString(), 1200, echo); + } } - try { - const resData = await this._handle(payload); - return OB11Response.ok(resData, echo); - } catch (e: any) { - this.CoreContext.context.logger.logError('发生错误', e); - return OB11Response.error(e.stack?.toString() || e.toString(), 1200, echo); - } - } - protected async _handle(payload: PayloadType): Promise { - throw `pleas override ${this.actionName} _handle`; - } + protected async _handle(payload: PayloadType): Promise { + throw `pleas override ${this.actionName} _handle`; + } } export default BaseAction; diff --git a/src/onebot/action/OB11Response.ts b/src/onebot/action/OB11Response.ts index ddc9d72b..26d29464 100644 --- a/src/onebot/action/OB11Response.ts +++ b/src/onebot/action/OB11Response.ts @@ -3,30 +3,30 @@ import { OB11Return } from '../types'; import { isNull } from '../../common/utils/helper'; export class OB11Response { - static res(data: T, status: string, retcode: number, message: string = ''): OB11Return { - return { - status: status, - retcode: retcode, - data: data, - message: message, - wording: message, - echo: null - }; - } - - static ok(data: T, echo: any = null) { - const res = OB11Response.res(data, 'ok', 0); - if (!isNull(echo)) { - res.echo = echo; + static res(data: T, status: string, retcode: number, message: string = ''): OB11Return { + return { + status: status, + retcode: retcode, + data: data, + message: message, + wording: message, + echo: null + }; } - return res; - } - static error(err: string, retcode: number, echo: any = null) { - const res = OB11Response.res(null, 'failed', retcode, err); - if (!isNull(echo)) { - res.echo = echo; + static ok(data: T, echo: any = null) { + const res = OB11Response.res(data, 'ok', 0); + if (!isNull(echo)) { + res.echo = echo; + } + return res; + } + + static error(err: string, retcode: number, echo: any = null) { + const res = OB11Response.res(null, 'failed', retcode, err); + if (!isNull(echo)) { + res.echo = echo; + } + return res; } - return res; - } } diff --git a/src/onebot/action/extends/CreateCollection.ts b/src/onebot/action/extends/CreateCollection.ts index e72178d0..dc4dec5c 100644 --- a/src/onebot/action/extends/CreateCollection.ts +++ b/src/onebot/action/extends/CreateCollection.ts @@ -2,25 +2,25 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - rawData: { type: 'string' }, - brief: { type: 'string' } - }, - required: ['brief', 'rawData'], + type: 'object', + properties: { + rawData: { type: 'string' }, + brief: { type: 'string' } + }, + required: ['brief', 'rawData'], } as const satisfies JSONSchema; type Payload = FromSchema; export class CreateCollection extends BaseAction { - actionName = ActionName.CreateCollection; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - return await this.CoreContext.getApiContext().CollectionApi.createCollection( - this.CoreContext.selfInfo.uin, - this.CoreContext.selfInfo.uid, - this.CoreContext.selfInfo.nick, - payload.brief, payload.rawData - ); - } + actionName = ActionName.CreateCollection; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + return await this.CoreContext.getApiContext().CollectionApi.createCollection( + this.CoreContext.selfInfo.uin, + this.CoreContext.selfInfo.uid, + this.CoreContext.selfInfo.nick, + payload.brief, payload.rawData + ); + } } diff --git a/src/onebot/action/extends/FetchCustomFace.ts b/src/onebot/action/extends/FetchCustomFace.ts index b98e6fd7..89ccdcf5 100644 --- a/src/onebot/action/extends/FetchCustomFace.ts +++ b/src/onebot/action/extends/FetchCustomFace.ts @@ -2,20 +2,20 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; const SchemaData = { - type: 'object', - properties: { - count: { type: 'number' }, - } + type: 'object', + properties: { + count: { type: 'number' }, + } } as const satisfies JSONSchema; type Payload = FromSchema; export class FetchCustomFace extends BaseAction { - actionName = ActionName.FetchCustomFace; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { + actionName = ActionName.FetchCustomFace; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { //48 可能正好是QQ需要的一个页面的数量 Tagged Mlikiowa - const ret = await this.CoreContext.getApiContext().MsgApi.fetchFavEmojiList(payload.count || 48); - return ret.emojiInfoList.map(e => e.url); - } + const ret = await this.CoreContext.getApiContext().MsgApi.fetchFavEmojiList(payload.count || 48); + return ret.emojiInfoList.map(e => e.url); + } } diff --git a/src/onebot/action/extends/FetchEmojioLike.ts b/src/onebot/action/extends/FetchEmojioLike.ts index 29f54527..4ae82c28 100644 --- a/src/onebot/action/extends/FetchEmojioLike.ts +++ b/src/onebot/action/extends/FetchEmojioLike.ts @@ -4,29 +4,29 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { MessageUnique } from '@/common/utils/MessageUnique'; const SchemaData = { - type: 'object', - properties: { - user_id: { type: 'string' }, - group_id: { type: 'string' }, - emojiId: { type: 'string' }, - emojiType: { type: 'string' }, - message_id: { type: ['string', 'number'] }, - count: { type: 'number' } - }, - required: ['emojiId', 'emojiType', 'message_id'] + type: 'object', + properties: { + user_id: { type: 'string' }, + group_id: { type: 'string' }, + emojiId: { type: 'string' }, + emojiType: { type: 'string' }, + message_id: { type: ['string', 'number'] }, + count: { type: 'number' } + }, + required: ['emojiId', 'emojiType', 'message_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export class FetchEmojioLike extends BaseAction { - actionName = ActionName.FetchEmojioLike; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const msgIdPeer = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); - if(!msgIdPeer) throw new Error('消息不存在'); - const msg = (await NTQQMsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0]; - const ret = await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer,msg.msgSeq,payload.emojiId,payload.emojiType,payload.count); - return ret; - } + actionName = ActionName.FetchEmojioLike; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const msgIdPeer = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); + if(!msgIdPeer) throw new Error('消息不存在'); + const msg = (await NTQQMsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0]; + const ret = await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer,msg.msgSeq,payload.emojiId,payload.emojiType,payload.count); + return ret; + } } diff --git a/src/onebot/action/extends/GetCollectionList.ts b/src/onebot/action/extends/GetCollectionList.ts index 67d58cc6..ab2a868a 100644 --- a/src/onebot/action/extends/GetCollectionList.ts +++ b/src/onebot/action/extends/GetCollectionList.ts @@ -4,21 +4,21 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - category: { type: 'number' }, - count: { type: 'number' } - }, - required: ['category', 'count'], + type: 'object', + properties: { + category: { type: 'number' }, + count: { type: 'number' } + }, + required: ['category', 'count'], } as const satisfies JSONSchema; type Payload = FromSchema; export class GetCollectionList extends BaseAction { - actionName = ActionName.GetCollectionList; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQCollectionApi = this.CoreContext.getApiContext().CollectionApi; - return await NTQQCollectionApi.getAllCollection(payload.category, payload.count); - } + actionName = ActionName.GetCollectionList; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQCollectionApi = this.CoreContext.getApiContext().CollectionApi; + return await NTQQCollectionApi.getAllCollection(payload.category, payload.count); + } } diff --git a/src/onebot/action/extends/GetFriendWithCategory.ts b/src/onebot/action/extends/GetFriendWithCategory.ts index 5431fb1e..fcc87086 100644 --- a/src/onebot/action/extends/GetFriendWithCategory.ts +++ b/src/onebot/action/extends/GetFriendWithCategory.ts @@ -4,14 +4,14 @@ import { ActionName } from '../types'; import { OB11Constructor } from '@/onebot/helper/constructor'; export class GetFriendWithCategory extends BaseAction { - actionName = ActionName.GetFriendsWithCategory; + actionName = ActionName.GetFriendsWithCategory; - protected async _handle(payload: void) { - if (this.CoreContext.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { - //全新逻辑 - return OB11Constructor.friendsV2(await this.CoreContext.getApiContext().FriendApi.getBuddyV2ExWithCate(true)); - } else { - throw new Error('this ntqq version not support, must be 26702 or later'); + protected async _handle(payload: void) { + if (this.CoreContext.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { + //全新逻辑 + return OB11Constructor.friendsV2(await this.CoreContext.getApiContext().FriendApi.getBuddyV2ExWithCate(true)); + } else { + throw new Error('this ntqq version not support, must be 26702 or later'); + } } - } } diff --git a/src/onebot/action/extends/GetGroupAddRequest.ts b/src/onebot/action/extends/GetGroupAddRequest.ts index f4b9391f..d9167328 100644 --- a/src/onebot/action/extends/GetGroupAddRequest.ts +++ b/src/onebot/action/extends/GetGroupAddRequest.ts @@ -9,21 +9,21 @@ interface OB11GroupRequestNotify { } export default class GetGroupAddRequest extends BaseAction { - actionName = ActionName.GetGroupIgnoreAddRequest; + actionName = ActionName.GetGroupIgnoreAddRequest; - protected async _handle(payload: null): Promise { - const data = await this.CoreContext.getApiContext().GroupApi.getGroupIgnoreNotifies(); - // log(data); - // const notifies: GroupNotify[] = data.notifies.filter(notify => notify.status === GroupNotifyStatus.WAIT_HANDLE); - // const returnData: OB11GroupRequestNotify[] = []; - // for (const notify of notifies) { - // const uin = || (await NTQQUserApi.getUserDetailInfo(notify.user1.uid))?.uin; - // returnData.push({ - // group_id: parseInt(notify.group.groupCode), - // user_id: parseInt(uin), - // flag: notify.seq - // }); - // } - return null; - } + protected async _handle(payload: null): Promise { + const data = await this.CoreContext.getApiContext().GroupApi.getGroupIgnoreNotifies(); + // log(data); + // const notifies: GroupNotify[] = data.notifies.filter(notify => notify.status === GroupNotifyStatus.WAIT_HANDLE); + // const returnData: OB11GroupRequestNotify[] = []; + // for (const notify of notifies) { + // const uin = || (await NTQQUserApi.getUserDetailInfo(notify.user1.uid))?.uin; + // returnData.push({ + // group_id: parseInt(notify.group.groupCode), + // user_id: parseInt(uin), + // flag: notify.seq + // }); + // } + return null; + } } diff --git a/src/onebot/action/extends/GetProfileLike.ts b/src/onebot/action/extends/GetProfileLike.ts index aff7df11..984a0469 100644 --- a/src/onebot/action/extends/GetProfileLike.ts +++ b/src/onebot/action/extends/GetProfileLike.ts @@ -1,14 +1,14 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; export class GetProfileLike extends BaseAction { - actionName = ActionName.GetProfileLike; - protected async _handle(payload: void) { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const ret = await NTQQUserApi.getProfileLike(this.CoreContext.selfInfo.uid); - const listdata: any[] = ret.info.userLikeInfos[0].favoriteInfo.userInfos; - for (let i = 0; i < listdata.length; i++) { - listdata[i].uin = parseInt((await NTQQUserApi.getUinByUid(listdata[i].uid)) || ''); + actionName = ActionName.GetProfileLike; + protected async _handle(payload: void) { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const ret = await NTQQUserApi.getProfileLike(this.CoreContext.selfInfo.uid); + const listdata: any[] = ret.info.userLikeInfos[0].favoriteInfo.userInfos; + for (let i = 0; i < listdata.length; i++) { + listdata[i].uin = parseInt((await NTQQUserApi.getUinByUid(listdata[i].uid)) || ''); + } + return listdata; } - return listdata; - } } diff --git a/src/onebot/action/extends/GetRobotUinRange.ts b/src/onebot/action/extends/GetRobotUinRange.ts index 89398a59..e887c5cc 100644 --- a/src/onebot/action/extends/GetRobotUinRange.ts +++ b/src/onebot/action/extends/GetRobotUinRange.ts @@ -2,11 +2,11 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { NTQQUserApi } from '@/core/apis'; export class GetRobotUinRange extends BaseAction> { - actionName = ActionName.GetRobotUinRange; + actionName = ActionName.GetRobotUinRange; - protected async _handle(payload: void) { + protected async _handle(payload: void) { // console.log(await NTQQUserApi.getRobotUinRange()); - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - return await NTQQUserApi.getRobotUinRange(); - } + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + return await NTQQUserApi.getRobotUinRange(); + } } diff --git a/src/onebot/action/extends/OCRImage.ts b/src/onebot/action/extends/OCRImage.ts index cc388e05..07b9a857 100644 --- a/src/onebot/action/extends/OCRImage.ts +++ b/src/onebot/action/extends/OCRImage.ts @@ -5,41 +5,41 @@ import { checkFileReceived, uri2local } from '@/common/utils/file'; import fs from 'fs'; const SchemaData = { - type: 'object', - properties: { - image: { type: 'string' }, - }, - required: ['image'] + type: 'object', + properties: { + image: { type: 'string' }, + }, + required: ['image'] } as const satisfies JSONSchema; type Payload = FromSchema; export class OCRImage extends BaseAction { - actionName = ActionName.OCRImage; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi; - const { path, isLocal, errMsg,success } = (await uri2local(this.CoreContext.NapCatTempPath,payload.image)); - if (!success) { - throw `OCR ${payload.image}失败,image字段可能格式不正确`; + actionName = ActionName.OCRImage; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi; + const { path, isLocal, errMsg,success } = (await uri2local(this.CoreContext.NapCatTempPath,payload.image)); + if (!success) { + throw `OCR ${payload.image}失败,image字段可能格式不正确`; + } + if (path) { + await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断 + const ret = await NTQQSystemApi.ORCImage(path); + if (!isLocal) { + fs.unlink(path, () => { }); + } + if (!ret) { + throw `OCR ${payload.file}失败`; + } + return ret.result; + } + if (!isLocal) { + fs.unlink(path, () => { }); + } + throw `OCR ${payload.file}失败,文件可能不存在`; } - if (path) { - await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断 - const ret = await NTQQSystemApi.ORCImage(path); - if (!isLocal) { - fs.unlink(path, () => { }); - } - if (!ret) { - throw `OCR ${payload.file}失败`; - } - return ret.result; - } - if (!isLocal) { - fs.unlink(path, () => { }); - } - throw `OCR ${payload.file}失败,文件可能不存在`; - } } export class IOCRImage extends OCRImage { - actionName = ActionName.IOCRImage; + actionName = ActionName.IOCRImage; } diff --git a/src/onebot/action/extends/SetGroupHeader.ts b/src/onebot/action/extends/SetGroupHeader.ts index 3f6c34ad..fc7322a3 100644 --- a/src/onebot/action/extends/SetGroupHeader.ts +++ b/src/onebot/action/extends/SetGroupHeader.ts @@ -11,47 +11,47 @@ interface Payload { } export default class SetGroupHeader extends BaseAction { - actionName = ActionName.SetGroupHeader; - // 用不着复杂检测 - protected async check(payload: Payload): Promise { - if (!payload.file || typeof payload.file != 'string' || !payload.groupCode || typeof payload.groupCode != 'string') { - return { - valid: false, - message: 'file和groupCode字段不能为空或者类型错误', - }; + actionName = ActionName.SetGroupHeader; + // 用不着复杂检测 + protected async check(payload: Payload): Promise { + if (!payload.file || typeof payload.file != 'string' || !payload.groupCode || typeof payload.groupCode != 'string') { + return { + valid: false, + message: 'file和groupCode字段不能为空或者类型错误', + }; + } + return { + valid: true, + }; } - return { - valid: true, - }; - } - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.file)); - if (!success) { - throw `头像${payload.file}设置失败,file字段可能格式不正确`; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.file)); + if (!success) { + throw `头像${payload.file}设置失败,file字段可能格式不正确`; + } + if (path) { + await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断 + const ret = await NTQQGroupApi.setGroupAvatar(payload.groupCode, path); + if (!isLocal) { + fs.unlink(path, () => { }); + } + if (!ret) { + throw `头像${payload.file}设置失败,api无返回`; + } + // log(`头像设置返回:${JSON.stringify(ret)}`) + // if (ret['result'] == 1004022) { + // throw `头像${payload.file}设置失败,文件可能不是图片格式`; + // } else if (ret['result'] != 0) { + // throw `头像${payload.file}设置失败,未知的错误,${ret['result']}:${ret['errMsg']}`; + // } + return ret; + } else { + if (!isLocal) { + fs.unlink(path, () => { }); + } + throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`; + } + return null; } - if (path) { - await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断 - const ret = await NTQQGroupApi.setGroupAvatar(payload.groupCode, path); - if (!isLocal) { - fs.unlink(path, () => { }); - } - if (!ret) { - throw `头像${payload.file}设置失败,api无返回`; - } - // log(`头像设置返回:${JSON.stringify(ret)}`) - // if (ret['result'] == 1004022) { - // throw `头像${payload.file}设置失败,文件可能不是图片格式`; - // } else if (ret['result'] != 0) { - // throw `头像${payload.file}设置失败,未知的错误,${ret['result']}:${ret['errMsg']}`; - // } - return ret; - } else { - if (!isLocal) { - fs.unlink(path, () => { }); - } - throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`; - } - return null; - } } diff --git a/src/onebot/action/extends/SetLongNick.ts b/src/onebot/action/extends/SetLongNick.ts index e339671a..22f9356d 100644 --- a/src/onebot/action/extends/SetLongNick.ts +++ b/src/onebot/action/extends/SetLongNick.ts @@ -5,21 +5,21 @@ import { NTQQUserApi } from '@/core/apis'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - longNick: { type: 'string' }, - }, - required: [ 'longNick'], + type: 'object', + properties: { + longNick: { type: 'string' }, + }, + required: [ 'longNick'], } as const satisfies JSONSchema; type Payload = FromSchema; export class SetLongNick extends BaseAction { - actionName = ActionName.SetLongNick; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const ret = await NTQQUserApi.setLongNick(payload.longNick); - return ret; - } + actionName = ActionName.SetLongNick; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const ret = await NTQQUserApi.setLongNick(payload.longNick); + return ret; + } } diff --git a/src/onebot/action/extends/SetOnlineStatus.ts b/src/onebot/action/extends/SetOnlineStatus.ts index 53a76e78..86a81933 100644 --- a/src/onebot/action/extends/SetOnlineStatus.ts +++ b/src/onebot/action/extends/SetOnlineStatus.ts @@ -5,32 +5,32 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; // 设置在线状态 const SchemaData = { - type: 'object', - properties: { - status: { type: 'number' }, - extStatus: { type: 'number' }, - batteryStatus: { type: 'number' } - }, - required: ['status', 'extStatus', 'batteryStatus'], + type: 'object', + properties: { + status: { type: 'number' }, + extStatus: { type: 'number' }, + batteryStatus: { type: 'number' } + }, + required: ['status', 'extStatus', 'batteryStatus'], } as const satisfies JSONSchema; type Payload = FromSchema; export class SetOnlineStatus extends BaseAction { - actionName = ActionName.SetOnlineStatus; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { + actionName = ActionName.SetOnlineStatus; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { // 可设置状态 // { status: 10, extStatus: 1027, batteryStatus: 0 } // { status: 30, extStatus: 0, batteryStatus: 0 } // { status: 50, extStatus: 0, batteryStatus: 0 } // { status: 60, extStatus: 0, batteryStatus: 0 } // { status: 70, extStatus: 0, batteryStatus: 0 } - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const ret = await NTQQUserApi.setSelfOnlineStatus(payload.status, payload.extStatus, payload.batteryStatus); - if (ret.result !== 0) { - throw new Error('设置在线状态失败'); + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const ret = await NTQQUserApi.setSelfOnlineStatus(payload.status, payload.extStatus, payload.batteryStatus); + if (ret.result !== 0) { + throw new Error('设置在线状态失败'); + } + return null; } - return null; - } } diff --git a/src/onebot/action/extends/SetQQAvatar.ts b/src/onebot/action/extends/SetQQAvatar.ts index 45ca8fd7..b3cea0d1 100644 --- a/src/onebot/action/extends/SetQQAvatar.ts +++ b/src/onebot/action/extends/SetQQAvatar.ts @@ -7,46 +7,46 @@ interface Payload { } export default class SetAvatar extends BaseAction { - actionName = ActionName.SetQQAvatar; - // 用不着复杂检测 - protected async check(payload: Payload): Promise { - if (!payload.file || typeof payload.file != 'string') { - return { - valid: false, - message: 'file字段不能为空或者类型错误', - }; + actionName = ActionName.SetQQAvatar; + // 用不着复杂检测 + protected async check(payload: Payload): Promise { + if (!payload.file || typeof payload.file != 'string') { + return { + valid: false, + message: 'file字段不能为空或者类型错误', + }; + } + return { + valid: true, + }; } - return { - valid: true, - }; - } - protected async _handle(payload: Payload): Promise { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.file)); - if (!success) { - throw `头像${payload.file}设置失败,file字段可能格式不正确`; + protected async _handle(payload: Payload): Promise { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.file)); + if (!success) { + throw `头像${payload.file}设置失败,file字段可能格式不正确`; + } + if (path) { + await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断 + const ret = await NTQQUserApi.setQQAvatar(path); + if (!isLocal) { + fs.unlink(path, () => { }); + } + if (!ret) { + throw `头像${payload.file}设置失败,api无返回`; + } + // log(`头像设置返回:${JSON.stringify(ret)}`) + if (ret['result'] == 1004022) { + throw `头像${payload.file}设置失败,文件可能不是图片格式`; + } else if (ret['result'] != 0) { + throw `头像${payload.file}设置失败,未知的错误,${ret['result']}:${ret['errMsg']}`; + } + } else { + if (!isLocal) { + fs.unlink(path, () => { }); + } + throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`; + } + return null; } - if (path) { - await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断 - const ret = await NTQQUserApi.setQQAvatar(path); - if (!isLocal) { - fs.unlink(path, () => { }); - } - if (!ret) { - throw `头像${payload.file}设置失败,api无返回`; - } - // log(`头像设置返回:${JSON.stringify(ret)}`) - if (ret['result'] == 1004022) { - throw `头像${payload.file}设置失败,文件可能不是图片格式`; - } else if (ret['result'] != 0) { - throw `头像${payload.file}设置失败,未知的错误,${ret['result']}:${ret['errMsg']}`; - } - } else { - if (!isLocal) { - fs.unlink(path, () => { }); - } - throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`; - } - return null; - } } diff --git a/src/onebot/action/extends/SetSelfProfile.ts b/src/onebot/action/extends/SetSelfProfile.ts index 1f333e30..1860b8b9 100644 --- a/src/onebot/action/extends/SetSelfProfile.ts +++ b/src/onebot/action/extends/SetSelfProfile.ts @@ -4,29 +4,29 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - nick: { type: 'string' }, - longNick: { type: 'string' }, - sex: { type: 'number' }//传Sex值?建议传0 - }, - required: ['nick', 'longNick', 'sex'], + type: 'object', + properties: { + nick: { type: 'string' }, + longNick: { type: 'string' }, + sex: { type: 'number' }//传Sex值?建议传0 + }, + required: ['nick', 'longNick', 'sex'], } as const satisfies JSONSchema; type Payload = FromSchema; export class SetSelfProfile extends BaseAction { - actionName = ActionName.SetSelfProfile; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const ret = await NTQQUserApi.modifySelfProfile({ - nick: payload.nick, - longNick: payload.longNick, - sex: payload.sex, - birthday: { birthday_year: '', birthday_month: '', birthday_day: '' }, - location: undefined - }); - return ret; - } + actionName = ActionName.SetSelfProfile; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const ret = await NTQQUserApi.modifySelfProfile({ + nick: payload.nick, + longNick: payload.longNick, + sex: payload.sex, + birthday: { birthday_year: '', birthday_month: '', birthday_day: '' }, + location: undefined + }); + return ret; + } } diff --git a/src/onebot/action/extends/TranslateEnWordToZn.ts b/src/onebot/action/extends/TranslateEnWordToZn.ts index 2197f07d..381163b7 100644 --- a/src/onebot/action/extends/TranslateEnWordToZn.ts +++ b/src/onebot/action/extends/TranslateEnWordToZn.ts @@ -4,27 +4,27 @@ import { NTQQSystemApi } from '@/core/apis'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - words: { - type: 'array', - items: { type: 'string' } - } - }, - required: ['words'], + type: 'object', + properties: { + words: { + type: 'array', + items: { type: 'string' } + } + }, + required: ['words'], } as const satisfies JSONSchema; type Payload = FromSchema; export class TranslateEnWordToZn extends BaseAction | null> { - actionName = ActionName.TranslateEnWordToZn; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi; - const ret = await NTQQSystemApi.translateEnWordToZn(payload.words); - if (ret.result !== 0) { - throw new Error('翻译失败'); + actionName = ActionName.TranslateEnWordToZn; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi; + const ret = await NTQQSystemApi.translateEnWordToZn(payload.words); + if (ret.result !== 0) { + throw new Error('翻译失败'); + } + return ret.words; } - return ret.words; - } } diff --git a/src/onebot/action/extends/sharePeer.ts b/src/onebot/action/extends/sharePeer.ts index 9bb4d925..91e576fa 100644 --- a/src/onebot/action/extends/sharePeer.ts +++ b/src/onebot/action/extends/sharePeer.ts @@ -3,44 +3,44 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - user_id: { type: 'string' }, - group_id: { type: 'string' }, - phoneNumber: { type: 'string' }, - }, + type: 'object', + properties: { + user_id: { type: 'string' }, + group_id: { type: 'string' }, + phoneNumber: { type: 'string' }, + }, } as const satisfies JSONSchema; type Payload = FromSchema; export class sharePeer extends BaseAction { - actionName = ActionName.SharePeer; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - if (payload.group_id) { - return await NTQQGroupApi.getGroupRecommendContactArkJson(payload.group_id); - } else if (payload.user_id) { - return await NTQQUserApi.getBuddyRecommendContactArkJson(payload.user_id, payload.phoneNumber || ''); + actionName = ActionName.SharePeer; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + if (payload.group_id) { + return await NTQQGroupApi.getGroupRecommendContactArkJson(payload.group_id); + } else if (payload.user_id) { + return await NTQQUserApi.getBuddyRecommendContactArkJson(payload.user_id, payload.phoneNumber || ''); + } } - } } const SchemaDataGroupEx = { - type: 'object', - properties: { - group_id: { type: 'string' }, - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: 'string' }, + }, + required: ['group_id'] } as const satisfies JSONSchema; type PayloadGroupEx = FromSchema; export class shareGroupEx extends BaseAction { - actionName = ActionName.ShareGroupEx; - PayloadSchema = SchemaDataGroupEx; - protected async _handle(payload: PayloadGroupEx) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - return await NTQQGroupApi.getArkJsonGroupShare(payload.group_id); - } + actionName = ActionName.ShareGroupEx; + PayloadSchema = SchemaDataGroupEx; + protected async _handle(payload: PayloadGroupEx) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + return await NTQQGroupApi.getArkJsonGroupShare(payload.group_id); + } } \ No newline at end of file diff --git a/src/onebot/action/file/DelGroupFile.ts b/src/onebot/action/file/DelGroupFile.ts index a7016259..2f805fa0 100644 --- a/src/onebot/action/file/DelGroupFile.ts +++ b/src/onebot/action/file/DelGroupFile.ts @@ -2,21 +2,21 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['string', 'number'] }, - file_id: { type: 'string' }, - }, - required: ['group_id', 'file_id'] + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + file_id: { type: 'string' }, + }, + required: ['group_id', 'file_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export class DelGroupFile extends BaseAction { - actionName = ActionName.DelGroupFile; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - return await NTQQGroupApi.DelGroupFile(payload.group_id.toString(), [payload.file_id]); - } + actionName = ActionName.DelGroupFile; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + return await NTQQGroupApi.DelGroupFile(payload.group_id.toString(), [payload.file_id]); + } } diff --git a/src/onebot/action/file/DelGroupFileFolder.ts b/src/onebot/action/file/DelGroupFileFolder.ts index ad9cdc47..3a9ad509 100644 --- a/src/onebot/action/file/DelGroupFileFolder.ts +++ b/src/onebot/action/file/DelGroupFileFolder.ts @@ -4,21 +4,21 @@ import { ActionName } from '../types'; import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['string', 'number'] }, - folder_id: { type: 'string' }, - }, - required: ['group_id', 'folder_id'] + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + folder_id: { type: 'string' }, + }, + required: ['group_id', 'folder_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export class DelGroupFileFolder extends BaseAction { - actionName = ActionName.DelGroupFileFolder; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - return (await NTQQGroupApi.DelGroupFileFolder(payload.group_id.toString(), payload.folder_id)).groupFileCommonResult; - } + actionName = ActionName.DelGroupFileFolder; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + return (await NTQQGroupApi.DelGroupFileFolder(payload.group_id.toString(), payload.folder_id)).groupFileCommonResult; + } } diff --git a/src/onebot/action/file/GetFile.ts b/src/onebot/action/file/GetFile.ts index 00f992b6..7068aae3 100644 --- a/src/onebot/action/file/GetFile.ts +++ b/src/onebot/action/file/GetFile.ts @@ -17,170 +17,170 @@ export interface GetFileResponse { base64?: string; } const GetFileBase_PayloadSchema = { - type: 'object', - properties: { - file: { type: 'string' } - }, - required: ['file'] + type: 'object', + properties: { + file: { type: 'string' } + }, + required: ['file'] } as const satisfies JSONSchema; export class GetFileBase extends BaseAction { - PayloadSchema: any = GetFileBase_PayloadSchema; - private getElement(msg: RawMessage): { id: string, element: VideoElement | FileElement } { - let element = msg.elements.find(e => e.fileElement); - if (!element) { - element = msg.elements.find(e => e.videoElement); - if (element) { - return { id: element.elementId, element: element.videoElement }; - } else { - throw new Error('找不到文件'); - } + PayloadSchema: any = GetFileBase_PayloadSchema; + private getElement(msg: RawMessage): { id: string, element: VideoElement | FileElement } { + let element = msg.elements.find(e => e.fileElement); + if (!element) { + element = msg.elements.find(e => e.videoElement); + if (element) { + return { id: element.elementId, element: element.videoElement }; + } else { + throw new Error('找不到文件'); + } + } + return { id: element.elementId, element: element.fileElement }; } - return { id: element.elementId, element: element.fileElement }; - } - protected async _handle(payload: GetFilePayload): Promise { - const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const NTQQFileApi = this.CoreContext.getApiContext().FileApi; - let UuidData: { + protected async _handle(payload: GetFilePayload): Promise { + const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const NTQQFileApi = this.CoreContext.getApiContext().FileApi; + let UuidData: { high: string; low: string; } | undefined; - try { - UuidData = UUIDConverter.decode(payload.file); - if (UuidData) { - const peerUin = UuidData.high; - const msgId = UuidData.low; - const isGroup: boolean = !!(await NTQQGroupApi.getGroups(false)).find(e => e.groupCode == peerUin); - let peer: Peer | undefined; - //识别Peer - if (isGroup) { - peer = { chatType: ChatType.group, peerUid: peerUin }; - } - const PeerUid = await NTQQUserApi.getUidByUin(peerUin); - if (PeerUid) { - const isBuddy = await NTQQFriendApi.isBuddy(PeerUid); - if (isBuddy) { - peer = { chatType: ChatType.friend, peerUid: PeerUid }; - } else { - peer = { chatType: ChatType.temp, peerUid: PeerUid }; - } - } - if (!peer) { - throw new Error('chattype not support'); - } - const msgList = await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]); - if (msgList.msgList.length == 0) { - throw new Error('msg not found'); - } - const msg = msgList.msgList[0]; - const findEle = msg.elements.find(e => e.elementType == ElementType.VIDEO || e.elementType == ElementType.FILE || e.elementType == ElementType.PTT); - if (!findEle) { - throw new Error('element not found'); - } - const downloadPath = await NTQQFileApi.downloadMedia(msgId, msg.chatType, msg.peerUid, findEle.elementId, '', ''); - const fileSize = findEle?.videoElement?.fileSize || findEle?.fileElement?.fileSize || findEle?.pttElement?.fileSize || '0'; - const fileName = findEle?.videoElement?.fileName || findEle?.fileElement?.fileName || findEle?.pttElement?.fileName || ''; - const res: GetFileResponse = { - file: downloadPath, - url: downloadPath, - file_size: fileSize, - file_name: fileName - }; - if (true/*enableLocalFile2Url*/) { - try { - res.base64 = await fs.readFile(downloadPath, 'base64'); - } catch (e) { - throw new Error('文件下载失败. ' + e); - } - } - //不手动删除?文件持久化了 - return res; - } - } catch { - - } - - const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems; - if (NTSearchNameResult.length !== 0) { - const MsgId = NTSearchNameResult[0].msgId; - let peer: Peer | undefined = undefined; - if (NTSearchNameResult[0].chatType == ChatType.group) { - peer = { chatType: ChatType.group, peerUid: NTSearchNameResult[0].groupChatInfo[0].groupCode }; - } - if (!peer) { - throw new Error('chattype not support'); - } - const msgList: RawMessage[] = (await NTQQMsgApi.getMsgsByMsgId(peer, [MsgId]))?.msgList; - if (!msgList || msgList.length == 0) { - throw new Error('msg not found'); - } - const msg = msgList[0]; - const file = msg.elements.filter(e => e.elementType == NTSearchNameResult[0].elemType); - if (file.length == 0) { - throw new Error('file not found'); - } - const downloadPath = await NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid, file[0].elementId, '', ''); - const res: GetFileResponse = { - file: downloadPath, - url: downloadPath, - file_size: NTSearchNameResult[0].fileSize.toString(), - file_name: NTSearchNameResult[0].fileName - }; - if (true/*enableLocalFile2Url*/) { try { - res.base64 = await fs.readFile(downloadPath, 'base64'); - } catch (e) { - throw new Error('文件下载失败. ' + e); - } - } - //不手动删除?文件持久化了 - return res; - } - throw new Error('file not found'); - // let cache = await dbUtil.getFileCacheByName(payload.file); - // if (!cache) { - // cache = await dbUtil.getFileCacheByUuid(payload.file); - // } - // if (!cache) { - // throw new Error('file not found'); - // } - // const { enableLocalFile2Url } = ob11Config; - // try { - // await fs.access(cache.path, fs.constants.F_OK); - // } catch (e) { - // logDebug('local file not found, start download...'); - // // if (cache.url) { - // // const downloadResult = await uri2local(cache.url); - // // if (downloadResult.success) { - // // cache.path = downloadResult.path; - // // dbUtil.updateFileCache(cache).then(); - // // } else { - // // throw new Error('file download failed. ' + downloadResult.errMsg); - // // } - // // } else { - // // // 没有url的可能是私聊文件或者群文件,需要自己下载 - // // log('需要调用 NTQQ 下载文件api'); - // let peer = MessageUnique.getPeerByMsgId(cache.msgId); - // let msg = await NTQQMsgApi.getMsgsByMsgId(peer?.Peer!,cache.msgId); - // // log('文件 msg', msg); - // if (msg) { - // // 构建下载函数 - // const downloadPath = await NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid, - // cache.elementId, '', ''); - // // await sleep(1000); + UuidData = UUIDConverter.decode(payload.file); + if (UuidData) { + const peerUin = UuidData.high; + const msgId = UuidData.low; + const isGroup: boolean = !!(await NTQQGroupApi.getGroups(false)).find(e => e.groupCode == peerUin); + let peer: Peer | undefined; + //识别Peer + if (isGroup) { + peer = { chatType: ChatType.group, peerUid: peerUin }; + } + const PeerUid = await NTQQUserApi.getUidByUin(peerUin); + if (PeerUid) { + const isBuddy = await NTQQFriendApi.isBuddy(PeerUid); + if (isBuddy) { + peer = { chatType: ChatType.friend, peerUid: PeerUid }; + } else { + peer = { chatType: ChatType.temp, peerUid: PeerUid }; + } + } + if (!peer) { + throw new Error('chattype not support'); + } + const msgList = await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]); + if (msgList.msgList.length == 0) { + throw new Error('msg not found'); + } + const msg = msgList.msgList[0]; + const findEle = msg.elements.find(e => e.elementType == ElementType.VIDEO || e.elementType == ElementType.FILE || e.elementType == ElementType.PTT); + if (!findEle) { + throw new Error('element not found'); + } + const downloadPath = await NTQQFileApi.downloadMedia(msgId, msg.chatType, msg.peerUid, findEle.elementId, '', ''); + const fileSize = findEle?.videoElement?.fileSize || findEle?.fileElement?.fileSize || findEle?.pttElement?.fileSize || '0'; + const fileName = findEle?.videoElement?.fileName || findEle?.fileElement?.fileName || findEle?.pttElement?.fileName || ''; + const res: GetFileResponse = { + file: downloadPath, + url: downloadPath, + file_size: fileSize, + file_name: fileName + }; + if (true/*enableLocalFile2Url*/) { + try { + res.base64 = await fs.readFile(downloadPath, 'base64'); + } catch (e) { + throw new Error('文件下载失败. ' + e); + } + } + //不手动删除?文件持久化了 + return res; + } + } catch { - // // log('download result', downloadPath); - // let peer = MessageUnique.getPeerByMsgId(cache.msgId); - // msg = await NTQQMsgApi.getMsgsByMsgId(peer?.Peer!,cache.msgId); - // // log('下载完成后的msg', msg); - // cache.path = downloadPath!; - // dbUtil.updateFileCache(cache).then(); - // // log('下载完成后的msg', msg); - // // } - // } + } + + const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems; + if (NTSearchNameResult.length !== 0) { + const MsgId = NTSearchNameResult[0].msgId; + let peer: Peer | undefined = undefined; + if (NTSearchNameResult[0].chatType == ChatType.group) { + peer = { chatType: ChatType.group, peerUid: NTSearchNameResult[0].groupChatInfo[0].groupCode }; + } + if (!peer) { + throw new Error('chattype not support'); + } + const msgList: RawMessage[] = (await NTQQMsgApi.getMsgsByMsgId(peer, [MsgId]))?.msgList; + if (!msgList || msgList.length == 0) { + throw new Error('msg not found'); + } + const msg = msgList[0]; + const file = msg.elements.filter(e => e.elementType == NTSearchNameResult[0].elemType); + if (file.length == 0) { + throw new Error('file not found'); + } + const downloadPath = await NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid, file[0].elementId, '', ''); + const res: GetFileResponse = { + file: downloadPath, + url: downloadPath, + file_size: NTSearchNameResult[0].fileSize.toString(), + file_name: NTSearchNameResult[0].fileName + }; + if (true/*enableLocalFile2Url*/) { + try { + res.base64 = await fs.readFile(downloadPath, 'base64'); + } catch (e) { + throw new Error('文件下载失败. ' + e); + } + } + //不手动删除?文件持久化了 + return res; + } + throw new Error('file not found'); + // let cache = await dbUtil.getFileCacheByName(payload.file); + // if (!cache) { + // cache = await dbUtil.getFileCacheByUuid(payload.file); + // } + // if (!cache) { + // throw new Error('file not found'); + // } + // const { enableLocalFile2Url } = ob11Config; + // try { + // await fs.access(cache.path, fs.constants.F_OK); + // } catch (e) { + // logDebug('local file not found, start download...'); + // // if (cache.url) { + // // const downloadResult = await uri2local(cache.url); + // // if (downloadResult.success) { + // // cache.path = downloadResult.path; + // // dbUtil.updateFileCache(cache).then(); + // // } else { + // // throw new Error('file download failed. ' + downloadResult.errMsg); + // // } + // // } else { + // // // 没有url的可能是私聊文件或者群文件,需要自己下载 + // // log('需要调用 NTQQ 下载文件api'); + // let peer = MessageUnique.getPeerByMsgId(cache.msgId); + // let msg = await NTQQMsgApi.getMsgsByMsgId(peer?.Peer!,cache.msgId); + // // log('文件 msg', msg); + // if (msg) { + // // 构建下载函数 + // const downloadPath = await NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid, + // cache.elementId, '', ''); + // // await sleep(1000); + + // // log('download result', downloadPath); + // let peer = MessageUnique.getPeerByMsgId(cache.msgId); + // msg = await NTQQMsgApi.getMsgsByMsgId(peer?.Peer!,cache.msgId); + // // log('下载完成后的msg', msg); + // cache.path = downloadPath!; + // dbUtil.updateFileCache(cache).then(); + // // log('下载完成后的msg', msg); + // // } + // } // } // // log('file found', cache); @@ -200,16 +200,16 @@ export class GetFileBase extends BaseAction { // } // } //return res; - } + } } const GetFile_PayloadSchema = { - type: 'object', - properties: { - file_id: { type: 'string' }, - file: { type: 'string' } - }, - required: ['file_id'] + type: 'object', + properties: { + file_id: { type: 'string' }, + file: { type: 'string' } + }, + required: ['file_id'] } as const satisfies JSONSchema; type GetFile_Payload_Internal = FromSchema; @@ -219,10 +219,10 @@ interface GetFile_Payload extends GetFile_Payload_Internal { } export default class GetFile extends GetFileBase { - actionName = ActionName.GetFile; - PayloadSchema = GetFile_PayloadSchema; - protected async _handle(payload: GetFile_Payload): Promise { - payload.file = payload.file_id; - return super._handle(payload); - } + actionName = ActionName.GetFile; + PayloadSchema = GetFile_PayloadSchema; + protected async _handle(payload: GetFile_Payload): Promise { + payload.file = payload.file_id; + return super._handle(payload); + } } diff --git a/src/onebot/action/file/GetGroupFileCount.ts b/src/onebot/action/file/GetGroupFileCount.ts index dbf17a2d..8c150dbd 100644 --- a/src/onebot/action/file/GetGroupFileCount.ts +++ b/src/onebot/action/file/GetGroupFileCount.ts @@ -4,21 +4,21 @@ import { ActionName } from '../types'; import { NTQQGroupApi, NTQQUserApi } from '@/core/apis'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['string', 'number'] }, - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + }, + required: ['group_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export class GetGroupFileCount extends BaseAction { - actionName = ActionName.GetGroupFileCount; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const ret = await NTQQGroupApi.GetGroupFileCount([payload.group_id?.toString()]); - return { count: ret.groupFileCounts[0] }; - } + actionName = ActionName.GetGroupFileCount; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const ret = await NTQQGroupApi.GetGroupFileCount([payload.group_id?.toString()]); + return { count: ret.groupFileCounts[0] }; + } } diff --git a/src/onebot/action/file/GetGroupFileList.ts b/src/onebot/action/file/GetGroupFileList.ts index 0a4f1d6c..c02f74bf 100644 --- a/src/onebot/action/file/GetGroupFileList.ts +++ b/src/onebot/action/file/GetGroupFileList.ts @@ -2,29 +2,29 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['string', 'number'] }, - start_index: { type: 'number' }, - file_count: { type: 'number' }, - }, - required: ['group_id', 'start_index', 'file_count'] + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + start_index: { type: 'number' }, + file_count: { type: 'number' }, + }, + required: ['group_id', 'start_index', 'file_count'] } as const satisfies JSONSchema; type Payload = FromSchema; export class GetGroupFileList extends BaseAction }> { - actionName = ActionName.GetGroupFileList; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const ret = await NTQQMsgApi.getGroupFileList(payload.group_id.toString(), { - sortType: 1, - fileCount: payload.file_count, - startIndex: payload.start_index, - sortOrder: 2, - showOnlinedocFolder: 0 - }).catch((e) => { return []; }); - return { FileList: ret }; - } + actionName = ActionName.GetGroupFileList; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const ret = await NTQQMsgApi.getGroupFileList(payload.group_id.toString(), { + sortType: 1, + fileCount: payload.file_count, + startIndex: payload.start_index, + sortOrder: 2, + showOnlinedocFolder: 0 + }).catch((e) => { return []; }); + return { FileList: ret }; + } } diff --git a/src/onebot/action/file/GetImage.ts b/src/onebot/action/file/GetImage.ts index 457ccb29..ee239a55 100644 --- a/src/onebot/action/file/GetImage.ts +++ b/src/onebot/action/file/GetImage.ts @@ -3,5 +3,5 @@ import { ActionName } from '../types'; export default class GetImage extends GetFileBase { - actionName = ActionName.GetImage; + actionName = ActionName.GetImage; } \ No newline at end of file diff --git a/src/onebot/action/file/GetRecord.ts b/src/onebot/action/file/GetRecord.ts index 25435974..cea9ecd5 100644 --- a/src/onebot/action/file/GetRecord.ts +++ b/src/onebot/action/file/GetRecord.ts @@ -6,10 +6,10 @@ interface Payload extends GetFilePayload { } export default class GetRecord extends GetFileBase { - actionName = ActionName.GetRecord; + actionName = ActionName.GetRecord; - protected async _handle(payload: Payload): Promise { - const res = super._handle(payload); - return res; - } + protected async _handle(payload: Payload): Promise { + const res = super._handle(payload); + return res; + } } \ No newline at end of file diff --git a/src/onebot/action/file/SetGroupFileFolder.ts b/src/onebot/action/file/SetGroupFileFolder.ts index 0ff52a43..3442565b 100644 --- a/src/onebot/action/file/SetGroupFileFolder.ts +++ b/src/onebot/action/file/SetGroupFileFolder.ts @@ -2,21 +2,21 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['string', 'number'] }, - folder_name: { type: 'string' }, - }, - required: ['group_id', 'folder_name'] + type: 'object', + properties: { + group_id: { type: ['string', 'number'] }, + folder_name: { type: 'string' }, + }, + required: ['group_id', 'folder_name'] } as const satisfies JSONSchema; type Payload = FromSchema; export class SetGroupFileFolder extends BaseAction { - actionName = ActionName.SetGroupFileFolder; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - return (await NTQQGroupApi.CreatGroupFileFolder(payload.group_id.toString(), payload.folder_name)).resultWithGroupItem; - } + actionName = ActionName.SetGroupFileFolder; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + return (await NTQQGroupApi.CreatGroupFileFolder(payload.group_id.toString(), payload.folder_name)).resultWithGroupItem; + } } diff --git a/src/onebot/action/go-cqhttp/DownloadFile.ts b/src/onebot/action/go-cqhttp/DownloadFile.ts index 11cb7101..e4bb4761 100644 --- a/src/onebot/action/go-cqhttp/DownloadFile.ts +++ b/src/onebot/action/go-cqhttp/DownloadFile.ts @@ -9,74 +9,74 @@ interface FileResponse { file: string; } const SchemaData = { - type: 'object', - properties: { - thread_count: { type: 'number' }, - url: { type: 'string' }, - base64: { type: 'string' }, - name: { type: 'string' }, - headers: { - type: ['string', 'array'], - items: { - type: 'string' - } - } - }, + type: 'object', + properties: { + thread_count: { type: 'number' }, + url: { type: 'string' }, + base64: { type: 'string' }, + name: { type: 'string' }, + headers: { + type: ['string', 'array'], + items: { + type: 'string' + } + } + }, } as const satisfies JSONSchema; type Payload = FromSchema; export default class GoCQHTTPDownloadFile extends BaseAction { - actionName = ActionName.GoCQHTTP_DownloadFile; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const isRandomName = !payload.name; - const name = payload.name || randomUUID(); - const filePath = joinPath(this.CoreContext.NapCatTempPath, name); + actionName = ActionName.GoCQHTTP_DownloadFile; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const isRandomName = !payload.name; + const name = payload.name || randomUUID(); + const filePath = joinPath(this.CoreContext.NapCatTempPath, name); - if (payload.base64) { - fs.writeFileSync(filePath, payload.base64, 'base64'); - } else if (payload.url) { - const headers = this.getHeaders(payload.headers); - const buffer = await httpDownload({ url: payload.url, headers: headers }); - fs.writeFileSync(filePath, Buffer.from(buffer), 'binary'); - } else { - throw new Error('不存在任何文件, 无法下载'); - } - if (fs.existsSync(filePath)) { - - if (isRandomName) { - // 默认实现要名称未填写时文件名为文件 md5 - const md5 = await calculateFileMD5(filePath); - const newPath = joinPath(this.CoreContext.NapCatTempPath, md5); - fs.renameSync(filePath, newPath); - return { file: newPath }; - } - return { file: filePath }; - } else { - throw new Error('文件写入失败, 检查权限'); - } - } - - getHeaders(headersIn?: string | string[]): Record { - const headers: Record = {}; - if (typeof headersIn == 'string') { - headersIn = headersIn.split('[\\r\\n]'); - } - if (Array.isArray(headersIn)) { - for (const headerItem of headersIn) { - const spilt = headerItem.indexOf('='); - if (spilt < 0) { - headers[headerItem] = ''; + if (payload.base64) { + fs.writeFileSync(filePath, payload.base64, 'base64'); + } else if (payload.url) { + const headers = this.getHeaders(payload.headers); + const buffer = await httpDownload({ url: payload.url, headers: headers }); + fs.writeFileSync(filePath, Buffer.from(buffer), 'binary'); } else { - const key = headerItem.substring(0, spilt); - headers[key] = headerItem.substring(0, spilt + 1); + throw new Error('不存在任何文件, 无法下载'); + } + if (fs.existsSync(filePath)) { + + if (isRandomName) { + // 默认实现要名称未填写时文件名为文件 md5 + const md5 = await calculateFileMD5(filePath); + const newPath = joinPath(this.CoreContext.NapCatTempPath, md5); + fs.renameSync(filePath, newPath); + return { file: newPath }; + } + return { file: filePath }; + } else { + throw new Error('文件写入失败, 检查权限'); } - } } - if (!headers['Content-Type']) { - headers['Content-Type'] = 'application/octet-stream'; + + getHeaders(headersIn?: string | string[]): Record { + const headers: Record = {}; + if (typeof headersIn == 'string') { + headersIn = headersIn.split('[\\r\\n]'); + } + if (Array.isArray(headersIn)) { + for (const headerItem of headersIn) { + const spilt = headerItem.indexOf('='); + if (spilt < 0) { + headers[headerItem] = ''; + } else { + const key = headerItem.substring(0, spilt); + headers[key] = headerItem.substring(0, spilt + 1); + } + } + } + if (!headers['Content-Type']) { + headers['Content-Type'] = 'application/octet-stream'; + } + return headers; } - return headers; - } } diff --git a/src/onebot/action/go-cqhttp/GetForwardMsg.ts b/src/onebot/action/go-cqhttp/GetForwardMsg.ts index b1b5057c..a6f20799 100644 --- a/src/onebot/action/go-cqhttp/GetForwardMsg.ts +++ b/src/onebot/action/go-cqhttp/GetForwardMsg.ts @@ -7,11 +7,11 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { MessageUnique } from '@/common/utils/MessageUnique'; const SchemaData = { - type: 'object', - properties: { - message_id: { type: 'string' }, - id: { type: 'string' } - }, + type: 'object', + properties: { + message_id: { type: 'string' }, + id: { type: 'string' } + }, } as const satisfies JSONSchema; type Payload = FromSchema; @@ -21,33 +21,33 @@ interface Response { } export class GoCQHTTPGetForwardMsgAction extends BaseAction { - actionName = ActionName.GoCQHTTP_GetForwardMsg; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const msgId = payload.message_id || payload.id; - if (!msgId) { - throw Error('message_id is required'); + actionName = ActionName.GoCQHTTP_GetForwardMsg; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const msgId = payload.message_id || payload.id; + if (!msgId) { + throw Error('message_id is required'); + } + const rootMsgId = MessageUnique.getShortIdByMsgId(msgId); + const rootMsg = MessageUnique.getMsgIdAndPeerByShortId(rootMsgId || parseInt(msgId)); + if (!rootMsg) { + throw Error('msg not found'); + } + const data = await NTQQMsgApi.getMultiMsg(rootMsg.Peer, rootMsg.MsgId, rootMsg.MsgId); + if (!data || data.result !== 0) { + throw Error('找不到相关的聊天记录' + data?.errMsg); + } + const msgList = data.msgList; + const messages = await Promise.all(msgList.map(async msg => { + const resMsg = await OB11Constructor.message(this.CoreContext, msg, "array"); + resMsg.message_id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId)!; + return resMsg; + })); + messages.map(msg => { + (msg).content = msg.message; + delete (msg).message; + }); + return { messages }; } - const rootMsgId = MessageUnique.getShortIdByMsgId(msgId); - const rootMsg = MessageUnique.getMsgIdAndPeerByShortId(rootMsgId || parseInt(msgId)); - if (!rootMsg) { - throw Error('msg not found'); - } - const data = await NTQQMsgApi.getMultiMsg(rootMsg.Peer, rootMsg.MsgId, rootMsg.MsgId); - if (!data || data.result !== 0) { - throw Error('找不到相关的聊天记录' + data?.errMsg); - } - const msgList = data.msgList; - const messages = await Promise.all(msgList.map(async msg => { - const resMsg = await OB11Constructor.message(this.CoreContext, msg, "array"); - resMsg.message_id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId)!; - return resMsg; - })); - messages.map(msg => { - (msg).content = msg.message; - delete (msg).message; - }); - return { messages }; - } } diff --git a/src/onebot/action/go-cqhttp/GetFriendMsgHistory.ts b/src/onebot/action/go-cqhttp/GetFriendMsgHistory.ts index e694c046..61cafa72 100644 --- a/src/onebot/action/go-cqhttp/GetFriendMsgHistory.ts +++ b/src/onebot/action/go-cqhttp/GetFriendMsgHistory.ts @@ -12,48 +12,48 @@ interface Response { } const SchemaData = { - type: 'object', - properties: { - user_id: { type: ['number', 'string'] }, - message_seq: { type: 'number' }, - count: { type: 'number' }, - reverseOrder: { type: 'boolean' } - }, - required: ['user_id'] + type: 'object', + properties: { + user_id: { type: ['number', 'string'] }, + message_seq: { type: 'number' }, + count: { type: 'number' }, + reverseOrder: { type: 'boolean' } + }, + required: ['user_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class GetFriendMsgHistory extends BaseAction { - actionName = ActionName.GetFriendMsgHistory; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; - //处理参数 - const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - const MsgCount = payload.count || 20; - const isReverseOrder = payload.reverseOrder || true; - if (!uid) throw `记录${payload.user_id}不存在`; - const friend = await NTQQFriendApi.isBuddy(uid); - const peer = { chatType: friend ? ChatType.friend : ChatType.temp, peerUid: uid }; + actionName = ActionName.GetFriendMsgHistory; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; + //处理参数 + const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + const MsgCount = payload.count || 20; + const isReverseOrder = payload.reverseOrder || true; + if (!uid) throw `记录${payload.user_id}不存在`; + const friend = await NTQQFriendApi.isBuddy(uid); + const peer = { chatType: friend ? ChatType.friend : ChatType.temp, peerUid: uid }; - //拉取消息 - let msgList: RawMessage[]; - if (!payload.message_seq || payload.message_seq == 0) { - msgList = (await NTQQMsgApi.getLastestMsgByUids(peer, MsgCount)).msgList; - } else { - const startMsgId = MessageUnique.getMsgIdAndPeerByShortId(payload.message_seq)?.MsgId; - if (!startMsgId) throw `消息${payload.message_seq}不存在`; - msgList = (await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList; + //拉取消息 + let msgList: RawMessage[]; + if (!payload.message_seq || payload.message_seq == 0) { + msgList = (await NTQQMsgApi.getLastestMsgByUids(peer, MsgCount)).msgList; + } else { + const startMsgId = MessageUnique.getMsgIdAndPeerByShortId(payload.message_seq)?.MsgId; + if (!startMsgId) throw `消息${payload.message_seq}不存在`; + msgList = (await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList; + } + if (isReverseOrder) msgList.reverse(); + await Promise.all(msgList.map(async msg => { + msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId); + })); + //转换消息 + const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(this.CoreContext, msg, "array"))); + return { 'messages': ob11MsgList }; } - if (isReverseOrder) msgList.reverse(); - await Promise.all(msgList.map(async msg => { - msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId); - })); - //转换消息 - const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(this.CoreContext, msg, "array"))); - return { 'messages': ob11MsgList }; - } } diff --git a/src/onebot/action/go-cqhttp/GetGroupHonorInfo.ts b/src/onebot/action/go-cqhttp/GetGroupHonorInfo.ts index 9669a709..d5e50387 100644 --- a/src/onebot/action/go-cqhttp/GetGroupHonorInfo.ts +++ b/src/onebot/action/go-cqhttp/GetGroupHonorInfo.ts @@ -4,24 +4,24 @@ import { ActionName } from '../types'; import { WebHonorType } from '@/core/entities'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - type: { enum: [WebHonorType.ALL, WebHonorType.EMOTION, WebHonorType.LEGEND, WebHonorType.PERFORMER, WebHonorType.STRONG_NEWBIE, WebHonorType.TALKATIVE] } - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + type: { enum: [WebHonorType.ALL, WebHonorType.EMOTION, WebHonorType.LEGEND, WebHonorType.PERFORMER, WebHonorType.STRONG_NEWBIE, WebHonorType.TALKATIVE] } + }, + required: ['group_id'] } as const satisfies JSONSchema; // enum是不是有点抽象 type Payload = FromSchema; export class GetGroupHonorInfo extends BaseAction> { - actionName = ActionName.GetGroupHonorInfo; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - if (!payload.type) { - payload.type = WebHonorType.ALL; + actionName = ActionName.GetGroupHonorInfo; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + if (!payload.type) { + payload.type = WebHonorType.ALL; + } + const NTQQWebApi = this.CoreContext.getApiContext().WebApi; + return await NTQQWebApi.getGroupHonorInfo(payload.group_id.toString(), payload.type); } - const NTQQWebApi = this.CoreContext.getApiContext().WebApi; - return await NTQQWebApi.getGroupHonorInfo(payload.group_id.toString(), payload.type); - } } diff --git a/src/onebot/action/go-cqhttp/GetGroupMsgHistory.ts b/src/onebot/action/go-cqhttp/GetGroupMsgHistory.ts index f8ced55b..6f352444 100644 --- a/src/onebot/action/go-cqhttp/GetGroupMsgHistory.ts +++ b/src/onebot/action/go-cqhttp/GetGroupMsgHistory.ts @@ -10,43 +10,43 @@ interface Response { } const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['number', 'string'] }, - message_seq: { type: 'number' }, - count: { type: 'number' }, - reverseOrder: { type: 'boolean' } - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: ['number', 'string'] }, + message_seq: { type: 'number' }, + count: { type: 'number' }, + reverseOrder: { type: 'boolean' } + }, + required: ['group_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class GoCQHTTPGetGroupMsgHistory extends BaseAction { - actionName = ActionName.GoCQHTTP_GetGroupMsgHistory; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - //处理参数 - const isReverseOrder = payload.reverseOrder || true; - const MsgCount = payload.count || 20; - const peer: Peer = { chatType: ChatType.group, peerUid: payload.group_id.toString() }; - //拉取消息 - let msgList: RawMessage[]; - if (!payload.message_seq || payload.message_seq == 0) { - msgList = (await NTQQMsgApi.getLastestMsgByUids(peer, MsgCount)).msgList; - } else { - const startMsgId = MessageUnique.getMsgIdAndPeerByShortId(payload.message_seq)?.MsgId; - if (!startMsgId) throw `消息${payload.message_seq}不存在`; - msgList = (await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList; - } - if (isReverseOrder) msgList.reverse(); - await Promise.all(msgList.map(async msg => { - msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId); - })); + actionName = ActionName.GoCQHTTP_GetGroupMsgHistory; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + //处理参数 + const isReverseOrder = payload.reverseOrder || true; + const MsgCount = payload.count || 20; + const peer: Peer = { chatType: ChatType.group, peerUid: payload.group_id.toString() }; + //拉取消息 + let msgList: RawMessage[]; + if (!payload.message_seq || payload.message_seq == 0) { + msgList = (await NTQQMsgApi.getLastestMsgByUids(peer, MsgCount)).msgList; + } else { + const startMsgId = MessageUnique.getMsgIdAndPeerByShortId(payload.message_seq)?.MsgId; + if (!startMsgId) throw `消息${payload.message_seq}不存在`; + msgList = (await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList; + } + if (isReverseOrder) msgList.reverse(); + await Promise.all(msgList.map(async msg => { + msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId); + })); - //转换消息 - const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(this.CoreContext, msg, "array"))); - return { 'messages': ob11MsgList }; - } + //转换消息 + const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(this.CoreContext, msg, "array"))); + return { 'messages': ob11MsgList }; + } } diff --git a/src/onebot/action/go-cqhttp/GetOnlineClient.ts b/src/onebot/action/go-cqhttp/GetOnlineClient.ts index 85643e5b..3e46b557 100644 --- a/src/onebot/action/go-cqhttp/GetOnlineClient.ts +++ b/src/onebot/action/go-cqhttp/GetOnlineClient.ts @@ -4,21 +4,21 @@ import { JSONSchema } from 'json-schema-to-ts'; import { sleep } from '@/common/utils/helper'; const SchemaData = { - type: 'object', - properties: { - no_cache: { type: 'boolean' }, - } + type: 'object', + properties: { + no_cache: { type: 'boolean' }, + } } as const satisfies JSONSchema; export class GetOnlineClient extends BaseAction> { - actionName = ActionName.GetOnlineClient; + actionName = ActionName.GetOnlineClient; - protected async _handle(payload: void) { + protected async _handle(payload: void) { //注册监听 - const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi; - NTQQSystemApi.getOnlineDev(); - await sleep(500); + const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi; + NTQQSystemApi.getOnlineDev(); + await sleep(500); - return []; - } + return []; + } } diff --git a/src/onebot/action/go-cqhttp/GetStrangerInfo.ts b/src/onebot/action/go-cqhttp/GetStrangerInfo.ts index e56cd79f..887adc23 100644 --- a/src/onebot/action/go-cqhttp/GetStrangerInfo.ts +++ b/src/onebot/action/go-cqhttp/GetStrangerInfo.ts @@ -5,38 +5,38 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { calcQQLevel } from '@/common/utils/qqlevel'; const SchemaData = { - type: 'object', - properties: { - user_id: { type: ['number', 'string'] }, - }, - required: ['user_id'] + type: 'object', + properties: { + user_id: { type: ['number', 'string'] }, + }, + required: ['user_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class GoCQHTTPGetStrangerInfo extends BaseAction { - actionName = ActionName.GoCQHTTP_GetStrangerInfo; + actionName = ActionName.GoCQHTTP_GetStrangerInfo; - protected async _handle(payload: Payload): Promise { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const user_id = payload.user_id.toString(); - const extendData = await NTQQUserApi.getUserDetailInfoByUin(user_id); - const uid = (await NTQQUserApi.getUidByUin(user_id))!; - if (!uid || uid.indexOf('*') != -1) { - const ret = { - ...extendData, - user_id: parseInt(extendData.info.uin) || 0, - nickname: extendData.info.nick, - sex: OB11UserSex.unknown, - age: (extendData.info.birthday_year == 0) ? 0 : new Date().getFullYear() - extendData.info.birthday_year, - qid: extendData.info.qid, - level: extendData.info.qqLevel && calcQQLevel(extendData.info.qqLevel) || 0, - login_days: 0, - uid: '' - }; - return ret; + protected async _handle(payload: Payload): Promise { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const user_id = payload.user_id.toString(); + const extendData = await NTQQUserApi.getUserDetailInfoByUin(user_id); + const uid = (await NTQQUserApi.getUidByUin(user_id))!; + if (!uid || uid.indexOf('*') != -1) { + const ret = { + ...extendData, + user_id: parseInt(extendData.info.uin) || 0, + nickname: extendData.info.nick, + sex: OB11UserSex.unknown, + age: (extendData.info.birthday_year == 0) ? 0 : new Date().getFullYear() - extendData.info.birthday_year, + qid: extendData.info.qid, + level: extendData.info.qqLevel && calcQQLevel(extendData.info.qqLevel) || 0, + login_days: 0, + uid: '' + }; + return ret; + } + const data = { ...extendData, ...(await NTQQUserApi.getUserDetailInfo(uid)) }; + return OB11Constructor.stranger(data); } - const data = { ...extendData, ...(await NTQQUserApi.getUserDetailInfo(uid)) }; - return OB11Constructor.stranger(data); - } } diff --git a/src/onebot/action/go-cqhttp/QuickAction.ts b/src/onebot/action/go-cqhttp/QuickAction.ts index 43fc8983..8652169b 100644 --- a/src/onebot/action/go-cqhttp/QuickAction.ts +++ b/src/onebot/action/go-cqhttp/QuickAction.ts @@ -8,9 +8,9 @@ interface Payload{ } export class GoCQHTTPHandleQuickAction extends BaseAction{ - actionName = ActionName.GoCQHTTP_HandleQuickAction; - protected async _handle(payload: Payload): Promise { - handleQuickOperation(payload.context, payload.operation,this.CoreContext).then().catch(this.CoreContext.context.logger.logError); - return null; - } + actionName = ActionName.GoCQHTTP_HandleQuickAction; + protected async _handle(payload: Payload): Promise { + handleQuickOperation(payload.context, payload.operation,this.CoreContext).then().catch(this.CoreContext.context.logger.logError); + return null; + } } \ No newline at end of file diff --git a/src/onebot/action/go-cqhttp/SendForwardMsg.ts b/src/onebot/action/go-cqhttp/SendForwardMsg.ts index fab6d218..155276a3 100644 --- a/src/onebot/action/go-cqhttp/SendForwardMsg.ts +++ b/src/onebot/action/go-cqhttp/SendForwardMsg.ts @@ -3,18 +3,18 @@ import { OB11PostSendMsg } from '../../types'; import { ActionName } from '../types'; // 未验证 export class GoCQHTTPSendForwardMsg extends SendMsg { - actionName = ActionName.GoCQHTTP_SendForwardMsg; + actionName = ActionName.GoCQHTTP_SendForwardMsg; - protected async check(payload: OB11PostSendMsg) { - if (payload.messages) payload.message = normalize(payload.messages); - return super.check(payload); - } + protected async check(payload: OB11PostSendMsg) { + if (payload.messages) payload.message = normalize(payload.messages); + return super.check(payload); + } } export class GoCQHTTPSendPrivateForwardMsg extends GoCQHTTPSendForwardMsg { - actionName = ActionName.GoCQHTTP_SendPrivateForwardMsg; + actionName = ActionName.GoCQHTTP_SendPrivateForwardMsg; } export class GoCQHTTPSendGroupForwardMsg extends GoCQHTTPSendForwardMsg { - actionName = ActionName.GoCQHTTP_SendGroupForwardMsg; + actionName = ActionName.GoCQHTTP_SendGroupForwardMsg; } diff --git a/src/onebot/action/go-cqhttp/SendGroupNotice.ts b/src/onebot/action/go-cqhttp/SendGroupNotice.ts index 2924550f..751d95e1 100644 --- a/src/onebot/action/go-cqhttp/SendGroupNotice.ts +++ b/src/onebot/action/go-cqhttp/SendGroupNotice.ts @@ -4,58 +4,58 @@ import { ActionName } from '../types'; import { unlink } from 'node:fs'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['number', 'string'] }, - content: { type: 'string' }, - image: { type: 'string' }, - pinned: { type: 'number' }, - confirmRequired: { type: 'number' } - }, - required: ['group_id', 'content'] + type: 'object', + properties: { + group_id: { type: ['number', 'string'] }, + content: { type: 'string' }, + image: { type: 'string' }, + pinned: { type: 'number' }, + confirmRequired: { type: 'number' } + }, + required: ['group_id', 'content'] } as const satisfies JSONSchema; type Payload = FromSchema; export class SendGroupNotice extends BaseAction { - actionName = ActionName.GoCQHTTP_SendGroupNotice; - protected async _handle(payload: Payload) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - let UploadImage: { id: string, width: number, height: number } | undefined = undefined; - if (payload.image) { - //公告图逻辑 - const { errMsg, path, isLocal, success } = (await uri2local(this.CoreContext.NapCatTempPath,payload.image)); - if (!success) { - throw `群公告${payload.image}设置失败,image字段可能格式不正确`; - } - if (!path) { - throw `群公告${payload.image}设置失败,获取资源失败`; - } - await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断 - const ImageUploadResult = await NTQQGroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path); - if (ImageUploadResult.errCode != 0) { - throw `群公告${payload.image}设置失败,图片上传失败`; - } - if (!isLocal) { - unlink(path, () => { }); - } - UploadImage = ImageUploadResult.picInfo; - } - let Notice_Pinned = 0; - let Notice_confirmRequired = 0; - if (!payload.pinned) { - Notice_Pinned = 0; - } - if (!payload.confirmRequired) { - Notice_confirmRequired = 0; - } - const PublishGroupBulletinResult = await NTQQGroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, Notice_Pinned, Notice_confirmRequired); + actionName = ActionName.GoCQHTTP_SendGroupNotice; + protected async _handle(payload: Payload) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + let UploadImage: { id: string, width: number, height: number } | undefined = undefined; + if (payload.image) { + //公告图逻辑 + const { errMsg, path, isLocal, success } = (await uri2local(this.CoreContext.NapCatTempPath,payload.image)); + if (!success) { + throw `群公告${payload.image}设置失败,image字段可能格式不正确`; + } + if (!path) { + throw `群公告${payload.image}设置失败,获取资源失败`; + } + await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断 + const ImageUploadResult = await NTQQGroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path); + if (ImageUploadResult.errCode != 0) { + throw `群公告${payload.image}设置失败,图片上传失败`; + } + if (!isLocal) { + unlink(path, () => { }); + } + UploadImage = ImageUploadResult.picInfo; + } + let Notice_Pinned = 0; + let Notice_confirmRequired = 0; + if (!payload.pinned) { + Notice_Pinned = 0; + } + if (!payload.confirmRequired) { + Notice_confirmRequired = 0; + } + const PublishGroupBulletinResult = await NTQQGroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, Notice_Pinned, Notice_confirmRequired); - if (PublishGroupBulletinResult.result != 0) { - throw `设置群公告失败,错误信息:${PublishGroupBulletinResult.errMsg}`; + if (PublishGroupBulletinResult.result != 0) { + throw `设置群公告失败,错误信息:${PublishGroupBulletinResult.errMsg}`; + } + // 下面实现扬了 + //await WebApi.setGroupNotice(payload.group_id, payload.content) ; + return null; } - // 下面实现扬了 - //await WebApi.setGroupNotice(payload.group_id, payload.content) ; - return null; - } } diff --git a/src/onebot/action/go-cqhttp/UploadGroupFile.ts b/src/onebot/action/go-cqhttp/UploadGroupFile.ts index 1632c888..f8df6a0d 100644 --- a/src/onebot/action/go-cqhttp/UploadGroupFile.ts +++ b/src/onebot/action/go-cqhttp/UploadGroupFile.ts @@ -7,33 +7,33 @@ import { uri2local } from '@/common/utils/file'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { SendMsgElementConstructor } from '@/onebot/helper/msg'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['number', 'string'] }, - file: { type: 'string' }, - name: { type: 'string' }, - folder: { type: 'string' }, - folder_id: { type: 'string' }//临时扩展 - }, - required: ['group_id', 'file', 'name'] + type: 'object', + properties: { + group_id: { type: ['number', 'string'] }, + file: { type: 'string' }, + name: { type: 'string' }, + folder: { type: 'string' }, + folder_id: { type: 'string' }//临时扩展 + }, + required: ['group_id', 'file', 'name'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class GoCQHTTPUploadGroupFile extends BaseAction { - actionName = ActionName.GoCQHTTP_UploadGroupFile; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - let file = payload.file; - if (fs.existsSync(file)) { - file = `file://${file}`; + actionName = ActionName.GoCQHTTP_UploadGroupFile; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + let file = payload.file; + if (fs.existsSync(file)) { + file = `file://${file}`; + } + const downloadResult = await uri2local(this.CoreContext.NapCatTempPath, file); + if (!downloadResult.success) { + throw new Error(downloadResult.errMsg); + } + const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(this.CoreContext, downloadResult.path, payload.name, payload.folder_id); + await sendMsg(this.CoreContext, { chatType: ChatType.group, peerUid: payload.group_id.toString() }, [sendFileEle], [], true); + return null; } - const downloadResult = await uri2local(this.CoreContext.NapCatTempPath, file); - if (!downloadResult.success) { - throw new Error(downloadResult.errMsg); - } - const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(this.CoreContext, downloadResult.path, payload.name, payload.folder_id); - await sendMsg(this.CoreContext, { chatType: ChatType.group, peerUid: payload.group_id.toString() }, [sendFileEle], [], true); - return null; - } } diff --git a/src/onebot/action/go-cqhttp/UploadPrivareFile.ts b/src/onebot/action/go-cqhttp/UploadPrivareFile.ts index 8f0f5c0e..a1a01eab 100644 --- a/src/onebot/action/go-cqhttp/UploadPrivareFile.ts +++ b/src/onebot/action/go-cqhttp/UploadPrivareFile.ts @@ -1,4 +1,4 @@ -import BaseAction from '../BaseAction';; +import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { ChatType, Peer, SendFileElement } from '@/core/entities'; import fs from 'fs'; @@ -7,45 +7,45 @@ import { uri2local } from '@/common/utils/file'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { SendMsgElementConstructor } from '@/onebot/helper/msg'; const SchemaData = { - type: 'object', - properties: { - user_id: { type: ['number', 'string'] }, - file: { type: 'string' }, - name: { type: 'string' } - }, - required: ['user_id', 'file', 'name'] + type: 'object', + properties: { + user_id: { type: ['number', 'string'] }, + file: { type: 'string' }, + name: { type: 'string' } + }, + required: ['user_id', 'file', 'name'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class GoCQHTTPUploadPrivateFile extends BaseAction { - actionName = ActionName.GOCQHTTP_UploadPrivateFile; - PayloadSchema = SchemaData; - async getPeer(payload: Payload): Promise { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; - if (payload.user_id) { - const peerUid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - if (!peerUid) { - throw `私聊${payload.user_id}不存在`; - } - const isBuddy = await NTQQFriendApi.isBuddy(peerUid); - return { chatType: isBuddy ? ChatType.friend : ChatType.temp, peerUid }; + actionName = ActionName.GOCQHTTP_UploadPrivateFile; + PayloadSchema = SchemaData; + async getPeer(payload: Payload): Promise { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; + if (payload.user_id) { + const peerUid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + if (!peerUid) { + throw `私聊${payload.user_id}不存在`; + } + const isBuddy = await NTQQFriendApi.isBuddy(peerUid); + return { chatType: isBuddy ? ChatType.friend : ChatType.temp, peerUid }; + } + throw '缺少参数 user_id'; } - throw '缺少参数 user_id'; - } - protected async _handle(payload: Payload): Promise { - const peer = await this.getPeer(payload); - let file = payload.file; - if (fs.existsSync(file)) { - file = `file://${file}`; + protected async _handle(payload: Payload): Promise { + const peer = await this.getPeer(payload); + let file = payload.file; + if (fs.existsSync(file)) { + file = `file://${file}`; + } + const downloadResult = await uri2local(this.CoreContext.NapCatTempPath, file); + if (!downloadResult.success) { + throw new Error(downloadResult.errMsg); + } + const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(this.CoreContext, downloadResult.path, payload.name); + await sendMsg(this.CoreContext, peer, [sendFileEle], [], true); + return null; } - const downloadResult = await uri2local(this.CoreContext.NapCatTempPath, file); - if (!downloadResult.success) { - throw new Error(downloadResult.errMsg); - } - const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(this.CoreContext, downloadResult.path, payload.name); - await sendMsg(this.CoreContext, peer, [sendFileEle], [], true); - return null; - } } diff --git a/src/onebot/action/group/DelEssenceMsg.ts b/src/onebot/action/group/DelEssenceMsg.ts index 90ee8b0f..55f38087 100644 --- a/src/onebot/action/group/DelEssenceMsg.ts +++ b/src/onebot/action/group/DelEssenceMsg.ts @@ -5,27 +5,27 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { MessageUnique } from '@/common/utils/MessageUnique'; const SchemaData = { - type: 'object', - properties: { - message_id: { type: ['number', 'string'] } - }, - required: ['message_id'] + type: 'object', + properties: { + message_id: { type: ['number', 'string'] } + }, + required: ['message_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class DelEssenceMsg extends BaseAction { - actionName = ActionName.DelEssenceMsg; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); - if (!msg) { - throw new Error('msg not found'); + actionName = ActionName.DelEssenceMsg; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); + if (!msg) { + throw new Error('msg not found'); + } + return await NTQQGroupApi.removeGroupEssence( + msg.Peer.peerUid, + msg.MsgId + ); } - return await NTQQGroupApi.removeGroupEssence( - msg.Peer.peerUid, - msg.MsgId - ); - } } diff --git a/src/onebot/action/group/GetGroupEssence.ts b/src/onebot/action/group/GetGroupEssence.ts index 2b2cce53..e6d30a4c 100644 --- a/src/onebot/action/group/GetGroupEssence.ts +++ b/src/onebot/action/group/GetGroupEssence.ts @@ -4,25 +4,25 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - pages: { type: 'number' }, - }, - required: ['group_id', 'pages'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + pages: { type: 'number' }, + }, + required: ['group_id', 'pages'] } as const satisfies JSONSchema; type Payload = FromSchema; export class GetGroupEssence extends BaseAction { - actionName = ActionName.GoCQHTTP_GetEssenceMsg; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQWebApi = this.CoreContext.getApiContext().WebApi; - const ret = await NTQQWebApi.getGroupEssenceMsg(payload.group_id.toString(), payload.pages.toString()); - if (!ret) { - throw new Error('获取失败'); + actionName = ActionName.GoCQHTTP_GetEssenceMsg; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQWebApi = this.CoreContext.getApiContext().WebApi; + const ret = await NTQQWebApi.getGroupEssenceMsg(payload.group_id.toString(), payload.pages.toString()); + if (!ret) { + throw new Error('获取失败'); + } + return ret; } - return ret; - } } diff --git a/src/onebot/action/group/GetGroupInfo.ts b/src/onebot/action/group/GetGroupInfo.ts index f427b366..4cd36a34 100644 --- a/src/onebot/action/group/GetGroupInfo.ts +++ b/src/onebot/action/group/GetGroupInfo.ts @@ -5,27 +5,27 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['number', 'string'] }, - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: ['number', 'string'] }, + }, + required: ['group_id'] } as const satisfies JSONSchema; type Payload = FromSchema; class GetGroupInfo extends BaseAction { - actionName = ActionName.GetGroupInfo; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const group = (await NTQQGroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString()); - if (group) { - return OB11Constructor.group(group); - } else { - throw `群${payload.group_id}不存在`; + actionName = ActionName.GetGroupInfo; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const group = (await NTQQGroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString()); + if (group) { + return OB11Constructor.group(group); + } else { + throw `群${payload.group_id}不存在`; + } } - } } export default GetGroupInfo; diff --git a/src/onebot/action/group/GetGroupList.ts b/src/onebot/action/group/GetGroupList.ts index 05721085..1e2fa647 100644 --- a/src/onebot/action/group/GetGroupList.ts +++ b/src/onebot/action/group/GetGroupList.ts @@ -6,22 +6,22 @@ import { Group } from '@/core/entities'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; // no_cache get时传字符串 const SchemaData = { - type: 'object', - properties: { - no_cache: { type: ['boolean', 'string'] }, - } + type: 'object', + properties: { + no_cache: { type: ['boolean', 'string'] }, + } } as const satisfies JSONSchema; type Payload = FromSchema; class GetGroupList extends BaseAction { - actionName = ActionName.GetGroupList; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const groupList: Group[] = await NTQQGroupApi.getGroups(payload?.no_cache === true || payload.no_cache === 'true'); - return OB11Constructor.groups(groupList); - } + actionName = ActionName.GetGroupList; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const groupList: Group[] = await NTQQGroupApi.getGroups(payload?.no_cache === true || payload.no_cache === 'true'); + return OB11Constructor.groups(groupList); + } } export default GetGroupList; diff --git a/src/onebot/action/group/GetGroupMemberInfo.ts b/src/onebot/action/group/GetGroupMemberInfo.ts index e2bdc694..3b53fcb3 100644 --- a/src/onebot/action/group/GetGroupMemberInfo.ts +++ b/src/onebot/action/group/GetGroupMemberInfo.ts @@ -4,74 +4,74 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['number', 'string'] }, - user_id: { type: ['number', 'string'] }, - no_cache: { type: ['boolean', 'string'] }, - }, - required: ['group_id', 'user_id'] + type: 'object', + properties: { + group_id: { type: ['number', 'string'] }, + user_id: { type: ['number', 'string'] }, + no_cache: { type: ['boolean', 'string'] }, + }, + required: ['group_id', 'user_id'] } as const satisfies JSONSchema; type Payload = FromSchema; class GetGroupMemberInfo extends BaseAction { - actionName = ActionName.GetGroupMemberInfo; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const NTQQWebApi = this.CoreContext.getApiContext().WebApi; - const isNocache = payload.no_cache == true || payload.no_cache === 'true'; - const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - if (!uid) { - throw (`Uin2Uid Error ${payload.user_id}不存在`); - } - const member = await NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache); - if (!member) { - throw (`群(${payload.group_id})成员${payload.user_id}不存在`); - } - try { - const info = (await NTQQUserApi.getUserDetailInfo(member.uid)); - this.CoreContext.context.logger.logDebug('群成员详细信息结果', info); - Object.assign(member, info); - } catch (e) { - this.CoreContext.context.logger.logDebug('获取群成员详细信息失败, 只能返回基础信息', e); - } - const date = Math.round(Date.now() / 1000); - const retMember = OB11Constructor.groupMember(payload.group_id.toString(), member); - if (!this.CoreContext.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { - const SelfInfoInGroup = await NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), this.CoreContext.selfInfo.uid, isNocache); - let isPrivilege = false; - if (SelfInfoInGroup) { - isPrivilege = SelfInfoInGroup.role === 3 || SelfInfoInGroup.role === 4; - } - if (isPrivilege) { - const webGroupMembers = await NTQQWebApi.getGroupMembers(payload.group_id.toString()); - for (let i = 0, len = webGroupMembers.length; i < len; i++) { - if (webGroupMembers[i]?.uin && webGroupMembers[i].uin === retMember.user_id) { - retMember.join_time = webGroupMembers[i]?.join_time; - retMember.last_sent_time = webGroupMembers[i]?.last_speak_time; - retMember.qage = webGroupMembers[i]?.qage; - retMember.level = webGroupMembers[i]?.lv.level.toString(); - } + actionName = ActionName.GetGroupMemberInfo; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const NTQQWebApi = this.CoreContext.getApiContext().WebApi; + const isNocache = payload.no_cache == true || payload.no_cache === 'true'; + const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + if (!uid) { + throw (`Uin2Uid Error ${payload.user_id}不存在`); } - } else { - const LastestMsgList = await NTQQGroupApi.getLatestMsg(payload.group_id.toString(), [payload.user_id.toString()]); - if (LastestMsgList?.msgList?.length && LastestMsgList?.msgList?.length > 0) { - const last_send_time = LastestMsgList.msgList[0].msgTime; - if (last_send_time && last_send_time != '0' && last_send_time != '') { - retMember.last_sent_time = parseInt(last_send_time); - retMember.join_time = Math.round(Date.now() / 1000);//兜底数据 防止群管乱杀 - } + const member = await NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache); + if (!member) { + throw (`群(${payload.group_id})成员${payload.user_id}不存在`); } - } - } else { - // Mlikiowa V2.0.0 Refactor Todo - // retMember.last_sent_time = parseInt((await getGroupMember(payload.group_id.toString(), retMember.user_id))?.lastSpeakTime || date.toString()); - // retMember.join_time = parseInt((await getGroupMember(payload.group_id.toString(), retMember.user_id))?.joinTime || date.toString()); + try { + const info = (await NTQQUserApi.getUserDetailInfo(member.uid)); + this.CoreContext.context.logger.logDebug('群成员详细信息结果', info); + Object.assign(member, info); + } catch (e) { + this.CoreContext.context.logger.logDebug('获取群成员详细信息失败, 只能返回基础信息', e); + } + const date = Math.round(Date.now() / 1000); + const retMember = OB11Constructor.groupMember(payload.group_id.toString(), member); + if (!this.CoreContext.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { + const SelfInfoInGroup = await NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), this.CoreContext.selfInfo.uid, isNocache); + let isPrivilege = false; + if (SelfInfoInGroup) { + isPrivilege = SelfInfoInGroup.role === 3 || SelfInfoInGroup.role === 4; + } + if (isPrivilege) { + const webGroupMembers = await NTQQWebApi.getGroupMembers(payload.group_id.toString()); + for (let i = 0, len = webGroupMembers.length; i < len; i++) { + if (webGroupMembers[i]?.uin && webGroupMembers[i].uin === retMember.user_id) { + retMember.join_time = webGroupMembers[i]?.join_time; + retMember.last_sent_time = webGroupMembers[i]?.last_speak_time; + retMember.qage = webGroupMembers[i]?.qage; + retMember.level = webGroupMembers[i]?.lv.level.toString(); + } + } + } else { + const LastestMsgList = await NTQQGroupApi.getLatestMsg(payload.group_id.toString(), [payload.user_id.toString()]); + if (LastestMsgList?.msgList?.length && LastestMsgList?.msgList?.length > 0) { + const last_send_time = LastestMsgList.msgList[0].msgTime; + if (last_send_time && last_send_time != '0' && last_send_time != '') { + retMember.last_sent_time = parseInt(last_send_time); + retMember.join_time = Math.round(Date.now() / 1000);//兜底数据 防止群管乱杀 + } + } + } + } else { + // Mlikiowa V2.0.0 Refactor Todo + // retMember.last_sent_time = parseInt((await getGroupMember(payload.group_id.toString(), retMember.user_id))?.lastSpeakTime || date.toString()); + // retMember.join_time = parseInt((await getGroupMember(payload.group_id.toString(), retMember.user_id))?.joinTime || date.toString()); + } + return retMember; } - return retMember; - } } export default GetGroupMemberInfo; \ No newline at end of file diff --git a/src/onebot/action/group/GetGroupMemberList.ts b/src/onebot/action/group/GetGroupMemberList.ts index 2350ebe8..3f569f98 100644 --- a/src/onebot/action/group/GetGroupMemberList.ts +++ b/src/onebot/action/group/GetGroupMemberList.ts @@ -5,101 +5,101 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['number', 'string'] }, - no_cache: { type: ['boolean', 'string'] }, - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: ['number', 'string'] }, + no_cache: { type: ['boolean', 'string'] }, + }, + required: ['group_id'] } as const satisfies JSONSchema; type Payload = FromSchema; class GetGroupMemberList extends BaseAction { - actionName = ActionName.GetGroupMemberList; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const NTQQWebApi = this.CoreContext.getApiContext().WebApi; - const isNocache = payload.no_cache == true || payload.no_cache === 'true'; + actionName = ActionName.GetGroupMemberList; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const NTQQWebApi = this.CoreContext.getApiContext().WebApi; + const isNocache = payload.no_cache == true || payload.no_cache === 'true'; - const GroupList = await NTQQGroupApi.getGroups(isNocache); - const group = GroupList.find(item => item.groupCode == payload.group_id); - if (!group) { - throw (`群${payload.group_id}不存在`); - } - const groupMembers = await NTQQGroupApi.getGroupMembers(payload.group_id.toString()); - const groupMembersArr = Array.from(groupMembers.values()); - const groupMembersUids = groupMembersArr.map(e => e.uid); - let _groupMembers = groupMembersArr.map(item => { return OB11Constructor.groupMember(group.groupCode, item); }); - - const MemberMap: Map = new Map(); - // 转为Map 方便索引 - let GroupMemberUids: string[] = []; - const date = Math.round(Date.now() / 1000); - for (let i = 0, len = _groupMembers.length; i < len; i++) { - // 保证基础数据有这个 同时避免群管插件过于依赖这个杀了 - _groupMembers[i].join_time = date; - _groupMembers[i].last_sent_time = date; - MemberMap.set(_groupMembers[i].user_id, _groupMembers[i]); - } - - if (!this.CoreContext.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { - const selfRole = groupMembers.get(this.CoreContext.selfInfo.uid)?.role; - const isPrivilege = selfRole === 3 || selfRole === 4; - - if (isPrivilege) { - const webGroupMembers = await NTQQWebApi.getGroupMembers(payload.group_id.toString()); - for (let i = 0, len = webGroupMembers.length; i < len; i++) { - if (!webGroupMembers[i]?.uin) { - continue; - } - const MemberData = MemberMap.get(webGroupMembers[i]?.uin); - if (MemberData) { - MemberData.join_time = webGroupMembers[i]?.join_time; - MemberData.last_sent_time = webGroupMembers[i]?.last_speak_time; - MemberData.qage = webGroupMembers[i]?.qage; - MemberData.level = webGroupMembers[i]?.lv.level.toString(); - MemberMap.set(webGroupMembers[i]?.uin, MemberData); - } + const GroupList = await NTQQGroupApi.getGroups(isNocache); + const group = GroupList.find(item => item.groupCode == payload.group_id); + if (!group) { + throw (`群${payload.group_id}不存在`); } - } else { - if (isNocache) { - const DateMap = await NTQQGroupApi.getGroupMemberLatestSendTimeCache(payload.group_id.toString(), groupMembersUids);//开始从本地拉取 - for (const DateUin of DateMap.keys()) { - const MemberData = MemberMap.get(parseInt(DateUin)); - if (MemberData) { - MemberData.last_sent_time = parseInt(DateMap.get(DateUin)!); - //join_time 有基础数据兜底 + const groupMembers = await NTQQGroupApi.getGroupMembers(payload.group_id.toString()); + const groupMembersArr = Array.from(groupMembers.values()); + const groupMembersUids = groupMembersArr.map(e => e.uid); + let _groupMembers = groupMembersArr.map(item => { return OB11Constructor.groupMember(group.groupCode, item); }); + + const MemberMap: Map = new Map(); + // 转为Map 方便索引 + const GroupMemberUids: string[] = []; + const date = Math.round(Date.now() / 1000); + for (let i = 0, len = _groupMembers.length; i < len; i++) { + // 保证基础数据有这个 同时避免群管插件过于依赖这个杀了 + _groupMembers[i].join_time = date; + _groupMembers[i].last_sent_time = date; + MemberMap.set(_groupMembers[i].user_id, _groupMembers[i]); + } + + if (!this.CoreContext.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { + const selfRole = groupMembers.get(this.CoreContext.selfInfo.uid)?.role; + const isPrivilege = selfRole === 3 || selfRole === 4; + + if (isPrivilege) { + const webGroupMembers = await NTQQWebApi.getGroupMembers(payload.group_id.toString()); + for (let i = 0, len = webGroupMembers.length; i < len; i++) { + if (!webGroupMembers[i]?.uin) { + continue; + } + const MemberData = MemberMap.get(webGroupMembers[i]?.uin); + if (MemberData) { + MemberData.join_time = webGroupMembers[i]?.join_time; + MemberData.last_sent_time = webGroupMembers[i]?.last_speak_time; + MemberData.qage = webGroupMembers[i]?.qage; + MemberData.level = webGroupMembers[i]?.lv.level.toString(); + MemberMap.set(webGroupMembers[i]?.uin, MemberData); + } + } + } else { + if (isNocache) { + const DateMap = await NTQQGroupApi.getGroupMemberLatestSendTimeCache(payload.group_id.toString(), groupMembersUids);//开始从本地拉取 + for (const DateUin of DateMap.keys()) { + const MemberData = MemberMap.get(parseInt(DateUin)); + if (MemberData) { + MemberData.last_sent_time = parseInt(DateMap.get(DateUin)!); + //join_time 有基础数据兜底 + } + } + } else { + _groupMembers.forEach(item => { + item.last_sent_time = date; + item.join_time = date; + }); + } } - } } else { - _groupMembers.forEach(item => { - item.last_sent_time = date; - item.join_time = date; - }); + // Mlikiowa V2.0.0 Refactor Todo + // _groupMembers.forEach(async item => { + // item.last_sent_time = parseInt((await getGroupMember(payload.group_id.toString(), item.user_id))?.lastSpeakTime || date.toString()); + // item.join_time = parseInt((await getGroupMember(payload.group_id.toString(), item.user_id))?.joinTime || date.toString()); + // }); } - } - } else { - // Mlikiowa V2.0.0 Refactor Todo - // _groupMembers.forEach(async item => { - // item.last_sent_time = parseInt((await getGroupMember(payload.group_id.toString(), item.user_id))?.lastSpeakTime || date.toString()); - // item.join_time = parseInt((await getGroupMember(payload.group_id.toString(), item.user_id))?.joinTime || date.toString()); - // }); + // 还原索引到Array 一同返回 + + // let retData: any[] = []; + // for (let retMem of MemberMap.values()) { + // retMem.level = TypeConvert.toString(retMem.level) as any; + // retData.push(retMem) + // } + + // _groupMembers = Array.from(retData); + + _groupMembers = Array.from(MemberMap.values()); + return _groupMembers; } - // 还原索引到Array 一同返回 - - // let retData: any[] = []; - // for (let retMem of MemberMap.values()) { - // retMem.level = TypeConvert.toString(retMem.level) as any; - // retData.push(retMem) - // } - - // _groupMembers = Array.from(retData); - - _groupMembers = Array.from(MemberMap.values()); - return _groupMembers; - } } export default GetGroupMemberList; diff --git a/src/onebot/action/group/GetGroupNotice.ts b/src/onebot/action/group/GetGroupNotice.ts index aae37c82..34a34b76 100644 --- a/src/onebot/action/group/GetGroupNotice.ts +++ b/src/onebot/action/group/GetGroupNotice.ts @@ -16,11 +16,11 @@ interface GroupNotice { } const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + }, + required: ['group_id'] } as const satisfies JSONSchema; type Payload = FromSchema; @@ -28,33 +28,33 @@ type Payload = FromSchema; type ApiGroupNotice = GroupNotice & WebApiGroupNoticeFeed; export class GetGroupNotice extends BaseAction { - actionName = ActionName.GoCQHTTP_GetGroupNotice; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQWebApi = this.CoreContext.getApiContext().WebApi; + actionName = ActionName.GoCQHTTP_GetGroupNotice; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQWebApi = this.CoreContext.getApiContext().WebApi; - const group = payload.group_id.toString(); - const ret = await NTQQWebApi.getGroupNotice(group); - if (!ret) { - throw new Error('获取公告失败'); - } - const retNotices: GroupNotice[] = new Array(); - for (const key in ret.feeds) { - const retApiNotice: WebApiGroupNoticeFeed = ret.feeds[key]; - const retNotice: GroupNotice = { - // ...ret.feeds[key], - sender_id: retApiNotice.u, - publish_time: retApiNotice.pubt, - message: { - text: retApiNotice.msg.text, - image: retApiNotice.msg.pics?.map((pic) => { - return { id: pic.id, height: pic.h, width: pic.w }; - }) || [] + const group = payload.group_id.toString(); + const ret = await NTQQWebApi.getGroupNotice(group); + if (!ret) { + throw new Error('获取公告失败'); + } + const retNotices: GroupNotice[] = new Array(); + for (const key in ret.feeds) { + const retApiNotice: WebApiGroupNoticeFeed = ret.feeds[key]; + const retNotice: GroupNotice = { + // ...ret.feeds[key], + sender_id: retApiNotice.u, + publish_time: retApiNotice.pubt, + message: { + text: retApiNotice.msg.text, + image: retApiNotice.msg.pics?.map((pic) => { + return { id: pic.id, height: pic.h, width: pic.w }; + }) || [] + } + }; + retNotices.push(retNotice); } - }; - retNotices.push(retNotice); - } - return retNotices; - } + return retNotices; + } } diff --git a/src/onebot/action/group/GetGroupSystemMsg.ts b/src/onebot/action/group/GetGroupSystemMsg.ts index 62d659cc..eb57f66a 100644 --- a/src/onebot/action/group/GetGroupSystemMsg.ts +++ b/src/onebot/action/group/GetGroupSystemMsg.ts @@ -3,46 +3,46 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['number', 'string'] } - }, + type: 'object', + properties: { + group_id: { type: ['number', 'string'] } + }, } as const satisfies JSONSchema; type Payload = FromSchema; export class GetGroupSystemMsg extends BaseAction { - actionName = ActionName.GetGroupSystemMsg; - protected async _handle(payload: void) { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - // 默认10条 该api未完整实现 包括响应数据规范化 类型规范化 - const SingleScreenNotifies = await NTQQGroupApi.getSingleScreenNotifies(10); - const retData: any = { InvitedRequest: [], join_requests: [] }; - for (const SSNotify of SingleScreenNotifies) { - if (SSNotify.type == 1) { - retData.InvitedRequest.push({ - request_id: SSNotify.seq, - invitor_uin: await NTQQUserApi.getUinByUid(SSNotify.user1?.uid), - invitor_nick: SSNotify.user1?.nickName, - group_id: SSNotify.group?.groupCode, - group_name: SSNotify.group?.groupName, - checked: SSNotify.status === 1 ? false : true, - actor: await NTQQUserApi.getUinByUid(SSNotify.user2?.uid) || 0, - }); - } else if (SSNotify.type == 7) { - retData.join_requests.push({ - request_id: SSNotify.seq, - requester_uin: await NTQQUserApi.getUinByUid(SSNotify.user1?.uid), - requester_nick: SSNotify.user1?.nickName, - group_id: SSNotify.group?.groupCode, - group_name: SSNotify.group?.groupName, - checked: SSNotify.status === 1 ? false : true, - actor: await NTQQUserApi.getUinByUid(SSNotify.user2?.uid) || 0, - }); - } - } + actionName = ActionName.GetGroupSystemMsg; + protected async _handle(payload: void) { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + // 默认10条 该api未完整实现 包括响应数据规范化 类型规范化 + const SingleScreenNotifies = await NTQQGroupApi.getSingleScreenNotifies(10); + const retData: any = { InvitedRequest: [], join_requests: [] }; + for (const SSNotify of SingleScreenNotifies) { + if (SSNotify.type == 1) { + retData.InvitedRequest.push({ + request_id: SSNotify.seq, + invitor_uin: await NTQQUserApi.getUinByUid(SSNotify.user1?.uid), + invitor_nick: SSNotify.user1?.nickName, + group_id: SSNotify.group?.groupCode, + group_name: SSNotify.group?.groupName, + checked: SSNotify.status === 1 ? false : true, + actor: await NTQQUserApi.getUinByUid(SSNotify.user2?.uid) || 0, + }); + } else if (SSNotify.type == 7) { + retData.join_requests.push({ + request_id: SSNotify.seq, + requester_uin: await NTQQUserApi.getUinByUid(SSNotify.user1?.uid), + requester_nick: SSNotify.user1?.nickName, + group_id: SSNotify.group?.groupCode, + group_name: SSNotify.group?.groupName, + checked: SSNotify.status === 1 ? false : true, + actor: await NTQQUserApi.getUinByUid(SSNotify.user2?.uid) || 0, + }); + } + } - return retData; - } + return retData; + } } diff --git a/src/onebot/action/group/GetGuildList.ts b/src/onebot/action/group/GetGuildList.ts index ea36304b..f297b618 100644 --- a/src/onebot/action/group/GetGuildList.ts +++ b/src/onebot/action/group/GetGuildList.ts @@ -2,9 +2,9 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; export default class GetGuildList extends BaseAction { - actionName = ActionName.GetGuildList; + actionName = ActionName.GetGuildList; - protected async _handle(payload: null): Promise { - return null; - } + protected async _handle(payload: null): Promise { + return null; + } } \ No newline at end of file diff --git a/src/onebot/action/group/SendGroupMsg.ts b/src/onebot/action/group/SendGroupMsg.ts index 22c06831..a156fc4e 100644 --- a/src/onebot/action/group/SendGroupMsg.ts +++ b/src/onebot/action/group/SendGroupMsg.ts @@ -4,14 +4,14 @@ import { OB11PostSendMsg } from '../../types'; // 未检测参数 class SendGroupMsg extends SendMsg { - actionName = ActionName.SendGroupMsg; - contextMode: ContextMode = ContextMode.Group; + actionName = ActionName.SendGroupMsg; + contextMode: ContextMode = ContextMode.Group; - protected async check(payload: OB11PostSendMsg): Promise { - delete payload.user_id; - payload.message_type = 'group'; - return super.check(payload); - } + protected async check(payload: OB11PostSendMsg): Promise { + delete payload.user_id; + payload.message_type = 'group'; + return super.check(payload); + } } export default SendGroupMsg; diff --git a/src/onebot/action/group/SetEssenceMsg.ts b/src/onebot/action/group/SetEssenceMsg.ts index 02986b92..02a3d70c 100644 --- a/src/onebot/action/group/SetEssenceMsg.ts +++ b/src/onebot/action/group/SetEssenceMsg.ts @@ -4,27 +4,27 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { MessageUnique } from '@/common/utils/MessageUnique'; const SchemaData = { - type: 'object', - properties: { - message_id: { type: ['number', 'string'] } - }, - required: ['message_id'] + type: 'object', + properties: { + message_id: { type: ['number', 'string'] } + }, + required: ['message_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetEssenceMsg extends BaseAction { - actionName = ActionName.SetEssenceMsg; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); - if (!msg) { - throw new Error('msg not found'); + actionName = ActionName.SetEssenceMsg; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); + if (!msg) { + throw new Error('msg not found'); + } + return await NTQQGroupApi.addGroupEssence( + msg.Peer.peerUid, + msg.MsgId + ); } - return await NTQQGroupApi.addGroupEssence( - msg.Peer.peerUid, - msg.MsgId - ); - } } diff --git a/src/onebot/action/group/SetGroupAddRequest.ts b/src/onebot/action/group/SetGroupAddRequest.ts index 418c7f7a..3c67a164 100644 --- a/src/onebot/action/group/SetGroupAddRequest.ts +++ b/src/onebot/action/group/SetGroupAddRequest.ts @@ -5,28 +5,28 @@ import { NTQQGroupApi } from '@/core/apis/group'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - flag: { type: 'string' }, - approve: { type: ['string', 'boolean'] }, - reason: { type: 'string', nullable: true, } - }, - required: ['flag'], + type: 'object', + properties: { + flag: { type: 'string' }, + approve: { type: ['string', 'boolean'] }, + reason: { type: 'string', nullable: true, } + }, + required: ['flag'], } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetGroupAddRequest extends BaseAction { - actionName = ActionName.SetGroupAddRequest; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const flag = payload.flag.toString(); - const approve = payload.approve?.toString() !== 'false'; - await NTQQGroupApi.handleGroupRequest(flag, - approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject, - payload.reason || " " - ); - return null; - } + actionName = ActionName.SetGroupAddRequest; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const flag = payload.flag.toString(); + const approve = payload.approve?.toString() !== 'false'; + await NTQQGroupApi.handleGroupRequest(flag, + approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject, + payload.reason || " " + ); + return null; + } } diff --git a/src/onebot/action/group/SetGroupAdmin.ts b/src/onebot/action/group/SetGroupAdmin.ts index 4f9feb27..8a4fe067 100644 --- a/src/onebot/action/group/SetGroupAdmin.ts +++ b/src/onebot/action/group/SetGroupAdmin.ts @@ -5,26 +5,26 @@ import { NTQQGroupApi } from '@/core/apis/group'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - user_id: { type: [ 'number' , 'string' ] }, - enable: { type: 'boolean' } - }, - required: ['group_id', 'user_id'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + user_id: { type: [ 'number' , 'string' ] }, + enable: { type: 'boolean' } + }, + required: ['group_id', 'user_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetGroupAdmin extends BaseAction { - actionName = ActionName.SetGroupAdmin; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - let uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()) - if(!uid) throw new Error('get Uid Error') - await NTQQGroupApi.setMemberRole(payload.group_id.toString(), uid, payload.enable ? GroupMemberRole.admin : GroupMemberRole.normal); - return null; - } + actionName = ActionName.SetGroupAdmin; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + if(!uid) throw new Error('get Uid Error'); + await NTQQGroupApi.setMemberRole(payload.group_id.toString(), uid, payload.enable ? GroupMemberRole.admin : GroupMemberRole.normal); + return null; + } } diff --git a/src/onebot/action/group/SetGroupBan.ts b/src/onebot/action/group/SetGroupBan.ts index eaf77c26..e2087336 100644 --- a/src/onebot/action/group/SetGroupBan.ts +++ b/src/onebot/action/group/SetGroupBan.ts @@ -3,27 +3,27 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: ['number', 'string'] }, - user_id: { type: ['number', 'string'] }, - duration: { type: ['number', 'string'] } - }, - required: ['group_id', 'user_id', 'duration'] + type: 'object', + properties: { + group_id: { type: ['number', 'string'] }, + user_id: { type: ['number', 'string'] }, + duration: { type: ['number', 'string'] } + }, + required: ['group_id', 'user_id', 'duration'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetGroupBan extends BaseAction { - actionName = ActionName.SetGroupBan; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - if(!uid) throw new Error('uid error'); - await NTQQGroupApi.banMember(payload.group_id.toString(), - [{ uid: uid, timeStamp: parseInt(payload.duration.toString()) }]); - return null; - } + actionName = ActionName.SetGroupBan; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + if(!uid) throw new Error('uid error'); + await NTQQGroupApi.banMember(payload.group_id.toString(), + [{ uid: uid, timeStamp: parseInt(payload.duration.toString()) }]); + return null; + } } diff --git a/src/onebot/action/group/SetGroupCard.ts b/src/onebot/action/group/SetGroupCard.ts index 5fe8f060..3fe91b2d 100644 --- a/src/onebot/action/group/SetGroupCard.ts +++ b/src/onebot/action/group/SetGroupCard.ts @@ -3,23 +3,23 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - user_id: { type: [ 'number' , 'string' ] }, - card: { type: 'string' } - }, - required: ['group_id', 'user_id', 'card'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + user_id: { type: [ 'number' , 'string' ] }, + card: { type: 'string' } + }, + required: ['group_id', 'user_id', 'card'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetGroupCard extends BaseAction { - actionName = ActionName.SetGroupCard; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - await NTQQGroupApi.setMemberCard(payload.group_id.toString(), member.uid, payload.card || ''); - return null; - } + actionName = ActionName.SetGroupCard; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + await NTQQGroupApi.setMemberCard(payload.group_id.toString(), member.uid, payload.card || ''); + return null; + } } diff --git a/src/onebot/action/group/SetGroupKick.ts b/src/onebot/action/group/SetGroupKick.ts index 4d4e791d..143b379f 100644 --- a/src/onebot/action/group/SetGroupKick.ts +++ b/src/onebot/action/group/SetGroupKick.ts @@ -5,27 +5,27 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - user_id: { type: [ 'number' , 'string' ] }, - reject_add_request: { type: [ 'boolean' , 'string' ] } - }, - required: ['group_id', 'user_id'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + user_id: { type: [ 'number' , 'string' ] }, + reject_add_request: { type: [ 'boolean' , 'string' ] } + }, + required: ['group_id', 'user_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetGroupKick extends BaseAction { - actionName = ActionName.SetGroupKick; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const rejectReq = payload.reject_add_request?.toString() == 'true'; - const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - if(!uid) throw new Error('get Uid Error') - await NTQQGroupApi.kickMember(payload.group_id.toString(), [uid], rejectReq); - return null; - } + actionName = ActionName.SetGroupKick; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const rejectReq = payload.reject_add_request?.toString() == 'true'; + const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + if(!uid) throw new Error('get Uid Error'); + await NTQQGroupApi.kickMember(payload.group_id.toString(), [uid], rejectReq); + return null; + } } diff --git a/src/onebot/action/group/SetGroupLeave.ts b/src/onebot/action/group/SetGroupLeave.ts index 2648caa9..3874c50b 100644 --- a/src/onebot/action/group/SetGroupLeave.ts +++ b/src/onebot/action/group/SetGroupLeave.ts @@ -2,24 +2,20 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - is_dismiss: { type: 'boolean' } - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + is_dismiss: { type: 'boolean' } + }, + required: ['group_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetGroupLeave extends BaseAction { - actionName = ActionName.SetGroupLeave; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - try { - await NTQQGroupApi.quitGroup(payload.group_id.toString()); - } catch (e) { - throw e; + actionName = ActionName.SetGroupLeave; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + await NTQQGroupApi.quitGroup(payload.group_id.toString()); } - } } diff --git a/src/onebot/action/group/SetGroupName.ts b/src/onebot/action/group/SetGroupName.ts index 60958702..4c63581d 100644 --- a/src/onebot/action/group/SetGroupName.ts +++ b/src/onebot/action/group/SetGroupName.ts @@ -4,21 +4,21 @@ import { ActionName } from '../types'; import { NTQQGroupApi } from '@/core/apis/group'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - group_name: { type: 'string' } - }, - required: ['group_id', 'group_name'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + group_name: { type: 'string' } + }, + required: ['group_id', 'group_name'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetGroupName extends BaseAction { - actionName = ActionName.SetGroupName; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - await NTQQGroupApi.setGroupName(payload.group_id.toString(), payload.group_name); - return null; - } + actionName = ActionName.SetGroupName; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + await NTQQGroupApi.setGroupName(payload.group_id.toString(), payload.group_name); + return null; + } } diff --git a/src/onebot/action/group/SetGroupWholeBan.ts b/src/onebot/action/group/SetGroupWholeBan.ts index e2e0efd6..08ba465c 100644 --- a/src/onebot/action/group/SetGroupWholeBan.ts +++ b/src/onebot/action/group/SetGroupWholeBan.ts @@ -2,23 +2,23 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; const SchemaData = { - type: 'object', - properties: { - group_id: { type: [ 'number' , 'string' ] }, - enable: { type: ['boolean','string'] } - }, - required: ['group_id'] + type: 'object', + properties: { + group_id: { type: [ 'number' , 'string' ] }, + enable: { type: ['boolean','string'] } + }, + required: ['group_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetGroupWholeBan extends BaseAction { - actionName = ActionName.SetGroupWholeBan; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const enable = payload.enable?.toString() !== 'false'; - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - await NTQQGroupApi.banGroup(payload.group_id.toString(), enable); - return null; - } + actionName = ActionName.SetGroupWholeBan; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const enable = payload.enable?.toString() !== 'false'; + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + await NTQQGroupApi.banGroup(payload.group_id.toString(), enable); + return null; + } } diff --git a/src/onebot/action/index.ts b/src/onebot/action/index.ts index 18f4f721..27940f64 100644 --- a/src/onebot/action/index.ts +++ b/src/onebot/action/index.ts @@ -15,9 +15,9 @@ import CanSendRecord from './system/CanSendRecord'; import CanSendImage from './system/CanSendImage'; import GetStatus from './system/GetStatus'; import { - GoCQHTTPSendForwardMsg, - GoCQHTTPSendGroupForwardMsg, - GoCQHTTPSendPrivateForwardMsg + GoCQHTTPSendForwardMsg, + GoCQHTTPSendGroupForwardMsg, + GoCQHTTPSendPrivateForwardMsg } from './go-cqhttp/SendForwardMsg'; import GoCQHTTPGetStrangerInfo from './go-cqhttp/GetStrangerInfo'; import SendLike from './user/SendLike'; @@ -77,94 +77,94 @@ import { FetchEmojioLike } from './extends/FetchEmojioLike'; import { NapCatCore } from '@/core'; export function createActionMap(context: NapCatCore) { - let actionHandlers = [ - new FetchEmojioLike(context), - new GetFile(context), - new SetSelfProfile(context), - new shareGroupEx(context), - new sharePeer(context), - new CreateCollection(context), - new SetLongNick(context), - new ForwardFriendSingleMsg(context), - new ForwardGroupSingleMsg(context), - new MarkGroupMsgAsRead(context), - new MarkPrivateMsgAsRead(context), - new SetQQAvatar(context), - new TranslateEnWordToZn(context), - new GetGroupFileCount(context), - new GetGroupFileList(context), - new SetGroupFileFolder(context), - new DelGroupFile(context), - new DelGroupFileFolder(context), - // onebot11 - new SendLike(context), - new GetMsg(context), - new GetLoginInfo(context), - new GetFriendList(context), - new GetGroupList(context), - new GetGroupInfo(context), - new GetGroupMemberList(context), - new GetGroupMemberInfo(context), - new SendGroupMsg(context), - new SendPrivateMsg(context), - new SendMsg(context), - new DeleteMsg(context), - new SetGroupAddRequest(context), - new SetFriendAddRequest(context), - new SetGroupLeave(context), - new GetVersionInfo(context), - new CanSendRecord(context), - new CanSendImage(context), - new GetStatus(context), - new SetGroupWholeBan(context), - new SetGroupBan(context), - new SetGroupKick(context), - new SetGroupAdmin(context), - new SetGroupName(context), - new SetGroupCard(context), - new GetImage(context), - new GetRecord(context), - new SetMsgEmojiLike(context), - new GetCookies(context), - new SetOnlineStatus(context), - new GetRobotUinRange(context), - new GetFriendWithCategory(context), - //以下为go-cqhttp api - new GetOnlineClient(context), - new OCRImage(context), - new IOCRImage(context), - new GetGroupHonorInfo(context), - new SendGroupNotice(context), - new GetGroupNotice(context), - new GetGroupEssence(context), - new GoCQHTTPSendForwardMsg(context), - new GoCQHTTPSendGroupForwardMsg(context), - new GoCQHTTPSendPrivateForwardMsg(context), - new GoCQHTTPGetStrangerInfo(context), - new GoCQHTTPDownloadFile(context), - new GetGuildList(context), - new GoCQHTTPMarkMsgAsRead(context), - new GoCQHTTPUploadGroupFile(context), - new GoCQHTTPGetGroupMsgHistory(context), - new GoCQHTTPGetForwardMsgAction(context), - new GetFriendMsgHistory(context), - new GoCQHTTPHandleQuickAction(context), - new GetGroupSystemMsg(context), - new DelEssenceMsg(context), - new SetEssenceMsg(context), - new GetRecentContact(context), - new MarkAllMsgAsRead(context), - new GetProfileLike(context), - new SetGroupHeader(context), - new FetchCustomFace(context), - new GoCQHTTPUploadPrivateFile(context) - ]; - const actionMap = new Map>(); - for (const action of actionHandlers) { - actionMap.set(action.actionName, action); - actionMap.set(action.actionName + '_async', action); - actionMap.set(action.actionName + '_rate_limited', action); - } + const actionHandlers = [ + new FetchEmojioLike(context), + new GetFile(context), + new SetSelfProfile(context), + new shareGroupEx(context), + new sharePeer(context), + new CreateCollection(context), + new SetLongNick(context), + new ForwardFriendSingleMsg(context), + new ForwardGroupSingleMsg(context), + new MarkGroupMsgAsRead(context), + new MarkPrivateMsgAsRead(context), + new SetQQAvatar(context), + new TranslateEnWordToZn(context), + new GetGroupFileCount(context), + new GetGroupFileList(context), + new SetGroupFileFolder(context), + new DelGroupFile(context), + new DelGroupFileFolder(context), + // onebot11 + new SendLike(context), + new GetMsg(context), + new GetLoginInfo(context), + new GetFriendList(context), + new GetGroupList(context), + new GetGroupInfo(context), + new GetGroupMemberList(context), + new GetGroupMemberInfo(context), + new SendGroupMsg(context), + new SendPrivateMsg(context), + new SendMsg(context), + new DeleteMsg(context), + new SetGroupAddRequest(context), + new SetFriendAddRequest(context), + new SetGroupLeave(context), + new GetVersionInfo(context), + new CanSendRecord(context), + new CanSendImage(context), + new GetStatus(context), + new SetGroupWholeBan(context), + new SetGroupBan(context), + new SetGroupKick(context), + new SetGroupAdmin(context), + new SetGroupName(context), + new SetGroupCard(context), + new GetImage(context), + new GetRecord(context), + new SetMsgEmojiLike(context), + new GetCookies(context), + new SetOnlineStatus(context), + new GetRobotUinRange(context), + new GetFriendWithCategory(context), + //以下为go-cqhttp api + new GetOnlineClient(context), + new OCRImage(context), + new IOCRImage(context), + new GetGroupHonorInfo(context), + new SendGroupNotice(context), + new GetGroupNotice(context), + new GetGroupEssence(context), + new GoCQHTTPSendForwardMsg(context), + new GoCQHTTPSendGroupForwardMsg(context), + new GoCQHTTPSendPrivateForwardMsg(context), + new GoCQHTTPGetStrangerInfo(context), + new GoCQHTTPDownloadFile(context), + new GetGuildList(context), + new GoCQHTTPMarkMsgAsRead(context), + new GoCQHTTPUploadGroupFile(context), + new GoCQHTTPGetGroupMsgHistory(context), + new GoCQHTTPGetForwardMsgAction(context), + new GetFriendMsgHistory(context), + new GoCQHTTPHandleQuickAction(context), + new GetGroupSystemMsg(context), + new DelEssenceMsg(context), + new SetEssenceMsg(context), + new GetRecentContact(context), + new MarkAllMsgAsRead(context), + new GetProfileLike(context), + new SetGroupHeader(context), + new FetchCustomFace(context), + new GoCQHTTPUploadPrivateFile(context) + ]; + const actionMap = new Map>(); + for (const action of actionHandlers) { + actionMap.set(action.actionName, action); + actionMap.set(action.actionName + '_async', action); + actionMap.set(action.actionName + '_rate_limited', action); + } - return actionMap; + return actionMap; } diff --git a/src/onebot/action/msg/DeleteMsg.ts b/src/onebot/action/msg/DeleteMsg.ts index f5444c1c..a666e6b1 100644 --- a/src/onebot/action/msg/DeleteMsg.ts +++ b/src/onebot/action/msg/DeleteMsg.ts @@ -5,48 +5,48 @@ import { MessageUnique } from '@/common/utils/MessageUnique'; import { NodeIKernelMsgListener } from '@/core'; const SchemaData = { - type: 'object', - properties: { - message_id: { - oneOf: [ - { type: 'number' }, - { type: 'string' } - ] - } - }, - required: ['message_id'] + type: 'object', + properties: { + message_id: { + oneOf: [ + { type: 'number' }, + { type: 'string' } + ] + } + }, + required: ['message_id'] } as const satisfies JSONSchema; type Payload = FromSchema; class DeleteMsg extends BaseAction { - actionName = ActionName.DeleteMsg; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const msg = MessageUnique.getMsgIdAndPeerByShortId(Number(payload.message_id)); - if (msg) { - let ret = this.CoreContext.eventWrapper.RegisterListen - ( - 'NodeIKernelMsgListener/onMsgInfoListUpdate', - 1, - 5000, - (msgs) => { - if (msgs.find(m => m.msgId === msg.MsgId && m.recallTime !== '0')) { - return true; + actionName = ActionName.DeleteMsg; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const msg = MessageUnique.getMsgIdAndPeerByShortId(Number(payload.message_id)); + if (msg) { + const ret = this.CoreContext.eventWrapper.RegisterListen + ( + 'NodeIKernelMsgListener/onMsgInfoListUpdate', + 1, + 5000, + (msgs) => { + if (msgs.find(m => m.msgId === msg.MsgId && m.recallTime !== '0')) { + return true; + } + return false; + } + ).catch(e => new Promise((resolve, reject) => { resolve(undefined); })); + await NTQQMsgApi.recallMsg(msg.Peer, [msg.MsgId]); + const data = await ret; + if (!data) { + throw new Error('Recall failed'); } - return false; - } - ).catch(e => new Promise((resolve, reject) => { resolve(undefined) })); - await NTQQMsgApi.recallMsg(msg.Peer, [msg.MsgId]); - let data = await ret; - if (!data) { - throw new Error('Recall failed'); - } - //await sleep(100); - //await NTQQMsgApi.getMsgsByMsgId(msg.Peer, [msg.MsgId]); + //await sleep(100); + //await NTQQMsgApi.getMsgsByMsgId(msg.Peer, [msg.MsgId]); + } } - } } export default DeleteMsg; diff --git a/src/onebot/action/msg/ForwardSingleMsg.ts b/src/onebot/action/msg/ForwardSingleMsg.ts index 952f8c36..31f55ddf 100644 --- a/src/onebot/action/msg/ForwardSingleMsg.ts +++ b/src/onebot/action/msg/ForwardSingleMsg.ts @@ -5,54 +5,54 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { MessageUnique } from '@/common/utils/MessageUnique'; const SchemaData = { - type: 'object', - properties: { - message_id: { type: 'number' }, - group_id: { type: ['number', 'string'] }, - user_id: { type: ['number', 'string'] } - }, - required: ['message_id'] + type: 'object', + properties: { + message_id: { type: 'number' }, + group_id: { type: ['number', 'string'] }, + user_id: { type: ['number', 'string'] } + }, + required: ['message_id'] } as const satisfies JSONSchema; type Payload = FromSchema; class ForwardSingleMsg extends BaseAction { - protected async getTargetPeer(payload: Payload): Promise { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - if (payload.user_id) { - const peerUid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - if (!peerUid) { - throw new Error(`无法找到私聊对象${payload.user_id}`); - } - return { chatType: ChatType.friend, peerUid }; + protected async getTargetPeer(payload: Payload): Promise { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + if (payload.user_id) { + const peerUid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + if (!peerUid) { + throw new Error(`无法找到私聊对象${payload.user_id}`); + } + return { chatType: ChatType.friend, peerUid }; + } + return { chatType: ChatType.group, peerUid: payload.group_id!.toString() }; } - return { chatType: ChatType.group, peerUid: payload.group_id!.toString() }; - } - protected async _handle(payload: Payload): Promise { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const msg = MessageUnique.getMsgIdAndPeerByShortId(payload.message_id); - if (!msg) { - throw new Error(`无法找到消息${payload.message_id}`); + protected async _handle(payload: Payload): Promise { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const msg = MessageUnique.getMsgIdAndPeerByShortId(payload.message_id); + if (!msg) { + throw new Error(`无法找到消息${payload.message_id}`); + } + const peer = await this.getTargetPeer(payload); + const ret = await NTQQMsgApi.forwardMsg(msg.Peer, + peer, + [msg.MsgId], + ); + if (ret.result !== 0) { + throw new Error(`转发消息失败 ${ret.errMsg}`); + } + return null; } - const peer = await this.getTargetPeer(payload); - const ret = await NTQQMsgApi.forwardMsg(msg.Peer, - peer, - [msg.MsgId], - ); - if (ret.result !== 0) { - throw new Error(`转发消息失败 ${ret.errMsg}`); - } - return null; - } } export class ForwardFriendSingleMsg extends ForwardSingleMsg { - PayloadSchema = SchemaData; - actionName = ActionName.ForwardFriendSingleMsg; + PayloadSchema = SchemaData; + actionName = ActionName.ForwardFriendSingleMsg; } export class ForwardGroupSingleMsg extends ForwardSingleMsg { - PayloadSchema = SchemaData; - actionName = ActionName.ForwardGroupSingleMsg; + PayloadSchema = SchemaData; + actionName = ActionName.ForwardGroupSingleMsg; } diff --git a/src/onebot/action/msg/GetMsg.ts b/src/onebot/action/msg/GetMsg.ts index 4f84d8ae..b2b53023 100644 --- a/src/onebot/action/msg/GetMsg.ts +++ b/src/onebot/action/msg/GetMsg.ts @@ -9,42 +9,42 @@ import { MessageUnique } from '@/common/utils/MessageUnique'; export type ReturnDataType = OB11Message const SchemaData = { - type: 'object', - properties: { - message_id: { type: ['number', 'string'] }, - }, - required: ['message_id'] + type: 'object', + properties: { + message_id: { type: ['number', 'string'] }, + }, + required: ['message_id'] } as const satisfies JSONSchema; type Payload = FromSchema; class GetMsg extends BaseAction { - actionName = ActionName.GetMsg; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - // log("history msg ids", Object.keys(msgHistory)); - if (!payload.message_id) { - throw Error('参数message_id不能为空'); + actionName = ActionName.GetMsg; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + // log("history msg ids", Object.keys(msgHistory)); + if (!payload.message_id) { + throw Error('参数message_id不能为空'); + } + const MsgShortId = await MessageUnique.getShortIdByMsgId(payload.message_id.toString()); + const msgIdWithPeer = await MessageUnique.getMsgIdAndPeerByShortId(MsgShortId || parseInt(payload.message_id.toString())); + if (!msgIdWithPeer) { + throw ('消息不存在'); + } + const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType }; + const msg = await NTQQMsgApi.getMsgsByMsgId( + peer, + [msgIdWithPeer?.MsgId || payload.message_id.toString()]); + const retMsg = await OB11Constructor.message(this.CoreContext, msg.msgList[0], "array"); + try { + retMsg.message_id = MessageUnique.createMsg(peer, msg.msgList[0].msgId)!; + retMsg.message_seq = retMsg.message_id; + retMsg.real_id = retMsg.message_id; + } catch (e) { + } + return retMsg; } - const MsgShortId = await MessageUnique.getShortIdByMsgId(payload.message_id.toString()); - const msgIdWithPeer = await MessageUnique.getMsgIdAndPeerByShortId(MsgShortId || parseInt(payload.message_id.toString())); - if (!msgIdWithPeer) { - throw ('消息不存在'); - } - const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType }; - const msg = await NTQQMsgApi.getMsgsByMsgId( - peer, - [msgIdWithPeer?.MsgId || payload.message_id.toString()]); - const retMsg = await OB11Constructor.message(this.CoreContext, msg.msgList[0], "array"); - try { - retMsg.message_id = MessageUnique.createMsg(peer, msg.msgList[0].msgId)!; - retMsg.message_seq = retMsg.message_id; - retMsg.real_id = retMsg.message_id; - } catch (e) { - } - return retMsg; - } } export default GetMsg; diff --git a/src/onebot/action/msg/MarkMsgAsRead.ts b/src/onebot/action/msg/MarkMsgAsRead.ts index 01f1e8ba..c55987bd 100644 --- a/src/onebot/action/msg/MarkMsgAsRead.ts +++ b/src/onebot/action/msg/MarkMsgAsRead.ts @@ -5,50 +5,50 @@ import { NTQQFriendApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - user_id: { type: ['number', 'string'] }, - group_id: { type: ['number', 'string'] } - } + type: 'object', + properties: { + user_id: { type: ['number', 'string'] }, + group_id: { type: ['number', 'string'] } + } } as const satisfies JSONSchema; type PlayloadType = FromSchema; class MarkMsgAsRead extends BaseAction { - async getPeer(payload: PlayloadType): Promise { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; - if (payload.user_id) { - const peerUid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - if (!peerUid) { - throw `私聊${payload.user_id}不存在`; - } - const isBuddy = await NTQQFriendApi.isBuddy(peerUid); - return { chatType: isBuddy ? ChatType.friend : ChatType.temp, peerUid }; + async getPeer(payload: PlayloadType): Promise { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; + if (payload.user_id) { + const peerUid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + if (!peerUid) { + throw `私聊${payload.user_id}不存在`; + } + const isBuddy = await NTQQFriendApi.isBuddy(peerUid); + return { chatType: isBuddy ? ChatType.friend : ChatType.temp, peerUid }; + } + if (!payload.group_id) { + throw '缺少参数 group_id 或 user_id'; + } + return { chatType: ChatType.group, peerUid: payload.group_id.toString() }; } - if (!payload.group_id) { - throw '缺少参数 group_id 或 user_id'; + protected async _handle(payload: PlayloadType): Promise { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + // 调用API + const ret = await NTQQMsgApi.setMsgRead(await this.getPeer(payload)); + if (ret.result != 0) { + throw ('设置已读失败,' + ret.errMsg); + } + return null; } - return { chatType: ChatType.group, peerUid: payload.group_id.toString() }; - } - protected async _handle(payload: PlayloadType): Promise { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - // 调用API - const ret = await NTQQMsgApi.setMsgRead(await this.getPeer(payload)); - if (ret.result != 0) { - throw ('设置已读失败,' + ret.errMsg); - } - return null; - } } // 以下为非标准实现 export class MarkPrivateMsgAsRead extends MarkMsgAsRead { - PayloadSchema = SchemaData; - actionName = ActionName.MarkPrivateMsgAsRead; + PayloadSchema = SchemaData; + actionName = ActionName.MarkPrivateMsgAsRead; } export class MarkGroupMsgAsRead extends MarkMsgAsRead { - PayloadSchema = SchemaData; - actionName = ActionName.MarkGroupMsgAsRead; + PayloadSchema = SchemaData; + actionName = ActionName.MarkGroupMsgAsRead; } @@ -57,19 +57,19 @@ interface Payload { } export class GoCQHTTPMarkMsgAsRead extends BaseAction { - actionName = ActionName.GoCQHTTP_MarkMsgAsRead; + actionName = ActionName.GoCQHTTP_MarkMsgAsRead; - protected async _handle(payload: Payload): Promise { - return null; - } + protected async _handle(payload: Payload): Promise { + return null; + } } export class MarkAllMsgAsRead extends BaseAction { - actionName = ActionName._MarkAllMsgAsRead; + actionName = ActionName._MarkAllMsgAsRead; - protected async _handle(payload: Payload): Promise { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - await NTQQMsgApi.markallMsgAsRead(); - return null; - } + protected async _handle(payload: Payload): Promise { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + await NTQQMsgApi.markallMsgAsRead(); + return null; + } } diff --git a/src/onebot/action/msg/SendMsg/check-send-message.ts b/src/onebot/action/msg/SendMsg/check-send-message.ts index 76100a5e..ddbc0a2b 100644 --- a/src/onebot/action/msg/SendMsg/check-send-message.ts +++ b/src/onebot/action/msg/SendMsg/check-send-message.ts @@ -1,36 +1,36 @@ import { OB11MessageData } from '@/onebot/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; + function checkUri(uri: string): boolean { + const pattern = /^(file:\/\/|http:\/\/|https:\/\/|base64:\/\/)/; + return pattern.test(uri); } - } - return 200; + + 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/onebot/action/msg/SendMsg/create-send-elements.ts b/src/onebot/action/msg/SendMsg/create-send-elements.ts index 3ea27810..09082dab 100644 --- a/src/onebot/action/msg/SendMsg/create-send-elements.ts +++ b/src/onebot/action/msg/SendMsg/create-send-elements.ts @@ -10,23 +10,23 @@ export type MessageContext = { peer: Peer } async function handleOb11FileLikeMessage( - coreContext: NapCatCore, - { data: inputdata }: OB11MessageFileBase, - { deleteAfterSentFiles }: MessageContext + coreContext: NapCatCore, + { data: inputdata }: OB11MessageFileBase, + { deleteAfterSentFiles }: MessageContext ) { - //有的奇怪的框架将url作为参数 而不是file 此时优先url 同时注意可能传入的是非file://开头的目录 By Mlikiowa - const { path, isLocal, fileName, errMsg, success } = (await uri2local(coreContext.NapCatTempPath, inputdata?.url || inputdata.file)); + //有的奇怪的框架将url作为参数 而不是file 此时优先url 同时注意可能传入的是非file://开头的目录 By Mlikiowa + const { path, isLocal, fileName, errMsg, success } = (await uri2local(coreContext.NapCatTempPath, inputdata?.url || inputdata.file)); - if (!success) { - coreContext.context.logger.logError('文件下载失败', errMsg); - throw Error('文件下载失败' + errMsg); - } + if (!success) { + coreContext.context.logger.logError('文件下载失败', errMsg); + throw Error('文件下载失败' + errMsg); + } - if (!isLocal) { // 只删除http和base64转过来的文件 - deleteAfterSentFiles.push(path); - } + if (!isLocal) { // 只删除http和base64转过来的文件 + deleteAfterSentFiles.push(path); + } - return { path, fileName: inputdata.name || fileName }; + return { path, fileName: inputdata.name || fileName }; } const _handlers: { @@ -38,149 +38,150 @@ const _handlers: { context: MessageContext ) => Promise } = { - [OB11MessageDataType.text]: async (coreContext, { data: { text } }) => SendMsgElementConstructor.text(coreContext, text), + [OB11MessageDataType.text]: async (coreContext, { data: { text } }) => SendMsgElementConstructor.text(coreContext, text), - [OB11MessageDataType.at]: async (coreContext, { data: { qq: atQQ } }, context) => { - if (!context.peer) return undefined; + [OB11MessageDataType.at]: async (coreContext, { data: { qq: atQQ } }, context) => { + if (!context.peer) return undefined; - if (atQQ === 'all') return SendMsgElementConstructor.at(coreContext, atQQ, atQQ, AtType.atAll, '全体成员'); + if (atQQ === 'all') return SendMsgElementConstructor.at(coreContext, atQQ, atQQ, AtType.atAll, '全体成员'); - // then the qq is a group member - // Mlikiowa V2.0.0 Refactor Todo - let uid = await coreContext.getApiContext().UserApi.getUidByUin(atQQ); - if (!uid) throw new Error('Get Uid Error') - return SendMsgElementConstructor.at(coreContext, atQQ, uid, AtType.atUser, ""); - }, - [OB11MessageDataType.reply]: async (coreContext, { data: { id } }) => { - const replyMsgM = MessageUnique.getMsgIdAndPeerByShortId(parseInt(id)); - if (!replyMsgM) { - coreContext.context.logger.logWarn('回复消息不存在', id); - return undefined; - } - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const replyMsg = (await NTQQMsgApi.getMsgsByMsgId(replyMsgM?.Peer!, [replyMsgM?.MsgId!])).msgList[0]; - return replyMsg ? - SendMsgElementConstructor.reply(coreContext, replyMsg.msgSeq, replyMsg.msgId, replyMsg.senderUin!, replyMsg.senderUin!) : - undefined; - }, + // then the qq is a group member + // Mlikiowa V2.0.0 Refactor Todo + const uid = await coreContext.getApiContext().UserApi.getUidByUin(atQQ); + if (!uid) throw new Error('Get Uid Error'); + return SendMsgElementConstructor.at(coreContext, atQQ, uid, AtType.atUser, ""); + }, + [OB11MessageDataType.reply]: async (coreContext, { data: { id } }) => { + const replyMsgM = MessageUnique.getMsgIdAndPeerByShortId(parseInt(id)); + if (!replyMsgM) { + coreContext.context.logger.logWarn('回复消息不存在', id); + return undefined; + } + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const replyMsg = (await NTQQMsgApi.getMsgsByMsgId( + replyMsgM.Peer, [replyMsgM.MsgId!])).msgList[0]; + return replyMsg ? + SendMsgElementConstructor.reply(coreContext, replyMsg.msgSeq, replyMsg.msgId, replyMsg.senderUin!, replyMsg.senderUin!) : + undefined; + }, - [OB11MessageDataType.face]: async (coreContext, { data: { id } }) => SendMsgElementConstructor.face(coreContext, parseInt(id)), + [OB11MessageDataType.face]: async (coreContext, { data: { id } }) => SendMsgElementConstructor.face(coreContext, parseInt(id)), - [OB11MessageDataType.mface]: async (coreContext, { - data: { - emoji_package_id, emoji_id, key, summary - } - }) => SendMsgElementConstructor.mface(coreContext, emoji_package_id, emoji_id, key, summary), + [OB11MessageDataType.mface]: async (coreContext, { + data: { + emoji_package_id, emoji_id, key, summary + } + }) => SendMsgElementConstructor.mface(coreContext, emoji_package_id, emoji_id, key, summary), - // File service - [OB11MessageDataType.image]: async (coreContext, sendMsg, context) => { - const PicEle = await SendMsgElementConstructor.pic( - coreContext, - (await handleOb11FileLikeMessage(coreContext, sendMsg, context)).path, - sendMsg.data.summary || '', - sendMsg.data.subType || 0 - ); - context.deleteAfterSentFiles.push(PicEle.picElement.sourcePath); - return PicEle; - }, // currently not supported - [OB11MessageDataType.file]: async (coreContext, sendMsg, context) => { - const { path, fileName } = await handleOb11FileLikeMessage(coreContext, sendMsg, context); - //logDebug('发送文件', path, fileName); - const FileEle = await SendMsgElementConstructor.file(coreContext, path, fileName); - // 清除Upload的应该 - // context.deleteAfterSentFiles.push(fileName || FileEle.fileElement.filePath); - return FileEle; - }, + // File service + [OB11MessageDataType.image]: async (coreContext, sendMsg, context) => { + const PicEle = await SendMsgElementConstructor.pic( + coreContext, + (await handleOb11FileLikeMessage(coreContext, sendMsg, context)).path, + sendMsg.data.summary || '', + sendMsg.data.subType || 0 + ); + context.deleteAfterSentFiles.push(PicEle.picElement.sourcePath); + return PicEle; + }, // currently not supported + [OB11MessageDataType.file]: async (coreContext, sendMsg, context) => { + const { path, fileName } = await handleOb11FileLikeMessage(coreContext, sendMsg, context); + //logDebug('发送文件', path, fileName); + const FileEle = await SendMsgElementConstructor.file(coreContext, path, fileName); + // 清除Upload的应该 + // context.deleteAfterSentFiles.push(fileName || FileEle.fileElement.filePath); + return FileEle; + }, - [OB11MessageDataType.video]: async (coreContext, sendMsg, context) => { - const { path, fileName } = await handleOb11FileLikeMessage(coreContext, sendMsg, context); + [OB11MessageDataType.video]: async (coreContext, sendMsg, context) => { + const { path, fileName } = await handleOb11FileLikeMessage(coreContext, sendMsg, context); - //logDebug('发送视频', path, fileName); - let thumb = sendMsg.data.thumb; - if (thumb) { - const uri2LocalRes = await uri2local(coreContext.NapCatTempPath, thumb); - if (uri2LocalRes.success) thumb = uri2LocalRes.path; - } - const videoEle = await SendMsgElementConstructor.video(coreContext, path, fileName, thumb); - //未测试 - context.deleteAfterSentFiles.push(videoEle.videoElement.filePath); - return videoEle; - }, + //logDebug('发送视频', path, fileName); + let thumb = sendMsg.data.thumb; + if (thumb) { + const uri2LocalRes = await uri2local(coreContext.NapCatTempPath, thumb); + if (uri2LocalRes.success) thumb = uri2LocalRes.path; + } + const videoEle = await SendMsgElementConstructor.video(coreContext, path, fileName, thumb); + //未测试 + context.deleteAfterSentFiles.push(videoEle.videoElement.filePath); + return videoEle; + }, - [OB11MessageDataType.voice]: async (coreContext, sendMsg, context) => SendMsgElementConstructor.ptt(coreContext, (await handleOb11FileLikeMessage(coreContext, sendMsg, context)).path), + [OB11MessageDataType.voice]: async (coreContext, sendMsg, context) => SendMsgElementConstructor.ptt(coreContext, (await handleOb11FileLikeMessage(coreContext, sendMsg, context)).path), - [OB11MessageDataType.json]: async (coreContext, { data: { data } }) => SendMsgElementConstructor.ark(coreContext, data), + [OB11MessageDataType.json]: async (coreContext, { data: { data } }) => SendMsgElementConstructor.ark(coreContext, data), - [OB11MessageDataType.dice]: async (coreContext, { data: { result } }) => SendMsgElementConstructor.dice(coreContext, result), + [OB11MessageDataType.dice]: async (coreContext, { data: { result } }) => SendMsgElementConstructor.dice(coreContext, result), - [OB11MessageDataType.RPS]: async (coreContext, { data: { result } }) => SendMsgElementConstructor.rps(coreContext, result), + [OB11MessageDataType.RPS]: async (coreContext, { data: { result } }) => SendMsgElementConstructor.rps(coreContext, result), - [OB11MessageDataType.markdown]: async (coreContext, { data: { content } }) => SendMsgElementConstructor.markdown(coreContext, content), + [OB11MessageDataType.markdown]: async (coreContext, { data: { content } }) => SendMsgElementConstructor.markdown(coreContext, content), - [OB11MessageDataType.music]: async (coreContext, { data }) => { + [OB11MessageDataType.music]: async (coreContext, { data }) => { // 保留, 直到...找到更好的解决方案 - if (data.type === 'custom') { - if (!data.url) { - coreContext.context.logger.logError('自定义音卡缺少参数url'); - return undefined; - } - if (!data.audio) { - coreContext.context.logger.logError('自定义音卡缺少参数audio'); - return undefined; - } - if (!data.title) { - coreContext.context.logger.logError('自定义音卡缺少参数title'); - return undefined; - } - } else { - if (!['qq', '163'].includes(data.type)) { - coreContext.context.logger.logError('音乐卡片type错误, 只支持qq、163、custom,当前type:', data.type); - return undefined; - } - if (!data.id) { - coreContext.context.logger.logError('音乐卡片缺少参数id'); - return undefined; - } + if (data.type === 'custom') { + if (!data.url) { + coreContext.context.logger.logError('自定义音卡缺少参数url'); + return undefined; + } + if (!data.audio) { + coreContext.context.logger.logError('自定义音卡缺少参数audio'); + return undefined; + } + if (!data.title) { + coreContext.context.logger.logError('自定义音卡缺少参数title'); + return undefined; + } + } else { + if (!['qq', '163'].includes(data.type)) { + coreContext.context.logger.logError('音乐卡片type错误, 只支持qq、163、custom,当前type:', data.type); + return undefined; + } + if (!data.id) { + coreContext.context.logger.logError('音乐卡片缺少参数id'); + return undefined; + } + } + + let postData: IdMusicSignPostData | CustomMusicSignPostData; + if (data.type === 'custom' && data.content) { + const { content, ...others } = data; + postData = { singer: content, ...others }; + } else { + postData = data; + } + // Mlikiowa V2.0.0 Refactor Todo + const signUrl = ""; + if (!signUrl) { + if (data.type === 'qq') { + //const musicJson = (await SignMusicWrapper(data.id.toString())).data.arkResult.slice(0, -1); + //return SendMsgElementConstructor.ark(musicJson); + } + throw Error('音乐消息签名地址未配置'); + } + try { + const musicJson = await RequestUtil.HttpGetJson(signUrl, 'POST', postData); + return SendMsgElementConstructor.ark(coreContext, musicJson); + } catch (e) { + coreContext.context.logger.logError('生成音乐消息失败', e); + } + }, + + [OB11MessageDataType.node]: async (coreContext) => undefined, + + [OB11MessageDataType.forward]: async (coreContext) => undefined, + + [OB11MessageDataType.xml]: async (coreContext) => undefined, + + [OB11MessageDataType.poke]: async (coreContext) => undefined, + + [OB11MessageDataType.Location]: async (coreContext) => { + return SendMsgElementConstructor.location(coreContext); + }, + [OB11MessageDataType.miniapp]: function (CoreContext: NapCatCore, sendMsg: never, context: MessageContext): Promise { + throw new Error('Function not implemented.'); } - - let postData: IdMusicSignPostData | CustomMusicSignPostData; - if (data.type === 'custom' && data.content) { - const { content, ...others } = data; - postData = { singer: content, ...others }; - } else { - postData = data; - } - // Mlikiowa V2.0.0 Refactor Todo - const signUrl = ""; - if (!signUrl) { - if (data.type === 'qq') { - //const musicJson = (await SignMusicWrapper(data.id.toString())).data.arkResult.slice(0, -1); - //return SendMsgElementConstructor.ark(musicJson); - } - throw Error('音乐消息签名地址未配置'); - } - try { - const musicJson = await RequestUtil.HttpGetJson(signUrl, 'POST', postData); - return SendMsgElementConstructor.ark(coreContext, musicJson); - } catch (e) { - coreContext.context.logger.logError('生成音乐消息失败', e); - } - }, - - [OB11MessageDataType.node]: async (coreContext) => undefined, - - [OB11MessageDataType.forward]: async (coreContext) => undefined, - - [OB11MessageDataType.xml]: async (coreContext) => undefined, - - [OB11MessageDataType.poke]: async (coreContext) => undefined, - - [OB11MessageDataType.Location]: async (coreContext) => { - return SendMsgElementConstructor.location(coreContext); - }, - [OB11MessageDataType.miniapp]: function (CoreContext: NapCatCore, sendMsg: never, context: MessageContext): Promise { - throw new Error('Function not implemented.'); - } }; const handlers = <{ @@ -192,46 +193,46 @@ const handlers = <{ }>_handlers; export default async function createSendElements( - CoreContext: NapCatCore, - messageData: OB11MessageData[], - peer: Peer, - ignoreTypes: OB11MessageDataType[] = [] + CoreContext: NapCatCore, + messageData: OB11MessageData[], + peer: Peer, + ignoreTypes: OB11MessageDataType[] = [] ) { - const deleteAfterSentFiles: string[] = []; - const callResultList: Array> = []; - for (const sendMsg of messageData) { - if (ignoreTypes.includes(sendMsg.type)) { - continue; + const deleteAfterSentFiles: string[] = []; + const callResultList: Array> = []; + for (const sendMsg of messageData) { + if (ignoreTypes.includes(sendMsg.type)) { + continue; + } + const callResult = handlers[sendMsg.type]( + CoreContext, + sendMsg, + { peer, deleteAfterSentFiles } + )?.catch(undefined); + callResultList.push(callResult); } - const callResult = handlers[sendMsg.type]( - CoreContext, - sendMsg, - { peer, deleteAfterSentFiles } - )?.catch(undefined); - callResultList.push(callResult); - } - const ret = await Promise.all(callResultList); - const sendElements: SendMessageElement[] = ret.filter(ele => ele) as SendMessageElement[]; - return { sendElements, deleteAfterSentFiles }; + const ret = await Promise.all(callResultList); + const sendElements: SendMessageElement[] = ret.filter(ele => ele) as SendMessageElement[]; + return { sendElements, deleteAfterSentFiles }; } export async function createSendElementsParallel( - CoreContext: NapCatCore, - messageData: OB11MessageData[], - peer: Peer, - ignoreTypes: OB11MessageDataType[] = [] + CoreContext: NapCatCore, + messageData: OB11MessageData[], + peer: Peer, + ignoreTypes: OB11MessageDataType[] = [] ) { - const deleteAfterSentFiles: string[] = []; - const sendElements = ( + const deleteAfterSentFiles: string[] = []; + const sendElements = ( await Promise.all( - messageData.map(async sendMsg => ignoreTypes.includes(sendMsg.type) ? - undefined : - handlers[sendMsg.type](CoreContext, sendMsg, { peer, deleteAfterSentFiles })) + messageData.map(async sendMsg => ignoreTypes.includes(sendMsg.type) ? + undefined : + handlers[sendMsg.type](CoreContext, sendMsg, { peer, deleteAfterSentFiles })) ).then( - results => results.filter( - element => element !== undefined - ) + results => results.filter( + element => element !== undefined + ) ) ); - return { sendElements, deleteAfterSentFiles }; + return { sendElements, deleteAfterSentFiles }; } diff --git a/src/onebot/action/msg/SendMsg/handle-forward-node.ts b/src/onebot/action/msg/SendMsg/handle-forward-node.ts index d29f8e36..014f54fa 100644 --- a/src/onebot/action/msg/SendMsg/handle-forward-node.ts +++ b/src/onebot/action/msg/SendMsg/handle-forward-node.ts @@ -2,118 +2,118 @@ import { ChatType, ElementType, NapCatCore, Peer, RawMessage, SendMessageElement import { MessageUnique } from '@/common/utils/MessageUnique'; import { OB11MessageDataType, OB11MessageNode } from '@/onebot/types'; import createSendElements from './create-send-elements'; -import { normalize, sendMsg } from "../SendMsg/index" +import { normalize, sendMsg } from "../SendMsg/index"; async function cloneMsg(coreContext: NapCatCore, msg: RawMessage): Promise { - const selfPeer = { - chatType: ChatType.friend, - peerUid: coreContext.selfInfo.uid - }; - const logger = coreContext.context.logger; - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - //logDebug('克隆的目标消息', msg); + const selfPeer = { + chatType: ChatType.friend, + peerUid: coreContext.selfInfo.uid + }; + const logger = coreContext.context.logger; + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + //logDebug('克隆的目标消息', msg); - const sendElements: SendMessageElement[] = []; + const sendElements: SendMessageElement[] = []; - for (const element of msg.elements) { - sendElements.push(element as SendMessageElement); - } + for (const element of msg.elements) { + sendElements.push(element as SendMessageElement); + } - if (sendElements.length === 0) { - logger.logDebug('需要clone的消息无法解析,将会忽略掉', msg); - } - try { - const nodeMsg = await NTQQMsgApi.sendMsg(selfPeer, sendElements, true); - return nodeMsg; - } catch (e) { - logger.logError(e, '克隆转发消息失败,将忽略本条消息', msg); - } + if (sendElements.length === 0) { + logger.logDebug('需要clone的消息无法解析,将会忽略掉', msg); + } + try { + const nodeMsg = await NTQQMsgApi.sendMsg(selfPeer, sendElements, true); + return nodeMsg; + } catch (e) { + logger.logError(e, '克隆转发消息失败,将忽略本条消息', msg); + } } export async function handleForwardNode(coreContext: NapCatCore, destPeer: Peer, messageNodes: OB11MessageNode[]): Promise { - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const selfPeer = { - chatType: ChatType.friend, - peerUid: coreContext.selfInfo.uid - }; - let nodeMsgIds: string[] = []; - const logger = coreContext.context.logger; - for (const messageNode of messageNodes) { - const nodeId = messageNode.data.id; - if (nodeId) { - //对Mgsid和OB11ID混用情况兜底 - const nodeMsg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(nodeId)) || MessageUnique.getPeerByMsgId(nodeId); - if (!nodeMsg) { - logger.logError('转发消息失败,未找到消息', nodeId); - continue; - } - nodeMsgIds.push(nodeMsg.MsgId); + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const selfPeer = { + chatType: ChatType.friend, + peerUid: coreContext.selfInfo.uid + }; + let nodeMsgIds: string[] = []; + const logger = coreContext.context.logger; + for (const messageNode of messageNodes) { + const nodeId = messageNode.data.id; + if (nodeId) { + //对Mgsid和OB11ID混用情况兜底 + const nodeMsg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(nodeId)) || MessageUnique.getPeerByMsgId(nodeId); + if (!nodeMsg) { + logger.logError('转发消息失败,未找到消息', nodeId); + continue; + } + nodeMsgIds.push(nodeMsg.MsgId); + } else { + // 自定义的消息 + try { + const OB11Data = normalize(messageNode.data.content); + //筛选node消息 + const isNodeMsg = OB11Data.filter(e => e.type === OB11MessageDataType.node).length;//找到子转发消息 + if (isNodeMsg !== 0) { + if (isNodeMsg !== OB11Data.length) { logger.logError('子消息中包含非node消息 跳过不合法部分'); continue; } + const nodeMsg = await handleForwardNode(coreContext, selfPeer, OB11Data.filter(e => e.type === OB11MessageDataType.node)); + if (nodeMsg) { nodeMsgIds.push(nodeMsg.msgId); MessageUnique.createMsg(selfPeer, nodeMsg.msgId); } + //完成子卡片生成跳过后续 + continue; + } + const { sendElements } = await createSendElements(coreContext,OB11Data, destPeer); + //拆分消息 + const MixElement = sendElements.filter(element => element.elementType !== ElementType.FILE && element.elementType !== ElementType.VIDEO); + const SingleElement = sendElements.filter(element => element.elementType === ElementType.FILE || element.elementType === ElementType.VIDEO).map(e => [e]); + const AllElement: SendMessageElement[][] = [MixElement, ...SingleElement].filter(e => e !== undefined && e.length !== 0); + const MsgNodeList: Promise[] = []; + for (const sendElementsSplitElement of AllElement) { + MsgNodeList.push(sendMsg(coreContext,selfPeer, sendElementsSplitElement, [], true).catch(e => new Promise((resolve, reject) => { resolve(undefined); }))); + } + (await Promise.allSettled(MsgNodeList)).map((result) => { + if (result.status === 'fulfilled' && result.value) { + nodeMsgIds.push(result.value.msgId); + MessageUnique.createMsg(selfPeer, result.value.msgId); + } + }); + } catch (e) { + logger.logDebug('生成转发消息节点失败', e); + } + } + } + const nodeMsgArray: Array = []; + let srcPeer: Peer | undefined = undefined; + let needSendSelf = false; + //检测是否处于同一个Peer 不在同一个peer则全部消息由自身发送 + for (const msgId of nodeMsgIds) { + const nodeMsgPeer = MessageUnique.getPeerByMsgId(msgId); + if (!nodeMsgPeer) { + logger.logError('转发消息失败,未找到消息', msgId); + continue; + } + const nodeMsg = (await NTQQMsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0]; + srcPeer = srcPeer ?? { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid }; + if (srcPeer.peerUid !== nodeMsg.peerUid) { + needSendSelf = true; + } + nodeMsgArray.push(nodeMsg); + } + nodeMsgIds = nodeMsgArray.map(msg => msg.msgId); + let retMsgIds: string[] = []; + if (needSendSelf) { + for (const [index, msg] of nodeMsgArray.entries()) { + if (msg.peerUid === coreContext.selfInfo.uid) continue; + const ClonedMsg = await cloneMsg(coreContext, msg); + if (ClonedMsg) retMsgIds.push(ClonedMsg.msgId); + } } else { - // 自定义的消息 - try { - let OB11Data = normalize(messageNode.data.content); - //筛选node消息 - let isNodeMsg = OB11Data.filter(e => e.type === OB11MessageDataType.node).length;//找到子转发消息 - if (isNodeMsg !== 0) { - if (isNodeMsg !== OB11Data.length) { logger.logError('子消息中包含非node消息 跳过不合法部分'); continue; } - const nodeMsg = await handleForwardNode(coreContext, selfPeer, OB11Data.filter(e => e.type === OB11MessageDataType.node)); - if (nodeMsg) { nodeMsgIds.push(nodeMsg.msgId); MessageUnique.createMsg(selfPeer, nodeMsg.msgId) }; - //完成子卡片生成跳过后续 - continue; - } - const { sendElements } = await createSendElements(coreContext,OB11Data, destPeer); - //拆分消息 - let MixElement = sendElements.filter(element => element.elementType !== ElementType.FILE && element.elementType !== ElementType.VIDEO); - let SingleElement = sendElements.filter(element => element.elementType === ElementType.FILE || element.elementType === ElementType.VIDEO).map(e => [e]); - let AllElement: SendMessageElement[][] = [MixElement, ...SingleElement].filter(e => e !== undefined && e.length !== 0); - const MsgNodeList: Promise[] = []; - for (const sendElementsSplitElement of AllElement) { - MsgNodeList.push(sendMsg(coreContext,selfPeer, sendElementsSplitElement, [], true).catch(e => new Promise((resolve, reject) => { resolve(undefined) }))); - } - (await Promise.allSettled(MsgNodeList)).map((result) => { - if (result.status === 'fulfilled' && result.value) { - nodeMsgIds.push(result.value.msgId); - MessageUnique.createMsg(selfPeer, result.value.msgId); - } - }); - } catch (e) { - logger.logDebug('生成转发消息节点失败', e); - } + retMsgIds = nodeMsgIds; } - } - const nodeMsgArray: Array = []; - let srcPeer: Peer | undefined = undefined; - let needSendSelf = false; - //检测是否处于同一个Peer 不在同一个peer则全部消息由自身发送 - for (let msgId of nodeMsgIds) { - const nodeMsgPeer = MessageUnique.getPeerByMsgId(msgId); - if (!nodeMsgPeer) { - logger.logError('转发消息失败,未找到消息', msgId); - continue; + if (nodeMsgIds.length === 0) throw Error('转发消息失败,生成节点为空'); + try { + logger.logDebug('开发转发', srcPeer, destPeer, nodeMsgIds); + return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, nodeMsgIds); + } catch (e) { + logger.logError('forward failed', e); + return null; } - const nodeMsg = (await NTQQMsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0]; - srcPeer = srcPeer ?? { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid }; - if (srcPeer.peerUid !== nodeMsg.peerUid) { - needSendSelf = true; - } - nodeMsgArray.push(nodeMsg); - } - nodeMsgIds = nodeMsgArray.map(msg => msg.msgId); - let retMsgIds: string[] = []; - if (needSendSelf) { - for (const [index, msg] of nodeMsgArray.entries()) { - if (msg.peerUid === coreContext.selfInfo.uid) continue; - const ClonedMsg = await cloneMsg(coreContext, msg); - if (ClonedMsg) retMsgIds.push(ClonedMsg.msgId); - } - } else { - retMsgIds = nodeMsgIds; - } - if (nodeMsgIds.length === 0) throw Error('转发消息失败,生成节点为空'); - try { - logger.logDebug('开发转发', srcPeer, destPeer, nodeMsgIds); - return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, nodeMsgIds); - } catch (e) { - logger.logError('forward failed', e); - return null; - } } diff --git a/src/onebot/action/msg/SendMsg/index.ts b/src/onebot/action/msg/SendMsg/index.ts index e0e64da8..e41765ae 100644 --- a/src/onebot/action/msg/SendMsg/index.ts +++ b/src/onebot/action/msg/SendMsg/index.ts @@ -1,10 +1,10 @@ import { - OB11MessageData, - OB11MessageDataType, - OB11MessageMixType, - OB11MessageNode, - OB11PostSendMsg + OB11MessageData, + OB11MessageDataType, + OB11MessageMixType, + OB11MessageNode, + OB11PostSendMsg } from '@/onebot/types'; import { ActionName, BaseCheckResult } from '@/onebot/action/types'; import fs from 'node:fs'; @@ -26,147 +26,147 @@ export enum ContextMode { } // 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]; + return typeof message === 'string' ? ( + autoEscape ? + [{ type: OB11MessageDataType.text, data: { text: message } }] : + decodeCQCode(message) + ) : Array.isArray(message) ? message : [message]; } export { createSendElements }; export async function sendMsg(coreContext: NapCatCore, peer: Peer, sendElements: SendMessageElement[], deleteAfterSentFiles: string[], waitComplete = true) { - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const logger = coreContext.context.logger; - if (!sendElements.length) { - throw ('消息体无法解析, 请检查是否发送了不支持的消息类型'); - } - let totalSize = 0; - let timeout = 10000; - try { - for (const fileElement of sendElements) { - if (fileElement.elementType === ElementType.PTT) { - totalSize += fs.statSync(fileElement.pttElement.filePath).size; - } - if (fileElement.elementType === ElementType.FILE) { - totalSize += fs.statSync(fileElement.fileElement.filePath).size; - } - if (fileElement.elementType === ElementType.VIDEO) { - totalSize += fs.statSync(fileElement.videoElement.filePath).size; - } - if (fileElement.elementType === ElementType.PIC) { - totalSize += fs.statSync(fileElement.picElement.sourcePath).size; - } + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const logger = coreContext.context.logger; + if (!sendElements.length) { + throw ('消息体无法解析, 请检查是否发送了不支持的消息类型'); } - //且 PredictTime ((totalSize / 1024 / 512) * 1000)不等于Nan - const PredictTime = totalSize / 1024 / 256 * 1000; - if (!Number.isNaN(PredictTime)) { - timeout += PredictTime;// 10S Basic Timeout + PredictTime( For File 512kb/s ) + let totalSize = 0; + let timeout = 10000; + try { + for (const fileElement of sendElements) { + if (fileElement.elementType === ElementType.PTT) { + totalSize += fs.statSync(fileElement.pttElement.filePath).size; + } + if (fileElement.elementType === ElementType.FILE) { + totalSize += fs.statSync(fileElement.fileElement.filePath).size; + } + if (fileElement.elementType === ElementType.VIDEO) { + totalSize += fs.statSync(fileElement.videoElement.filePath).size; + } + if (fileElement.elementType === ElementType.PIC) { + totalSize += fs.statSync(fileElement.picElement.sourcePath).size; + } + } + //且 PredictTime ((totalSize / 1024 / 512) * 1000)不等于Nan + const PredictTime = totalSize / 1024 / 256 * 1000; + if (!Number.isNaN(PredictTime)) { + timeout += PredictTime;// 10S Basic Timeout + PredictTime( For File 512kb/s ) + } + } catch (e) { + logger.logError('发送消息计算预计时间异常', e); } - } catch (e) { - logger.logError('发送消息计算预计时间异常', e); - } - const returnMsg = await NTQQMsgApi.sendMsg(peer, sendElements, waitComplete, timeout); - try { + const returnMsg = await NTQQMsgApi.sendMsg(peer, sendElements, waitComplete, timeout); + try { returnMsg!.id = MessageUnique.createMsg({ chatType: peer.chatType, guildId: '', peerUid: peer.peerUid }, returnMsg!.msgId); - } catch (e: any) { - logger.logDebug('发送消息id获取失败', e); + } catch (e: any) { + logger.logDebug('发送消息id获取失败', e); returnMsg!.id = 0; - } - deleteAfterSentFiles.map((f) => { fsPromise.unlink(f).then().catch(e => logger.logError('发送消息删除文件失败', e)); }); - return returnMsg; + } + deleteAfterSentFiles.map((f) => { fsPromise.unlink(f).then().catch(e => logger.logError('发送消息删除文件失败', e)); }); + return returnMsg; } async function createContext(coreContext: NapCatCore, payload: OB11PostSendMsg, contextMode: ContextMode): Promise { - // 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. - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - const NTQQUserApi = coreContext.getApiContext().UserApi; - if ((contextMode === ContextMode.Group || contextMode === ContextMode.Normal) && payload.group_id) { - const group = (await NTQQGroupApi.getGroups()).find(e => e.groupCode == payload.group_id?.toString()) - return { - chatType: ChatType.group, - peerUid: payload.group_id.toString() - }; - } - if ((contextMode === ContextMode.Private || contextMode === ContextMode.Normal) && payload.user_id) { - const Uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - const isBuddy = await NTQQFriendApi.isBuddy(Uid!); - //console.log("[调试代码] UIN:", payload.user_id, " UID:", Uid, " IsBuddy:", isBuddy); - return { - chatType: isBuddy ? ChatType.friend : ChatType.temp, - peerUid: Uid! - }; - } - throw '请指定 group_id 或 user_id'; + // 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. + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + const NTQQUserApi = coreContext.getApiContext().UserApi; + if ((contextMode === ContextMode.Group || contextMode === ContextMode.Normal) && payload.group_id) { + const group = (await NTQQGroupApi.getGroups()).find(e => e.groupCode == payload.group_id?.toString()); + return { + chatType: ChatType.group, + peerUid: payload.group_id.toString() + }; + } + if ((contextMode === ContextMode.Private || contextMode === ContextMode.Normal) && payload.user_id) { + const Uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + const isBuddy = await NTQQFriendApi.isBuddy(Uid!); + //console.log("[调试代码] UIN:", payload.user_id, " UID:", Uid, " IsBuddy:", isBuddy); + return { + chatType: isBuddy ? ChatType.friend : ChatType.temp, + peerUid: Uid! + }; + } + 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; + if (Array.isArray(payload.message)) { + return payload.message.filter(msg => msg.type == msgType).length; + } + return 0; } export class SendMsg extends BaseAction { - actionName = ActionName.SendMsg; - contextMode = ContextMode.Normal; + actionName = ActionName.SendMsg; + contextMode = ContextMode.Normal; - protected async check(payload: OB11PostSendMsg): Promise { - const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; - const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const messages = normalize(payload.message); - const nodeElementLength = getSpecialMsgNum(payload, OB11MessageDataType.node); - if (nodeElementLength > 0 && nodeElementLength != messages.length) { - return { valid: false, message: '转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素' }; + protected async check(payload: OB11PostSendMsg): Promise { + const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; + const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const messages = normalize(payload.message); + const nodeElementLength = getSpecialMsgNum(payload, OB11MessageDataType.node); + if (nodeElementLength > 0 && nodeElementLength != 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}不存在` }; + // } + if (payload.user_id && payload.message_type !== 'group') { + const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); + const isBuddy = await NTQQFriendApi.isBuddy(uid!); + // 此处有问题 + if (!isBuddy) { + //return { valid: false, message: '异常消息' }; + } + } + return { valid: true }; } - // if (payload.message_type !== 'private' && payload.group_id && !(await getGroup(payload.group_id))) { - // return { valid: false, message: `群${payload.group_id}不存在` }; - // } - if (payload.user_id && payload.message_type !== 'group') { - const uid = await NTQQUserApi.getUidByUin(payload.user_id.toString()); - const isBuddy = await NTQQFriendApi.isBuddy(uid!); - // 此处有问题 - if (!isBuddy) { - //return { valid: false, message: '异常消息' }; - } + + protected async _handle(payload: OB11PostSendMsg): Promise<{ message_id: number }> { + const peer = await createContext(this.CoreContext, payload, this.contextMode); + + const messages = normalize( + payload.message, + payload.auto_escape === true || payload.auto_escape === 'true' + ); + + if (getSpecialMsgNum(payload, OB11MessageDataType.node)) { + const returnMsg = await handleForwardNode(this.CoreContext,peer, messages as OB11MessageNode[]); + if (returnMsg) { + const msgShortId = MessageUnique.createMsg({ guildId: '', peerUid: peer.peerUid, chatType: peer.chatType }, returnMsg!.msgId); + return { message_id: msgShortId! }; + } else { + throw Error('发送转发消息失败'); + } + } else { + // if (getSpecialMsgNum(payload, OB11MessageDataType.music)) { + // const music: OB11MessageCustomMusic = messages[0] as OB11MessageCustomMusic; + // if (music) { + // } + // } + } + // log("send msg:", peer, sendElements) + + const { sendElements, deleteAfterSentFiles } = await createSendElements(this.CoreContext, messages, peer); + //console.log(peer, JSON.stringify(sendElements,null,2)); + const returnMsg = await sendMsg(this.CoreContext, peer, sendElements, deleteAfterSentFiles); + return { message_id: returnMsg!.id! }; } - return { valid: true }; - } - - protected async _handle(payload: OB11PostSendMsg): Promise<{ message_id: number }> { - const peer = await createContext(this.CoreContext, payload, this.contextMode); - - const messages = normalize( - payload.message, - payload.auto_escape === true || payload.auto_escape === 'true' - ); - - if (getSpecialMsgNum(payload, OB11MessageDataType.node)) { - const returnMsg = await handleForwardNode(this.CoreContext,peer, messages as OB11MessageNode[]); - if (returnMsg) { - const msgShortId = MessageUnique.createMsg({ guildId: '', peerUid: peer.peerUid, chatType: peer.chatType }, returnMsg!.msgId); - return { message_id: msgShortId! }; - } else { - throw Error('发送转发消息失败'); - } - } else { - // if (getSpecialMsgNum(payload, OB11MessageDataType.music)) { - // const music: OB11MessageCustomMusic = messages[0] as OB11MessageCustomMusic; - // if (music) { - // } - // } - } - // log("send msg:", peer, sendElements) - - const { sendElements, deleteAfterSentFiles } = await createSendElements(this.CoreContext, messages, peer); - //console.log(peer, JSON.stringify(sendElements,null,2)); - const returnMsg = await sendMsg(this.CoreContext, peer, sendElements, deleteAfterSentFiles); - return { message_id: returnMsg!.id! }; - } } export default SendMsg; diff --git a/src/onebot/action/msg/SendPrivateMsg.ts b/src/onebot/action/msg/SendPrivateMsg.ts index 7c5cd7e3..25af0f9a 100644 --- a/src/onebot/action/msg/SendPrivateMsg.ts +++ b/src/onebot/action/msg/SendPrivateMsg.ts @@ -3,13 +3,13 @@ import { ActionName, BaseCheckResult } from '../types'; import { OB11PostSendMsg } from '../../types'; // 未检测参数 class SendPrivateMsg extends SendMsg { - actionName = ActionName.SendPrivateMsg; - contextMode: ContextMode = ContextMode.Private; + actionName = ActionName.SendPrivateMsg; + contextMode: ContextMode = ContextMode.Private; - protected async check(payload: OB11PostSendMsg): Promise { - payload.message_type = 'private'; - return super.check(payload); - } + protected async check(payload: OB11PostSendMsg): Promise { + payload.message_type = 'private'; + return super.check(payload); + } } export default SendPrivateMsg; diff --git a/src/onebot/action/msg/SetMsgEmojiLike.ts b/src/onebot/action/msg/SetMsgEmojiLike.ts index da9de4b4..85bc9f54 100644 --- a/src/onebot/action/msg/SetMsgEmojiLike.ts +++ b/src/onebot/action/msg/SetMsgEmojiLike.ts @@ -5,32 +5,32 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { MessageUnique } from '@/common/utils/MessageUnique'; const SchemaData = { - type: 'object', - properties: { - message_id: { type: ['string', 'number'] }, - emoji_id: { type: ['string', 'number'] } - }, - required: ['message_id', 'emoji_id'] + type: 'object', + properties: { + message_id: { type: ['string', 'number'] }, + emoji_id: { type: ['string', 'number'] } + }, + required: ['message_id', 'emoji_id'] } as const satisfies JSONSchema; type Payload = FromSchema; export class SetMsgEmojiLike extends BaseAction { - actionName = ActionName.SetMsgEmojiLike; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); - if (!msg) { - throw new Error('msg not found'); + actionName = ActionName.SetMsgEmojiLike; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); + if (!msg) { + throw new Error('msg not found'); + } + if (!payload.emoji_id) { + throw new Error('emojiId not found'); + } + const msgData = (await NTQQMsgApi.getMsgsByMsgId(msg.Peer, [msg.MsgId])).msgList; + if (!msgData || msgData.length == 0 || !msgData[0].msgSeq) { + throw new Error('find msg by msgid error'); + } + return await NTQQMsgApi.setEmojiLike(msg.Peer, msgData[0].msgSeq, payload.emoji_id.toString(), true); } - if (!payload.emoji_id) { - throw new Error('emojiId not found'); - } - const msgData = (await NTQQMsgApi.getMsgsByMsgId(msg.Peer, [msg.MsgId])).msgList; - if (!msgData || msgData.length == 0 || !msgData[0].msgSeq) { - throw new Error('find msg by msgid error'); - } - return await NTQQMsgApi.setEmojiLike(msg.Peer, msgData[0].msgSeq, payload.emoji_id.toString(), true); - } } diff --git a/src/onebot/action/system/CanSendImage.ts b/src/onebot/action/system/CanSendImage.ts index 459c3e66..c89559a7 100644 --- a/src/onebot/action/system/CanSendImage.ts +++ b/src/onebot/action/system/CanSendImage.ts @@ -6,5 +6,5 @@ interface ReturnType { } export default class CanSendImage extends CanSendRecord { - actionName = ActionName.CanSendImage; + actionName = ActionName.CanSendImage; } diff --git a/src/onebot/action/system/CanSendRecord.ts b/src/onebot/action/system/CanSendRecord.ts index 07741cfa..4d2f6a5c 100644 --- a/src/onebot/action/system/CanSendRecord.ts +++ b/src/onebot/action/system/CanSendRecord.ts @@ -6,11 +6,11 @@ interface ReturnType { } export default class CanSendRecord extends BaseAction { - actionName = ActionName.CanSendRecord; + actionName = ActionName.CanSendRecord; - protected async _handle(_payload: void): Promise { - return { - yes: true - }; - } + protected async _handle(_payload: void): Promise { + return { + yes: true + }; + } } diff --git a/src/onebot/action/system/GetLoginInfo.ts b/src/onebot/action/system/GetLoginInfo.ts index 6dcbfaca..e123e77b 100644 --- a/src/onebot/action/system/GetLoginInfo.ts +++ b/src/onebot/action/system/GetLoginInfo.ts @@ -5,11 +5,11 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; class GetLoginInfo extends BaseAction { - actionName = ActionName.GetLoginInfo; + actionName = ActionName.GetLoginInfo; - protected async _handle(payload: null) { - return OB11Constructor.selfInfo(this.CoreContext.selfInfo); - } + protected async _handle(payload: null) { + return OB11Constructor.selfInfo(this.CoreContext.selfInfo); + } } export default GetLoginInfo; diff --git a/src/onebot/action/system/GetStatus.ts b/src/onebot/action/system/GetStatus.ts index 715e5b1b..7121afab 100644 --- a/src/onebot/action/system/GetStatus.ts +++ b/src/onebot/action/system/GetStatus.ts @@ -2,13 +2,13 @@ import BaseAction from '../BaseAction'; import { ActionName } from '../types'; export default class GetStatus extends BaseAction { - actionName = ActionName.GetStatus; + actionName = ActionName.GetStatus; - protected async _handle(payload: any): Promise { - return { - online: !!this.CoreContext.selfInfo.online, - good: true, - stat:{} - }; - } + protected async _handle(payload: any): Promise { + return { + online: !!this.CoreContext.selfInfo.online, + good: true, + stat:{} + }; + } } diff --git a/src/onebot/action/system/GetVersionInfo.ts b/src/onebot/action/system/GetVersionInfo.ts index 4c7a3105..9b7a4217 100644 --- a/src/onebot/action/system/GetVersionInfo.ts +++ b/src/onebot/action/system/GetVersionInfo.ts @@ -3,13 +3,13 @@ import { ActionName } from '../types'; import { napcat_version } from '@/common/framework/napcat'; export default class GetVersionInfo extends BaseAction { - actionName = ActionName.GetVersionInfo; + actionName = ActionName.GetVersionInfo; - protected async _handle(payload: any): Promise { - return { - app_name: 'NapCat.Onebot', - protocol_version: 'v11', - app_version: napcat_version - }; - } + protected async _handle(payload: any): Promise { + return { + app_name: 'NapCat.Onebot', + protocol_version: 'v11', + app_version: napcat_version + }; + } } diff --git a/src/onebot/action/user/GetCookies.ts b/src/onebot/action/user/GetCookies.ts index 7d136fc8..4993e08f 100644 --- a/src/onebot/action/user/GetCookies.ts +++ b/src/onebot/action/user/GetCookies.ts @@ -7,65 +7,65 @@ interface Response { bkn: string } const SchemaData = { - type: 'object', - properties: { - domain: { type: 'string' } - }, - required: ['domain'] + type: 'object', + properties: { + domain: { type: 'string' } + }, + required: ['domain'] } as const satisfies JSONSchema; type Payload = FromSchema; export class GetCookies extends BaseAction { - actionName = ActionName.GetCookies; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQWebApi = this.CoreContext.getApiContext().WebApi; - // if (!payload.domain) { - // throw new Error('缺少参数 domain'); - // } - // if (payload.domain.endsWith('qzone.qq.com')) { - // // 兼容整个 *.qzone.qq.com - // const data = (await NTQQUserApi.getQzoneCookies()); - // const Bkn = WebApi.genBkn(data.p_skey); - // const CookieValue = 'p_skey=' + data.p_skey + '; skey=' + data.skey + '; p_uin=o' + selfInfo.uin + '; uin=o' + selfInfo.uin; - // return { cookies: CookieValue }; - // } - // // 取Skey - // // 先NodeIKernelTicketService.forceFetchClientKey('') - // // 返回值 - // // { - // // result: 0, - // // errMsg: '', - // // url: '', - // // keyIndex: '19', - // // clientKey: 'clientKey', - // // expireTime: '7200' - // // } - // // request https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=1627126029&clientkey=key - // // &u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=keyIndex - // const _PSkey = (await NTQQUserApi.getPSkey([payload.domain]))[payload.domain]; - // // 取Pskey - // // NodeIKernelTipOffService.getPskey([ 'qun.qq.com' ], true ) - // // { - // // domainPskeyMap: 0, - // // errMsg: 'success', - // // domainPskeyMap: Map(1) { - // // 'qun.qq.com' => 'pskey' - // // } - // // } - // if (!_PSkey || !_Skey) { - // throw new Error('获取Cookies失败'); - // } - // const cookies = `p_skey=${_PSkey}; skey=${_Skey}; p_uin=o${selfInfo.uin}; uin=o${selfInfo.uin}`; - // return { - // cookies - // }; - const cookiesObject = await NTQQUserApi.getCookies(payload.domain); - //把获取到的cookiesObject转换成 k=v; 格式字符串拼接在一起 - const cookies = Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); - const bkn = NTQQWebApi.getBknFromCookie(cookiesObject.p_skey); - return { cookies, bkn }; - } + actionName = ActionName.GetCookies; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQWebApi = this.CoreContext.getApiContext().WebApi; + // if (!payload.domain) { + // throw new Error('缺少参数 domain'); + // } + // if (payload.domain.endsWith('qzone.qq.com')) { + // // 兼容整个 *.qzone.qq.com + // const data = (await NTQQUserApi.getQzoneCookies()); + // const Bkn = WebApi.genBkn(data.p_skey); + // const CookieValue = 'p_skey=' + data.p_skey + '; skey=' + data.skey + '; p_uin=o' + selfInfo.uin + '; uin=o' + selfInfo.uin; + // return { cookies: CookieValue }; + // } + // // 取Skey + // // 先NodeIKernelTicketService.forceFetchClientKey('') + // // 返回值 + // // { + // // result: 0, + // // errMsg: '', + // // url: '', + // // keyIndex: '19', + // // clientKey: 'clientKey', + // // expireTime: '7200' + // // } + // // request https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=1627126029&clientkey=key + // // &u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=keyIndex + // const _PSkey = (await NTQQUserApi.getPSkey([payload.domain]))[payload.domain]; + // // 取Pskey + // // NodeIKernelTipOffService.getPskey([ 'qun.qq.com' ], true ) + // // { + // // domainPskeyMap: 0, + // // errMsg: 'success', + // // domainPskeyMap: Map(1) { + // // 'qun.qq.com' => 'pskey' + // // } + // // } + // if (!_PSkey || !_Skey) { + // throw new Error('获取Cookies失败'); + // } + // const cookies = `p_skey=${_PSkey}; skey=${_Skey}; p_uin=o${selfInfo.uin}; uin=o${selfInfo.uin}`; + // return { + // cookies + // }; + const cookiesObject = await NTQQUserApi.getCookies(payload.domain); + //把获取到的cookiesObject转换成 k=v; 格式字符串拼接在一起 + const cookies = Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); + const bkn = NTQQWebApi.getBknFromCookie(cookiesObject.p_skey); + return { cookies, bkn }; + } } diff --git a/src/onebot/action/user/GetFriendList.ts b/src/onebot/action/user/GetFriendList.ts index c505aece..01be3385 100644 --- a/src/onebot/action/user/GetFriendList.ts +++ b/src/onebot/action/user/GetFriendList.ts @@ -6,19 +6,19 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; // no_cache get时传字符串 const SchemaData = { - type: 'object', - properties: { - no_cache: { type: ['boolean', 'string'] }, - } + type: 'object', + properties: { + no_cache: { type: ['boolean', 'string'] }, + } } as const satisfies JSONSchema; type Payload = FromSchema; export default class GetFriendList extends BaseAction { - actionName = ActionName.GetFriendList; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - //全新逻辑 - const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; - return OB11Constructor.friendsV2(await NTQQFriendApi.getBuddyV2(payload?.no_cache === true || payload?.no_cache === 'true')); - } + actionName = ActionName.GetFriendList; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + //全新逻辑 + const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; + return OB11Constructor.friendsV2(await NTQQFriendApi.getBuddyV2(payload?.no_cache === true || payload?.no_cache === 'true')); + } } diff --git a/src/onebot/action/user/GetRecentContact.ts b/src/onebot/action/user/GetRecentContact.ts index 97cfee34..2476716a 100644 --- a/src/onebot/action/user/GetRecentContact.ts +++ b/src/onebot/action/user/GetRecentContact.ts @@ -5,49 +5,49 @@ import { ActionName } from '../types'; import { OB11Constructor } from '@/onebot/helper/data'; const SchemaData = { - type: 'object', - properties: { - count: { type: ['number', 'string'] } - } + type: 'object', + properties: { + count: { type: ['number', 'string'] } + } } as const satisfies JSONSchema; type Payload = FromSchema; export default class GetRecentContact extends BaseAction { - actionName = ActionName.GetRecentContact; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload) { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; - const ret = await NTQQUserApi.getRecentContactListSnapShot(parseInt((payload.count || 10).toString())); - const data = await Promise.all(ret.info.changedList.map(async (t) => { - const FastMsg = await NTQQMsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]); - if (FastMsg.msgList.length > 0) { - //扩展ret.info.changedList - const lastestMsg = await OB11Constructor.message(this.CoreContext, FastMsg.msgList[0], "array"); - return { - lastestMsg: lastestMsg, - peerUin: t.peerUin, - remark: t.remark, - msgTime: t.msgTime, - chatType: t.chatType, - msgId: t.msgId, - sendNickName: t.sendNickName, - sendMemberName: t.sendMemberName, - peerName: t.peerName - }; - } - return { - peerUin: t.peerUin, - remark: t.remark, - msgTime: t.msgTime, - chatType: t.chatType, - msgId: t.msgId, - sendNickName: t.sendNickName, - sendMemberName: t.sendMemberName, - peerName: t.peerName - }; - })); - return data; - } + actionName = ActionName.GetRecentContact; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload) { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; + const ret = await NTQQUserApi.getRecentContactListSnapShot(parseInt((payload.count || 10).toString())); + const data = await Promise.all(ret.info.changedList.map(async (t) => { + const FastMsg = await NTQQMsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]); + if (FastMsg.msgList.length > 0) { + //扩展ret.info.changedList + const lastestMsg = await OB11Constructor.message(this.CoreContext, FastMsg.msgList[0], "array"); + return { + lastestMsg: lastestMsg, + peerUin: t.peerUin, + remark: t.remark, + msgTime: t.msgTime, + chatType: t.chatType, + msgId: t.msgId, + sendNickName: t.sendNickName, + sendMemberName: t.sendMemberName, + peerName: t.peerName + }; + } + return { + peerUin: t.peerUin, + remark: t.remark, + msgTime: t.msgTime, + chatType: t.chatType, + msgId: t.msgId, + sendNickName: t.sendNickName, + sendMemberName: t.sendMemberName, + peerName: t.peerName + }; + })); + return data; + } } diff --git a/src/onebot/action/user/SendLike.ts b/src/onebot/action/user/SendLike.ts index 9105f030..567fad45 100644 --- a/src/onebot/action/user/SendLike.ts +++ b/src/onebot/action/user/SendLike.ts @@ -4,33 +4,33 @@ import { ActionName } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { - type: 'object', - properties: { - user_id: { type: ['number', 'string'] }, - times: { type: ['number', 'string'] } - }, - required: ['user_id', 'times'] + type: 'object', + properties: { + user_id: { type: ['number', 'string'] }, + times: { type: ['number', 'string'] } + }, + required: ['user_id', 'times'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SendLike extends BaseAction { - actionName = ActionName.SendLike; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQUserApi = this.CoreContext.getApiContext().UserApi; - //logDebug('点赞参数', payload); - try { - const qq = payload.user_id.toString(); - const uid: string = await NTQQUserApi.getUidByUin(qq) || ''; - const result = await NTQQUserApi.like(uid, parseInt(payload.times?.toString()) || 1); - //logDebug('点赞结果', result); - if (result.result !== 0) { - throw Error(result.errMsg); - } - } catch (e) { - throw `点赞失败 ${e}`; + actionName = ActionName.SendLike; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQUserApi = this.CoreContext.getApiContext().UserApi; + //logDebug('点赞参数', payload); + try { + const qq = payload.user_id.toString(); + const uid: string = await NTQQUserApi.getUidByUin(qq) || ''; + const result = await NTQQUserApi.like(uid, parseInt(payload.times?.toString()) || 1); + //logDebug('点赞结果', result); + if (result.result !== 0) { + throw Error(result.errMsg); + } + } catch (e) { + throw `点赞失败 ${e}`; + } + return null; } - return null; - } } diff --git a/src/onebot/action/user/SetFriendAddRequest.ts b/src/onebot/action/user/SetFriendAddRequest.ts index 12e7550f..75ac0a05 100644 --- a/src/onebot/action/user/SetFriendAddRequest.ts +++ b/src/onebot/action/user/SetFriendAddRequest.ts @@ -4,24 +4,24 @@ import { ActionName } from '../types'; import { NTQQFriendApi } from '@/core/apis/friend'; const SchemaData = { - type: 'object', - properties: { - flag: { type: 'string' }, - approve: { type: ['string', 'boolean'] }, - remark: { type: 'string' } - }, - required: ['flag'] + type: 'object', + properties: { + flag: { type: 'string' }, + approve: { type: ['string', 'boolean'] }, + remark: { type: 'string' } + }, + required: ['flag'] } as const satisfies JSONSchema; type Payload = FromSchema; export default class SetFriendAddRequest extends BaseAction { - actionName = ActionName.SetFriendAddRequest; - PayloadSchema = SchemaData; - protected async _handle(payload: Payload): Promise { - const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; - const approve = payload.approve?.toString() !== 'false'; - await NTQQFriendApi.handleFriendRequest(payload.flag, approve); - return null; - } + actionName = ActionName.SetFriendAddRequest; + PayloadSchema = SchemaData; + protected async _handle(payload: Payload): Promise { + const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; + const approve = payload.approve?.toString() !== 'false'; + await NTQQFriendApi.handleFriendRequest(payload.flag, approve); + return null; + } } diff --git a/src/onebot/event/OB11BaseEvent.ts b/src/onebot/event/OB11BaseEvent.ts index 377ad9ac..9446cd42 100644 --- a/src/onebot/event/OB11BaseEvent.ts +++ b/src/onebot/event/OB11BaseEvent.ts @@ -10,7 +10,7 @@ export enum EventType { export abstract class OB11BaseEvent { - time = Math.floor(Date.now() / 1000); - self_id = parseInt(selfInfo.uin); - post_type: EventType = EventType.META; + time = Math.floor(Date.now() / 1000); + self_id = parseInt(selfInfo.uin); + post_type: EventType = EventType.META; } diff --git a/src/onebot/event/message/OB11BaseMessageEvent.ts b/src/onebot/event/message/OB11BaseMessageEvent.ts index 8ed0f8f6..63960ef3 100644 --- a/src/onebot/event/message/OB11BaseMessageEvent.ts +++ b/src/onebot/event/message/OB11BaseMessageEvent.ts @@ -1,5 +1,5 @@ import { EventType, OB11BaseEvent } from '../OB11BaseEvent'; export abstract class OB11BaseMessageEvent extends OB11BaseEvent { - post_type = EventType.MESSAGE; + post_type = EventType.MESSAGE; } \ No newline at end of file diff --git a/src/onebot/event/meta/OB11BaseMetaEvent.ts b/src/onebot/event/meta/OB11BaseMetaEvent.ts index 4a1b9344..279f9696 100644 --- a/src/onebot/event/meta/OB11BaseMetaEvent.ts +++ b/src/onebot/event/meta/OB11BaseMetaEvent.ts @@ -1,6 +1,6 @@ import { EventType, OB11BaseEvent } from '../OB11BaseEvent'; export abstract class OB11BaseMetaEvent extends OB11BaseEvent { - post_type = EventType.META; - meta_event_type: string; + post_type = EventType.META; + meta_event_type: string; } \ No newline at end of file diff --git a/src/onebot/event/meta/OB11HeartbeatEvent.ts b/src/onebot/event/meta/OB11HeartbeatEvent.ts index ad2a0c55..628f1c58 100644 --- a/src/onebot/event/meta/OB11HeartbeatEvent.ts +++ b/src/onebot/event/meta/OB11HeartbeatEvent.ts @@ -6,16 +6,16 @@ interface HeartbeatStatus { } export class OB11HeartbeatEvent extends OB11BaseMetaEvent { - meta_event_type = 'heartbeat'; - status: HeartbeatStatus; - interval: number; + meta_event_type = 'heartbeat'; + status: HeartbeatStatus; + interval: number; - public constructor(isOnline: boolean, isGood: boolean, interval: number) { - super(); - this.interval = interval; - this.status = { - online: isOnline, - good: isGood - }; - } + public constructor(isOnline: boolean, isGood: boolean, interval: number) { + super(); + this.interval = interval; + this.status = { + online: isOnline, + good: isGood + }; + } } \ No newline at end of file diff --git a/src/onebot/event/meta/OB11LifeCycleEvent.ts b/src/onebot/event/meta/OB11LifeCycleEvent.ts index a28f91eb..6c9e513e 100644 --- a/src/onebot/event/meta/OB11LifeCycleEvent.ts +++ b/src/onebot/event/meta/OB11LifeCycleEvent.ts @@ -7,11 +7,11 @@ export enum LifeCycleSubType { } export class OB11LifeCycleEvent extends OB11BaseMetaEvent { - meta_event_type = 'lifecycle'; - sub_type: LifeCycleSubType; + meta_event_type = 'lifecycle'; + sub_type: LifeCycleSubType; - public constructor(subType: LifeCycleSubType) { - super(); - this.sub_type = subType; - } + public constructor(subType: LifeCycleSubType) { + super(); + this.sub_type = subType; + } } \ No newline at end of file diff --git a/src/onebot/event/notice/OB11BaseNoticeEvent.ts b/src/onebot/event/notice/OB11BaseNoticeEvent.ts index 15c45893..982d7448 100644 --- a/src/onebot/event/notice/OB11BaseNoticeEvent.ts +++ b/src/onebot/event/notice/OB11BaseNoticeEvent.ts @@ -1,5 +1,5 @@ import { EventType, OB11BaseEvent } from '../OB11BaseEvent'; export abstract class OB11BaseNoticeEvent extends OB11BaseEvent { - post_type = EventType.NOTICE; + post_type = EventType.NOTICE; } \ No newline at end of file diff --git a/src/onebot/event/notice/OB11FriendAddNoticeEvent.ts b/src/onebot/event/notice/OB11FriendAddNoticeEvent.ts index 185b574f..5825147a 100644 --- a/src/onebot/event/notice/OB11FriendAddNoticeEvent.ts +++ b/src/onebot/event/notice/OB11FriendAddNoticeEvent.ts @@ -1,11 +1,11 @@ import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent'; export class OB11FriendAddNoticeEvent extends OB11BaseNoticeEvent { - notice_type = 'friend_add'; - user_id: number; + notice_type = 'friend_add'; + user_id: number; - public constructor(user_Id: number) { - super(); - this.user_id = user_Id; - } + public constructor(user_Id: number) { + super(); + this.user_id = user_Id; + } } \ No newline at end of file diff --git a/src/onebot/event/notice/OB11FriendRecallNoticeEvent.ts b/src/onebot/event/notice/OB11FriendRecallNoticeEvent.ts index 2e374878..401799f2 100644 --- a/src/onebot/event/notice/OB11FriendRecallNoticeEvent.ts +++ b/src/onebot/event/notice/OB11FriendRecallNoticeEvent.ts @@ -1,13 +1,13 @@ import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent'; export class OB11FriendRecallNoticeEvent extends OB11BaseNoticeEvent { - notice_type = 'friend_recall'; - user_id: number; - message_id: number; + notice_type = 'friend_recall'; + user_id: number; + message_id: number; - public constructor(userId: number, messageId: number) { - super(); - this.user_id = userId; - this.message_id = messageId; - } + public constructor(userId: number, messageId: number) { + super(); + this.user_id = userId; + this.message_id = messageId; + } } \ No newline at end of file diff --git a/src/onebot/event/notice/OB11GroupAdminNoticeEvent.ts b/src/onebot/event/notice/OB11GroupAdminNoticeEvent.ts index a968de43..739e772c 100644 --- a/src/onebot/event/notice/OB11GroupAdminNoticeEvent.ts +++ b/src/onebot/event/notice/OB11GroupAdminNoticeEvent.ts @@ -1,6 +1,6 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; export class OB11GroupAdminNoticeEvent extends OB11GroupNoticeEvent { - notice_type = 'group_admin'; - sub_type: 'set' | 'unset' = "set"; // "set" | "unset" + notice_type = 'group_admin'; + sub_type: 'set' | 'unset' = "set"; // "set" | "unset" } \ No newline at end of file diff --git a/src/onebot/event/notice/OB11GroupBanEvent.ts b/src/onebot/event/notice/OB11GroupBanEvent.ts index 9b47fc36..d28de97e 100644 --- a/src/onebot/event/notice/OB11GroupBanEvent.ts +++ b/src/onebot/event/notice/OB11GroupBanEvent.ts @@ -1,17 +1,17 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; export class OB11GroupBanEvent extends OB11GroupNoticeEvent { - notice_type = 'group_ban'; - operator_id: number; - duration: number; - sub_type: 'ban' | 'lift_ban'; + notice_type = 'group_ban'; + operator_id: number; + duration: number; + sub_type: 'ban' | 'lift_ban'; - constructor(groupId: number, userId: number, operatorId: number, duration: number, sub_type: 'ban' | 'lift_ban') { - super(); - this.group_id = groupId; - this.operator_id = operatorId; - this.user_id = userId; - this.duration = duration; - this.sub_type = sub_type; - } + constructor(groupId: number, userId: number, operatorId: number, duration: number, sub_type: 'ban' | 'lift_ban') { + super(); + this.group_id = groupId; + this.operator_id = operatorId; + this.user_id = userId; + this.duration = duration; + this.sub_type = sub_type; + } } diff --git a/src/onebot/event/notice/OB11GroupCardEvent.ts b/src/onebot/event/notice/OB11GroupCardEvent.ts index 1c2e4bc0..0fbbf651 100644 --- a/src/onebot/event/notice/OB11GroupCardEvent.ts +++ b/src/onebot/event/notice/OB11GroupCardEvent.ts @@ -1,16 +1,16 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; export class OB11GroupCardEvent extends OB11GroupNoticeEvent { - notice_type = 'group_card'; - card_new: string; - card_old: string; + notice_type = 'group_card'; + card_new: string; + card_old: string; - constructor(groupId: number, userId: number, cardNew: string, cardOld: string) { - super(); - this.group_id = groupId; - this.user_id = userId; - this.card_new = cardNew; - this.card_old = cardOld; - } + constructor(groupId: number, userId: number, cardNew: string, cardOld: string) { + super(); + this.group_id = groupId; + this.user_id = userId; + this.card_new = cardNew; + this.card_old = cardOld; + } } diff --git a/src/onebot/event/notice/OB11GroupDecreaseEvent.ts b/src/onebot/event/notice/OB11GroupDecreaseEvent.ts index 33da8563..b888fdb2 100644 --- a/src/onebot/event/notice/OB11GroupDecreaseEvent.ts +++ b/src/onebot/event/notice/OB11GroupDecreaseEvent.ts @@ -3,15 +3,15 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; export type GroupDecreaseSubType = 'leave' | 'kick' | 'kick_me'; export class OB11GroupDecreaseEvent extends OB11GroupNoticeEvent { - notice_type = 'group_decrease'; - sub_type: GroupDecreaseSubType = 'leave'; // TODO: 实现其他几种子类型的识别 ("leave" | "kick" | "kick_me") - operator_id: number; + notice_type = 'group_decrease'; + sub_type: GroupDecreaseSubType = 'leave'; // TODO: 实现其他几种子类型的识别 ("leave" | "kick" | "kick_me") + operator_id: number; - constructor(groupId: number, userId: number, operatorId: number, subType: GroupDecreaseSubType = 'leave') { - super(); - this.group_id = groupId; - this.operator_id = operatorId; // 实际上不应该这么实现,但是现在还没有办法识别用户是被踢出的,还是自己主动退出的 - this.user_id = userId; - this.sub_type = subType; - } + constructor(groupId: number, userId: number, operatorId: number, subType: GroupDecreaseSubType = 'leave') { + super(); + this.group_id = groupId; + this.operator_id = operatorId; // 实际上不应该这么实现,但是现在还没有办法识别用户是被踢出的,还是自己主动退出的 + this.user_id = userId; + this.sub_type = subType; + } } diff --git a/src/onebot/event/notice/OB11GroupEssenceEvent.ts b/src/onebot/event/notice/OB11GroupEssenceEvent.ts index ae1053e1..80c714bc 100644 --- a/src/onebot/event/notice/OB11GroupEssenceEvent.ts +++ b/src/onebot/event/notice/OB11GroupEssenceEvent.ts @@ -1,14 +1,14 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; export class OB11GroupEssenceEvent extends OB11GroupNoticeEvent { - notice_type = 'essence'; - message_id: number; - sender_id: number; - sub_type: 'add' | 'delete' = 'add'; + notice_type = 'essence'; + message_id: number; + sender_id: number; + sub_type: 'add' | 'delete' = 'add'; - constructor(groupId: number, message_id: number, sender_id: number) { - super(); - this.group_id = groupId; - this.message_id = message_id; - this.sender_id = sender_id; - } + constructor(groupId: number, message_id: number, sender_id: number) { + super(); + this.group_id = groupId; + this.message_id = message_id; + this.sender_id = sender_id; + } } diff --git a/src/onebot/event/notice/OB11GroupIncreaseEvent.ts b/src/onebot/event/notice/OB11GroupIncreaseEvent.ts index b0a86880..51500c39 100644 --- a/src/onebot/event/notice/OB11GroupIncreaseEvent.ts +++ b/src/onebot/event/notice/OB11GroupIncreaseEvent.ts @@ -2,14 +2,14 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; type GroupIncreaseSubType = 'approve' | 'invite'; export class OB11GroupIncreaseEvent extends OB11GroupNoticeEvent { - notice_type = 'group_increase'; - operator_id: number; - sub_type: GroupIncreaseSubType; - constructor(groupId: number, userId: number, operatorId: number, subType: GroupIncreaseSubType = 'approve') { - super(); - this.group_id = groupId; - this.operator_id = operatorId; - this.user_id = userId; - this.sub_type = subType; - } + notice_type = 'group_increase'; + operator_id: number; + sub_type: GroupIncreaseSubType; + constructor(groupId: number, userId: number, operatorId: number, subType: GroupIncreaseSubType = 'approve') { + super(); + this.group_id = groupId; + this.operator_id = operatorId; + this.user_id = userId; + this.sub_type = subType; + } } diff --git a/src/onebot/event/notice/OB11GroupNoticeEvent.ts b/src/onebot/event/notice/OB11GroupNoticeEvent.ts index 3e046f87..8fe7e0f9 100644 --- a/src/onebot/event/notice/OB11GroupNoticeEvent.ts +++ b/src/onebot/event/notice/OB11GroupNoticeEvent.ts @@ -1,6 +1,6 @@ import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent'; export abstract class OB11GroupNoticeEvent extends OB11BaseNoticeEvent { - group_id: number = 0; - user_id: number = 0; + group_id: number = 0; + user_id: number = 0; } \ No newline at end of file diff --git a/src/onebot/event/notice/OB11GroupRecallNoticeEvent.ts b/src/onebot/event/notice/OB11GroupRecallNoticeEvent.ts index 8d35ca1b..77381349 100644 --- a/src/onebot/event/notice/OB11GroupRecallNoticeEvent.ts +++ b/src/onebot/event/notice/OB11GroupRecallNoticeEvent.ts @@ -1,15 +1,15 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; export class OB11GroupRecallNoticeEvent extends OB11GroupNoticeEvent { - notice_type = 'group_recall'; - operator_id: number; - message_id: number; + notice_type = 'group_recall'; + operator_id: number; + message_id: number; - constructor(groupId: number, userId: number, operatorId: number, messageId: number) { - super(); - this.group_id = groupId; - this.user_id = userId; - this.operator_id = operatorId; - this.message_id = messageId; - } + constructor(groupId: number, userId: number, operatorId: number, messageId: number) { + super(); + this.group_id = groupId; + this.user_id = userId; + this.operator_id = operatorId; + this.message_id = messageId; + } } \ No newline at end of file diff --git a/src/onebot/event/notice/OB11GroupTitleEvent.ts b/src/onebot/event/notice/OB11GroupTitleEvent.ts index 41eace84..faee4e8a 100644 --- a/src/onebot/event/notice/OB11GroupTitleEvent.ts +++ b/src/onebot/event/notice/OB11GroupTitleEvent.ts @@ -1,15 +1,15 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; export class OB11GroupTitleEvent extends OB11GroupNoticeEvent { - notice_type = 'notify'; - sub_type = 'title'; - title: string; + notice_type = 'notify'; + sub_type = 'title'; + title: string; - constructor(groupId: number, userId: number, title: string) { - super(); - this.group_id = groupId; - this.user_id = userId; - this.title = title; - } + constructor(groupId: number, userId: number, title: string) { + super(); + this.group_id = groupId; + this.user_id = userId; + this.title = title; + } } diff --git a/src/onebot/event/notice/OB11GroupUploadNoticeEvent.ts b/src/onebot/event/notice/OB11GroupUploadNoticeEvent.ts index d5514872..c907a672 100644 --- a/src/onebot/event/notice/OB11GroupUploadNoticeEvent.ts +++ b/src/onebot/event/notice/OB11GroupUploadNoticeEvent.ts @@ -8,13 +8,13 @@ export interface GroupUploadFile{ } export class OB11GroupUploadNoticeEvent extends OB11GroupNoticeEvent { - notice_type = 'group_upload'; - file: GroupUploadFile; + notice_type = 'group_upload'; + file: GroupUploadFile; - constructor(groupId: number, userId: number, file: GroupUploadFile) { - super(); - this.group_id = groupId; - this.user_id = userId; - this.file = file; - } + constructor(groupId: number, userId: number, file: GroupUploadFile) { + super(); + this.group_id = groupId; + this.user_id = userId; + this.file = file; + } } \ No newline at end of file diff --git a/src/onebot/event/notice/OB11InputStatusEvent.ts b/src/onebot/event/notice/OB11InputStatusEvent.ts index ba255bc3..864dd6ec 100644 --- a/src/onebot/event/notice/OB11InputStatusEvent.ts +++ b/src/onebot/event/notice/OB11InputStatusEvent.ts @@ -1,16 +1,16 @@ import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent'; //输入状态事件 初步完成 Mlikio wa Todo 需要做一些过滤 export class OB11InputStatusEvent extends OB11BaseNoticeEvent { - notice_type = 'notify'; - sub_type = 'input_status'; - status_text = "对方正在输入..." - eventType = 1; - user_id = 0; - constructor(user_id: number, eventType: number, status_text: string) { - super(); - this.user_id = user_id; - this.eventType = eventType; - this.status_text = status_text; - } + notice_type = 'notify'; + sub_type = 'input_status'; + status_text = "对方正在输入..."; + eventType = 1; + user_id = 0; + constructor(user_id: number, eventType: number, status_text: string) { + super(); + this.user_id = user_id; + this.eventType = eventType; + this.status_text = status_text; + } } diff --git a/src/onebot/event/notice/OB11MsgEmojiLikeEvent.ts b/src/onebot/event/notice/OB11MsgEmojiLikeEvent.ts index 1af5ced7..8fc9b445 100644 --- a/src/onebot/event/notice/OB11MsgEmojiLikeEvent.ts +++ b/src/onebot/event/notice/OB11MsgEmojiLikeEvent.ts @@ -6,15 +6,15 @@ export interface MsgEmojiLike { } export class OB11GroupMsgEmojiLikeEvent extends OB11GroupNoticeEvent { - notice_type = 'group_msg_emoji_like'; - message_id: number; - likes: MsgEmojiLike[]; + notice_type = 'group_msg_emoji_like'; + message_id: number; + likes: MsgEmojiLike[]; - constructor(groupId: number, userId: number, messageId: number, likes: MsgEmojiLike[]) { - super(); - this.group_id = groupId; - this.user_id = userId; // 可为空,表示是对别人的消息操作,如果是对bot自己的消息则不为空 - this.message_id = messageId; - this.likes = likes; - } + constructor(groupId: number, userId: number, messageId: number, likes: MsgEmojiLike[]) { + super(); + this.group_id = groupId; + this.user_id = userId; // 可为空,表示是对别人的消息操作,如果是对bot自己的消息则不为空 + this.message_id = messageId; + this.likes = likes; + } } diff --git a/src/onebot/event/notice/OB11PokeEvent.ts b/src/onebot/event/notice/OB11PokeEvent.ts index 192b558e..22592d89 100644 --- a/src/onebot/event/notice/OB11PokeEvent.ts +++ b/src/onebot/event/notice/OB11PokeEvent.ts @@ -1,32 +1,32 @@ import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent'; class OB11PokeEvent extends OB11BaseNoticeEvent { - notice_type = 'notify'; - sub_type = 'poke'; - target_id = 0; - user_id = 0; + notice_type = 'notify'; + sub_type = 'poke'; + target_id = 0; + user_id = 0; } export class OB11FriendPokeEvent extends OB11PokeEvent { - raw_info: any; - //raw_message nb等框架标准为string - constructor(user_id: number, target_id: number, raw_message: any) { - super(); - this.target_id = target_id; - this.user_id = user_id; - this.raw_info = raw_message; - } + raw_info: any; + //raw_message nb等框架标准为string + constructor(user_id: number, target_id: number, raw_message: any) { + super(); + this.target_id = target_id; + this.user_id = user_id; + this.raw_info = raw_message; + } } export class OB11GroupPokeEvent extends OB11PokeEvent { - group_id: number; - raw_info: any; - //raw_message nb等框架标准为string - constructor(group_id: number, user_id: number = 0, target_id: number = 0, raw_message: any) { - super(); - this.group_id = group_id; - this.target_id = target_id; - this.user_id = user_id; - this.raw_info = raw_message; - } + group_id: number; + raw_info: any; + //raw_message nb等框架标准为string + constructor(group_id: number, user_id: number = 0, target_id: number = 0, raw_message: any) { + super(); + this.group_id = group_id; + this.target_id = target_id; + this.user_id = user_id; + this.raw_info = raw_message; + } } diff --git a/src/onebot/event/request/OB11FriendRequest.ts b/src/onebot/event/request/OB11FriendRequest.ts index 522aa483..cadbd3f5 100644 --- a/src/onebot/event/request/OB11FriendRequest.ts +++ b/src/onebot/event/request/OB11FriendRequest.ts @@ -3,9 +3,9 @@ import { EventType } from '../OB11BaseEvent'; export class OB11FriendRequestEvent extends OB11BaseNoticeEvent { - post_type = EventType.REQUEST; - user_id: number = 0; - request_type = 'friend' as const; - comment: string = ''; - flag: string = ''; + post_type = EventType.REQUEST; + user_id: number = 0; + request_type = 'friend' as const; + comment: string = ''; + flag: string = ''; } diff --git a/src/onebot/event/request/OB11GroupRequest.ts b/src/onebot/event/request/OB11GroupRequest.ts index e06677e6..13b6b6d3 100644 --- a/src/onebot/event/request/OB11GroupRequest.ts +++ b/src/onebot/event/request/OB11GroupRequest.ts @@ -3,9 +3,9 @@ import { EventType } from '../OB11BaseEvent'; export class OB11GroupRequestEvent extends OB11GroupNoticeEvent { - post_type = EventType.REQUEST; - request_type = 'group' as const; - sub_type: 'add' | 'invite' = 'add'; - comment: string = ''; - flag: string = ''; + post_type = EventType.REQUEST; + request_type = 'group' as const; + sub_type: 'add' | 'invite' = 'add'; + comment: string = ''; + flag: string = ''; } diff --git a/src/onebot/helper/config.ts b/src/onebot/helper/config.ts index f1ce8615..e2275163 100644 --- a/src/onebot/helper/config.ts +++ b/src/onebot/helper/config.ts @@ -39,38 +39,38 @@ import { ConfigBase } from '@/common/utils/ConfigBase'; // } export class OB11Config extends ConfigBase { - name: string = 'onebot11'; - http = { - enable: false, - host: '', - port: 3000, - secret: '', - enableHeart: false, - enablePost: false, - postUrls: [], - }; - ws = { - enable: false, - host: '', - port: 3001, - }; - reverseWs = { - enable: false, - urls: [], - }; - debug = false; - heartInterval = 30000; - messagePostFormat: 'array' | 'string' = 'array'; - enableLocalFile2Url = true; - musicSignUrl = ''; - reportSelfMessage = false; - token = ''; - GroupLocalTime = { - Record: false, - RecordList: [] as Array - }; + name: string = 'onebot11'; + http = { + enable: false, + host: '', + port: 3000, + secret: '', + enableHeart: false, + enablePost: false, + postUrls: [], + }; + ws = { + enable: false, + host: '', + port: 3001, + }; + reverseWs = { + enable: false, + urls: [], + }; + debug = false; + heartInterval = 30000; + messagePostFormat: 'array' | 'string' = 'array'; + enableLocalFile2Url = true; + musicSignUrl = ''; + reportSelfMessage = false; + token = ''; + GroupLocalTime = { + Record: false, + RecordList: [] as Array + }; - protected getKeys(): string[] | null { - return null; - } + protected getKeys(): string[] | null { + return null; + } } diff --git a/src/onebot/helper/cqcode.ts b/src/onebot/helper/cqcode.ts index 5c20dcc3..14eb175c 100644 --- a/src/onebot/helper/cqcode.ts +++ b/src/onebot/helper/cqcode.ts @@ -3,82 +3,82 @@ import { OB11MessageData } from '../types'; const pattern = /\[CQ:(\w+)((,\w+=[^,\]]*)*)\]/; function unescape(source: string) { - return String(source) - .replace(/[/g, '[') - .replace(/]/g, ']') - .replace(/,/g, ',') - .replace(/&/g, '&'); + return String(source) + .replace(/[/g, '[') + .replace(/]/g, ']') + .replace(/,/g, ',') + .replace(/&/g, '&'); } function from(source: string) { - const capture = pattern.exec(source); - if (!capture) return null; - const [, type, attrs] = capture; - const data: Record = {}; - attrs && attrs.slice(1).split(',').forEach((str) => { - const index = str.indexOf('='); - data[str.slice(0, index)] = unescape(str.slice(index + 1)); - }); - return { type, data, capture }; + const capture = pattern.exec(source); + if (!capture) return null; + const [, type, attrs] = capture; + const data: Record = {}; + attrs && attrs.slice(1).split(',').forEach((str) => { + const index = str.indexOf('='); + data[str.slice(0, index)] = unescape(str.slice(index + 1)); + }); + return { type, data, capture }; } function h(type: string, data: any) { - return { - type, - data, - }; + return { + type, + data, + }; } export function decodeCQCode(source: string): OB11MessageData[] { - const elements: any[] = []; - let result: ReturnType; - while ((result = from(source))) { - const { type, data, capture } = result; - if (capture.index) { - elements.push(h('text', { text: unescape(source.slice(0, capture.index)) })); + const elements: any[] = []; + let result: ReturnType; + while ((result = from(source))) { + const { type, data, capture } = result; + if (capture.index) { + elements.push(h('text', { text: unescape(source.slice(0, capture.index)) })); + } + elements.push(h(type, data)); + source = source.slice(capture.index + capture[0].length); } - elements.push(h(type, data)); - source = source.slice(capture.index + capture[0].length); - } - if (source) elements.push(h('text', { text: unescape(source) })); - return elements; + if (source) elements.push(h('text', { text: unescape(source) })); + return elements; } export function encodeCQCode(data: OB11MessageData) { - const CQCodeEscapeText = (text: string) => { - return text.replace(/&/g, '&') - .replace(/\[/g, '[') - .replace(/\]/g, ']'); + const CQCodeEscapeText = (text: string) => { + return text.replace(/&/g, '&') + .replace(/\[/g, '[') + .replace(/\]/g, ']'); - }; + }; - const CQCodeEscape = (text: string) => { - return text.replace(/&/g, '&') - .replace(/\[/g, '[') - .replace(/\]/g, ']') - .replace(/,/g, ','); - }; + const CQCodeEscape = (text: string) => { + return text.replace(/&/g, '&') + .replace(/\[/g, '[') + .replace(/\]/g, ']') + .replace(/,/g, ','); + }; - if (data.type === 'text') { - return CQCodeEscapeText(data.data.text); - } - - let result = '[CQ:' + data.type; - for (const name in data.data) { - const value = data.data[name]; - if (value === undefined) { - continue; + if (data.type === 'text') { + return CQCodeEscapeText(data.data.text); } - try { - const text = value.toString(); - result += `,${name}=${CQCodeEscape(text)}`; - } catch (error) { - // If it can't be converted, skip this name-value pair + + let result = '[CQ:' + data.type; + for (const name in data.data) { + const value = data.data[name]; + if (value === undefined) { + continue; + } + try { + const text = value.toString(); + result += `,${name}=${CQCodeEscape(text)}`; + } catch (error) { + // If it can't be converted, skip this name-value pair + } } - } - result += ']'; - return result; + result += ']'; + return result; } // const result = parseCQCode("[CQ:at,qq=114514]早上好啊[CQ:image,file=http://baidu.com/1.jpg,type=show,id=40004]") diff --git a/src/onebot/helper/data.ts b/src/onebot/helper/data.ts index 8324d149..7f98013a 100644 --- a/src/onebot/helper/data.ts +++ b/src/onebot/helper/data.ts @@ -1,30 +1,30 @@ import fastXmlParser, { XMLParser } from 'fast-xml-parser'; import { - OB11Group, - OB11GroupMember, - OB11GroupMemberRole, - OB11Message, - OB11MessageData, - OB11MessageDataType, - OB11User, - OB11UserSex + OB11Group, + OB11GroupMember, + OB11GroupMemberRole, + OB11Message, + OB11MessageData, + OB11MessageDataType, + OB11User, + OB11UserSex } from '../types'; import { - AtType, - ChatType, - FaceIndex, - Friend, - FriendV2, - GrayTipElementSubType, - Group, - GroupMember, - Peer, - RawMessage, - SelfInfo, - Sex, - TipGroupElementType, - User, - VideoElement + AtType, + ChatType, + FaceIndex, + Friend, + FriendV2, + GrayTipElementSubType, + Group, + GroupMember, + Peer, + RawMessage, + SelfInfo, + Sex, + TipGroupElementType, + User, + VideoElement } from '@/core/entities'; import { EventType } from '../event/OB11BaseEvent'; import { encodeCQCode } from './cqcode'; @@ -48,636 +48,642 @@ import { NapCatCore } from '@/core'; export class OB11Constructor { - static async message(coreContext: NapCatCore, msg: RawMessage, messagePostFormat: any): Promise { - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - const NTQQUserApi = coreContext.getApiContext().UserApi; - const NTQQFileApi = coreContext.getApiContext().FileApi; - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - const logger = coreContext.context.logger; - const message_type = msg.chatType == ChatType.group ? 'group' : 'private'; - const resMsg: OB11Message = { - self_id: parseInt(coreContext.selfInfo.uin), - user_id: parseInt(msg.senderUin!), - time: parseInt(msg.msgTime) || Date.now(), - message_id: msg.id!, - message_seq: msg.id!, - real_id: msg.id!, - message_type: msg.chatType == ChatType.group ? 'group' : 'private', - sender: { - user_id: parseInt(msg.senderUin || '0'), - nickname: msg.sendNickName, - card: msg.sendMemberName || '', - }, - raw_message: '', - font: 14, - sub_type: 'friend', - message: messagePostFormat === 'string' ? '' : [], - message_format: messagePostFormat === 'string' ? 'string' : 'array', - post_type: coreContext.selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE, - }; - if (msg.chatType == ChatType.group) { - resMsg.sub_type = 'normal'; // 这里go-cqhttp是group,而onebot11标准是normal, 蛋疼 - resMsg.group_id = parseInt(msg.peerUin); - //直接去QQNative取 - const memberList = await NTQQGroupApi.getGroupMembers(msg.peerUin); - let member = memberList.get(msg.senderUin!); - if (member) { - resMsg.sender.role = OB11Constructor.groupMemberRole(member.role); - resMsg.sender.nickname = member.nick; - } - } - else if (msg.chatType == ChatType.friend) { - resMsg.sub_type = 'friend'; - resMsg.sender.nickname = (await NTQQUserApi.getUserDetailInfo(msg.senderUid)).nick; - //const user = await NTQQUserApi.getUserDetailInfoByUin(msg.senderUin!); - //resMsg.sender.nickname = user.info.nick; - } - else if (msg.chatType == ChatType.temp) { - resMsg.sub_type = 'group'; - } - for (const element of msg.elements) { - let message_data: OB11MessageData = { - data: {} as any, - type: 'unknown' as any - }; - if (element.textElement && element.textElement?.atType !== AtType.notAt) { - let qq: `${number}` | 'all'; - let name: string | undefined; - if (element.textElement.atType == AtType.atAll) { - qq = 'all'; - } - else { - const { atNtUid, content } = element.textElement; - let atQQ = element.textElement.atUid; - if (!atQQ || atQQ === '0') { - atQQ = await NTQQUserApi.getUinByUid(atNtUid); - } - if (atQQ) { - qq = atQQ as `${number}`; - name = content.replace('@', ''); - } - } - message_data = { - type: OB11MessageDataType.at, - data: { - qq: qq!, - name - } + static async message(coreContext: NapCatCore, msg: RawMessage, messagePostFormat: any): Promise { + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + const NTQQUserApi = coreContext.getApiContext().UserApi; + const NTQQFileApi = coreContext.getApiContext().FileApi; + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + const logger = coreContext.context.logger; + const message_type = msg.chatType == ChatType.group ? 'group' : 'private'; + const resMsg: OB11Message = { + self_id: parseInt(coreContext.selfInfo.uin), + user_id: parseInt(msg.senderUin!), + time: parseInt(msg.msgTime) || Date.now(), + message_id: msg.id!, + message_seq: msg.id!, + real_id: msg.id!, + message_type: msg.chatType == ChatType.group ? 'group' : 'private', + sender: { + user_id: parseInt(msg.senderUin || '0'), + nickname: msg.sendNickName, + card: msg.sendMemberName || '', + }, + raw_message: '', + font: 14, + sub_type: 'friend', + message: messagePostFormat === 'string' ? '' : [], + message_format: messagePostFormat === 'string' ? 'string' : 'array', + post_type: coreContext.selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE, }; - } - else if (element.textElement) { - message_data['type'] = OB11MessageDataType.text; - - let text = element.textElement.content; - if (!text.trim()) { - continue; - } - // 兼容 9.7.x 换行符 - if (text.indexOf('\n') === -1 && text.indexOf('\r\n') === -1) { - text = text.replace(/\r/g, '\n'); - } - message_data['data']['text'] = text; - } - else if (element.replyElement) { - message_data['type'] = OB11MessageDataType.reply; - //log("收到回复消息", element.replyElement); - try { - const records = msg.records.find(msgRecord => msgRecord.msgId === element.replyElement.sourceMsgIdInRecords); - const peer = { - chatType: msg.chatType, - peerUid: msg.peerUid, - guildId: '', - }; - let replyMsg: RawMessage | undefined; - if (!records) throw new Error('找不到回复消息'); - replyMsg = (await NTQQMsgApi.getMsgsBySeqAndCount({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, element.replyElement.replayMsgSeq, 1, true, true)).msgList[0]; - if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { - replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replyElement.replayMsgSeq)).msgList[0]; - } - if (msg.peerUin == '284840486') { - //合并消息内侧 消息具体定位不到 - } - if ((!replyMsg || records.msgRandom !== replyMsg.msgRandom) && msg.peerUin !== '284840486') { - throw new Error('回复消息消息验证失败'); - } - message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgId)?.toString(); - //log("找到回复消息", message_data['data']['id'], replyMsg.msgList[0].msgId) - } catch (e: any) { - message_data['type'] = 'unknown' as any; - message_data['data'] = undefined; - logger.logError('获取不到引用的消息', e.stack, element.replyElement.replayMsgSeq); - } - - } - else if (element.picElement) { - message_data['type'] = OB11MessageDataType.image; - // message_data["data"]["file"] = element.picElement.sourcePath - message_data['data']['file'] = element.picElement.fileName; - message_data['data']['subType'] = element.picElement.picSubType; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - // message_data["data"]["path"] = element.picElement.sourcePath - - try { - message_data['data']['url'] = await NTQQFileApi.getImageUrl(element.picElement); - } catch (e: any) { - logger.logError('获取图片url失败', e.stack); - } - //console.log(message_data['data']['url']) - // message_data["data"]["file_id"] = element.picElement.fileUuid - message_data['data']['file_size'] = element.picElement.fileSize; - } - else if (element.fileElement) { - const FileElement = element.fileElement; - message_data['type'] = OB11MessageDataType.file; - message_data['data']['file'] = FileElement.fileName; - message_data['data']['path'] = FileElement.filePath; - message_data['data']['url'] = FileElement.filePath; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - message_data['data']['file_size'] = FileElement.fileSize; - await NTQQFileApi.addFileCache({ - peerUid: msg.peerUid, - chatType: msg.chatType, - guildId: '', - }, - msg.msgId, - msg.msgSeq, - msg.senderUid, - element.elementId, - element.elementType.toString(), - FileElement.fileSize, - FileElement.fileName - ); - } - else if (element.videoElement) { - const videoElement: VideoElement = element.videoElement; - //读取视频链接并兜底 - let videoUrl;//Array - if (msg.peerUin = '284840486') { - //合并消息内部 应该进行特殊处理 可能需要重写peer 待测试与研究 Mlikiowa Taged TODO - } - try { - - videoUrl = await NTQQFileApi.getVideoUrl({ - chatType: msg.chatType, - peerUid: msg.peerUid, - guildId: '0' - }, msg.msgId, element.elementId); - } catch (error) { - videoUrl = undefined; - } - //读取在线URL - let videoDownUrl = undefined; - - if (videoUrl) { - const videoDownUrlTemp = videoUrl.find((url) => { if (url.url) { return true; } return false; }); - if (videoDownUrlTemp) { - videoDownUrl = videoDownUrlTemp.url; - } - } - //开始兜底 - if (!videoDownUrl) { - videoDownUrl = videoElement.filePath; - } - message_data['type'] = OB11MessageDataType.video; - message_data['data']['file'] = videoElement.fileName; - message_data['data']['path'] = videoDownUrl; - message_data['data']['url'] = videoDownUrl; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - message_data['data']['file_size'] = videoElement.fileSize; - - await NTQQFileApi.addFileCache({ - peerUid: msg.peerUid, - chatType: msg.chatType, - guildId: '', - }, - msg.msgId, - msg.msgSeq, - msg.senderUid, - element.elementId, - element.elementType.toString(), - videoElement.fileSize || '0', - videoElement.fileName - ); - } - else if (element.pttElement) { - message_data['type'] = OB11MessageDataType.voice; - message_data['data']['file'] = element.pttElement.fileName; - message_data['data']['path'] = element.pttElement.filePath; - //message_data['data']['file_id'] = element.pttElement.fileUuid; - message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); - message_data['data']['file_size'] = element.pttElement.fileSize; - await NTQQFileApi.addFileCache({ - peerUid: msg.peerUid, - chatType: msg.chatType, - guildId: '', - }, - msg.msgId, - msg.msgSeq, - msg.senderUid, - element.elementId, - element.elementType.toString(), - element.pttElement.fileSize || '0', - element.pttElement.fileUuid || '' - ); - //以uuid作为文件名 - } - else if (element.arkElement) { - message_data['type'] = OB11MessageDataType.json; - message_data['data']['data'] = element.arkElement.bytesData; - } - else if (element.faceElement) { - const faceId = element.faceElement.faceIndex; - if (faceId === FaceIndex.dice) { - message_data['type'] = OB11MessageDataType.dice; - message_data['data']['result'] = element.faceElement.resultId; - } - else if (faceId === FaceIndex.RPS) { - message_data['type'] = OB11MessageDataType.RPS; - message_data['data']['result'] = element.faceElement.resultId; - } - else { - message_data['type'] = OB11MessageDataType.face; - message_data['data']['id'] = element.faceElement.faceIndex.toString(); - } - } - else if (element.marketFaceElement) { - message_data['type'] = OB11MessageDataType.mface; - message_data['data']['summary'] = element.marketFaceElement.faceName; - const md5 = element.marketFaceElement.emojiId; - // 取md5的前两位 - const dir = md5.substring(0, 2); - // 获取组装url - // const url = `https://p.qpic.cn/CDN_STATIC/0/data/imgcache/htdocs/club/item/parcel/item/${dir}/${md5}/300x300.gif?max_age=31536000`; - const url = `https://gxh.vip.qq.com/club/item/parcel/item/${dir}/${md5}/raw300.gif`; - message_data['data']['url'] = url; - message_data['data']['emoji_id'] = element.marketFaceElement.emojiId; - message_data['data']['emoji_package_id'] = String(element.marketFaceElement.emojiPackageId); - message_data['data']['key'] = element.marketFaceElement.key; - //mFaceCache.set(md5, element.marketFaceElement.faceName); - } - else if (element.markdownElement) { - message_data['type'] = OB11MessageDataType.markdown; - message_data['data']['data'] = element.markdownElement.content; - } - else if (element.multiForwardMsgElement) { - message_data['type'] = OB11MessageDataType.forward; - message_data['data']['id'] = msg.msgId; - const ParentMsgPeer = msg.parentMsgPeer ?? { chatType: msg.chatType, guildId: '', peerUid: msg.peerUid }; - //判断是否在合并消息内 - msg.parentMsgIdList = msg.parentMsgIdList ?? []; - //首次列表不存在则开始创建 - msg.parentMsgIdList.push(msg.msgId); - //let parentMsgId = msg.parentMsgIdList[msg.parentMsgIdList.length - 2 < 0 ? 0 : msg.parentMsgIdList.length - 2]; - //加入自身MsgId - let MultiMsgs = (await NTQQMsgApi.getMultiMsg(ParentMsgPeer, msg.parentMsgIdList[0], msg.msgId))?.msgList; - //拉取下级消息 - if (!MultiMsgs) continue; - //拉取失败则跳过 - message_data['data']['content'] = []; - for (let MultiMsg of MultiMsgs) { - //对每条拉取的消息传递ParentMsgPeer修正Peer - MultiMsg.parentMsgPeer = ParentMsgPeer; - MultiMsg.parentMsgIdList = msg.parentMsgIdList; - MultiMsg.id = MessageUnique.createMsg(ParentMsgPeer, MultiMsg.msgId);//该ID仅用查看 无法调用 - let msgList = await OB11Constructor.message(coreContext, MultiMsg, "array"); - message_data['data']['content'].push(msgList); - //console.log("合并消息", msgList); - } - } - if ((message_data.type as string) !== 'unknown' && message_data.data) { - const cqCode = encodeCQCode(message_data); - - if (messagePostFormat === 'string') { - (resMsg.message as string) += cqCode; - } - else (resMsg.message as OB11MessageData[]).push(message_data); - resMsg.raw_message += cqCode; - } - - } - resMsg.raw_message = resMsg.raw_message.trim(); - return resMsg; - } - static async PrivateEvent(coreContext: NapCatCore, msg: RawMessage): Promise { - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - const NTQQUserApi = coreContext.getApiContext().UserApi; - const NTQQFileApi = coreContext.getApiContext().FileApi; - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - const logger = coreContext.context.logger; - if (msg.chatType !== ChatType.friend) { - return; - } - for (const element of msg.elements) { - if (element.grayTipElement) { - if (element.grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) { - const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr); - - if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) { - //判断业务类型 - //Poke事件 - let pokedetail: any[] = json.items; - //筛选item带有uid的元素 - pokedetail = pokedetail.filter(item => item.uid); - //console.log("[NapCat] 群拍一拍 群:", pokedetail, parseInt(msg.peerUid), " ", await NTQQUserApi.getUinByUid(pokedetail[0].uid), "拍了拍", await NTQQUserApi.getUinByUid(pokedetail[1].uid)); - if (pokedetail.length == 2) { - return new OB11FriendPokeEvent(parseInt((await NTQQUserApi.getUinByUid(pokedetail[0].uid))!), parseInt((await NTQQUserApi.getUinByUid(pokedetail[1].uid))!), pokedetail); + if (msg.chatType == ChatType.group) { + resMsg.sub_type = 'normal'; // 这里go-cqhttp是group,而onebot11标准是normal, 蛋疼 + resMsg.group_id = parseInt(msg.peerUin); + //直接去QQNative取 + const memberList = await NTQQGroupApi.getGroupMembers(msg.peerUin); + const member = memberList.get(msg.senderUin!); + if (member) { + resMsg.sender.role = OB11Constructor.groupMemberRole(member.role); + resMsg.sender.nickname = member.nick; } - } - //下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE } - if (element.grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER) { - //好友添加成功事件 - if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') { - return new OB11FriendAddNoticeEvent(parseInt(msg.peerUin)); - } + else if (msg.chatType == ChatType.friend) { + resMsg.sub_type = 'friend'; + resMsg.sender.nickname = (await NTQQUserApi.getUserDetailInfo(msg.senderUid)).nick; + //const user = await NTQQUserApi.getUserDetailInfoByUin(msg.senderUin!); + //resMsg.sender.nickname = user.info.nick; } - } - } - } - static async GroupEvent(coreContext:NapCatCore,msg: RawMessage): Promise { - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - const NTQQUserApi = coreContext.getApiContext().UserApi; - const NTQQFileApi = coreContext.getApiContext().FileApi; - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - const logger = coreContext.context.logger; - if (msg.chatType !== ChatType.group) { - return; - } - //log("group msg", msg); - // Mlikiowa V2.0.0 Refactor Todo - // if (msg.senderUin && msg.senderUin !== '0') { - // const member = await getGroupMember(msg.peerUid, msg.senderUin); - // if (member && member.cardName !== msg.sendMemberName) { - // const newCardName = msg.sendMemberName || ''; - // const event = new OB11GroupCardEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName); - // member.cardName = newCardName; - // return event; - // } - // } - - for (const element of msg.elements) { - const grayTipElement = element.grayTipElement; - const groupElement = grayTipElement?.groupElement; - if (groupElement) { - // log("收到群提示消息", groupElement) - if (groupElement.type == TipGroupElementType.memberIncrease) { - logger.logDebug('收到群成员增加消息', groupElement); - await sleep(1000); - const member = await getGroupMember(msg.peerUid, groupElement.memberUid); - const memberUin = member?.uin; - // if (!memberUin) { - // memberUin = (await NTQQUserApi.getUserDetailInfo(groupElement.memberUid)).uin - // } - // log("获取新群成员QQ", memberUin) - const adminMember = await getGroupMember(msg.peerUid, groupElement.adminUid); - // log("获取同意新成员入群的管理员", adminMember) - if (memberUin) { - const operatorUin = adminMember?.uin || memberUin; - const event = new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(operatorUin)); - // log("构造群增加事件", event) - return event; - } + else if (msg.chatType == ChatType.temp) { + resMsg.sub_type = 'group'; } - else if (groupElement.type === TipGroupElementType.ban) { - logger.logDebug('收到群群员禁言提示', groupElement); - const memberUid = groupElement.shutUp!.member.uid; - const adminUid = groupElement.shutUp!.admin.uid; - let memberUin: string = ''; - let duration = parseInt(groupElement.shutUp!.duration); - const sub_type: 'ban' | 'lift_ban' = duration > 0 ? 'ban' : 'lift_ban'; - // log('OB11被禁言事件', adminUid); - if (memberUid) { - memberUin = (await getGroupMember(msg.peerUid, memberUid))?.uin || ''; // || (await NTQQUserApi.getUserDetailInfo(memberUid))?.uin - } - else { - memberUin = '0'; // 0表示全员禁言 - if (duration > 0) { - duration = -1; - } - } - const adminUin = (await getGroupMember(msg.peerUid, adminUid))?.uin; // || (await NTQQUserApi.getUserDetailInfo(adminUid))?.uin - // log('OB11被禁言事件', memberUin, adminUin, duration, sub_type); - if (memberUin && adminUin) { - const event = new OB11GroupBanEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(adminUin), duration, sub_type); - return event; - } - } - else if (groupElement.type == TipGroupElementType.kicked) { - logger.logDebug(`收到我被踢出或退群提示, 群${msg.peerUid}`, groupElement); - NTQQGroupApi.quitGroup(msg.peerUid).then(); - try { - const adminUin = (await getGroupMember(msg.peerUid, groupElement.adminUid))?.uin || (await NTQQUserApi.getUidByUin(groupElement.adminUid)); - if (adminUin) { - return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(coreContext.selfInfo.uin), parseInt(adminUin), 'kick_me'); - } - } catch (e) { - return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(coreContext.selfInfo.uin), 0, 'leave'); - } - } - } - else if (element.fileElement) { - return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin || ''), { - id: element.fileElement.fileUuid!, - name: element.fileElement.fileName, - size: parseInt(element.fileElement.fileSize), - busid: element.fileElement.fileBizId || 0 - }); - } - if (grayTipElement) { - //console.log('收到群提示消息', grayTipElement); - if (grayTipElement.xmlElement?.templId === '10382') { - const emojiLikeData = new fastXmlParser.XMLParser({ - ignoreAttributes: false, - attributeNamePrefix: '' - }).parse(grayTipElement.xmlElement.content); - logger.logDebug('收到表情回应我的消息', emojiLikeData); - try { - const senderUin = emojiLikeData.gtip.qq.jp; - const msgSeq = emojiLikeData.gtip.url.msgseq; - const emojiId = emojiLikeData.gtip.face.id; - - const replyMsgList = (await NTQQMsgApi.getMsgsBySeqAndCount({ chatType: ChatType.group, guildId: '', peerUid: msg.peerUid }, msgSeq, 1, true, true)).msgList; - if (replyMsgList.length < 1) { - return; - } - console.log('表情回应消息', msgSeq, " 结算ID", replyMsgList[0].msgId); - const replyMsg = replyMsgList[0]; - return new OB11GroupMsgEmojiLikeEvent(parseInt(msg.peerUid), parseInt(senderUin), MessageUnique.getShortIdByMsgId(replyMsg?.msgId!)!, [{ - emoji_id: emojiId, - count: 1 - }]); - } catch (e: any) { - logger.logError('解析表情回应消息失败', e.stack); - } - } - if (grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER) { - logger.logDebug('收到新人被邀请进群消息', grayTipElement); - const xmlElement = grayTipElement.xmlElement; - if (xmlElement?.content) { - const regex = /jp="(\d+)"/g; - - const matches = []; - let match = null; - - while ((match = regex.exec(xmlElement.content)) !== null) { - matches.push(match[1]); - } - // log("新人进群匹配到的QQ号", matches) - if (matches.length === 2) { - const [inviter, invitee] = matches; - return new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(invitee), parseInt(inviter), 'invite'); - } - } - } - //代码歧义 GrayTipElementSubType.MEMBER_NEW_TITLE - else if (grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) { - const json = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr); - if (grayTipElement.jsonGrayTipElement.busiId == 1061) { - //判断业务类型 - //Poke事件 - const pokedetail: any[] = json.items; - //筛选item带有uid的元素 - const poke_uid = pokedetail.filter(item => item.uid); - if (poke_uid.length == 2) { - return new OB11GroupPokeEvent(parseInt(msg.peerUid), parseInt((await NTQQUserApi.getUinByUid(poke_uid[0].uid))!), parseInt((await NTQQUserApi.getUinByUid(poke_uid[1].uid))!), pokedetail); - } - } - if (grayTipElement.jsonGrayTipElement.busiId == 2401) { - const searchParams = new URL(json.items[0].jp).searchParams; - const msgSeq = searchParams.get('msgSeq')!; - const Group = searchParams.get('groupCode'); - const Businessid = searchParams.get('businessid'); - const Peer: Peer = { - guildId: '', - chatType: ChatType.group, - peerUid: Group! + for (const element of msg.elements) { + let message_data: OB11MessageData = { + data: {} as any, + type: 'unknown' as any }; - const msgData = await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true); - return new OB11GroupEssenceEvent(parseInt(msg.peerUid), MessageUnique.getShortIdByMsgId(msgData.msgList[0].msgId)!, parseInt(msgData.msgList[0].senderUin)); - // 获取MsgSeq+Peer可获取具体消息 - } - if (grayTipElement.jsonGrayTipElement.busiId == 2407) { - //下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE - const memberUin = json.items[1].param[0]; - const title = json.items[3].txt; - logger.logDebug('收到群成员新头衔消息', json); - return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title); - } + if (element.textElement && element.textElement?.atType !== AtType.notAt) { + let qq: `${number}` | 'all'; + let name: string | undefined; + if (element.textElement.atType == AtType.atAll) { + qq = 'all'; + } + else { + const { atNtUid, content } = element.textElement; + let atQQ = element.textElement.atUid; + if (!atQQ || atQQ === '0') { + atQQ = await NTQQUserApi.getUinByUid(atNtUid); + } + if (atQQ) { + qq = atQQ as `${number}`; + name = content.replace('@', ''); + } + } + message_data = { + type: OB11MessageDataType.at, + data: { + qq: qq!, + name + } + }; + } + else if (element.textElement) { + message_data['type'] = OB11MessageDataType.text; + + let text = element.textElement.content; + if (!text.trim()) { + continue; + } + // 兼容 9.7.x 换行符 + if (text.indexOf('\n') === -1 && text.indexOf('\r\n') === -1) { + text = text.replace(/\r/g, '\n'); + } + message_data['data']['text'] = text; + } + else if (element.replyElement) { + message_data['type'] = OB11MessageDataType.reply; + //log("收到回复消息", element.replyElement); + try { + const records = msg.records.find(msgRecord => msgRecord.msgId === element.replyElement.sourceMsgIdInRecords); + const peer = { + chatType: msg.chatType, + peerUid: msg.peerUid, + guildId: '', + }; + let replyMsg: RawMessage | undefined; + if (!records) throw new Error('找不到回复消息'); + replyMsg = (await NTQQMsgApi.getMsgsBySeqAndCount({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, element.replyElement.replayMsgSeq, 1, true, true)).msgList[0]; + if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { + replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replyElement.replayMsgSeq)).msgList[0]; + } + if (msg.peerUin == '284840486') { + //合并消息内侧 消息具体定位不到 + } + if ((!replyMsg || records.msgRandom !== replyMsg.msgRandom) && msg.peerUin !== '284840486') { + throw new Error('回复消息消息验证失败'); + } + message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgId)?.toString(); + //log("找到回复消息", message_data['data']['id'], replyMsg.msgList[0].msgId) + } catch (e: any) { + message_data['type'] = 'unknown' as any; + message_data['data'] = undefined; + logger.logError('获取不到引用的消息', e.stack, element.replyElement.replayMsgSeq); + } + + } + else if (element.picElement) { + message_data['type'] = OB11MessageDataType.image; + // message_data["data"]["file"] = element.picElement.sourcePath + message_data['data']['file'] = element.picElement.fileName; + message_data['data']['subType'] = element.picElement.picSubType; + message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); + // message_data["data"]["path"] = element.picElement.sourcePath + + try { + message_data['data']['url'] = await NTQQFileApi.getImageUrl(element.picElement); + } catch (e: any) { + logger.logError('获取图片url失败', e.stack); + } + //console.log(message_data['data']['url']) + // message_data["data"]["file_id"] = element.picElement.fileUuid + message_data['data']['file_size'] = element.picElement.fileSize; + } + else if (element.fileElement) { + const FileElement = element.fileElement; + message_data['type'] = OB11MessageDataType.file; + message_data['data']['file'] = FileElement.fileName; + message_data['data']['path'] = FileElement.filePath; + message_data['data']['url'] = FileElement.filePath; + message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); + message_data['data']['file_size'] = FileElement.fileSize; + await NTQQFileApi.addFileCache({ + peerUid: msg.peerUid, + chatType: msg.chatType, + guildId: '', + }, + msg.msgId, + msg.msgSeq, + msg.senderUid, + element.elementId, + element.elementType.toString(), + FileElement.fileSize, + FileElement.fileName + ); + } + else if (element.videoElement) { + const videoElement: VideoElement = element.videoElement; + //读取视频链接并兜底 + let videoUrl;//Array + if (msg.peerUin === '284840486') { + //合并消息内部 应该进行特殊处理 可能需要重写peer 待测试与研究 Mlikiowa Taged TODO + } + try { + + videoUrl = await NTQQFileApi.getVideoUrl({ + chatType: msg.chatType, + peerUid: msg.peerUid, + guildId: '0' + }, msg.msgId, element.elementId); + } catch (error) { + videoUrl = undefined; + } + //读取在线URL + let videoDownUrl = undefined; + + if (videoUrl) { + const videoDownUrlTemp = videoUrl.find((url) => { if (url.url) { return true; } return false; }); + if (videoDownUrlTemp) { + videoDownUrl = videoDownUrlTemp.url; + } + } + //开始兜底 + if (!videoDownUrl) { + videoDownUrl = videoElement.filePath; + } + message_data['type'] = OB11MessageDataType.video; + message_data['data']['file'] = videoElement.fileName; + message_data['data']['path'] = videoDownUrl; + message_data['data']['url'] = videoDownUrl; + message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); + message_data['data']['file_size'] = videoElement.fileSize; + + await NTQQFileApi.addFileCache({ + peerUid: msg.peerUid, + chatType: msg.chatType, + guildId: '', + }, + msg.msgId, + msg.msgSeq, + msg.senderUid, + element.elementId, + element.elementType.toString(), + videoElement.fileSize || '0', + videoElement.fileName + ); + } + else if (element.pttElement) { + message_data['type'] = OB11MessageDataType.voice; + message_data['data']['file'] = element.pttElement.fileName; + message_data['data']['path'] = element.pttElement.filePath; + //message_data['data']['file_id'] = element.pttElement.fileUuid; + message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId); + message_data['data']['file_size'] = element.pttElement.fileSize; + await NTQQFileApi.addFileCache({ + peerUid: msg.peerUid, + chatType: msg.chatType, + guildId: '', + }, + msg.msgId, + msg.msgSeq, + msg.senderUid, + element.elementId, + element.elementType.toString(), + element.pttElement.fileSize || '0', + element.pttElement.fileUuid || '' + ); + //以uuid作为文件名 + } + else if (element.arkElement) { + message_data['type'] = OB11MessageDataType.json; + message_data['data']['data'] = element.arkElement.bytesData; + } + else if (element.faceElement) { + const faceId = element.faceElement.faceIndex; + if (faceId === FaceIndex.dice) { + message_data['type'] = OB11MessageDataType.dice; + message_data['data']['result'] = element.faceElement.resultId; + } + else if (faceId === FaceIndex.RPS) { + message_data['type'] = OB11MessageDataType.RPS; + message_data['data']['result'] = element.faceElement.resultId; + } + else { + message_data['type'] = OB11MessageDataType.face; + message_data['data']['id'] = element.faceElement.faceIndex.toString(); + } + } + else if (element.marketFaceElement) { + message_data['type'] = OB11MessageDataType.mface; + message_data['data']['summary'] = element.marketFaceElement.faceName; + const md5 = element.marketFaceElement.emojiId; + // 取md5的前两位 + const dir = md5.substring(0, 2); + // 获取组装url + // const url = `https://p.qpic.cn/CDN_STATIC/0/data/imgcache/htdocs/club/item/parcel/item/${dir}/${md5}/300x300.gif?max_age=31536000`; + const url = `https://gxh.vip.qq.com/club/item/parcel/item/${dir}/${md5}/raw300.gif`; + message_data['data']['url'] = url; + message_data['data']['emoji_id'] = element.marketFaceElement.emojiId; + message_data['data']['emoji_package_id'] = String(element.marketFaceElement.emojiPackageId); + message_data['data']['key'] = element.marketFaceElement.key; + //mFaceCache.set(md5, element.marketFaceElement.faceName); + } + else if (element.markdownElement) { + message_data['type'] = OB11MessageDataType.markdown; + message_data['data']['data'] = element.markdownElement.content; + } + else if (element.multiForwardMsgElement) { + message_data['type'] = OB11MessageDataType.forward; + message_data['data']['id'] = msg.msgId; + const ParentMsgPeer = msg.parentMsgPeer ?? { chatType: msg.chatType, guildId: '', peerUid: msg.peerUid }; + //判断是否在合并消息内 + msg.parentMsgIdList = msg.parentMsgIdList ?? []; + //首次列表不存在则开始创建 + msg.parentMsgIdList.push(msg.msgId); + //let parentMsgId = msg.parentMsgIdList[msg.parentMsgIdList.length - 2 < 0 ? 0 : msg.parentMsgIdList.length - 2]; + //加入自身MsgId + const MultiMsgs = (await NTQQMsgApi.getMultiMsg(ParentMsgPeer, msg.parentMsgIdList[0], msg.msgId))?.msgList; + //拉取下级消息 + if (!MultiMsgs) continue; + //拉取失败则跳过 + message_data['data']['content'] = []; + for (const MultiMsg of MultiMsgs) { + //对每条拉取的消息传递ParentMsgPeer修正Peer + MultiMsg.parentMsgPeer = ParentMsgPeer; + MultiMsg.parentMsgIdList = msg.parentMsgIdList; + MultiMsg.id = MessageUnique.createMsg(ParentMsgPeer, MultiMsg.msgId);//该ID仅用查看 无法调用 + const msgList = await OB11Constructor.message(coreContext, MultiMsg, "array"); + message_data['data']['content'].push(msgList); + //console.log("合并消息", msgList); + } + } + if ((message_data.type as string) !== 'unknown' && message_data.data) { + const cqCode = encodeCQCode(message_data); + + if (messagePostFormat === 'string') { + (resMsg.message as string) += cqCode; + } + else (resMsg.message as OB11MessageData[]).push(message_data); + resMsg.raw_message += cqCode; + } + } - } + resMsg.raw_message = resMsg.raw_message.trim(); + return resMsg; } - } - static friend(friend: User): OB11User { - return { - user_id: parseInt(friend.uin), - nickname: friend.nick, - remark: friend.remark, - sex: OB11Constructor.sex(friend.sex!), - level: friend.qqLevel && calcQQLevel(friend.qqLevel) || 0 - }; - } + static async PrivateEvent(coreContext: NapCatCore, msg: RawMessage): Promise { + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + const NTQQUserApi = coreContext.getApiContext().UserApi; + const NTQQFileApi = coreContext.getApiContext().FileApi; + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + const logger = coreContext.context.logger; + if (msg.chatType !== ChatType.friend) { + return; + } + for (const element of msg.elements) { + if (element.grayTipElement) { + if (element.grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) { + const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr); - static selfInfo(selfInfo: SelfInfo): OB11User { - return { - user_id: parseInt(selfInfo.uin), - nickname: selfInfo.nick, - }; - } - static friendsV2(friends: FriendV2[]): OB11User[] { - const data: OB11User[] = []; - friends.forEach(friend => { - const sexValue = this.sex(friend.baseInfo.sex!); - data.push({ - ...friend.baseInfo, - ...friend.coreInfo, - user_id: parseInt(friend.coreInfo.uin), - nickname: friend.coreInfo.nick, - remark: friend.coreInfo.nick, - sex: sexValue, - level: 0, - categroyName: friend.categroyName, - categoryId: friend.categoryId - }); - }); - return data; - } - static friends(friends: Friend[]): OB11User[] { - const data: OB11User[] = []; - friends.forEach(friend => { - const sexValue = this.sex(friend.sex!); - data.push({ user_id: parseInt(friend.uin), nickname: friend.nick, remark: friend.remark, sex: sexValue, level: 0 }); - }); - return data; - } + if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) { + //判断业务类型 + //Poke事件 + let pokedetail: any[] = json.items; + //筛选item带有uid的元素 + pokedetail = pokedetail.filter(item => item.uid); + //console.log("[NapCat] 群拍一拍 群:", pokedetail, parseInt(msg.peerUid), " ", await NTQQUserApi.getUinByUid(pokedetail[0].uid), "拍了拍", await NTQQUserApi.getUinByUid(pokedetail[1].uid)); + if (pokedetail.length == 2) { + return new OB11FriendPokeEvent(parseInt((await NTQQUserApi.getUinByUid(pokedetail[0].uid))!), parseInt((await NTQQUserApi.getUinByUid(pokedetail[1].uid))!), pokedetail); + } + } + //下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE + } + if (element.grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER) { + //好友添加成功事件 + if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') { + return new OB11FriendAddNoticeEvent(parseInt(msg.peerUin)); + } + } + } + } + } + static async GroupEvent(coreContext:NapCatCore,msg: RawMessage): Promise { + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + const NTQQUserApi = coreContext.getApiContext().UserApi; + const NTQQFileApi = coreContext.getApiContext().FileApi; + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + const logger = coreContext.context.logger; + if (msg.chatType !== ChatType.group) { + return; + } + //log("group msg", msg); + // Mlikiowa V2.0.0 Refactor Todo + // if (msg.senderUin && msg.senderUin !== '0') { + // const member = await getGroupMember(msg.peerUid, msg.senderUin); + // if (member && member.cardName !== msg.sendMemberName) { + // const newCardName = msg.sendMemberName || ''; + // const event = new OB11GroupCardEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName); + // member.cardName = newCardName; + // return event; + // } + // } - static groupMemberRole(role: number): OB11GroupMemberRole | undefined { - return { - 4: OB11GroupMemberRole.owner, - 3: OB11GroupMemberRole.admin, - 2: OB11GroupMemberRole.member - }[role]; - } + for (const element of msg.elements) { + const grayTipElement = element.grayTipElement; + const groupElement = grayTipElement?.groupElement; + if (groupElement) { + // log("收到群提示消息", groupElement) + if (groupElement.type == TipGroupElementType.memberIncrease) { + logger.logDebug('收到群成员增加消息', groupElement); + await sleep(1000); + const member = await getGroupMember(msg.peerUid, groupElement.memberUid); + const memberUin = member?.uin; + // if (!memberUin) { + // memberUin = (await NTQQUserApi.getUserDetailInfo(groupElement.memberUid)).uin + // } + // log("获取新群成员QQ", memberUin) + const adminMember = await getGroupMember(msg.peerUid, groupElement.adminUid); + // log("获取同意新成员入群的管理员", adminMember) + if (memberUin) { + const operatorUin = adminMember?.uin || memberUin; + const event = new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(operatorUin)); + // log("构造群增加事件", event) + return event; + } + } + else if (groupElement.type === TipGroupElementType.ban) { + logger.logDebug('收到群群员禁言提示', groupElement); + const memberUid = groupElement.shutUp!.member.uid; + const adminUid = groupElement.shutUp!.admin.uid; + let memberUin: string = ''; + let duration = parseInt(groupElement.shutUp!.duration); + const sub_type: 'ban' | 'lift_ban' = duration > 0 ? 'ban' : 'lift_ban'; + // log('OB11被禁言事件', adminUid); + if (memberUid) { + memberUin = (await getGroupMember(msg.peerUid, memberUid))?.uin || ''; // || (await NTQQUserApi.getUserDetailInfo(memberUid))?.uin + } + else { + memberUin = '0'; // 0表示全员禁言 + if (duration > 0) { + duration = -1; + } + } + const adminUin = (await getGroupMember(msg.peerUid, adminUid))?.uin; // || (await NTQQUserApi.getUserDetailInfo(adminUid))?.uin + // log('OB11被禁言事件', memberUin, adminUin, duration, sub_type); + if (memberUin && adminUin) { + const event = new OB11GroupBanEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(adminUin), duration, sub_type); + return event; + } + } + else if (groupElement.type == TipGroupElementType.kicked) { + logger.logDebug(`收到我被踢出或退群提示, 群${msg.peerUid}`, groupElement); + NTQQGroupApi.quitGroup(msg.peerUid).then(); + try { + const adminUin = (await getGroupMember(msg.peerUid, groupElement.adminUid))?.uin || (await NTQQUserApi.getUidByUin(groupElement.adminUid)); + if (adminUin) { + return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(coreContext.selfInfo.uin), parseInt(adminUin), 'kick_me'); + } + } catch (e) { + return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(coreContext.selfInfo.uin), 0, 'leave'); + } + } + } + else if (element.fileElement) { + return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin || ''), { + id: element.fileElement.fileUuid!, + name: element.fileElement.fileName, + size: parseInt(element.fileElement.fileSize), + busid: element.fileElement.fileBizId || 0 + }); + } + if (grayTipElement) { + //console.log('收到群提示消息', grayTipElement); + if (grayTipElement.xmlElement?.templId === '10382') { + const emojiLikeData = new fastXmlParser.XMLParser({ + ignoreAttributes: false, + attributeNamePrefix: '' + }).parse(grayTipElement.xmlElement.content); + logger.logDebug('收到表情回应我的消息', emojiLikeData); + try { + const senderUin = emojiLikeData.gtip.qq.jp; + const msgSeq = emojiLikeData.gtip.url.msgseq; + const emojiId = emojiLikeData.gtip.face.id; - static sex(sex: Sex): OB11UserSex { - const sexMap = { - [Sex.male]: OB11UserSex.male, - [Sex.female]: OB11UserSex.female, - [Sex.unknown]: OB11UserSex.unknown - }; - return sexMap[sex] || OB11UserSex.unknown; - } + const replyMsgList = (await NTQQMsgApi.getMsgsBySeqAndCount({ chatType: ChatType.group, guildId: '', peerUid: msg.peerUid }, msgSeq, 1, true, true)).msgList; + if (replyMsgList.length < 1) { + return; + } - static groupMember(group_id: string, member: GroupMember): OB11GroupMember { - return { - group_id: parseInt(group_id), - user_id: parseInt(member.uin), - nickname: member.nick, - card: member.cardName, - sex: OB11Constructor.sex(member.sex!), - age: 0, - area: '', - level: '0', - qq_level: member.qqLevel && calcQQLevel(member.qqLevel) || 0, - join_time: 0, // 暂时没法获取 - last_sent_time: 0, // 暂时没法获取 - title_expire_time: 0, - unfriendly: false, - card_changeable: true, - is_robot: member.isRobot, - shut_up_timestamp: member.shutUpTime, - role: OB11Constructor.groupMemberRole(member.role), - title: member.memberSpecialTitle || '', - }; - } + const replyMsg = replyMsgList[0]; + console.log('表情回应消息', msgSeq, " 结算ID", replyMsg.msgId); + return new OB11GroupMsgEmojiLikeEvent( + parseInt(msg.peerUid), + parseInt(senderUin), + MessageUnique.getShortIdByMsgId(replyMsg.msgId)!, + [{ + emoji_id: emojiId, + count: 1 + }] + ); + } catch (e: any) { + logger.logError('解析表情回应消息失败', e.stack); + } + } + if (grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER) { + logger.logDebug('收到新人被邀请进群消息', grayTipElement); + const xmlElement = grayTipElement.xmlElement; + if (xmlElement?.content) { + const regex = /jp="(\d+)"/g; - static stranger(user: User): OB11User { + const matches = []; + let match = null; + + while ((match = regex.exec(xmlElement.content)) !== null) { + matches.push(match[1]); + } + // log("新人进群匹配到的QQ号", matches) + if (matches.length === 2) { + const [inviter, invitee] = matches; + return new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(invitee), parseInt(inviter), 'invite'); + } + } + } + //代码歧义 GrayTipElementSubType.MEMBER_NEW_TITLE + else if (grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) { + const json = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr); + if (grayTipElement.jsonGrayTipElement.busiId == 1061) { + //判断业务类型 + //Poke事件 + const pokedetail: any[] = json.items; + //筛选item带有uid的元素 + const poke_uid = pokedetail.filter(item => item.uid); + if (poke_uid.length == 2) { + return new OB11GroupPokeEvent(parseInt(msg.peerUid), parseInt((await NTQQUserApi.getUinByUid(poke_uid[0].uid))!), parseInt((await NTQQUserApi.getUinByUid(poke_uid[1].uid))!), pokedetail); + } + } + if (grayTipElement.jsonGrayTipElement.busiId == 2401) { + const searchParams = new URL(json.items[0].jp).searchParams; + const msgSeq = searchParams.get('msgSeq')!; + const Group = searchParams.get('groupCode'); + const Businessid = searchParams.get('businessid'); + const Peer: Peer = { + guildId: '', + chatType: ChatType.group, + peerUid: Group! + }; + const msgData = await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true); + return new OB11GroupEssenceEvent(parseInt(msg.peerUid), MessageUnique.getShortIdByMsgId(msgData.msgList[0].msgId)!, parseInt(msgData.msgList[0].senderUin)); + // 获取MsgSeq+Peer可获取具体消息 + } + if (grayTipElement.jsonGrayTipElement.busiId == 2407) { + //下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE + const memberUin = json.items[1].param[0]; + const title = json.items[3].txt; + logger.logDebug('收到群成员新头衔消息', json); + return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title); + } + } + } + } + } + static friend(friend: User): OB11User { + return { + user_id: parseInt(friend.uin), + nickname: friend.nick, + remark: friend.remark, + sex: OB11Constructor.sex(friend.sex!), + level: friend.qqLevel && calcQQLevel(friend.qqLevel) || 0 + }; + } + + static selfInfo(selfInfo: SelfInfo): OB11User { + return { + user_id: parseInt(selfInfo.uin), + nickname: selfInfo.nick, + }; + } + static friendsV2(friends: FriendV2[]): OB11User[] { + const data: OB11User[] = []; + friends.forEach(friend => { + const sexValue = this.sex(friend.baseInfo.sex!); + data.push({ + ...friend.baseInfo, + ...friend.coreInfo, + user_id: parseInt(friend.coreInfo.uin), + nickname: friend.coreInfo.nick, + remark: friend.coreInfo.nick, + sex: sexValue, + level: 0, + categroyName: friend.categroyName, + categoryId: friend.categoryId + }); + }); + return data; + } + static friends(friends: Friend[]): OB11User[] { + const data: OB11User[] = []; + friends.forEach(friend => { + const sexValue = this.sex(friend.sex!); + data.push({ user_id: parseInt(friend.uin), nickname: friend.nick, remark: friend.remark, sex: sexValue, level: 0 }); + }); + return data; + } + + static groupMemberRole(role: number): OB11GroupMemberRole | undefined { + return { + 4: OB11GroupMemberRole.owner, + 3: OB11GroupMemberRole.admin, + 2: OB11GroupMemberRole.member + }[role]; + } + + static sex(sex: Sex): OB11UserSex { + const sexMap = { + [Sex.male]: OB11UserSex.male, + [Sex.female]: OB11UserSex.female, + [Sex.unknown]: OB11UserSex.unknown + }; + return sexMap[sex] || OB11UserSex.unknown; + } + + static groupMember(group_id: string, member: GroupMember): OB11GroupMember { + return { + group_id: parseInt(group_id), + user_id: parseInt(member.uin), + nickname: member.nick, + card: member.cardName, + sex: OB11Constructor.sex(member.sex!), + age: 0, + area: '', + level: '0', + qq_level: member.qqLevel && calcQQLevel(member.qqLevel) || 0, + join_time: 0, // 暂时没法获取 + last_sent_time: 0, // 暂时没法获取 + title_expire_time: 0, + unfriendly: false, + card_changeable: true, + is_robot: member.isRobot, + shut_up_timestamp: member.shutUpTime, + role: OB11Constructor.groupMemberRole(member.role), + title: member.memberSpecialTitle || '', + }; + } + + static stranger(user: User): OB11User { //logDebug('construct ob11 stranger', user); - return { - ...user, - user_id: parseInt(user.uin), - nickname: user.nick, - sex: OB11Constructor.sex(user.sex!), - age: 0, - qid: user.qid, - login_days: 0, - level: user.qqLevel && calcQQLevel(user.qqLevel) || 0, - }; - } + return { + ...user, + user_id: parseInt(user.uin), + nickname: user.nick, + sex: OB11Constructor.sex(user.sex!), + age: 0, + qid: user.qid, + login_days: 0, + level: user.qqLevel && calcQQLevel(user.qqLevel) || 0, + }; + } - static group(group: Group): OB11Group { - return { - group_id: parseInt(group.groupCode), - group_name: group.groupName, - member_count: group.memberCount, - max_member_count: group.maxMember - }; - } + static group(group: Group): OB11Group { + return { + group_id: parseInt(group.groupCode), + group_name: group.groupName, + member_count: group.memberCount, + max_member_count: group.maxMember + }; + } - static groups(groups: Group[]): OB11Group[] { - return groups.map(OB11Constructor.group); - } + static groups(groups: Group[]): OB11Group[] { + return groups.map(OB11Constructor.group); + } } diff --git a/src/onebot/helper/msg.ts b/src/onebot/helper/msg.ts index 8a0c7012..6720644a 100644 --- a/src/onebot/helper/msg.ts +++ b/src/onebot/helper/msg.ts @@ -1,17 +1,17 @@ import { - AtType, - ElementType, FaceIndex, FaceType, NapCatCore, PicElement, - PicType, - SendArkElement, - SendFaceElement, - SendFileElement, SendMarkdownElement, SendMarketFaceElement, - SendPicElement, - SendPttElement, - SendReplyElement, - sendShareLocationElement, - SendTextElement, - SendVideoElement, - viedo_type + AtType, + ElementType, FaceIndex, FaceType, NapCatCore, PicElement, + PicType, + SendArkElement, + SendFaceElement, + SendFileElement, SendMarkdownElement, SendMarketFaceElement, + SendPicElement, + SendPttElement, + SendReplyElement, + sendShareLocationElement, + SendTextElement, + SendVideoElement, + viedo_type } from '@/core'; import { promises as fs } from 'node:fs'; import ffmpeg from 'fluent-ffmpeg'; @@ -23,379 +23,379 @@ import { isNull } from '@/common/utils/helper'; import faceConfig from '@/core/external/face_config.json'; import * as pathLib from 'node:path'; export class SendMsgElementConstructor { - static location(CoreContext: NapCatCore): sendShareLocationElement { - return { - elementType: ElementType.SHARELOCATION, - elementId: '', - shareLocationElement: { - text: "测试", - ext: "" - } + static location(CoreContext: NapCatCore): sendShareLocationElement { + return { + elementType: ElementType.SHARELOCATION, + elementId: '', + shareLocationElement: { + text: "测试", + ext: "" + } + }; } - } - static text(CoreContext: NapCatCore, content: string): SendTextElement { - return { - elementType: ElementType.TEXT, - elementId: '', - textElement: { - content, - atType: AtType.notAt, - atUid: '', - atTinyId: '', - atNtUid: '', - }, - }; - } - - static at(CoreContext: NapCatCore, atUid: string, atNtUid: string, atType: AtType, atName: string): SendTextElement { - return { - elementType: ElementType.TEXT, - elementId: '', - textElement: { - content: `@${atName}`, - atType, - atUid, - atTinyId: '', - atNtUid, - }, - }; - } - - static reply(CoreContext: NapCatCore, msgSeq: string, msgId: string, senderUin: string, senderUinStr: string): SendReplyElement { - return { - elementType: ElementType.REPLY, - elementId: '', - replyElement: { - replayMsgSeq: msgSeq, // raw.msgSeq - replayMsgId: msgId, // raw.msgId - senderUin: senderUin, - senderUinStr: senderUinStr, - } - }; - } - - static async pic(coreContext: NapCatCore, picPath: string, summary: string = '', subType: 0 | 1 = 0): Promise { - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - const NTQQUserApi = coreContext.getApiContext().UserApi; - const NTQQFileApi = coreContext.getApiContext().FileApi; - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - const logger = coreContext.context.logger; - const { md5, fileName, path, fileSize } = await NTQQFileApi.uploadFile(picPath, ElementType.PIC, subType); - if (fileSize === 0) { - throw '文件异常,大小为0'; + static text(CoreContext: NapCatCore, content: string): SendTextElement { + return { + elementType: ElementType.TEXT, + elementId: '', + textElement: { + content, + atType: AtType.notAt, + atUid: '', + atTinyId: '', + atNtUid: '', + }, + }; } - const imageSize = await NTQQFileApi.getImageSize(picPath); - const picElement: any = { - md5HexStr: md5, - fileSize: fileSize.toString(), - picWidth: imageSize?.width, - picHeight: imageSize?.height, - fileName: fileName, - sourcePath: path, - original: true, - picType: isGIF(picPath) ? PicType.gif : PicType.jpg, - picSubType: subType, - fileUuid: '', - fileSubId: '', - thumbFileSize: 0, - summary - }; - //logDebug('图片信息', picElement); - return { - elementType: ElementType.PIC, - elementId: '', - picElement, - }; - } - static async file(coreContext: NapCatCore, filePath: string, fileName: string = '', folderId: string = ''): Promise { - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - const NTQQUserApi = coreContext.getApiContext().UserApi; - const NTQQFileApi = coreContext.getApiContext().FileApi; - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - const logger = coreContext.context.logger; - const { md5, fileName: _fileName, path, fileSize } = await NTQQFileApi.uploadFile(filePath, ElementType.FILE); - if (fileSize === 0) { - throw '文件异常,大小为0'; + static at(CoreContext: NapCatCore, atUid: string, atNtUid: string, atType: AtType, atName: string): SendTextElement { + return { + elementType: ElementType.TEXT, + elementId: '', + textElement: { + content: `@${atName}`, + atType, + atUid, + atTinyId: '', + atNtUid, + }, + }; } - const element: SendFileElement = { - elementType: ElementType.FILE, - elementId: '', - fileElement: { - fileName: fileName || _fileName, - folderId: folderId, - 'filePath': path!, - 'fileSize': (fileSize).toString(), - } - }; - return element; - } + static reply(CoreContext: NapCatCore, msgSeq: string, msgId: string, senderUin: string, senderUinStr: string): SendReplyElement { + return { + elementType: ElementType.REPLY, + elementId: '', + replyElement: { + replayMsgSeq: msgSeq, // raw.msgSeq + replayMsgId: msgId, // raw.msgId + senderUin: senderUin, + senderUinStr: senderUinStr, + } + }; + } - static async video(coreContext: NapCatCore, filePath: string, fileName: string = '', diyThumbPath: string = '', videotype: viedo_type = viedo_type.VIDEO_FORMAT_MP4): Promise { - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - const NTQQUserApi = coreContext.getApiContext().UserApi; - const NTQQFileApi = coreContext.getApiContext().FileApi; - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - const logger = coreContext.context.logger; - const { fileName: _fileName, path, fileSize, md5 } = await NTQQFileApi.uploadFile(filePath, ElementType.VIDEO); - if (fileSize === 0) { - throw '文件异常,大小为0'; + static async pic(coreContext: NapCatCore, picPath: string, summary: string = '', subType: 0 | 1 = 0): Promise { + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + const NTQQUserApi = coreContext.getApiContext().UserApi; + const NTQQFileApi = coreContext.getApiContext().FileApi; + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + const logger = coreContext.context.logger; + const { md5, fileName, path, fileSize } = await NTQQFileApi.uploadFile(picPath, ElementType.PIC, subType); + if (fileSize === 0) { + throw '文件异常,大小为0'; + } + const imageSize = await NTQQFileApi.getImageSize(picPath); + const picElement: any = { + md5HexStr: md5, + fileSize: fileSize.toString(), + picWidth: imageSize?.width, + picHeight: imageSize?.height, + fileName: fileName, + sourcePath: path, + original: true, + picType: isGIF(picPath) ? PicType.gif : PicType.jpg, + picSubType: subType, + fileUuid: '', + fileSubId: '', + thumbFileSize: 0, + summary + }; + //logDebug('图片信息', picElement); + return { + elementType: ElementType.PIC, + elementId: '', + picElement, + }; } - let thumb = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`); - thumb = pathLib.dirname(thumb); - // log("thumb 目录", thumb) - let videoInfo = { - width: 1920, height: 1080, - time: 15, - format: 'mp4', - size: fileSize, - filePath - }; - try { - videoInfo = await getVideoInfo(path, logger); - //logDebug('视频信息', videoInfo); - } catch (e) { - logger.logError('获取视频信息失败', e); + + static async file(coreContext: NapCatCore, filePath: string, fileName: string = '', folderId: string = ''): Promise { + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + const NTQQUserApi = coreContext.getApiContext().UserApi; + const NTQQFileApi = coreContext.getApiContext().FileApi; + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + const logger = coreContext.context.logger; + const { md5, fileName: _fileName, path, fileSize } = await NTQQFileApi.uploadFile(filePath, ElementType.FILE); + if (fileSize === 0) { + throw '文件异常,大小为0'; + } + const element: SendFileElement = { + elementType: ElementType.FILE, + elementId: '', + fileElement: { + fileName: fileName || _fileName, + folderId: folderId, + 'filePath': path!, + 'fileSize': (fileSize).toString(), + } + }; + + return element; } - const createThumb = new Promise((resolve, reject) => { - const thumbFileName = `${md5}_0.png`; - const thumbPath = pathLib.join(thumb, thumbFileName); - ffmpeg(filePath) - .on('end', () => { - }) - .on('error', (err) => { - logger.logDebug('获取视频封面失败,使用默认封面', err); - if (diyThumbPath) { - fs.copyFile(diyThumbPath, thumbPath).then(() => { - resolve(thumbPath); - }).catch(reject); - } else { - fs.writeFile(thumbPath, defaultVideoThumb).then(() => { - resolve(thumbPath); - }).catch(reject); - } - }) - .screenshots({ - timestamps: [0], - filename: thumbFileName, - folder: thumb, - size: videoInfo.width + 'x' + videoInfo.height - }).on('end', () => { - resolve(thumbPath); + + static async video(coreContext: NapCatCore, filePath: string, fileName: string = '', diyThumbPath: string = '', videotype: viedo_type = viedo_type.VIDEO_FORMAT_MP4): Promise { + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + const NTQQUserApi = coreContext.getApiContext().UserApi; + const NTQQFileApi = coreContext.getApiContext().FileApi; + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + const logger = coreContext.context.logger; + const { fileName: _fileName, path, fileSize, md5 } = await NTQQFileApi.uploadFile(filePath, ElementType.VIDEO); + if (fileSize === 0) { + throw '文件异常,大小为0'; + } + let thumb = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`); + thumb = pathLib.dirname(thumb); + // log("thumb 目录", thumb) + let videoInfo = { + width: 1920, height: 1080, + time: 15, + format: 'mp4', + size: fileSize, + filePath + }; + try { + videoInfo = await getVideoInfo(path, logger); + //logDebug('视频信息', videoInfo); + } catch (e) { + logger.logError('获取视频信息失败', e); + } + const createThumb = new Promise((resolve, reject) => { + const thumbFileName = `${md5}_0.png`; + const thumbPath = pathLib.join(thumb, thumbFileName); + ffmpeg(filePath) + .on('end', () => { + }) + .on('error', (err) => { + logger.logDebug('获取视频封面失败,使用默认封面', err); + if (diyThumbPath) { + fs.copyFile(diyThumbPath, thumbPath).then(() => { + resolve(thumbPath); + }).catch(reject); + } else { + fs.writeFile(thumbPath, defaultVideoThumb).then(() => { + resolve(thumbPath); + }).catch(reject); + } + }) + .screenshots({ + timestamps: [0], + filename: thumbFileName, + folder: thumb, + size: videoInfo.width + 'x' + videoInfo.height + }).on('end', () => { + resolve(thumbPath); + }); }); - }); - const thumbPath = new Map(); - const _thumbPath = await createThumb; - const thumbSize = (await fs.stat(_thumbPath)).size; - // log("生成缩略图", _thumbPath) - thumbPath.set(0, _thumbPath); - const thumbMd5 = await calculateFileMD5(_thumbPath); - const element: SendVideoElement = { - elementType: ElementType.VIDEO, - elementId: '', - videoElement: { - fileName: fileName || _fileName, - filePath: path, - videoMd5: md5, - thumbMd5, - fileTime: videoInfo.time, - thumbPath: thumbPath, - thumbSize, - thumbWidth: videoInfo.width, - thumbHeight: videoInfo.height, - fileSize: '' + fileSize, - //fileFormat: videotype - // fileUuid: "", - // transferStatus: 0, - // progress: 0, - // invalidState: 0, - // fileSubId: "", - // fileBizId: null, - // originVideoMd5: "", - // fileFormat: 2, - // import_rich_media_context: null, - // sourceVideoCodecFormat: 2 - } - }; - return element; - } + const thumbPath = new Map(); + const _thumbPath = await createThumb; + const thumbSize = (await fs.stat(_thumbPath)).size; + // log("生成缩略图", _thumbPath) + thumbPath.set(0, _thumbPath); + const thumbMd5 = await calculateFileMD5(_thumbPath); + const element: SendVideoElement = { + elementType: ElementType.VIDEO, + elementId: '', + videoElement: { + fileName: fileName || _fileName, + filePath: path, + videoMd5: md5, + thumbMd5, + fileTime: videoInfo.time, + thumbPath: thumbPath, + thumbSize, + thumbWidth: videoInfo.width, + thumbHeight: videoInfo.height, + fileSize: '' + fileSize, + //fileFormat: videotype + // fileUuid: "", + // transferStatus: 0, + // progress: 0, + // invalidState: 0, + // fileSubId: "", + // fileBizId: null, + // originVideoMd5: "", + // fileFormat: 2, + // import_rich_media_context: null, + // sourceVideoCodecFormat: 2 + } + }; + return element; + } - static async ptt(coreContext: NapCatCore, pttPath: string): Promise { - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - const NTQQUserApi = coreContext.getApiContext().UserApi; - const NTQQFileApi = coreContext.getApiContext().FileApi; - const NTQQMsgApi = coreContext.getApiContext().MsgApi; - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - const logger = coreContext.context.logger; - const { converted, path: silkPath, duration } = await encodeSilk(pttPath, coreContext.NapCatTempPath, coreContext.context.logger); - // log("生成语音", silkPath, duration); - if (!silkPath) { - throw '语音转换失败, 请检查语音文件是否正常'; + static async ptt(coreContext: NapCatCore, pttPath: string): Promise { + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + const NTQQUserApi = coreContext.getApiContext().UserApi; + const NTQQFileApi = coreContext.getApiContext().FileApi; + const NTQQMsgApi = coreContext.getApiContext().MsgApi; + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + const logger = coreContext.context.logger; + const { converted, path: silkPath, duration } = await encodeSilk(pttPath, coreContext.NapCatTempPath, coreContext.context.logger); + // log("生成语音", silkPath, duration); + if (!silkPath) { + throw '语音转换失败, 请检查语音文件是否正常'; + } + const { md5, fileName, path, fileSize } = await NTQQFileApi.uploadFile(silkPath!, ElementType.PTT); + if (fileSize === 0) { + throw '文件异常,大小为0'; + } + if (converted) { + fs.unlink(silkPath).then(); + } + return { + elementType: ElementType.PTT, + elementId: '', + pttElement: { + fileName: fileName, + filePath: path, + md5HexStr: md5, + fileSize: fileSize, + // duration: Math.max(1, Math.round(fileSize / 1024 / 3)), // 一秒钟大概是3kb大小, 小于1秒的按1秒算 + duration: duration || 1, + formatType: 1, + voiceType: 1, + voiceChangeType: 0, + canConvert2Text: true, + waveAmplitudes: [ + 0, 18, 9, 23, 16, 17, 16, 15, 44, 17, 24, 20, 14, 15, 17, + ], + fileSubId: '', + playState: 1, + autoConvertText: 0, + } + }; } - const { md5, fileName, path, fileSize } = await NTQQFileApi.uploadFile(silkPath!, ElementType.PTT); - if (fileSize === 0) { - throw '文件异常,大小为0'; - } - if (converted) { - fs.unlink(silkPath).then(); - } - return { - elementType: ElementType.PTT, - elementId: '', - pttElement: { - fileName: fileName, - filePath: path, - md5HexStr: md5, - fileSize: fileSize, - // duration: Math.max(1, Math.round(fileSize / 1024 / 3)), // 一秒钟大概是3kb大小, 小于1秒的按1秒算 - duration: duration || 1, - formatType: 1, - voiceType: 1, - voiceChangeType: 0, - canConvert2Text: true, - waveAmplitudes: [ - 0, 18, 9, 23, 16, 17, 16, 15, 44, 17, 24, 20, 14, 15, 17, - ], - fileSubId: '', - playState: 1, - autoConvertText: 0, - } - }; - } - // NodeIQQNTWrapperSession sendMsg [ - // "0", - // { - // "peerUid": "u_e_RIxgTs2NaJ68h0PwOPSg", - // "chatType": 1, - // "guildId": "" - // }, - // [ - // { - // "elementId": "0", - // "elementType": 6, - // "faceElement": { - // "faceIndex": 0, - // "faceType": 5, - // "msgType": 0, - // "pokeType": 1, - // "pokeStrength": 0 - // } - // } - // ], - // {} - // ] - static face(CoreContext: NapCatCore, faceId: number): SendFaceElement { + // NodeIQQNTWrapperSession sendMsg [ + // "0", + // { + // "peerUid": "u_e_RIxgTs2NaJ68h0PwOPSg", + // "chatType": 1, + // "guildId": "" + // }, + // [ + // { + // "elementId": "0", + // "elementType": 6, + // "faceElement": { + // "faceIndex": 0, + // "faceType": 5, + // "msgType": 0, + // "pokeType": 1, + // "pokeStrength": 0 + // } + // } + // ], + // {} + // ] + static face(CoreContext: NapCatCore, faceId: number): SendFaceElement { // 从face_config.json中获取表情名称 - const sysFaces = faceConfig.sysface; - const emojiFaces = faceConfig.emoji; - const face: any = sysFaces.find((face) => face.QSid === faceId.toString()); - faceId = parseInt(faceId.toString()); - // let faceType = parseInt(faceId.toString().substring(0, 1)); - let faceType = 1; - if (faceId >= 222) { - faceType = 2; + const sysFaces = faceConfig.sysface; + const emojiFaces = faceConfig.emoji; + const face: any = sysFaces.find((face) => face.QSid === faceId.toString()); + faceId = parseInt(faceId.toString()); + // let faceType = parseInt(faceId.toString().substring(0, 1)); + let faceType = 1; + if (faceId >= 222) { + faceType = 2; + } + if (face.AniStickerType) { + faceType = 3; + } + return { + elementType: ElementType.FACE, + elementId: '', + faceElement: { + faceIndex: faceId, + faceType, + faceText: face.QDes, + stickerId: face.AniStickerId, + stickerType: face.AniStickerType, + packId: face.AniStickerPackId, + sourceType: 1, + }, + }; } - if (face.AniStickerType) { - faceType = 3; + + static mface(CoreContext: NapCatCore, emojiPackageId: number, emojiId: string, key: string, faceName: string): SendMarketFaceElement { + return { + elementType: ElementType.MFACE, + marketFaceElement: { + emojiPackageId, + emojiId, + key, + faceName: faceName || '[商城表情]', + }, + }; } - return { - elementType: ElementType.FACE, - elementId: '', - faceElement: { - faceIndex: faceId, - faceType, - faceText: face.QDes, - stickerId: face.AniStickerId, - stickerType: face.AniStickerType, - packId: face.AniStickerPackId, - sourceType: 1, - }, - }; - } - static mface(CoreContext: NapCatCore, emojiPackageId: number, emojiId: string, key: string, faceName: string): SendMarketFaceElement { - return { - elementType: ElementType.MFACE, - marketFaceElement: { - emojiPackageId, - emojiId, - key, - faceName: faceName || '[商城表情]', - }, - }; - } - - static dice(CoreContext: NapCatCore, resultId: number | null): SendFaceElement { + static dice(CoreContext: NapCatCore, resultId: number | null): SendFaceElement { // 实际测试并不能控制结果 - // 随机1到6 - // if (isNull(resultId)) resultId = Math.floor(Math.random() * 6) + 1; - return { - elementType: ElementType.FACE, - elementId: '', - faceElement: { - faceIndex: FaceIndex.dice, - faceType: FaceType.dice, - 'faceText': '[骰子]', - 'packId': '1', - 'stickerId': '33', - 'sourceType': 1, - 'stickerType': 2, - // resultId: resultId.toString(), - 'surpriseId': '', - // "randomType": 1, - } - }; - } + // 随机1到6 + // if (isNull(resultId)) resultId = Math.floor(Math.random() * 6) + 1; + return { + elementType: ElementType.FACE, + elementId: '', + faceElement: { + faceIndex: FaceIndex.dice, + faceType: FaceType.dice, + 'faceText': '[骰子]', + 'packId': '1', + 'stickerId': '33', + 'sourceType': 1, + 'stickerType': 2, + // resultId: resultId.toString(), + 'surpriseId': '', + // "randomType": 1, + } + }; + } - // 猜拳(石头剪刀布)表情 - static rps(CoreContext: NapCatCore, resultId: number | null): SendFaceElement { + // 猜拳(石头剪刀布)表情 + static rps(CoreContext: NapCatCore, resultId: number | null): SendFaceElement { // 实际测试并不能控制结果 // if (isNull(resultId)) resultId = Math.floor(Math.random() * 3) + 1; - return { - elementType: ElementType.FACE, - elementId: '', - faceElement: { - 'faceIndex': FaceIndex.RPS, - 'faceText': '[包剪锤]', - 'faceType': 3, - 'packId': '1', - 'stickerId': '34', - 'sourceType': 1, - 'stickerType': 2, - // 'resultId': resultId.toString(), - 'surpriseId': '', - // "randomType": 1, - } - }; - } - - static ark(CoreContext: NapCatCore, data: any): SendArkElement { - if (typeof data !== 'string') { - data = JSON.stringify(data); + return { + elementType: ElementType.FACE, + elementId: '', + faceElement: { + 'faceIndex': FaceIndex.RPS, + 'faceText': '[包剪锤]', + 'faceType': 3, + 'packId': '1', + 'stickerId': '34', + 'sourceType': 1, + 'stickerType': 2, + // 'resultId': resultId.toString(), + 'surpriseId': '', + // "randomType": 1, + } + }; } - return { - elementType: ElementType.ARK, - elementId: '', - arkElement: { - bytesData: data, - linkInfo: null, - subElementType: null - } - }; - } - static markdown(CoreContext: NapCatCore, content: string): SendMarkdownElement { - return { - elementType: ElementType.MARKDOWN, - elementId: '', - markdownElement: { - content - } - }; - } + static ark(CoreContext: NapCatCore, data: any): SendArkElement { + if (typeof data !== 'string') { + data = JSON.stringify(data); + } + return { + elementType: ElementType.ARK, + elementId: '', + arkElement: { + bytesData: data, + linkInfo: null, + subElementType: null + } + }; + } + + static markdown(CoreContext: NapCatCore, content: string): SendMarkdownElement { + return { + elementType: ElementType.MARKDOWN, + elementId: '', + markdownElement: { + content + } + }; + } } diff --git a/src/onebot/server/http.ts b/src/onebot/server/http.ts index 53302df5..7e2e94b8 100644 --- a/src/onebot/server/http.ts +++ b/src/onebot/server/http.ts @@ -5,53 +5,53 @@ import { OB11HeartbeatEvent } from '@/onebot/event/meta/OB11HeartbeatEvent'; import { postOB11Event } from '@/onebot/server/postOB11Event'; class OB11HTTPServer extends HttpServerBase { - name = 'OneBot V11 server'; + name = 'OneBot V11 server'; - handleFailed(res: Response, payload: any, e: Error) { - res.send(OB11Response.error(e?.stack?.toString() || e.message || 'Error Handle', 200)); - } - - protected listen(port: number, host: string) { - if (ob11Config.http.enable) { - super.listen(port, host); + handleFailed(res: Response, payload: any, e: Error) { + res.send(OB11Response.error(e?.stack?.toString() || e.message || 'Error Handle', 200)); + } + + protected listen(port: number, host: string) { + if (ob11Config.http.enable) { + super.listen(port, host); + } } - } } export const ob11HTTPServer = new OB11HTTPServer(); setTimeout(() => { - for (const [actionName, action] of actionMap) { - for (const method of ['post', 'get']) { - ob11HTTPServer.registerRouter(method, actionName, (res, payload) => { - return action.handle(payload); - }); + for (const [actionName, action] of actionMap) { + for (const method of ['post', 'get']) { + ob11HTTPServer.registerRouter(method, actionName, (res, payload) => { + return action.handle(payload); + }); + } } - } }, 0); class HTTPHeart { - intervalId: NodeJS.Timeout | null = null; - start(NewHeartInterval: number | undefined = undefined) { - let { heartInterval } = ob11Config; - if (NewHeartInterval && !Number.isNaN(NewHeartInterval)) { - heartInterval = NewHeartInterval; + intervalId: NodeJS.Timeout | null = null; + start(NewHeartInterval: number | undefined = undefined) { + let { heartInterval } = ob11Config; + if (NewHeartInterval && !Number.isNaN(NewHeartInterval)) { + heartInterval = NewHeartInterval; + } + if (this.intervalId) { + clearInterval(this.intervalId); + } + this.intervalId = setInterval(() => { + // ws的心跳是ws自己维护的 + postOB11Event(new OB11HeartbeatEvent(!!selfInfo.online, true, heartInterval), false, false); + }, heartInterval); } - if (this.intervalId) { - clearInterval(this.intervalId); - } - this.intervalId = setInterval(() => { - // ws的心跳是ws自己维护的 - postOB11Event(new OB11HeartbeatEvent(!!selfInfo.online, true, heartInterval), false, false); - }, heartInterval); - } - stop() { - if (this.intervalId) { - clearInterval(this.intervalId); + stop() { + if (this.intervalId) { + clearInterval(this.intervalId); + } } - } } export const httpHeart = new HTTPHeart(); diff --git a/src/onebot/server/postOB11Event.ts b/src/onebot/server/postOB11Event.ts index c89e4932..9e489030 100644 --- a/src/onebot/server/postOB11Event.ts +++ b/src/onebot/server/postOB11Event.ts @@ -49,152 +49,152 @@ export type QuickAction = const eventWSList: WebSocketClass[] = []; export function registerWsEventSender(ws: WebSocketClass) { - eventWSList.push(ws); + eventWSList.push(ws); } export function unregisterWsEventSender(ws: WebSocketClass) { - const index = eventWSList.indexOf(ws); - if (index !== -1) { - eventWSList.splice(index, 1); - } + const index = eventWSList.indexOf(ws); + if (index !== -1) { + eventWSList.splice(index, 1); + } } export function postWsEvent(event: QuickActionEvent) { - for (const ws of eventWSList) { - new Promise(() => { - wsReply(ws, event); - }).then(); - } + for (const ws of eventWSList) { + new Promise(() => { + wsReply(ws, event); + }).then(); + } } export function postOB11Event( - msg: QuickActionEvent, - reportSelf = false, - postWs = true, - enablePost = true, - httpSecret: string | undefined = undefined, - coreContext: NapCatCore, - HttpPostUrl: string[] + msg: QuickActionEvent, + reportSelf = false, + postWs = true, + enablePost = true, + httpSecret: string | undefined = undefined, + coreContext: NapCatCore, + HttpPostUrl: string[] ) { - // 判断msg是否是event - if (!reportSelf) { - if (msg.post_type === 'message' && (msg as OB11Message).user_id.toString() == coreContext.selfInfo.uin) { - return; - } - } - if (enablePost) { - const msgStr = JSON.stringify(msg); - const hmac = crypto.createHmac('sha1', (httpSecret || "").toString()); - hmac.update(msgStr); - const sig = hmac.digest('hex'); - const headers: Record = { - 'Content-Type': 'application/json', - 'x-self-id': coreContext.selfInfo.uin - }; - if (httpSecret) { - headers['x-signature'] = 'sha1=' + sig; - } - for (const host of HttpPostUrl) { - fetch(host, { - method: 'POST', - headers, - body: msgStr - }).then(async (res) => { - //logDebug(`新消息事件HTTP上报成功: ${host} `, msgStr); - // todo: 处理不够优雅,应该使用高级泛型进行QuickAction类型识别 - let resJson: QuickAction; - try { - resJson = await res.json(); - //logDebug('新消息事件HTTP上报返回快速操作: ', JSON.stringify(resJson)); - } catch (e) { - coreContext.context.logger.logDebug('新消息事件HTTP上报没有返回快速操作,不需要处理'); - return; + // 判断msg是否是event + if (!reportSelf) { + if (msg.post_type === 'message' && (msg as OB11Message).user_id.toString() == coreContext.selfInfo.uin) { + return; } - try { - handleQuickOperation(msg as QuickActionEvent, resJson, coreContext).then().catch(coreContext.context.logger.logError); - } catch (e: any) { - coreContext.context.logger.logError('新消息事件HTTP上报返回快速操作失败', e); + } + if (enablePost) { + const msgStr = JSON.stringify(msg); + const hmac = crypto.createHmac('sha1', (httpSecret || "").toString()); + hmac.update(msgStr); + const sig = hmac.digest('hex'); + const headers: Record = { + 'Content-Type': 'application/json', + 'x-self-id': coreContext.selfInfo.uin + }; + if (httpSecret) { + headers['x-signature'] = 'sha1=' + sig; } + for (const host of HttpPostUrl) { + fetch(host, { + method: 'POST', + headers, + body: msgStr + }).then(async (res) => { + //logDebug(`新消息事件HTTP上报成功: ${host} `, msgStr); + // todo: 处理不够优雅,应该使用高级泛型进行QuickAction类型识别 + let resJson: QuickAction; + try { + resJson = await res.json(); + //logDebug('新消息事件HTTP上报返回快速操作: ', JSON.stringify(resJson)); + } catch (e) { + coreContext.context.logger.logDebug('新消息事件HTTP上报没有返回快速操作,不需要处理'); + return; + } + try { + handleQuickOperation(msg as QuickActionEvent, resJson, coreContext).then().catch(coreContext.context.logger.logError); + } catch (e: any) { + coreContext.context.logger.logError('新消息事件HTTP上报返回快速操作失败', e); + } - }, (err: any) => { - coreContext.context.logger.logError(`新消息事件HTTP上报失败: ${host} `, err, msg); - }); + }, (err: any) => { + coreContext.context.logger.logError(`新消息事件HTTP上报失败: ${host} `, err, msg); + }); + } + } + if (postWs) { + postWsEvent(msg); } - } - if (postWs) { - postWsEvent(msg); - } } async function handleMsg(msg: OB11Message, quickAction: QuickAction, coreContext: NapCatCore) { - const NTQQUserApi = coreContext.getApiContext().UserApi; - msg = msg as OB11Message; - const reply = quickAction.reply; - const peer: Peer = { - chatType: ChatType.friend, - peerUid: await NTQQUserApi.getUidByUin(msg.user_id.toString()) as string - }; - if (msg.message_type == 'private') { - if (msg.sub_type === 'group') { - peer.chatType = ChatType.temp; - } - } else { - peer.chatType = ChatType.group; - peer.peerUid = msg.group_id!.toString(); - } - if (reply) { - let group: string | undefined; - let replyMessage: OB11MessageData[] = []; - - if (msg.message_type == 'group') { - group = msg.group_id!.toString(); - replyMessage.push({ - type: 'reply', - data: { - id: msg.message_id.toString() + const NTQQUserApi = coreContext.getApiContext().UserApi; + msg = msg as OB11Message; + const reply = quickAction.reply; + const peer: Peer = { + chatType: ChatType.friend, + peerUid: await NTQQUserApi.getUidByUin(msg.user_id.toString()) as string + }; + if (msg.message_type == 'private') { + if (msg.sub_type === 'group') { + peer.chatType = ChatType.temp; } - } as OB11MessageReply); - if ((quickAction as QuickActionGroupMessage).at_sender) { - replyMessage.push({ - type: 'at', - data: { - qq: msg.user_id.toString() - } - } as OB11MessageAt); - } + } else { + peer.chatType = ChatType.group; + peer.peerUid = msg.group_id!.toString(); + } + if (reply) { + let group: string | undefined; + let replyMessage: OB11MessageData[] = []; + + if (msg.message_type == 'group') { + group = msg.group_id!.toString(); + replyMessage.push({ + type: 'reply', + data: { + id: msg.message_id.toString() + } + } as OB11MessageReply); + if ((quickAction as QuickActionGroupMessage).at_sender) { + replyMessage.push({ + type: 'at', + data: { + qq: msg.user_id.toString() + } + } as OB11MessageAt); + } + } + replyMessage = replyMessage.concat(normalize(reply, quickAction.auto_escape)); + const { sendElements, deleteAfterSentFiles } = await createSendElements(coreContext, replyMessage, peer); + sendMsg(coreContext, peer, sendElements, deleteAfterSentFiles, false).then().catch(coreContext.context.logger.logError); } - replyMessage = replyMessage.concat(normalize(reply, quickAction.auto_escape)); - const { sendElements, deleteAfterSentFiles } = await createSendElements(coreContext, replyMessage, peer); - sendMsg(coreContext, peer, sendElements, deleteAfterSentFiles, false).then().catch(coreContext.context.logger.logError); - } } async function handleGroupRequest(request: OB11GroupRequestEvent, quickAction: QuickActionGroupRequest, coreContext: NapCatCore) { - const NTQQGroupApi = coreContext.getApiContext().GroupApi; - if (!isNull(quickAction.approve)) { - NTQQGroupApi.handleGroupRequest( - request.flag, - quickAction.approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject, - quickAction.reason, - ).then().catch(coreContext.context.logger.logError); - } + const NTQQGroupApi = coreContext.getApiContext().GroupApi; + if (!isNull(quickAction.approve)) { + NTQQGroupApi.handleGroupRequest( + request.flag, + quickAction.approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject, + quickAction.reason, + ).then().catch(coreContext.context.logger.logError); + } } async function handleFriendRequest(request: OB11FriendRequestEvent, quickAction: QuickActionFriendRequest, coreContext: NapCatCore) { - const NTQQFriendApi = coreContext.getApiContext().FriendApi; - if (!isNull(quickAction.approve)) { - NTQQFriendApi.handleFriendRequest(request.flag, !!quickAction.approve).then().catch(coreContext.context.logger.logError); - } + const NTQQFriendApi = coreContext.getApiContext().FriendApi; + if (!isNull(quickAction.approve)) { + NTQQFriendApi.handleFriendRequest(request.flag, !!quickAction.approve).then().catch(coreContext.context.logger.logError); + } } export async function handleQuickOperation(context: QuickActionEvent, quickAction: QuickAction, coreContext: NapCatCore) { - if (context.post_type === 'message') { - handleMsg(context as OB11Message, quickAction, coreContext).then().catch(coreContext.context.logger.logError); - } - if (context.post_type === 'request') { - const friendRequest = context as OB11FriendRequestEvent; - const groupRequest = context as OB11GroupRequestEvent; - if ((friendRequest).request_type === 'friend') { - handleFriendRequest(friendRequest, quickAction, coreContext).then().catch(coreContext.context.logger.logError); + if (context.post_type === 'message') { + handleMsg(context as OB11Message, quickAction, coreContext).then().catch(coreContext.context.logger.logError); } - else if (groupRequest.request_type === 'group') { - handleGroupRequest(groupRequest, quickAction, coreContext).then().catch(coreContext.context.logger.logError); + if (context.post_type === 'request') { + const friendRequest = context as OB11FriendRequestEvent; + const groupRequest = context as OB11GroupRequestEvent; + if ((friendRequest).request_type === 'friend') { + handleFriendRequest(friendRequest, quickAction, coreContext).then().catch(coreContext.context.logger.logError); + } + else if (groupRequest.request_type === 'group') { + handleGroupRequest(groupRequest, quickAction, coreContext).then().catch(coreContext.context.logger.logError); + } } - } } \ No newline at end of file diff --git a/src/onebot/server/ws/ReverseWebsocket.ts b/src/onebot/server/ws/ReverseWebsocket.ts index 08792ce7..0747b2b6 100644 --- a/src/onebot/server/ws/ReverseWebsocket.ts +++ b/src/onebot/server/ws/ReverseWebsocket.ts @@ -15,132 +15,132 @@ import { selfInfo } from '@/core/data'; export let rwsList: ReverseWebsocket[] = []; export class ReverseWebsocket { - public websocket: WebSocketClass | undefined; - public url: string; - private running: boolean = false; + public websocket: WebSocketClass | undefined; + public url: string; + private running: boolean = false; - public constructor(url: string) { - this.url = url; - this.running = true; - this.connect(); - } + public constructor(url: string) { + this.url = url; + this.running = true; + this.connect(); + } - public stop() { - this.running = false; + public stop() { + this.running = false; this.websocket!.close(); - } - - public onopen() { - wsReply(this.websocket!, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT)); - } - - public async onmessage(msg: string) { - let receiveData: { action: ActionName | undefined, params: any, echo?: any } = { action: undefined, params: {} }; - let echo = null; - try { - receiveData = JSON.parse(msg.toString()); - echo = receiveData.echo; - //logDebug('收到反向Websocket消息', receiveData); - } catch (e) { - return wsReply(this.websocket!, OB11Response.error('json解析失败,请检查数据格式', 1400, echo)); } - const action: BaseAction | undefined = actionMap.get(receiveData.action!); - if (!action) { - return wsReply(this.websocket!, OB11Response.error('不支持的api ' + receiveData.action, 1404, echo)); + + public onopen() { + wsReply(this.websocket!, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT)); } - try { - receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 - const handleResult = await action.websocketHandle(receiveData.params, echo); - wsReply(this.websocket!, handleResult); - } catch (e) { - wsReply(this.websocket!, OB11Response.error(`api处理出错:${e}`, 1200, echo)); + + public async onmessage(msg: string) { + let receiveData: { action: ActionName | undefined, params: any, echo?: any } = { action: undefined, params: {} }; + let echo = null; + try { + receiveData = JSON.parse(msg.toString()); + echo = receiveData.echo; + //logDebug('收到反向Websocket消息', receiveData); + } catch (e) { + return wsReply(this.websocket!, OB11Response.error('json解析失败,请检查数据格式', 1400, echo)); + } + const action: BaseAction | undefined = actionMap.get(receiveData.action!); + if (!action) { + return wsReply(this.websocket!, OB11Response.error('不支持的api ' + receiveData.action, 1404, echo)); + } + try { + receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 + const handleResult = await action.websocketHandle(receiveData.params, echo); + wsReply(this.websocket!, handleResult); + } catch (e) { + wsReply(this.websocket!, OB11Response.error(`api处理出错:${e}`, 1200, echo)); + } } - } - public onclose = () => { - logError('反向ws断开', this.url); - unregisterWsEventSender(this.websocket!); - if (this.running) { - this.reconnect(); + public onclose = () => { + logError('反向ws断开', this.url); + unregisterWsEventSender(this.websocket!); + if (this.running) { + this.reconnect(); + } + }; + + public send(msg: string) { + if (this.websocket && this.websocket.readyState == WebSocket.OPEN) { + this.websocket.send(msg); + } } - }; - public send(msg: string) { - if (this.websocket && this.websocket.readyState == WebSocket.OPEN) { - this.websocket.send(msg); + private reconnect() { + setTimeout(() => { + this.connect(); + }, 3000); // TODO: 重连间隔在配置文件中实现 } - } - private reconnect() { - setTimeout(() => { - this.connect(); - }, 3000); // TODO: 重连间隔在配置文件中实现 - } - - private connect() { - const { token, heartInterval } = ob11Config; - this.websocket = new WebSocketClass(this.url, { - maxPayload: 1024 * 1024 * 1024, - handshakeTimeout: 2000, - perMessageDeflate: false, - headers: { - 'X-Self-ID': selfInfo.uin, - 'Authorization': `Bearer ${token}`, - 'x-client-role': 'Universal', // koishi-adapter-onebot 需要这个字段 - 'User-Agent': 'OneBot/11', - } - }); - registerWsEventSender(this.websocket); - logDebug('Trying to connect to the websocket server: ' + this.url); + private connect() { + const { token, heartInterval } = ob11Config; + this.websocket = new WebSocketClass(this.url, { + maxPayload: 1024 * 1024 * 1024, + handshakeTimeout: 2000, + perMessageDeflate: false, + headers: { + 'X-Self-ID': selfInfo.uin, + 'Authorization': `Bearer ${token}`, + 'x-client-role': 'Universal', // koishi-adapter-onebot 需要这个字段 + 'User-Agent': 'OneBot/11', + } + }); + registerWsEventSender(this.websocket); + logDebug('Trying to connect to the websocket server: ' + this.url); - this.websocket.on('open', () => { - logDebug('Connected to the websocket server: ' + this.url); - this.onopen(); - }); + this.websocket.on('open', () => { + logDebug('Connected to the websocket server: ' + this.url); + this.onopen(); + }); - this.websocket.on('message', async (data) => { - await this.onmessage(data.toString()); - }); + this.websocket.on('message', async (data) => { + await this.onmessage(data.toString()); + }); - this.websocket.on('error', log); + this.websocket.on('error', log); - const wsClientInterval = setInterval(() => { - wsReply(this.websocket!, new OB11HeartbeatEvent(!!selfInfo.online, true, heartInterval)); - }, heartInterval); // 心跳包 - this.websocket.on('close', () => { - clearInterval(wsClientInterval); - logDebug('The websocket connection: ' + this.url + ' closed, trying reconnecting...'); - this.onclose(); - }); - } + const wsClientInterval = setInterval(() => { + wsReply(this.websocket!, new OB11HeartbeatEvent(!!selfInfo.online, true, heartInterval)); + }, heartInterval); // 心跳包 + this.websocket.on('close', () => { + clearInterval(wsClientInterval); + logDebug('The websocket connection: ' + this.url + ' closed, trying reconnecting...'); + this.onclose(); + }); + } } class OB11ReverseWebsockets { - start() { - for (const url of ob11Config.reverseWs.urls) { - log('开始连接反向ws', url); - new Promise(() => { - try { - rwsList.push(new ReverseWebsocket(url)); - } catch (e: any) { - logError(e.stack); + start() { + for (const url of ob11Config.reverseWs.urls) { + log('开始连接反向ws', url); + new Promise(() => { + try { + rwsList.push(new ReverseWebsocket(url)); + } catch (e: any) { + logError(e.stack); + } + }).then(); } - }).then(); } - } - stop() { - for (const rws of rwsList) { - rws.stop(); + stop() { + for (const rws of rwsList) { + rws.stop(); + } + rwsList = [];//清空旧的反向ws } - rwsList = [];//清空旧的反向ws - } - restart() { - this.stop(); - this.start(); - } + restart() { + this.stop(); + this.start(); + } } export const ob11ReverseWebsockets = new OB11ReverseWebsockets(); diff --git a/src/onebot/server/ws/WebsocketServer.ts b/src/onebot/server/ws/WebsocketServer.ts index 838de2a5..d76e127c 100644 --- a/src/onebot/server/ws/WebsocketServer.ts +++ b/src/onebot/server/ws/WebsocketServer.ts @@ -19,67 +19,67 @@ const heartbeatRunning = false; class OB11WebsocketServer extends WebsocketServerBase { - public start(port: number | http.Server, host: string = '') { - this.token = ob11Config.token; - super.start(port, host); - } - - authorizeFailed(wsClient: WebSocket) { - wsClient.send(JSON.stringify(OB11Response.res(null, 'failed', 1403, 'token验证失败'))); - } - - async handleAction(wsClient: WebSocket, actionName: string, params: any, echo?: any) { - const action: BaseAction | undefined = actionMap.get(actionName); - if (!action) { - return wsReply(wsClient, OB11Response.error('不支持的api ' + actionName, 1404, echo)); + public start(port: number | http.Server, host: string = '') { + this.token = ob11Config.token; + super.start(port, host); } - try { - const handleResult = await action.websocketHandle(params, echo); - wsReply(wsClient, handleResult); - } catch (e: any) { - wsReply(wsClient, OB11Response.error(`api处理出错:${e.stack}`, 1200, echo)); - } - } - onConnect(wsClient: WebSocket, url: string, req: IncomingMessage) { - if (url == '/api' || url == '/api/' || url == '/') { - wsClient.on('message', async (msg) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - let receiveData: { action: ActionName, params?: any, echo?: any } = { action: '', params: {} }; - let echo = null; - try { - receiveData = JSON.parse(msg.toString()); - echo = receiveData.echo; - logDebug('收到正向Websocket消息', receiveData); - } catch (e) { - return wsReply(wsClient, OB11Response.error('json解析失败,请检查数据格式', 1400, echo)); + authorizeFailed(wsClient: WebSocket) { + wsClient.send(JSON.stringify(OB11Response.res(null, 'failed', 1403, 'token验证失败'))); + } + + async handleAction(wsClient: WebSocket, actionName: string, params: any, echo?: any) { + const action: BaseAction | undefined = actionMap.get(actionName); + if (!action) { + return wsReply(wsClient, OB11Response.error('不支持的api ' + actionName, 1404, echo)); + } + try { + const handleResult = await action.websocketHandle(params, echo); + wsReply(wsClient, handleResult); + } catch (e: any) { + wsReply(wsClient, OB11Response.error(`api处理出错:${e.stack}`, 1200, echo)); } - receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 - this.handleAction(wsClient, receiveData.action, receiveData.params, receiveData.echo).then(); - }); } - if (url == '/event' || url == '/event/' || url == '/') { - registerWsEventSender(wsClient); - logDebug('event上报ws客户端已连接'); + onConnect(wsClient: WebSocket, url: string, req: IncomingMessage) { + if (url == '/api' || url == '/api/' || url == '/') { + wsClient.on('message', async (msg) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + let receiveData: { action: ActionName, params?: any, echo?: any } = { action: '', params: {} }; + let echo = null; + try { + receiveData = JSON.parse(msg.toString()); + echo = receiveData.echo; + logDebug('收到正向Websocket消息', receiveData); + } catch (e) { + return wsReply(wsClient, OB11Response.error('json解析失败,请检查数据格式', 1400, echo)); + } + receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 + this.handleAction(wsClient, receiveData.action, receiveData.params, receiveData.echo).then(); + }); + } + if (url == '/event' || url == '/event/' || url == '/') { + registerWsEventSender(wsClient); - try { - wsReply(wsClient, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT)); - } catch (e) { - logError('发送生命周期失败', e); - } - const { heartInterval } = ob11Config; - const wsClientInterval = setInterval(() => { - wsReply(wsClient, new OB11HeartbeatEvent(!!selfInfo.online, true, heartInterval)); - }, heartInterval); // 心跳包 - wsClient.on('close', () => { - logError('event上报ws客户端已断开'); - clearInterval(wsClientInterval); - unregisterWsEventSender(wsClient); - }); + logDebug('event上报ws客户端已连接'); + + try { + wsReply(wsClient, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT)); + } catch (e) { + logError('发送生命周期失败', e); + } + const { heartInterval } = ob11Config; + const wsClientInterval = setInterval(() => { + wsReply(wsClient, new OB11HeartbeatEvent(!!selfInfo.online, true, heartInterval)); + }, heartInterval); // 心跳包 + wsClient.on('close', () => { + logError('event上报ws客户端已断开'); + clearInterval(wsClientInterval); + unregisterWsEventSender(wsClient); + }); + } } - } } export const ob11WebsocketServer = new OB11WebsocketServer(); diff --git a/src/onebot/server/ws/reply.ts b/src/onebot/server/ws/reply.ts index 7e53a1c6..ac497c81 100644 --- a/src/onebot/server/ws/reply.ts +++ b/src/onebot/server/ws/reply.ts @@ -6,18 +6,18 @@ import { isNull } from '@/common/utils/helper'; export function wsReply(wsClient: WebSocketClass, data: OB11Response | PostEventType) { - try { - const packet = Object.assign({}, data); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - if (isNull(packet['echo'])) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - delete packet['echo']; + try { + const packet = Object.assign({}, data); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + if (isNull(packet['echo'])) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + delete packet['echo']; + } + wsClient.send(JSON.stringify(packet)); + logDebug('ws 消息上报', wsClient.url || '', data); + } catch (e: any) { + logError('websocket 回复失败', e.stack, data); } - wsClient.send(JSON.stringify(packet)); - logDebug('ws 消息上报', wsClient.url || '', data); - } catch (e: any) { - logError('websocket 回复失败', e.stack, data); - } }