mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
57112c21a2 | ||
![]() |
0e8ceeb6c9 | ||
![]() |
f52b8d1f04 | ||
![]() |
f374cc77ae | ||
![]() |
7c694e7fae | ||
![]() |
932ffc2673 | ||
![]() |
3de5438139 | ||
![]() |
c4b5f34271 | ||
![]() |
22d3ac33a2 | ||
![]() |
2e5dd6535a | ||
![]() |
eac58a2a50 | ||
![]() |
e939ec0e52 | ||
![]() |
5b17a14a2a | ||
![]() |
8fb8c888f5 | ||
![]() |
4a2884509e |
@@ -36,6 +36,13 @@ NapCatQQ 是现代化的基于 NTQQ 的 Bot 协议端实现
|
|||||||
## 回家旅途
|
## 回家旅途
|
||||||
[QQ Group](https://qm.qq.com/q/I6LU87a0Yq)
|
[QQ Group](https://qm.qq.com/q/I6LU87a0Yq)
|
||||||
|
|
||||||
|
## 性能设计/协议标准
|
||||||
|
NapCat 已实现90%+的OneBot/GoCQ标准接口,并提供兼容性保留接口,其设计理念遵守 无数据库/异步优先/后台刷新 的性能思想。
|
||||||
|
|
||||||
|
由此设计带来一系列好处,在开发中,获取群员列表通常小于50Ms,单条文本消息发送在320Ms以内,在1k+的群聊流程运行,同时带来一些副作用,上报数据中大量使用Magic生成字段, 消息Id无法持久,无法上报撤回消息原始内容。
|
||||||
|
|
||||||
|
NapCat在设计理念下遵守OneBot规范大多数要求并且积极改进,任何合理的标准化issue与pr将被接收。
|
||||||
|
|
||||||
## 感谢他们
|
## 感谢他们
|
||||||
感谢 [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持 参考部分代码 已获授权
|
感谢 [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持 参考部分代码 已获授权
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"name": "NapCatQQ",
|
"name": "NapCatQQ",
|
||||||
"slug": "NapCat.Framework",
|
"slug": "NapCat.Framework",
|
||||||
"description": "高性能的 OneBot 11 协议实现",
|
"description": "高性能的 OneBot 11 协议实现",
|
||||||
"version": "4.2.19",
|
"version": "4.2.23",
|
||||||
"icon": "./logo.png",
|
"icon": "./logo.png",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"name": "napcat",
|
"name": "napcat",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "4.2.19",
|
"version": "4.2.23",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:universal": "npm run build:webui && vite build --mode universal || exit 1",
|
"build:universal": "npm run build:webui && vite build --mode universal || exit 1",
|
||||||
"build:framework": "npm run build:webui && vite build --mode framework || exit 1",
|
"build:framework": "npm run build:webui && vite build --mode framework || exit 1",
|
||||||
|
@@ -1 +1 @@
|
|||||||
export const napCatVersion = '4.2.19';
|
export const napCatVersion = '4.2.23';
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { FriendV2 } from '@/core/types';
|
import { FriendRequest, FriendV2 } from '@/core/types';
|
||||||
import { BuddyListReqType, InstanceContext, NapCatCore } from '@/core';
|
import { BuddyListReqType, InstanceContext, NapCatCore } from '@/core';
|
||||||
import { LimitedHashTable } from '@/common/message-unique';
|
import { LimitedHashTable } from '@/common/message-unique';
|
||||||
|
|
||||||
@@ -79,16 +79,10 @@ export class NTQQFriendApi {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleFriendRequest(flag: string, accept: boolean) {
|
async handleFriendRequest(notify: FriendRequest, accept: boolean) {
|
||||||
const data = flag.split('|');
|
|
||||||
if (data.length < 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const friendUid = data[0];
|
|
||||||
const reqTime = data[1];
|
|
||||||
this.context.session.getBuddyService()?.approvalFriendRequest({
|
this.context.session.getBuddyService()?.approvalFriendRequest({
|
||||||
friendUid: friendUid,
|
friendUid: notify.friendUid,
|
||||||
reqTime: reqTime,
|
reqTime: notify.reqTime,
|
||||||
accept,
|
accept,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ import {
|
|||||||
KickMemberV2Req,
|
KickMemberV2Req,
|
||||||
MemberExtSourceType,
|
MemberExtSourceType,
|
||||||
NapCatCore,
|
NapCatCore,
|
||||||
|
GroupNotify,
|
||||||
} from '@/core';
|
} from '@/core';
|
||||||
import { isNumeric, solveAsyncProblem } from '@/common/helper';
|
import { isNumeric, solveAsyncProblem } from '@/common/helper';
|
||||||
import { LimitedHashTable } from '@/common/message-unique';
|
import { LimitedHashTable } from '@/common/message-unique';
|
||||||
@@ -120,7 +121,7 @@ export class NTQQGroupApi {
|
|||||||
}
|
}
|
||||||
return this.groupMemberCache;
|
return this.groupMemberCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGroupMember(groupCode: string | number, memberUinOrUid: string | number) {
|
async getGroupMember(groupCode: string | number, memberUinOrUid: string | number) {
|
||||||
const groupCodeStr = groupCode.toString();
|
const groupCodeStr = groupCode.toString();
|
||||||
const memberUinOrUidStr = memberUinOrUid.toString();
|
const memberUinOrUidStr = memberUinOrUid.toString();
|
||||||
@@ -288,20 +289,15 @@ export class NTQQGroupApi {
|
|||||||
return this.context.session.getGroupService().uploadGroupBulletinPic(groupCode, _Pskey, imageurl);
|
return this.context.session.getGroupService().uploadGroupBulletinPic(groupCode, _Pskey, imageurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleGroupRequest(flag: string, operateType: NTGroupRequestOperateTypes, reason?: string) {
|
async handleGroupRequest(notify: GroupNotify, operateType: NTGroupRequestOperateTypes, reason?: string) {
|
||||||
const flagitem = flag.split('|');
|
|
||||||
const groupCode = flagitem[0];
|
|
||||||
const seq = flagitem[1];
|
|
||||||
const type = parseInt(flagitem[2]);
|
|
||||||
|
|
||||||
return this.context.session.getGroupService().operateSysNotify(
|
return this.context.session.getGroupService().operateSysNotify(
|
||||||
false,
|
false,
|
||||||
{
|
{
|
||||||
operateType: operateType,
|
operateType: operateType,
|
||||||
targetMsg: {
|
targetMsg: {
|
||||||
seq: seq, // 通知序列号
|
seq: notify.seq, // 通知序列号
|
||||||
type: type,
|
type: notify.type,
|
||||||
groupCode: groupCode,
|
groupCode: notify.group.groupCode,
|
||||||
postscript: reason ?? ' ', // 仅传空值可能导致处理失败,故默认给个空格
|
postscript: reason ?? ' ', // 仅传空值可能导致处理失败,故默认给个空格
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@@ -8,14 +8,10 @@ import { LRUCache } from '@/common/lru-cache';
|
|||||||
export class NTQQUserApi {
|
export class NTQQUserApi {
|
||||||
context: InstanceContext;
|
context: InstanceContext;
|
||||||
core: NapCatCore;
|
core: NapCatCore;
|
||||||
private uidCache: LRUCache<string, string>;
|
|
||||||
private uinCache: LRUCache<string, string>;
|
|
||||||
|
|
||||||
constructor(context: InstanceContext, core: NapCatCore) {
|
constructor(context: InstanceContext, core: NapCatCore) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.core = core;
|
this.core = core;
|
||||||
this.uidCache = new LRUCache(1000);
|
|
||||||
this.uinCache = new LRUCache(1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCoreAndBaseInfo(uids: string[]) {
|
async getCoreAndBaseInfo(uids: string[]) {
|
||||||
@@ -174,8 +170,8 @@ export class NTQQUserApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getUidByUinV2(Uin: string) {
|
async getUidByUinV2(Uin: string) {
|
||||||
if (this.uidCache.get(Uin)) {
|
if (!Uin) {
|
||||||
return this.uidCache.get(Uin);
|
return '';
|
||||||
}
|
}
|
||||||
const services = [
|
const services = [
|
||||||
() => this.context.session.getUixConvertService().getUid([Uin]).then((data) => data.uidInfo.get(Uin)).catch(() => undefined),
|
() => this.context.session.getUixConvertService().getUid([Uin]).then((data) => data.uidInfo.get(Uin)).catch(() => undefined),
|
||||||
@@ -188,16 +184,15 @@ export class NTQQUserApi {
|
|||||||
for (const service of services) {
|
for (const service of services) {
|
||||||
uid = await service();
|
uid = await service();
|
||||||
if (uid && uid.indexOf('*') == -1 && uid !== '') {
|
if (uid && uid.indexOf('*') == -1 && uid !== '') {
|
||||||
this.uidCache.put(Uin, uid);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return uid;
|
return uid ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUinByUidV2(Uid: string) {
|
async getUinByUidV2(Uid: string) {
|
||||||
if (this.uinCache.get(Uid)) {
|
if (!Uid) {
|
||||||
return this.uinCache.get(Uid);
|
return '0';
|
||||||
}
|
}
|
||||||
const services = [
|
const services = [
|
||||||
() => this.context.session.getUixConvertService().getUin([Uid]).then((data) => data.uinInfo.get(Uid)).catch(() => undefined),
|
() => this.context.session.getUixConvertService().getUin([Uid]).then((data) => data.uinInfo.get(Uid)).catch(() => undefined),
|
||||||
@@ -211,11 +206,10 @@ export class NTQQUserApi {
|
|||||||
for (const service of services) {
|
for (const service of services) {
|
||||||
uin = await service();
|
uin = await service();
|
||||||
if (uin && uin !== '0' && uin !== '') {
|
if (uin && uin !== '0' && uin !== '') {
|
||||||
this.uinCache.put(Uid, uin);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return uin;
|
return uin ?? '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRecentContactListSnapShot(count: number) {
|
async getRecentContactListSnapShot(count: number) {
|
||||||
|
14
src/core/external/appid.json
vendored
14
src/core/external/appid.json
vendored
@@ -98,5 +98,17 @@
|
|||||||
"6.9.61-29927": {
|
"6.9.61-29927": {
|
||||||
"appid": 537255836,
|
"appid": 537255836,
|
||||||
"qua": "V1_MAC_NQ_6.9.61_29927_GW_B"
|
"qua": "V1_MAC_NQ_6.9.61_29927_GW_B"
|
||||||
|
},
|
||||||
|
"9.9.17-30366": {
|
||||||
|
"appid": 537258389,
|
||||||
|
"qua": "V1_WIN_NQ_9.9.17_30366_GW_B"
|
||||||
|
},
|
||||||
|
"3.2.15-30366": {
|
||||||
|
"appid": 537258413,
|
||||||
|
"qua": "V1_LNX_NQ_3.2.15_30366_GW_B"
|
||||||
|
},
|
||||||
|
"6.9.62-30366": {
|
||||||
|
"appid": 537258401,
|
||||||
|
"qua": "V1_MAC_NQ_6.9.62_30366_GW_B"
|
||||||
}
|
}
|
||||||
}
|
}
|
22
src/core/external/offset.json
vendored
22
src/core/external/offset.json
vendored
@@ -102,5 +102,25 @@
|
|||||||
"6.9.61-29927-arm64": {
|
"6.9.61-29927-arm64": {
|
||||||
"send": "4038740",
|
"send": "4038740",
|
||||||
"recv": "403AF58"
|
"recv": "403AF58"
|
||||||
|
},
|
||||||
|
"9.9.17-30366-x64": {
|
||||||
|
"send": "39AB0B0",
|
||||||
|
"recv": "39AF4E4"
|
||||||
|
},
|
||||||
|
"3.2.15-30366-x64": {
|
||||||
|
"send": "A402380",
|
||||||
|
"recv": "A405C80"
|
||||||
|
},
|
||||||
|
"3.2.15-30366-arm64": {
|
||||||
|
"send": "70C3FA8",
|
||||||
|
"recv": "70C77E0"
|
||||||
|
},
|
||||||
|
"6.9.62-30366-x64": {
|
||||||
|
"send": "4669760",
|
||||||
|
"recv": "466BFCC"
|
||||||
|
},
|
||||||
|
"6.9.62-30366-arm64": {
|
||||||
|
"send": "4189770",
|
||||||
|
"recv": "418BF88"
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -187,11 +187,11 @@ export interface NodeIKernelGroupService {
|
|||||||
|
|
||||||
destroyGroup(groupCode: string): void;
|
destroyGroup(groupCode: string): void;
|
||||||
|
|
||||||
getSingleScreenNotifies(doubted: boolean, start_seq: string, num: number): Promise<GeneralCallResult>;
|
getSingleScreenNotifies(doubt: boolean, startSeq: string, count: number): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
clearGroupNotifies(groupCode: string): void;
|
clearGroupNotifies(groupCode: string): void;
|
||||||
|
|
||||||
getGroupNotifiesUnreadCount(unknown: boolean): Promise<GeneralCallResult>;
|
getGroupNotifiesUnreadCount(doubt: boolean): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
clearGroupNotifiesUnreadCount(doubt: boolean): void;
|
clearGroupNotifiesUnreadCount(doubt: boolean): void;
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@ export interface TextElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FaceElement {
|
export interface FaceElement {
|
||||||
|
pokeType?: number;
|
||||||
faceIndex: number;
|
faceIndex: number;
|
||||||
faceType: FaceType;
|
faceType: FaceType;
|
||||||
faceText?: string;
|
faceText?: string;
|
||||||
|
@@ -1,33 +1,37 @@
|
|||||||
import { GroupNotifyMsgStatus } from '@/core';
|
import { GroupNotifyMsgStatus } from '@/core';
|
||||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||||
import { ActionName } from '@/onebot/action/router';
|
import { ActionName } from '@/onebot/action/router';
|
||||||
|
import { Notify } from '@/onebot/types';
|
||||||
|
|
||||||
interface OB11GroupRequestNotify {
|
export default class GetGroupAddRequest extends OneBotAction<null, Notify[] | null> {
|
||||||
group_id: number,
|
|
||||||
user_id: number,
|
|
||||||
flag: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class GetGroupAddRequest extends OneBotAction<null, OB11GroupRequestNotify[] | null> {
|
|
||||||
actionName = ActionName.GetGroupIgnoreAddRequest;
|
actionName = ActionName.GetGroupIgnoreAddRequest;
|
||||||
|
|
||||||
async _handle(payload: null): Promise<OB11GroupRequestNotify[] | null> {
|
async _handle(payload: null): Promise<Notify[] | null> {
|
||||||
const ignoredNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(true, 10);
|
const NTQQUserApi = this.core.apis.UserApi;
|
||||||
const retData: any = {
|
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||||
join_requests: await Promise.all(
|
const ignoredNotifies = await NTQQGroupApi.getSingleScreenNotifies(true, 10);
|
||||||
ignoredNotifies
|
const retData: Notify[] = [];
|
||||||
.filter(notify => notify.type === 7)
|
|
||||||
.map(async SSNotify => ({
|
const notifyPromises = ignoredNotifies
|
||||||
request_id: SSNotify.group.groupCode + '|' + SSNotify.seq + '|' + SSNotify.type,
|
.filter(notify => notify.type === 7)
|
||||||
requester_uin: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1?.uid),
|
.map(async SSNotify => {
|
||||||
requester_nick: SSNotify.user1?.nickName,
|
const invitorUin = SSNotify.user1?.uid ? +await NTQQUserApi.getUinByUidV2(SSNotify.user1.uid) : 0;
|
||||||
group_id: SSNotify.group?.groupCode,
|
const actorUin = SSNotify.user2?.uid ? +await NTQQUserApi.getUinByUidV2(SSNotify.user2.uid) : 0;
|
||||||
group_name: SSNotify.group?.groupName,
|
retData.push({
|
||||||
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
request_id: +SSNotify.seq,
|
||||||
actor: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
invitor_uin: invitorUin,
|
||||||
}))),
|
invitor_nick: SSNotify.user1?.nickName,
|
||||||
};
|
group_id: +SSNotify.group?.groupCode,
|
||||||
|
message: SSNotify?.postscript,
|
||||||
|
group_name: SSNotify.group?.groupName,
|
||||||
|
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||||
|
actor: actorUin,
|
||||||
|
requester_nick: SSNotify.user1?.nickName,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(notifyPromises);
|
||||||
|
|
||||||
return retData;
|
return retData;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,26 +1,44 @@
|
|||||||
import { GroupNotifyMsgStatus } from '@/core';
|
import { GroupNotifyMsgStatus } from '@/core';
|
||||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||||
import { ActionName } from '@/onebot/action/router';
|
import { ActionName } from '@/onebot/action/router';
|
||||||
export class GetGroupIgnoredNotifies extends OneBotAction<void, any> {
|
import { Notify } from '@/onebot/types';
|
||||||
|
|
||||||
|
interface RetData {
|
||||||
|
InvitedRequest: Notify[];
|
||||||
|
join_requests: Notify[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GetGroupIgnoredNotifies extends OneBotAction<void, RetData> {
|
||||||
actionName = ActionName.GetGroupIgnoredNotifies;
|
actionName = ActionName.GetGroupIgnoredNotifies;
|
||||||
|
|
||||||
async _handle(payload: void) {
|
async _handle(): Promise<RetData> {
|
||||||
const ignoredNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(true, 10);
|
const SingleScreenNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(false, 50);
|
||||||
const retData: any = {
|
const retData: RetData = { InvitedRequest: [], join_requests: [] };
|
||||||
join_requests: await Promise.all(
|
|
||||||
ignoredNotifies
|
const notifyPromises = SingleScreenNotifies.map(async (SSNotify) => {
|
||||||
.filter(notify => notify.type === 7)
|
const invitorUin = SSNotify.user1?.uid ? +await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1.uid) : 0;
|
||||||
.map(async SSNotify => ({
|
const actorUin = SSNotify.user2?.uid ? +await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2.uid) : 0;
|
||||||
request_id: SSNotify.group.groupCode + '|' + SSNotify.seq + '|' + SSNotify.type,
|
const commonData = {
|
||||||
requester_uin: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1?.uid),
|
request_id: +SSNotify.seq,
|
||||||
requester_nick: SSNotify.user1?.nickName,
|
invitor_uin: invitorUin,
|
||||||
group_id: SSNotify.group?.groupCode,
|
invitor_nick: SSNotify.user1?.nickName,
|
||||||
group_name: SSNotify.group?.groupName,
|
group_id: +SSNotify.group?.groupCode,
|
||||||
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
message: SSNotify?.postscript,
|
||||||
actor: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
group_name: SSNotify.group?.groupName,
|
||||||
}))),
|
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||||
};
|
actor: actorUin,
|
||||||
|
requester_nick: SSNotify.user1?.nickName,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (SSNotify.type === 1) {
|
||||||
|
retData.InvitedRequest.push(commonData);
|
||||||
|
} else if (SSNotify.type === 7) {
|
||||||
|
retData.join_requests.push(commonData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(notifyPromises);
|
||||||
|
|
||||||
return retData;
|
return retData;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,9 +4,9 @@ import { ActionName } from '@/onebot/action/router';
|
|||||||
import { Static, Type } from '@sinclair/typebox';
|
import { Static, Type } from '@sinclair/typebox';
|
||||||
|
|
||||||
const SchemaData = Type.Object({
|
const SchemaData = Type.Object({
|
||||||
flag: Type.String(),
|
flag: Type.Union([Type.String(), Type.Number()]),
|
||||||
approve: Type.Optional(Type.Union([Type.Boolean(), Type.String()])),
|
approve: Type.Optional(Type.Union([Type.Boolean(), Type.String()])),
|
||||||
reason: Type.Union([Type.String({ default: ' ' }), Type.Null()]),
|
reason: Type.Optional(Type.Union([Type.String({ default: ' ' }), Type.Null()])),
|
||||||
});
|
});
|
||||||
|
|
||||||
type Payload = Static<typeof SchemaData>;
|
type Payload = Static<typeof SchemaData>;
|
||||||
@@ -18,10 +18,26 @@ export default class SetGroupAddRequest extends OneBotAction<Payload, null> {
|
|||||||
async _handle(payload: Payload): Promise<null> {
|
async _handle(payload: Payload): Promise<null> {
|
||||||
const flag = payload.flag.toString();
|
const flag = payload.flag.toString();
|
||||||
const approve = payload.approve?.toString() !== 'false';
|
const approve = payload.approve?.toString() !== 'false';
|
||||||
await this.core.apis.GroupApi.handleGroupRequest(flag,
|
const reason = payload.reason ?? ' ';
|
||||||
|
|
||||||
|
let notify = await this.findNotify(flag);
|
||||||
|
if (!notify) {
|
||||||
|
throw new Error('No such request');
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.core.apis.GroupApi.handleGroupRequest(
|
||||||
|
notify,
|
||||||
approve ? NTGroupRequestOperateTypes.KAGREE : NTGroupRequestOperateTypes.KREFUSE,
|
approve ? NTGroupRequestOperateTypes.KAGREE : NTGroupRequestOperateTypes.KREFUSE,
|
||||||
payload.reason ?? ' ',
|
reason,
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private async findNotify(flag: string) {
|
||||||
|
let notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(false, 100)).find(e => e.seq == flag);
|
||||||
|
if (!notify) {
|
||||||
|
notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(true, 100)).find(e => e.seq == flag);
|
||||||
|
}
|
||||||
|
return notify;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,38 +1,43 @@
|
|||||||
import { GroupNotifyMsgStatus } from '@/core';
|
import { GroupNotifyMsgStatus } from '@/core';
|
||||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||||
import { ActionName } from '@/onebot/action/router';
|
import { ActionName } from '@/onebot/action/router';
|
||||||
export class GetGroupSystemMsg extends OneBotAction<void, any> {
|
import { Notify } from '@/onebot/types';
|
||||||
|
|
||||||
|
interface RetData {
|
||||||
|
InvitedRequest: Notify[];
|
||||||
|
join_requests: Notify[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GetGroupSystemMsg extends OneBotAction<void, RetData> {
|
||||||
actionName = ActionName.GetGroupSystemMsg;
|
actionName = ActionName.GetGroupSystemMsg;
|
||||||
|
|
||||||
async _handle() {
|
async _handle(): Promise<RetData> {
|
||||||
const NTQQUserApi = this.core.apis.UserApi;
|
const SingleScreenNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(false, 50);
|
||||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
const retData: RetData = { InvitedRequest: [], join_requests: [] };
|
||||||
// 默认10条 该api未完整实现 包括响应数据规范化 类型规范化
|
|
||||||
const SingleScreenNotifies = await NTQQGroupApi.getSingleScreenNotifies(false, 10);
|
const notifyPromises = SingleScreenNotifies.map(async (SSNotify) => {
|
||||||
const retData: any = { InvitedRequest: [], join_requests: [] };
|
const invitorUin = SSNotify.user1?.uid ? +await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1.uid) : 0;
|
||||||
for (const SSNotify of SingleScreenNotifies) {
|
const actorUin = SSNotify.user2?.uid ? +await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2.uid) : 0;
|
||||||
if (SSNotify.type == 1) {
|
const commonData = {
|
||||||
retData.InvitedRequest.push({
|
request_id: +SSNotify.seq,
|
||||||
request_id: SSNotify.group.groupCode + '|' + SSNotify.seq + '|' + SSNotify.type,
|
invitor_uin: invitorUin,
|
||||||
invitor_uin: await NTQQUserApi.getUinByUidV2(SSNotify.user1?.uid),
|
invitor_nick: SSNotify.user1?.nickName,
|
||||||
invitor_nick: SSNotify.user1?.nickName,
|
group_id: +SSNotify.group?.groupCode,
|
||||||
group_id: SSNotify.group?.groupCode,
|
message: SSNotify?.postscript,
|
||||||
group_name: SSNotify.group?.groupName,
|
group_name: SSNotify.group?.groupName,
|
||||||
checked: SSNotify.status === GroupNotifyMsgStatus.KUNHANDLE ? false : true,
|
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||||
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
actor: actorUin,
|
||||||
});
|
requester_nick: SSNotify.user1?.nickName,
|
||||||
} else if (SSNotify.type == 7) {
|
};
|
||||||
retData.join_requests.push({
|
|
||||||
request_id: SSNotify.group.groupCode + '|' + SSNotify.seq + '|' + SSNotify.type,
|
if (SSNotify.type === 1) {
|
||||||
requester_uin: await NTQQUserApi.getUinByUidV2(SSNotify.user1?.uid),
|
retData.InvitedRequest.push(commonData);
|
||||||
requester_nick: SSNotify.user1?.nickName,
|
} else if (SSNotify.type === 7) {
|
||||||
group_id: SSNotify.group?.groupCode,
|
retData.join_requests.push(commonData);
|
||||||
group_name: SSNotify.group?.groupName,
|
|
||||||
checked: SSNotify.status === GroupNotifyMsgStatus.KUNHANDLE ? false : true,
|
|
||||||
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
await Promise.all(notifyPromises);
|
||||||
|
|
||||||
return retData;
|
return retData;
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ import { ActionName } from '@/onebot/action/router';
|
|||||||
import { Static, Type } from '@sinclair/typebox';
|
import { Static, Type } from '@sinclair/typebox';
|
||||||
|
|
||||||
const SchemaData = Type.Object({
|
const SchemaData = Type.Object({
|
||||||
flag: Type.String(),
|
flag: Type.Union([Type.String(), Type.Number()]),
|
||||||
approve: Type.Optional(Type.Union([Type.String(), Type.Boolean()])),
|
approve: Type.Optional(Type.Union([Type.String(), Type.Boolean()])),
|
||||||
remark: Type.Optional(Type.String())
|
remark: Type.Optional(Type.String())
|
||||||
});
|
});
|
||||||
@@ -16,14 +16,13 @@ export default class SetFriendAddRequest extends OneBotAction<Payload, null> {
|
|||||||
|
|
||||||
async _handle(payload: Payload): Promise<null> {
|
async _handle(payload: Payload): Promise<null> {
|
||||||
const approve = payload.approve?.toString() !== 'false';
|
const approve = payload.approve?.toString() !== 'false';
|
||||||
await this.core.apis.FriendApi.handleFriendRequest(payload.flag, approve);
|
let notify = (await this.core.apis.FriendApi.getBuddyReq()).buddyReqs.find(e => e.reqTime == payload.flag.toString());
|
||||||
|
if (!notify) {
|
||||||
|
throw new Error('No such request');
|
||||||
|
}
|
||||||
|
await this.core.apis.FriendApi.handleFriendRequest(notify, approve);
|
||||||
if (payload.remark) {
|
if (payload.remark) {
|
||||||
const data = payload.flag.split('|');
|
await this.core.apis.FriendApi.setBuddyRemark(notify.friendUid, payload.remark);
|
||||||
if (data.length < 2) {
|
|
||||||
throw new Error('Invalid flag');
|
|
||||||
}
|
|
||||||
const friendUid = data[0];
|
|
||||||
await this.core.apis.FriendApi.setBuddyRemark(friendUid, payload.remark);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -51,9 +51,9 @@ export class OneBotGroupApi {
|
|||||||
if (memberUin && adminUin) {
|
if (memberUin && adminUin) {
|
||||||
return new OB11GroupBanEvent(
|
return new OB11GroupBanEvent(
|
||||||
this.core,
|
this.core,
|
||||||
parseInt(GroupCode),
|
+GroupCode,
|
||||||
parseInt(memberUin),
|
+memberUin,
|
||||||
parseInt(adminUin),
|
+adminUin,
|
||||||
duration,
|
duration,
|
||||||
subType,
|
subType,
|
||||||
);
|
);
|
||||||
@@ -98,8 +98,8 @@ export class OneBotGroupApi {
|
|||||||
}
|
}
|
||||||
return new OB11GroupMsgEmojiLikeEvent(
|
return new OB11GroupMsgEmojiLikeEvent(
|
||||||
this.core,
|
this.core,
|
||||||
parseInt(groupCode),
|
+groupCode,
|
||||||
parseInt(senderUin),
|
+senderUin,
|
||||||
MessageUnique.getShortIdByMsgId(replyMsg.msgId)!,
|
MessageUnique.getShortIdByMsgId(replyMsg.msgId)!,
|
||||||
[{
|
[{
|
||||||
emoji_id: emojiId,
|
emoji_id: emojiId,
|
||||||
@@ -111,9 +111,10 @@ export class OneBotGroupApi {
|
|||||||
async parseCardChangedEvent(msg: RawMessage) {
|
async parseCardChangedEvent(msg: RawMessage) {
|
||||||
if (msg.senderUin && msg.senderUin !== '0') {
|
if (msg.senderUin && msg.senderUin !== '0') {
|
||||||
const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUid, msg.senderUin);
|
const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUid, msg.senderUin);
|
||||||
if (member && member.cardName !== msg.sendMemberName) {
|
const oldName = member?.cardName || member?.nick || '';
|
||||||
|
if (member && oldName !== msg.sendMemberName) {
|
||||||
const newCardName = msg.sendMemberName ?? '';
|
const newCardName = msg.sendMemberName ?? '';
|
||||||
const event = new OB11GroupCardEvent(this.core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName);
|
const event = new OB11GroupCardEvent(this.core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, oldName);
|
||||||
member.cardName = newCardName;
|
member.cardName = newCardName;
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
@@ -153,6 +153,17 @@ export class OneBotMsgApi {
|
|||||||
|
|
||||||
faceElement: async element => {
|
faceElement: async element => {
|
||||||
const faceIndex = element.faceIndex;
|
const faceIndex = element.faceIndex;
|
||||||
|
if (element.faceType == FaceType.Poke) {
|
||||||
|
return {
|
||||||
|
type: OB11MessageDataType.poke,
|
||||||
|
data: {
|
||||||
|
type: element?.pokeType?.toString() ?? '0',
|
||||||
|
id: faceIndex.toString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (faceIndex === FaceIndex.DICE) {
|
if (faceIndex === FaceIndex.DICE) {
|
||||||
return {
|
return {
|
||||||
type: OB11MessageDataType.dice,
|
type: OB11MessageDataType.dice,
|
||||||
|
@@ -333,7 +333,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
this.core,
|
this.core,
|
||||||
+requesterUin,
|
+requesterUin,
|
||||||
req.extWords,
|
req.extWords,
|
||||||
req.friendUid + '|' + req.reqTime
|
req.reqTime
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -365,8 +365,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
if (notifyTime < this.bootTime) {
|
if (notifyTime < this.bootTime) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
const flag = notify.seq;
|
||||||
const flag = notify.group.groupCode + '|' + notify.seq + '|' + notify.type;
|
|
||||||
this.context.logger.logDebug('收到群通知', notify);
|
this.context.logger.logDebug('收到群通知', notify);
|
||||||
if (
|
if (
|
||||||
[GroupNotifyMsgType.REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS].includes(notify.type) &&
|
[GroupNotifyMsgType.REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS].includes(notify.type) &&
|
||||||
@@ -405,8 +404,8 @@ export class NapCatOneBot11Adapter {
|
|||||||
this.context.logger.logDebug(`收到邀请我加群通知:${notify}`);
|
this.context.logger.logDebug(`收到邀请我加群通知:${notify}`);
|
||||||
const groupInviteEvent = new OB11GroupRequestEvent(
|
const groupInviteEvent = new OB11GroupRequestEvent(
|
||||||
this.core,
|
this.core,
|
||||||
parseInt(notify.group.groupCode),
|
+notify.group.groupCode,
|
||||||
parseInt(await this.core.apis.UserApi.getUinByUidV2(notify.user2.uid)),
|
+await this.core.apis.UserApi.getUinByUidV2(notify.user2.uid),
|
||||||
'invite',
|
'invite',
|
||||||
notify.postscript,
|
notify.postscript,
|
||||||
flag
|
flag
|
||||||
@@ -423,8 +422,8 @@ export class NapCatOneBot11Adapter {
|
|||||||
this.context.logger.logDebug(`收到群员邀请加群通知:${notify}`);
|
this.context.logger.logDebug(`收到群员邀请加群通知:${notify}`);
|
||||||
const groupInviteEvent = new OB11GroupRequestEvent(
|
const groupInviteEvent = new OB11GroupRequestEvent(
|
||||||
this.core,
|
this.core,
|
||||||
parseInt(notify.group.groupCode),
|
+notify.group.groupCode,
|
||||||
parseInt(await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid)),
|
+await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid),
|
||||||
'add',
|
'add',
|
||||||
notify.postscript,
|
notify.postscript,
|
||||||
flag
|
flag
|
||||||
@@ -571,6 +570,8 @@ export class NapCatOneBot11Adapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async emitFriendRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) {
|
private async emitFriendRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) {
|
||||||
|
const operatorUid = element.grayTipElement?.revokeElement.operatorUid;
|
||||||
|
if (!operatorUid) return undefined;
|
||||||
return new OB11FriendRecallNoticeEvent(
|
return new OB11FriendRecallNoticeEvent(
|
||||||
this.core,
|
this.core,
|
||||||
+message.senderUin,
|
+message.senderUin,
|
||||||
@@ -581,7 +582,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
private async emitGroupRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) {
|
private async emitGroupRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) {
|
||||||
const operatorUid = element.grayTipElement?.revokeElement.operatorUid;
|
const operatorUid = element.grayTipElement?.revokeElement.operatorUid;
|
||||||
if (!operatorUid) return undefined;
|
if (!operatorUid) return undefined;
|
||||||
const operatorId = message.senderUin ?? await this.core.apis.UserApi.getUinByUidV2(operatorUid);
|
const operatorId = await this.core.apis.UserApi.getUinByUidV2(operatorUid);
|
||||||
return new OB11GroupRecallNoticeEvent(
|
return new OB11GroupRecallNoticeEvent(
|
||||||
this.core,
|
this.core,
|
||||||
+message.peerUin,
|
+message.peerUin,
|
||||||
|
@@ -11,6 +11,17 @@ export interface OB11User {
|
|||||||
categoryName?: string; // 分组名称
|
categoryName?: string; // 分组名称
|
||||||
categoryId?: number; // 分组ID 999为特别关心
|
categoryId?: number; // 分组ID 999为特别关心
|
||||||
}
|
}
|
||||||
|
export interface Notify {
|
||||||
|
request_id: number;
|
||||||
|
invitor_uin: number;
|
||||||
|
invitor_nick?: string;
|
||||||
|
group_id?: number;
|
||||||
|
group_name?: string;
|
||||||
|
message?: string;
|
||||||
|
checked: boolean;
|
||||||
|
actor: number;
|
||||||
|
requester_nick?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export enum OB11UserSex {
|
export enum OB11UserSex {
|
||||||
male = 'male', // 男性
|
male = 'male', // 男性
|
||||||
|
@@ -71,6 +71,14 @@ export enum OB11MessageDataType {
|
|||||||
location = 'location'
|
location = 'location'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OB11MessagePoke {
|
||||||
|
type: OB11MessageDataType.poke;
|
||||||
|
data: {
|
||||||
|
type: string;
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// 商城表情消息接口定义
|
// 商城表情消息接口定义
|
||||||
export interface OB11MessageMFace {
|
export interface OB11MessageMFace {
|
||||||
type: OB11MessageDataType.mface;
|
type: OB11MessageDataType.mface;
|
||||||
@@ -247,7 +255,7 @@ export type OB11MessageData =
|
|||||||
OB11MessageAt | OB11MessageReply |
|
OB11MessageAt | OB11MessageReply |
|
||||||
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
||||||
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
|
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
|
||||||
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext;
|
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext | OB11MessagePoke;
|
||||||
|
|
||||||
// 发送消息接口定义
|
// 发送消息接口定义
|
||||||
export interface OB11PostSendMsg {
|
export interface OB11PostSendMsg {
|
||||||
|
Reference in New Issue
Block a user