Compare commits

..

19 Commits

Author SHA1 Message Date
手瓜一十雪
77505a6f5b release: 2.2.31 2024-09-01 09:31:59 +08:00
手瓜一十雪
19c729aa23 chore: appid 2024-09-01 09:30:38 +08:00
Wesley F. Young
595888128a release: 2.2.30 2024-08-31 23:43:01 +08:00
手瓜一十雪
51589d0eae fix: 群精华上限修改 2024-08-31 22:11:18 +08:00
Wesley F. Young
f1643ac549 fix: get file way 01 get by msg & seq id 2024-08-31 20:30:42 +08:00
手瓜一十雪
3f24461612 feat: support 27597 2024-08-31 19:01:25 +08:00
Wesley F. Young
b5deb198de refactor: inline all NTQQXxxApi uses 2024-08-31 16:00:03 +08:00
Wesley F. Young
78452cf6a9 chore: clean code for webapi.ts 2024-08-31 14:18:11 +08:00
Wesley F. Young
4b4a784f56 chore: clean code for user.ts 2024-08-31 14:11:22 +08:00
Wesley F. Young
3e53cbcf8f chore: clean code for system.ts 2024-08-31 14:09:25 +08:00
Wesley F. Young
f34740f1f0 chore: clean code for group.ts 2024-08-31 14:07:48 +08:00
Wesley F. Young
b406bdfc37 chore: clean code for group.ts 2024-08-31 14:02:36 +08:00
Wesley F. Young
03c056702c chore: clean code for friend.ts 2024-08-31 13:53:30 +08:00
Wesley F. Young
9c5f3f1946 chore: clean code for collection.ts 2024-08-31 13:37:22 +08:00
Wesley F. Young
b50d7c24e7 refactor: move CacheApi to cache.ts 2024-08-31 13:36:21 +08:00
Wesley F. Young
f05cf68945 chore: clean code for file.ts 2024-08-31 13:35:29 +08:00
Alen
efc1875e35 release: 2.2.29 2024-08-31 12:53:50 +08:00
Alen
df063e6762 Merge pull request #326 from cnxysoft/upmain
fix: 群成员信息
2024-08-31 11:55:56 +08:00
Alen
e5c55b4339 fix: 群成员信息 2024-08-31 11:53:07 +08:00
85 changed files with 418 additions and 764 deletions

View File

@@ -4,7 +4,7 @@
"name": "NapCatQQ",
"slug": "NapCat.Framework",
"description": "高性能的 OneBot 11 协议实现",
"version": "2.2.28",
"version": "2.2.31",
"icon": "./logo.png",
"authors": [
{

View File

@@ -2,7 +2,7 @@
"name": "napcat",
"private": true,
"type": "module",
"version": "2.2.28",
"version": "2.2.31",
"scripts": {
"build:framework": "vite build --mode framework",
"build:shell": "vite build --mode shell",

View File

@@ -138,19 +138,19 @@ export function isEqual(obj1: any, obj2: any) {
export function getDefaultQQVersionConfigInfo(): QQVersionConfigType {
if (os.platform() === 'linux') {
return {
baseVersion: '3.2.12-27254',
curVersion: '3.2.12-27254',
baseVersion: '3.2.12-27597',
curVersion: '3.2.12-27597',
prevVersion: '',
onErrorVersions: [],
buildId: '27254',
buildId: '27597',
};
}
return {
baseVersion: '9.9.15-27391',
curVersion: '9.9.15-27391',
baseVersion: '9.9.15-27597',
curVersion: '9.9.15-27597',
prevVersion: '',
onErrorVersions: [],
buildId: '27391',
buildId: '27597',
};
}

View File

@@ -71,6 +71,6 @@ export class QQBasicInfoWrapper {
// else
this.context.logger.log(`[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常`);
this.context.logger.log(`[QQ版本兼容性检测] ${fullVersion} 版本兼容性不佳,可能会导致一些功能无法正常使用`,);
return { appid: systemPlatform === 'linux' ? '537240795' : '537240709', qua: this.getQUAInternal() };
return { appid: systemPlatform === 'linux' ? '537243600' : '537243441', qua: this.getQUAInternal() };
}
}

View File

@@ -1 +1 @@
export const napCatVersion = '2.2.28';
export const napCatVersion = '2.2.31';

View File

@@ -16,7 +16,8 @@ export async function getVideoInfo(filePath: string, logger: LogWrapper) {
filePath: string
}>((resolve, reject) => {
const ffmpegPath = process.env.FFMPEG_PATH;
ffmpegPath && ffmpeg.setFfmpegPath(ffmpegPath);
if (ffmpegPath)
ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg(filePath).ffprobe((err: any, metadata: ffmpeg.FfprobeData) => {
if (err) {
reject(err);

63
src/core/apis/cache.ts Normal file
View File

@@ -0,0 +1,63 @@
import {
CacheFileListItem,
CacheFileType,
ChatCacheListItemBasic,
ChatType,
InstanceContext,
NapCatCore,
} from '@/core';
export class NTQQCacheApi {
context: InstanceContext;
core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) {
this.context = context;
this.core = core;
}
async setCacheSilentScan(isSilent: boolean = true) {
return '';
}
getCacheSessionPathList() {
return '';
}
clearCache(cacheKeys: Array<string> = ['tmp', 'hotUpdate']) {
// 参数未验证
return this.context.session.getStorageCleanService().clearCacheDataByKeys(cacheKeys);
}
addCacheScannedPaths(pathMap: object = {}) {
return this.context.session.getStorageCleanService().addCacheScanedPaths(pathMap);
}
scanCache() {
//return (await this.context.session.getStorageCleanService().scanCache()).size;
}
getHotUpdateCachePath() {
// 未实现
return '';
}
getDesktopTmpPath() {
// 未实现
return '';
}
getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) {
return this.context.session.getStorageCleanService().getChatCacheInfo(type, pageSize, 1, pageIndex);
}
getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) {
// const _lastRecord = lastRecord ? lastRecord : { fileType: fileType };
// 需要五个参数
// return napCatCore.session.getStorageCleanService().getFileCacheInfo();
}
async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) {
return this.context.session.getStorageCleanService().clearChatCacheInfo(chats, fileKeys);
}
}

View File

@@ -10,7 +10,7 @@ export class NTQQCollectionApi {
}
async createCollection(authorUin: string, authorUid: string, authorName: string, brief: string, rawData: string) {
const param = {
return this.context.session.getCollectionService().createNewCollectionItem({
commInfo: {
bid: 1,
category: 2,
@@ -43,12 +43,11 @@ export class NTQQCollectionApi {
fileList: [],
},
need_share_url: false,
};
return this.context.session.getCollectionService().createNewCollectionItem(param);
});
}
async getAllCollection(category: number = 0, count: number = 50) {
const param = {
return this.context.session.getCollectionService().getCollectionItemList({
category: category,
groupId: -1,
forceSync: true,
@@ -56,7 +55,6 @@ export class NTQQCollectionApi {
timeStamp: '0',
count: count,
searchDown: true,
};
return this.context.session.getCollectionService().getCollectionItemList(param);
});
}
}

View File

@@ -1,7 +1,4 @@
import {
CacheFileListItem,
CacheFileType,
ChatCacheListItemBasic,
ChatType,
ElementType,
IMAGE_HTTP_HOST,
@@ -26,10 +23,8 @@ import { calculateFileMD5, isGIF } from '@/common/file';
import pathLib from 'node:path';
import { defaultVideoThumbB64, getVideoInfo } from '@/common/video';
import ffmpeg from 'fluent-ffmpeg';
import fsnormal from 'node:fs';
import { encodeSilk } from '@/common/audio';
export class NTQQFileApi {
context: InstanceContext;
core: NapCatCore;
@@ -41,10 +36,6 @@ export class NTQQFileApi {
this.rkeyManager = new RkeyManager('http://napcat-sign.wumiao.wang:2082/rkey', this.context.logger);
}
async getFileType(filePath: string) {
return fileType.fileTypeFromFile(filePath);
}
async copyFile(filePath: string, destPath: string) {
await this.core.util.copyFile(filePath, destPath);
}
@@ -60,18 +51,15 @@ export class NTQQFileApi {
})).urlResult.domainUrl;
}
// 上传文件到QQ的文件夹
async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC, elementSubType: number = 0) {
// napCatCore.wrapper.util.
const fileMd5 = await calculateFileMD5(filePath);
let ext: string = (await this.getFileType(filePath))?.ext as string || '';
if (ext) {
ext = '.' + ext;
}
const extOrEmpty = (await fileType.fileTypeFromFile(filePath))?.ext;
const ext = extOrEmpty ? `.${extOrEmpty}` : '';
let fileName = `${path.basename(filePath)}`;
if (fileName.indexOf('.') === -1) {
fileName += ext;
}
const mediaPath = this.context.session.getMsgService().getRichMediaFilePathForGuild({
md5HexStr: fileMd5,
fileName: fileName,
@@ -82,6 +70,7 @@ export class NTQQFileApi {
downloadType: 1,
file_uuid: '',
});
await this.copyFile(filePath, mediaPath!);
const fileSize = await this.getFileSize(filePath);
return {
@@ -93,11 +82,7 @@ export class NTQQFileApi {
};
}
async createValidSendFileElement(
filePath: string,
fileName: string = '',
folderId: string = '',
): Promise<SendFileElement> {
async createValidSendFileElement(filePath: string, fileName: string = '', folderId: string = '',): Promise<SendFileElement> {
const {
fileName: _fileName,
path,
@@ -118,55 +103,36 @@ export class NTQQFileApi {
};
}
async createValidSendPicElement(
picPath: string,
summary: string = '',
subType: 0 | 1 = 0,
): Promise<SendPicElement> {
const {
md5,
fileName,
path,
fileSize,
} = await this.core.apis.FileApi.uploadFile(picPath, ElementType.PIC, subType);
async createValidSendPicElement(picPath: string, summary: string = '', subType: 0 | 1 = 0,): Promise<SendPicElement> {
const { md5, fileName, path, fileSize } = await this.core.apis.FileApi.uploadFile(picPath, ElementType.PIC, subType);
if (fileSize === 0) {
throw new Error('文件异常大小为0');
}
const imageSize = await this.core.apis.FileApi.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,
};
return {
elementType: ElementType.PIC,
elementId: '',
picElement,
picElement: {
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,
} as PicElement,
};
}
async createValidSendVideoElement(
filePath: string,
fileName: string = '',
diyThumbPath: string = '',
): Promise<SendVideoElement> {
async createValidSendVideoElement(filePath: string, fileName: string = '', diyThumbPath: string = ''): Promise<SendVideoElement> {
const logger = this.core.context.logger;
const {
fileName: _fileName,
path,
fileSize,
md5,
} = await this.core.apis.FileApi.uploadFile(filePath, ElementType.VIDEO);
const { fileName: _fileName, path, fileSize, md5 } = await this.core.apis.FileApi.uploadFile(filePath, ElementType.VIDEO);
if (fileSize === 0) {
throw new Error('文件异常大小为0');
}
@@ -182,9 +148,10 @@ export class NTQQFileApi {
try {
videoInfo = await getVideoInfo(path, logger);
} catch (e) {
logger.logError('获取视频信息失败', e);
logger.logError('获取视频信息失败,将使用默认值', e);
}
const createThumb = new Promise<string | undefined>((resolve, reject) => {
const thumbPath = new Map();
const _thumbPath = await new Promise<string | undefined>((resolve, reject) => {
const thumbFileName = `${md5}_0.png`;
const thumbPath = pathLib.join(thumb, thumbFileName);
ffmpeg(filePath)
@@ -195,7 +162,7 @@ export class NTQQFileApi {
resolve(thumbPath);
}).catch(reject);
} else {
fsnormal.writeFileSync(thumbPath, Buffer.from(defaultVideoThumbB64, 'base64'));
fs.writeFileSync(thumbPath, Buffer.from(defaultVideoThumbB64, 'base64'));
resolve(thumbPath);
}
})
@@ -204,31 +171,14 @@ export class NTQQFileApi {
filename: thumbFileName,
folder: thumb,
size: videoInfo.width + 'x' + videoInfo.height,
}).on('end', () => {
})
.on('end', () => {
resolve(thumbPath);
});
});
const thumbPath = new Map();
const _thumbPath = await createThumb;
const thumbSize = _thumbPath ? (await fsPromises.stat(_thumbPath)).size : 0;
// log("生成缩略图", _thumbPath)
thumbPath.set(0, _thumbPath);
const thumbMd5 = _thumbPath ? await calculateFileMD5(_thumbPath) : '';
// "fileElement": {
// "fileMd5": "",
// "fileName": "1.mp4",
// "filePath": "C:\\Users\\nanae\\OneDrive\\Desktop\\1.mp4",
// "fileSize": "1847007",
// "picHeight": 1280,
// "picWidth": 720,
// "picThumbPath": {},
// "file10MMd5": "",
// "fileSha": "",
// "fileSha3": "",
// "fileUuid": "",
// "fileSubId": "",
// "thumbFileSize": 750
// }
return {
elementType: ElementType.VIDEO,
elementId: '',
@@ -243,28 +193,12 @@ export class NTQQFileApi {
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
},
};
}
async createValidSendPttElement(pttPath: string): Promise<SendPttElement> {
const {
converted,
path: silkPath,
duration,
} = await encodeSilk(pttPath, this.core.NapCatTempPath, this.core.context.logger);
// 生成语音 Path: silkPath Time: duration
const { converted, path: silkPath, duration } = await encodeSilk(pttPath, this.core.NapCatTempPath, this.core.context.logger);
if (!silkPath) {
throw new Error('语音转换失败, 请检查语音文件是否正常');
}
@@ -283,7 +217,6 @@ export class NTQQFileApi {
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,
@@ -299,9 +232,6 @@ export class NTQQFileApi {
};
}
async downloadMediaByUuid() {
//napCatCore.session.getRichMediaService().downloadFileForFileUuid();
}
async downloadFileForModelId(peer: Peer, modelId: string, unknown: string, timeout = 1000 * 60 * 2) {
const [, fileTransNotifyInfo] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelRichMediaService/downloadFileForModelId',
@@ -314,6 +244,7 @@ export class NTQQFileApi {
);
return fileTransNotifyInfo.filePath;
}
async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) {
//logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force);
// 用于下载收到的消息中的图片等
@@ -328,7 +259,7 @@ export class NTQQFileApi {
return sourcePath;
}
}
const [, fileTransNotifyInfo] = await this.core.eventWrapper.callNormalEventV2(
const [, completeRetData] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelMsgService/downloadRichMedia',
'NodeIKernelMsgListener/onRichMediaDownloadComplete',
[{
@@ -348,29 +279,20 @@ export class NTQQFileApi {
1,
timeout,
);
const msg = await this.core.apis.MsgApi.getMsgsByMsgId({
guildId: '',
chatType: chatType,
peerUid: peerUid,
}, [msgId]);
const mixElement = msg.msgList.find((msg) => msg.msgId === msgId)?.elements.find((e) => e.elementId === elementId);
const mixElementInner = mixElement?.videoElement ?? mixElement?.fileElement ?? mixElement?.pttElement ?? mixElement?.picElement;
let realPath = mixElementInner?.filePath;
if (!realPath) {
const picThumbPath: Map<number, string> = (mixElementInner as any)?.picThumbPath;
const picThumbPathList = Array.from(picThumbPath.values());
if (picThumbPathList.length > 0) realPath = picThumbPathList[0];
}
return realPath;
return completeRetData.filePath;
}
async getImageSize(filePath: string): Promise<ISizeCalculationResult | undefined> {
async getImageSize(filePath: string): Promise<ISizeCalculationResult> {
return new Promise((resolve, reject) => {
imageSize(filePath, (err, dimensions) => {
if (err) {
reject(err);
} else {
resolve(dimensions);
if (!dimensions) {
reject(new Error('获取图片尺寸失败'));
} else {
resolve(dimensions);
}
}
});
});
@@ -443,11 +365,8 @@ export class NTQQFileApi {
'NodeIKernelFileAssistantListener/onFileSearch',
[
keys,
{
resultType: 2,
pageLimit: 1,
},
randomResultId
{ resultType: 2, pageLimit: 1 },
randomResultId,
],
(ret) => {
searchId = ret;
@@ -463,7 +382,7 @@ export class NTQQFileApi {
fileSize: number = 1024576,
estimatedTime: number = (fileSize * 1000 / 1024576) + 5000,
) {
const [, ret] = await this.core.eventWrapper.callNormalEventV2(
const [, fileData] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelFileAssistantService/downloadFile',
'NodeIKernelFileAssistantListener/onFileStatusChanged',
[[fileId]],
@@ -472,7 +391,7 @@ export class NTQQFileApi {
1,
estimatedTime, // estimate 1MB/s
);
return ret.filePath!;
return fileData.filePath!;
}
async getImageUrl(element: PicElement) {
@@ -482,20 +401,19 @@ export class NTQQFileApi {
const url: string = element.originImageUrl!; // 没有域名
const md5HexStr = element.md5HexStr;
const fileMd5 = element.md5HexStr;
// const fileUuid = element.fileUuid;
if (url) {
const UrlParse = new URL(IMAGE_HTTP_HOST + url);//临时解析拼接
const imageAppid = UrlParse.searchParams.get('appid');
const isNewPic = imageAppid && ['1406', '1407'].includes(imageAppid);
if (isNewPic) {
let UrlRkey = UrlParse.searchParams.get('rkey');
if (UrlRkey) {
const parsedUrl = new URL(IMAGE_HTTP_HOST + url);//临时解析拼接
const imageAppid = parsedUrl.searchParams.get('appid');
const isNTFlavoredPic = imageAppid && ['1406', '1407'].includes(imageAppid);
if (isNTFlavoredPic) {
let rkey = parsedUrl.searchParams.get('rkey');
if (rkey) {
return IMAGE_HTTP_HOST_NT + url;
}
const rkeyData = await this.rkeyManager.getRkey();
UrlRkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey;
return IMAGE_HTTP_HOST_NT + url + `${UrlRkey}`;
rkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey;
return IMAGE_HTTP_HOST_NT + url + `${rkey}`;
} else {
// 老的图片url不需要rkey
return IMAGE_HTTP_HOST + url;
@@ -509,57 +427,3 @@ export class NTQQFileApi {
}
}
export class NTQQFileCacheApi {
context: InstanceContext;
core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) {
this.context = context;
this.core = core;
}
async setCacheSilentScan(isSilent: boolean = true) {
return '';
}
getCacheSessionPathList() {
return '';
}
clearCache(cacheKeys: Array<string> = ['tmp', 'hotUpdate']) {
// 参数未验证
return this.context.session.getStorageCleanService().clearCacheDataByKeys(cacheKeys);
}
addCacheScannedPaths(pathMap: object = {}) {
return this.context.session.getStorageCleanService().addCacheScanedPaths(pathMap);
}
scanCache() {
//return (await this.context.session.getStorageCleanService().scanCache()).size;
}
getHotUpdateCachePath() {
// 未实现
return '';
}
getDesktopTmpPath() {
// 未实现
return '';
}
getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) {
return this.context.session.getStorageCleanService().getChatCacheInfo(type, pageSize, 1, pageIndex);
}
getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) {
// const _lastRecord = lastRecord ? lastRecord : { fileType: fileType };
// 需要五个参数
// return napCatCore.session.getStorageCleanService().getFileCacheInfo();
}
async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) {
return this.context.session.getStorageCleanService().clearChatCacheInfo(chats, fileKeys);
}
}

View File

@@ -16,47 +16,42 @@ export class NTQQFriendApi {
// }
}
async getBuddyV2(refresh = false): Promise<FriendV2[]> {
const uids: string[] = [];
async getBuddyV2SimpleInfoMap(refresh = false) {
const buddyService = this.context.session.getBuddyService();
const buddyListV2 = refresh ? await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL);
uids.push(...buddyListV2.data.flatMap(item => item.buddyUids));
const data = await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo', 'nodeStore', uids,
const uids = buddyListV2.data.flatMap(item => item.buddyUids);
return await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo',
'nodeStore',
uids,
);
return Array.from(data.values());
}
async getBuddyV2(refresh = false): Promise<FriendV2[]> {
return Array.from((await this.getBuddyV2SimpleInfoMap(refresh)).values());
}
async getBuddyIdMap(refresh = false): Promise<LimitedHashTable<string, string>> {
const uids: string[] = [];
const retMap: LimitedHashTable<string, string> = new LimitedHashTable<string, string>(5000);
const buddyService = this.context.session.getBuddyService();
const buddyListV2 = refresh ? await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL);
uids.push(...buddyListV2.data.flatMap(item => item.buddyUids));
const data = await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo', 'nodeStore', uids,
);
data.forEach((value) => {
retMap.set(value.uin!, value.uid!);
});
//console.log('getBuddyIdMap', retMap.getValue);
const data = await this.getBuddyV2SimpleInfoMap(refresh);
data.forEach((value) => retMap.set(value.uin!, value.uid!));
return retMap;
}
async getBuddyV2ExWithCate(refresh = false) {
const uids: string[] = [];
const categoryMap: Map<string, any> = new Map();
const buddyService = this.context.session.getBuddyService();
const buddyListV2 = refresh ? (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data : (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data;
uids.push(
...buddyListV2.flatMap(item => {
item.buddyUids.forEach(uid => {
categoryMap.set(uid, { categoryId: item.categoryId, categoryName: item.categroyName });
});
return item.buddyUids;
}));
const uids = buddyListV2.flatMap(item => {
item.buddyUids.forEach(uid => {
categoryMap.set(uid, { categoryId: item.categoryId, categoryName: item.categroyName });
});
return item.buddyUids;
});
const data = await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo', 'nodeStore', uids,
'NodeIKernelProfileService/getCoreAndBaseInfo',
'nodeStore',
uids,
);
return buddyListV2.map(category => ({
categoryId: category.categoryId,

View File

@@ -34,17 +34,20 @@ export class NTQQGroupApi {
}
this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`);
}
async fetchGroupEssenceList(groupCode: string) {
const pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
return this.context.session.getGroupService().fetchGroupEssenceList({
groupCode: groupCode,
pageStart: 0,
pageLimit: 300
pageLimit: 300,
}, pskey);
}
async clearGroupNotifiesUnreadCount(unk: boolean) {
return this.context.session.getGroupService().clearGroupNotifiesUnreadCount(unk);
}
async setGroupAvatar(gc: string, filePath: string) {
return this.context.session.getGroupService().setHeader(gc, filePath);
}
@@ -57,6 +60,7 @@ export class NTQQGroupApi {
);
return groupList;
}
async getGroupExtFE0Info(GroupCode: string[], forced = true) {
return this.context.session.getGroupService().getGroupExt0xEF0Info(
GroupCode,
@@ -93,11 +97,12 @@ export class NTQQGroupApi {
showPlayTogetherSwitch: 1,
starId: 1,
todoSeq: 1,
viewedMsgDisappearTime: 1
viewedMsgDisappearTime: 1,
},
forced
forced,
);
}
async getGroup(groupCode: string, forced = false) {
let group = this.groupCache.get(groupCode.toString());
if (!group) {
@@ -120,24 +125,13 @@ export class NTQQGroupApi {
return this.getGroupMemberLatestSendTime(GroupCode, uids);
}
/**
* 通过QQ自带数据库获取群成员最后发言时间(仅返回有效数据 且消耗延迟大 需要进行缓存)
* @param GroupCode 群号
* @param uids QQ号
* @returns Map<string, string> key: uin value: sendTime
* @example
* let ret = await NTQQGroupApi.getGroupMemberLastestSendTime('123456');
* for (let [uin, sendTime] of ret) {
* console.log(uin, sendTime);
* }
*/
async getGroupMemberLatestSendTime(GroupCode: string, uids: string[]) {
const getdata = async (uid: string) => {
const NTRet = await this.getLatestMsgByUids(GroupCode, [uid]);
if (NTRet.result != 0 && NTRet.msgList.length < 1) {
const getData = async (uid: string) => {
const msgListWrapper = await this.getLatestMsgByUids(GroupCode, [uid]);
if (msgListWrapper.result !== 0 && msgListWrapper.msgList.length < 1) {
return undefined;
}
return { sendUin: NTRet.msgList[0].senderUin, sendTime: NTRet.msgList[0].msgTime };
return { sendUin: msgListWrapper.msgList[0].senderUin, sendTime: msgListWrapper.msgList[0].msgTime };
};
const PromiseData: Promise<({
sendUin: string;
@@ -145,7 +139,7 @@ export class NTQQGroupApi {
} | undefined)>[] = [];
const ret: Map<string, string> = new Map();
for (const uid of uids) {
PromiseData.push(getdata(uid).catch(() => undefined));
PromiseData.push(getData(uid).catch(() => undefined));
}
const allRet = await runAllWithTimeout(PromiseData, 2500);
for (const PromiseDo of allRet) {
@@ -249,8 +243,7 @@ export class NTQQGroupApi {
}
async addGroupEssence(GroupCode: string, msgId: string) {
// 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
// 需要 ob11msgId -> msgId + (peer) -> msgSeq + msgRandom
const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({
chatType: 2,
guildId: '',
@@ -261,7 +254,7 @@ export class NTQQGroupApi {
msgRandom: parseInt(MsgData.msgList[0].msgRandom),
msgSeq: parseInt(MsgData.msgList[0].msgSeq),
};
// GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
// GetMsgByShortID(shortID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
return this.context.session.getGroupService().addGroupEssence(param);
}
@@ -270,8 +263,8 @@ export class NTQQGroupApi {
}
async deleteGroupBulletin(GroupCode: string, noticeId: string) {
const _Pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
return this.context.session.getGroupService().deleteGroupBulletin(GroupCode, _Pskey, noticeId);
const psKey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
return this.context.session.getGroupService().deleteGroupBulletin(GroupCode, psKey, noticeId);
}
async quitGroupV2(GroupCode: string, needDeleteLocalMsg: boolean) {
@@ -282,18 +275,17 @@ export class NTQQGroupApi {
//应该是直接返回不需要Listener的 未经测试 需测试再发布
return this.context.session.getGroupService().quitGroupV2(param);
}
async removeGroupEssenceBySeq(GroupCode: string, msgRandom: string, msgSeq: string) {
const param = {
groupCode: GroupCode,
msgRandom: parseInt(msgRandom),
msgSeq: parseInt(msgSeq),
};
// GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
return this.context.session.getGroupService().removeGroupEssence(param);
}
async removeGroupEssence(GroupCode: string, msgId: string) {
// 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({
chatType: 2,
guildId: '',
@@ -304,7 +296,6 @@ export class NTQQGroupApi {
msgRandom: parseInt(MsgData.msgList[0].msgRandom),
msgSeq: parseInt(MsgData.msgList[0].msgSeq),
};
// GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
return this.context.session.getGroupService().removeGroupEssence(param);
}
@@ -361,7 +352,7 @@ export class NTQQGroupApi {
if (membersFromFunc.status === 'fulfilled' && membersFromListener.status === 'fulfilled') {
return new Map([
...membersFromFunc.value.result.infos,
...membersFromListener.value[0].infos
...membersFromListener.value[0].infos,
]);
}
if (membersFromFunc.status === 'fulfilled') {
@@ -386,19 +377,6 @@ export class NTQQGroupApi {
this.context.logger.logDebug(`获取群(${groupQQ})成员列表结果:`, `members: ${result.result.infos.size}`); //, Array.from(result.result.infos.values()));
return result.result.infos;
/*
console.log(sceneId);
const result = await napCatCore.getGroupService().getNextMemberList(sceneId, num);
console.log(result);
return result;
*/
}
async getGroupNotifies() {
// 获取管理员变更
// 加群通知,退出通知,需要管理员权限
}
async getGroupFileCount(Gids: Array<string>) {
@@ -470,19 +448,12 @@ export class NTQQGroupApi {
return this.context.session.getGroupService().modifyGroupName(groupQQ, groupName, false);
}
// 头衔不可用
/*
async setGroupTitle(groupQQ: string, uid: string, title: string) {
}
*/
async publishGroupBulletin(groupQQ: string, content: string, picInfo: {
id: string,
width: number,
height: number
} | undefined = undefined, pinned: number = 0, confirmRequired: number = 0) {
const _Pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com');
const psKey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com');
//text是content内容url编码
const data = {
text: encodeURI(content),
@@ -491,7 +462,7 @@ export class NTQQGroupApi {
pinned: pinned,
confirmRequired: confirmRequired,
};
return this.context.session.getGroupService().publishGroupBulletin(groupQQ, _Pskey!, data);
return this.context.session.getGroupService().publishGroupBulletin(groupQQ, psKey!, data);
}
async getGroupRemainAtTimes(GroupCode: string) {

View File

@@ -5,4 +5,5 @@ export * from './msg';
export * from './user';
export * from './webapi';
export * from './sign';
export * from './system';
export * from './system';
export * from './cache';

View File

@@ -14,12 +14,15 @@ export class NTQQMsgApi {
this.context = context;
this.core = core;
}
async getAioFirstViewLatestMsgs(peer: Peer, MsgCount: number) {
return this.context.session.getMsgService().getAioFirstViewLatestMsgs(peer, MsgCount);
}
async getLatestDbMsgs(peer: Peer, MsgCount: number) {
return this.context.session.getMsgService().getLatestDbMsgs(peer, MsgCount);
}
async FetchLongMsg(peer: Peer, msgId: string) {
return this.context.session.getMsgService().fetchLongMsg(peer, msgId);
}
@@ -29,19 +32,10 @@ export class NTQQMsgApi {
}
async getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, count: number = 20) {
//console.log(peer, msgSeq, emojiId, emojiType, count);
//注意此处emojiType 可选值一般为1-2 2好像是unicode表情dec值 大部分情况 Taged M likiowa
return this.context.session.getMsgService().getMsgEmojiLikesList(peer, msgSeq, emojiId, emojiType, '', false, count);
}
// napCatCore: NapCatCore | null = null;
// enum BaseEmojiType {
// NORMAL_EMOJI,
// SUPER_EMOJI,
// RANDOM_SUPER_EMOJI,
// CHAIN_SUPER_EMOJI,
// EMOJI_EMOJI
// }
async setEmojiLike(peer: Peer, msgSeq: string, emojiId: string, set: boolean = true) {
// nt_qq//global//nt_data//Emoji//emoji-resource//sysface_res/apng/ 下可以看到所有QQ表情预览
// nt_qq\global\nt_data\Emoji\emoji-resource\face_config.json 里面有所有表情的id, 自带表情id是QSid, 标准emoji表情id是QCid
@@ -60,7 +54,7 @@ export class NTQQMsgApi {
return this.context.session.getMsgService().forwardMsg(msgIds, peer, [peer], new Map());
}
async getLastestMsgByUids(peer: Peer, count: number = 20, isReverseOrder: boolean = false) {
async getLatestMsgByUids(peer: Peer, count: number = 20, isReverseOrder: boolean = false) {
return await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
chatInfo: peer,
filterMsgType: [],
@@ -76,7 +70,7 @@ export class NTQQMsgApi {
async getMsgsByMsgId(peer: Peer | undefined, msgIds: string[] | undefined) {
if (!peer) throw new Error('peer is not allowed');
if (!msgIds) throw new Error('msgIds is not allowed');
//Mlikiowa 参数不合规会导致NC异常崩溃 原因是TX未对进入参数判断 对应Android标记@NotNull AndroidJADX分析可得
//MliKiowa: 参数不合规会导致NC异常崩溃 原因是TX未对进入参数判断 对应Android标记@NotNull AndroidJADX分析可得
return await this.context.session.getMsgService().getMsgsByMsgId(peer, msgIds);
}
@@ -90,7 +84,7 @@ export class NTQQMsgApi {
async queryMsgsWithFilterExWithSeq(peer: Peer, msgSeq: string) {
return await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', msgSeq, {
chatInfo: peer,//此处为Peer 为关键查询参数 没有啥也没有 by mlik iowa
chatInfo: peer,
filterMsgType: [],
filterSendersUid: [],
filterMsgToTime: '0',
@@ -134,10 +128,7 @@ export class NTQQMsgApi {
params,
],
() => true,
( /* groupFileListResult: GroupFileInfoUpdateParamType */) => {
//Developer Mlikiowa Todo: 此处有问题 无法判断是否成功
return true;
},
() => true, // Todo: 应当通过 groupFileListResult 判断
1,
5000,
);
@@ -157,14 +148,6 @@ export class NTQQMsgApi {
}
async PrepareTempChat(toUserUid: string, GroupCode: string, nickname: string) {
//By Jadx/Ida Mlikiowa
const TempGameSession = {
nickname: '',
gameAppId: '',
selfTinyId: '',
peerRoleId: '',
peerOpenId: '',
};
return this.context.session.getMsgService().prepareTempChat({
chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP,
peerUid: toUserUid,
@@ -173,7 +156,13 @@ export class NTQQMsgApi {
sig: '',
selfPhone: '',
selfUid: this.core.selfInfo.uid,
gameSession: TempGameSession,
gameSession: {
nickname: '',
gameAppId: '',
selfTinyId: '',
peerRoleId: '',
peerOpenId: '',
},
});
}
@@ -182,7 +171,7 @@ export class NTQQMsgApi {
}
async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
//唉? !我有个想法
//唉?!我有个想法
if (peer.chatType === ChatType.KCHATTYPETEMPC2CFROMGROUP && peer.guildId && peer.guildId !== '') {
const member = await this.core.apis.GroupApi.getGroupMember(peer.guildId, peer.peerUid!);
if (member) {
@@ -212,11 +201,7 @@ export class NTQQMsgApi {
1,
timeout,
);
return msgList.find(msgRecord => {
if (msgRecord.guildId === msgId) {
return true;
}
});
return msgList.find(msgRecord => msgRecord.guildId === msgId);
}
async generateMsgUniqueId(chatType: number, time: string) {
@@ -246,14 +231,10 @@ export class NTQQMsgApi {
new Map(),
],
() => true,
(msgRecords) => {
for (const msgRecord of msgRecords) {
if (msgRecord.peerUid == destPeer.peerUid && msgRecord.senderUid == this.core.selfInfo.uid) {
return true;
}
}
return false;
},
(msgRecords) => msgRecords.some(
msgRecord => msgRecord.peerUid === destPeer.peerUid
&& msgRecord.senderUid === this.core.selfInfo.uid
),
);
for (const msg of msgList) {
const arkElement = msg.elements.find(ele => ele.arkElement);
@@ -271,7 +252,7 @@ export class NTQQMsgApi {
throw new Error('转发消息超时');
}
async markallMsgAsRead() {
async markAllMsgAsRead() {
return this.context.session.getMsgService().setAllC2CAndGroupMsgRead();
}
}

View File

@@ -13,7 +13,7 @@ export class NTQQSystemApi {
return this.core.util.hasOtherRunningQQProcess();
}
async ORCImage(filePath: string) {
async ocrImage(filePath: string) {
return this.context.session.getNodeMiscService().wantWinScreenOCR(filePath);
}
@@ -21,20 +21,16 @@ export class NTQQSystemApi {
return this.context.session.getRichMediaService().translateEnWordToZn(words);
}
//调用会超时 没灯用 (好像是通知listener的) onLineDev
async getOnlineDev() {
return this.context.session.getMsgService().getOnLineDev();
}
//1-2-162b9b42-65b9-4405-a8ed-2e256ec8aa50
async getArkJsonCollection(cid: string) {
return await this.core.eventWrapper.callNoListenerEvent('NodeIKernelCollectionService/collectionArkShare', '1717662698058');
}
async BootMiniApp(appfile: string, params: string) {
async bootMiniApp(appFile: string, params: string) {
await this.context.session.getNodeMiscService().setMiniAppVersion('2.16.4');
// const c = await this.context.session.getNodeMiscService().getMiniAppPath();
return this.context.session.getNodeMiscService().startNewMiniApp(appfile, params);
return this.context.session.getNodeMiscService().startNewMiniApp(appFile, params);
}
}

View File

@@ -15,9 +15,7 @@ export class NTQQUserApi {
async getProfileLike(uid: string) {
return this.context.session.getProfileLikeService().getBuddyProfileLike({
friendUids: [
uid,
],
friendUids: [uid],
basic: 1,
vote: 1,
favorite: 0,
@@ -63,41 +61,6 @@ export class NTQQUserApi {
return this.context.session.getGroupService().setHeader(gc, filePath);
}
async fetchUserDetailInfos(uids: string[]) {
// TODO: 26702 以上使用新接口 .Dev MliKiowa
const retData: User[] = [];
const [_retData, _retListener] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelProfileService/fetchUserDetailInfo',
'NodeIKernelProfileListener/onUserDetailInfoChanged',
[
'BuddyProfileStore',
uids,
UserDetailSource.KSERVER,
[ProfileBizType.KALL],
],
() => true,
(profile) => {
if (uids.includes(profile.uid)) {
const RetUser: User = {
...profile.simpleInfo.coreInfo,
...profile.simpleInfo.status,
...profile.simpleInfo.vasInfo,
...profile.commonExt,
...profile.simpleInfo.baseInfo,
qqLevel: profile.commonExt.qqLevel,
pendantId: '',
};
retData.push(RetUser);
return true;
}
return false;
},
uids.length,
);
return retData;
}
async fetchUserDetailInfo(uid: string, mode: UserDetailSource = UserDetailSource.KDB) {
const [_retData, profile] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelProfileService/fetchUserDetailInfo',
@@ -156,7 +119,6 @@ export class NTQQUserApi {
version: 0,
aioKeywordVersion: 0,
});
// console.log(robotUinRanges?.response?.robotUinRanges);
return robotUinRanges?.response?.robotUinRanges;
}
@@ -170,7 +132,7 @@ export class NTQQUserApi {
//需要异常处理
async getSkey(): Promise<string | undefined> {
async getSKey(): Promise<string | undefined> {
const ClientKeyData = await this.forceFetchClientKey();
if (ClientKeyData.result !== 0) {
throw new Error('getClientKey Error');
@@ -181,7 +143,7 @@ export class NTQQUserApi {
const cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl);
const skey = cookies['skey'];
if (!skey) {
throw new Error('getSkey Skey is Empty');
throw new Error('SKey is Empty');
}
return skey;
}
@@ -194,8 +156,8 @@ export class NTQQUserApi {
if (uid) return uid;
uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin);
if (uid) return uid;
const unveifyUid = (await this.getUserDetailInfoByUinV2(Uin)).detail.uid;//从QQ Native 特殊转换
if (unveifyUid.indexOf('*') == -1) uid = unveifyUid;
const unverifiedUid = (await this.getUserDetailInfoByUinV2(Uin)).detail.uid;//从QQ Native 特殊转换
if (unverifiedUid.indexOf('*') == -1) uid = unverifiedUid;
//if (uid) return uid;
return uid;
}
@@ -231,7 +193,10 @@ export class NTQQUserApi {
}
async getUserDetailInfoByUinV2(Uin: string) {
return await this.core.eventWrapper.callNoListenerEvent('NodeIKernelProfileService/getUserDetailInfoByUin', Uin);
return await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getUserDetailInfoByUin',
Uin
);
}
async forceFetchClientKey() {

View File

@@ -26,8 +26,7 @@ export class NTQQWebApi {
msg_seq: msgSeq,
msg_random: msgRandom,
target_group_code: targetGroupCode,
}).toString()
}`;
}).toString()}`;
try {
return RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
} catch (e) {
@@ -35,16 +34,12 @@ export class NTQQWebApi {
}
}
async getGroupEssenceMsgAll(GroupCode: string) {
let ret: GroupEssenceMsgRet[] = [];
for (let i = 0; i < 4; i++) {
let data = await this.getGroupEssenceMsg(GroupCode, i, 50);
const ret: GroupEssenceMsgRet[] = [];
for (let i = 0; i < 20; i++) {
const data = await this.getGroupEssenceMsg(GroupCode, i, 50);
if (!data) break;
if (data.data.is_end) {
ret.push(data);
break;
}
ret.push(data);
if (data.data.is_end) break;
}
return ret;
}
@@ -55,19 +50,18 @@ export class NTQQWebApi {
page_start: page_start.toString(),
page_limit: page_limit.toString(),
group_code: GroupCode,
}).toString()
}`;
let ret;
}).toString()}`;
try {
ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>
(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
const ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>(
url,
'GET',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
return ret.retcode === 0 ? ret : undefined;
} catch {
return undefined;
}
if (ret.retcode !== 0) {
return undefined;
}
return ret;
}
async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> {
@@ -75,15 +69,18 @@ export class NTQQWebApi {
const memberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>();
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
const retList: Promise<WebApiGroupMemberRet>[] = [];
const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({
const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>(
`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({
st: '0',
end: '40',
sort: '1',
gc: GroupCode,
bkn: this.getBknFromCookie(cookieObject),
}).toString()
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
}).toString()}`,
'POST',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) {
return [];
} else {
@@ -95,15 +92,18 @@ export class NTQQWebApi {
const PageNum = Math.ceil(fastRet.count / 40);
//遍历批量请求
for (let i = 2; i <= PageNum; i++) {
const ret = RequestUtil.HttpGetJson<WebApiGroupMemberRet>
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({
const ret = RequestUtil.HttpGetJson<WebApiGroupMemberRet>(
`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({
st: ((i - 1) * 40).toString(),
end: (i * 40).toString(),
sort: '1',
gc: GroupCode,
bkn: this.getBknFromCookie(cookieObject),
}).toString()
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
}).toString()}`,
'POST',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
retList.push(ret);
}
//批量等待
@@ -135,16 +135,19 @@ export class NTQQWebApi {
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
let ret: any = undefined;
try {
ret = await RequestUtil.HttpGetJson<any>
(`https://web.qun.qq.com/cgi-bin/announce/add_qun_notice${new URLSearchParams({
ret = await RequestUtil.HttpGetJson<any>(
`https://web.qun.qq.com/cgi-bin/announce/add_qun_notice${new URLSearchParams({
bkn: this.getBknFromCookie(cookieObject),
qid: GroupCode,
text: Content,
pinned: '0',
type: '1',
settings: '{"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}',
}).toString()
}`, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
}).toString()}`,
'GET',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
return ret;
} catch (e) {
return undefined;
@@ -153,16 +156,24 @@ export class NTQQWebApi {
async getGroupNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet> {
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
let ret: WebApiGroupNoticeRet | undefined = undefined;
try {
const url = 'https://web.qun.qq.com/cgi-bin/announce/get_t_list?bkn=' +
this.getBknFromCookie(cookieObject) + '&qid=' + GroupCode + '&ft=23&ni=1&n=1&i=1&log_read=1&platform=1&s=-1&n=20';
ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
if (ret?.ec !== 0) {
return undefined;
}
return ret;
const ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(
`https://web.qun.qq.com/cgi-bin/announce/get_t_list?${new URLSearchParams({
bkn: this.getBknFromCookie(cookieObject),
qid: GroupCode,
ft: '23',
ni: '1',
n: '1',
i: '1',
log_read: '1',
platform: '1',
s: '-1',
}).toString()}&n=20`,
'GET',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
return ret?.ec === 0 ? ret : undefined;
} catch (e) {
return undefined;
}
@@ -171,14 +182,17 @@ export class NTQQWebApi {
async getGroupHonorInfo(groupCode: string, getType: WebHonorType) {
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
const getDataInternal = async (Internal_groupCode: string, Internal_type: number) => {
const url = `https://qun.qq.com/interactive/honorlist?${new URLSearchParams({
gc: Internal_groupCode,
type: Internal_type.toString(),
}).toString()
}`;
let resJson;
try {
const res = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
const res = await RequestUtil.HttpGetText(
`https://qun.qq.com/interactive/honorlist?${new URLSearchParams({
gc: Internal_groupCode,
type: Internal_type.toString(),
}).toString()}`,
'GET',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
const match = /window\.__INITIAL_STATE__=(.*?);/.exec(res);
if (match) {
resJson = JSON.parse(match[1].trim());
@@ -189,7 +203,7 @@ export class NTQQWebApi {
return resJson?.actorList;
}
} catch (e) {
this.context.logger.logDebug('获取当前群荣耀失败', url, e);
this.context.logger.logDebug('获取当前群荣耀失败', e);
}
return undefined;
};
@@ -268,10 +282,12 @@ export class NTQQWebApi {
this.context.logger.logError('获取快乐源泉失败');
}
}
// 冒尖小春笋好像已经被tx扬了 R.I.P.
if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) {
HonorInfo.strong_newbie_list = [];
}
return HonorInfo;
}

View File

@@ -1,34 +1,10 @@
{
"3.2.12-27187": {
"appid": 537240645,
"qua": "V1_LNX_NQ_3.2.12_27187_GW_B"
"3.2.12-27597": {
"appid": 537243600,
"qua": "V1_LNX_NQ_3.2.12_27597_GW_B"
},
"3.2.12-27206": {
"appid": 537240645,
"qua": "V1_LNX_NQ_3.2.12_27206_GW_B"
},
"3.2.12-27254": {
"appid": 537240795,
"qua": "V1_LNX_NQ_3.2.12_27254_GW_B"
},
"9.9.15-27187": {
"appid": 537240610,
"qua": "V1_WIN_NQ_9.9.15_27187_GW_B"
},
"9.9.15-27206": {
"appid": 537240610,
"qua": "V1_WIN_NQ_9.9.15_27206_GW_B"
},
"9.9.15-27254": {
"appid": 537240709,
"qua": "V1_WIN_NQ_9.9.15_27254_GW_B"
},
"9.9.15-27333": {
"appid": 537240709,
"qua": "V1_WIN_NQ_9.9.15_27333_GW_B"
},
"9.9.15-27391": {
"appid": 537240709,
"qua": "V1_WIN_NQ_9.9.15_27333_GW_B"
"9.9.15-27597": {
"appid": 537243441,
"qua": "V1_WIN_NQ_9.9.15_27597_GW_B"
}
}

View File

@@ -1,4 +0,0 @@
# nekodoge
此协议为替代QQ平台 OnebotV11长期不可靠问题
# 规划路线

View File

View File

@@ -1,19 +0,0 @@
import { createServer } from 'node:net';
export class NewAdapterNetwork {
constructor(public host: number, public port: number) { }
async open() {
const server = createServer((socket) => {
socket.on('data', (data) => {
});
socket.on('end', () => {
});
socket.on('connect', () => {
});
});
server.listen(this.port, this.host);
}
}

View File

@@ -24,10 +24,9 @@ export class FetchEmojiLike extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.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];
return await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer, msg.msgSeq, payload.emojiId, payload.emojiType, +(payload.count ?? 20));
const msg = (await this.core.apis.MsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0];
return await this.core.apis.MsgApi.getMsgEmojiLikesList(msgIdPeer.Peer, msg.msgSeq, payload.emojiId, payload.emojiType, +(payload.count ?? 20));
}
}

View File

@@ -18,7 +18,6 @@ export class GetCollectionList extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQCollectionApi = this.core.apis.CollectionApi;
return await NTQQCollectionApi.getAllCollection(parseInt(payload.category.toString()), +(payload.count ?? 1));
return await this.core.apis.CollectionApi.getAllCollection(parseInt(payload.category.toString()), +(payload.count ?? 1));
}
}

View File

@@ -17,8 +17,6 @@ export class GetGroupInfoEx extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
const groupInfoEx = (await NTQQGroupApi.getGroupExtFE0Info([payload.group_id.toString()])).result.groupExtInfos.get(payload.group_id.toString());
return groupInfoEx;
return (await this.core.apis.GroupApi.getGroupExtFE0Info([payload.group_id.toString()])).result.groupExtInfos.get(payload.group_id.toString());
}
}

View File

@@ -5,11 +5,10 @@ export class GetProfileLike extends BaseAction<void, any> {
actionName = ActionName.GetProfileLike;
async _handle(payload: void) {
const NTQQUserApi = this.core.apis.UserApi;
const ret = await NTQQUserApi.getProfileLike(this.core.selfInfo.uid);
const ret = await this.core.apis.UserApi.getProfileLike(this.core.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.getUinByUidV2(listdata[i].uid)) || '');
listdata[i].uin = parseInt((await this.core.apis.UserApi.getUinByUidV2(listdata[i].uid)) || '');
}
return listdata;
}

View File

@@ -5,7 +5,6 @@ export class GetRobotUinRange extends BaseAction<void, Array<any>> {
actionName = ActionName.GetRobotUinRange;
async _handle(payload: void) {
const NTQQUserApi = this.core.apis.UserApi;
return await NTQQUserApi.getRobotUinRange();
return await this.core.apis.UserApi.getRobotUinRange();
}
}

View File

@@ -19,14 +19,13 @@ export class OCRImage extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQSystemApi = this.core.apis.SystemApi;
const { path, isLocal, success } = (await uri2local(this.core.NapCatTempPath, payload.image));
if (!success) {
throw `OCR ${payload.image}失败,image字段可能格式不正确`;
}
if (path) {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQSystemApi.ORCImage(path);
const ret = await this.core.apis.SystemApi.ocrImage(path);
if (!isLocal) {
fs.unlink(path, () => {
});

View File

@@ -19,8 +19,6 @@ export class SetInputStatus extends BaseAction<Payload, any> {
actionName = ActionName.SetInputStatus;
async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
let peer: Peer;
if (payload.group_id) {
peer = {
@@ -28,7 +26,7 @@ export class SetInputStatus extends BaseAction<Payload, any> {
peerUid: payload.group_id,
};
} else if (payload.user_id) {
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id);
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id);
if (!uid) throw new Error('uid is empty');
peer = {
chatType: ChatType.KCHATTYPEC2C,
@@ -38,6 +36,6 @@ export class SetInputStatus extends BaseAction<Payload, any> {
throw new Error('请指定 group_id 或 user_id');
}
return await NTQQMsgApi.sendShowInputStatusReq(peer, parseInt(payload.eventType));
return await this.core.apis.MsgApi.sendShowInputStatusReq(peer, parseInt(payload.eventType));
}
}

View File

@@ -17,8 +17,6 @@ export class SetLongNick extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const ret = await NTQQUserApi.setLongNick(payload.longNick);
return ret;
return await this.core.apis.UserApi.setLongNick(payload.longNick);
}
}

View File

@@ -20,8 +20,7 @@ export class SetOnlineStatus extends BaseAction<Payload, null> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const ret = await NTQQUserApi.setSelfOnlineStatus(
const ret = await this.core.apis.UserApi.setSelfOnlineStatus(
parseInt(payload.status.toString()),
parseInt(payload.ext_status.toString()),
parseInt(payload.battery_status.toString()),

View File

@@ -24,14 +24,13 @@ export default class SetAvatar extends BaseAction<Payload, null> {
}
async _handle(payload: Payload): Promise<null> {
const NTQQUserApi = this.core.apis.UserApi;
const { path, isLocal, errMsg, success } = (await uri2local(this.core.NapCatTempPath, payload.file));
const { path, isLocal, success } = (await uri2local(this.core.NapCatTempPath, payload.file));
if (!success) {
throw `头像${payload.file}设置失败,file字段可能格式不正确`;
}
if (path) {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQUserApi.setQQAvatar(path);
const ret = await this.core.apis.UserApi.setQQAvatar(path);
if (!isLocal) {
fs.unlink(path, () => {
});

View File

@@ -19,12 +19,10 @@ export class SharePeer extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQGroupApi = this.core.apis.GroupApi;
if (payload.group_id) {
return await NTQQGroupApi.getGroupRecommendContactArkJson(payload.group_id);
return await this.core.apis.GroupApi.getGroupRecommendContactArkJson(payload.group_id);
} else if (payload.user_id) {
return await NTQQUserApi.getBuddyRecommendContactArkJson(payload.user_id, payload.phoneNumber || '');
return await this.core.apis.UserApi.getBuddyRecommendContactArkJson(payload.user_id, payload.phoneNumber || '');
}
}
}
@@ -44,7 +42,6 @@ export class ShareGroupEx extends BaseAction<PayloadGroupEx, any> {
payloadSchema = SchemaDataGroupEx;
async _handle(payload: PayloadGroupEx) {
const NTQQGroupApi = this.core.apis.GroupApi;
return await NTQQGroupApi.getArkJsonGroupShare(payload.group_id);
return await this.core.apis.GroupApi.getArkJsonGroupShare(payload.group_id);
}
}

View File

@@ -20,8 +20,7 @@ export class TranslateEnWordToZn extends BaseAction<Payload, Array<any> | null>
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQSystemApi = this.core.apis.SystemApi;
const ret = await NTQQSystemApi.translateEnWordToZn(payload.words);
const ret = await this.core.apis.SystemApi.translateEnWordToZn(payload.words);
if (ret.result !== 0) {
throw new Error('翻译失败');
}

View File

@@ -18,7 +18,6 @@ export class DelGroupFile extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
return await NTQQGroupApi.DelGroupFile(payload.group_id.toString(), [payload.file_id]);
return await this.core.apis.GroupApi.DelGroupFile(payload.group_id.toString(), [payload.file_id]);
}
}

View File

@@ -18,7 +18,7 @@ export class DelGroupFileFolder extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
return (await NTQQGroupApi.DelGroupFileFolder(payload.group_id.toString(), payload.folder_id)).groupFileCommonResult;
return (await this.core.apis.GroupApi.DelGroupFileFolder(
payload.group_id.toString(), payload.folder_id)).groupFileCommonResult;
}
}

View File

@@ -28,15 +28,12 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
payloadSchema: any = GetFileBase_PayloadSchema;
async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
const NTQQMsgApi = this.core.apis.MsgApi;
const NTQQFileApi = this.core.apis.FileApi;
//接收消息标记模式
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file);
if (contextMsgFile) {
const { peer, msgId, elementId } = contextMsgFile;
const downloadPath = await NTQQFileApi.downloadMedia(msgId, peer.chatType, peer.peerUid, elementId, '', '');
const mixElement = (await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]))?.msgList
const downloadPath = await this.core.apis.FileApi.downloadMedia(msgId, peer.chatType, peer.peerUid, elementId, '', '');
const mixElement = (await this.core.apis.MsgApi.getMsgsByMsgId(peer, [msgId]))?.msgList
.find(msg => msg.msgId === msgId)?.elements.find(e => e.elementId === elementId);
const mixElementInner = mixElement?.videoElement ?? mixElement?.fileElement ?? mixElement?.pttElement ?? mixElement?.picElement;
if (!mixElementInner) throw new Error('element not found');
@@ -64,7 +61,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
const contextModelIdFile = FileNapCatOneBotUUID.decodeModelId(payload.file);
if (contextModelIdFile) {
const { peer, modelId } = contextModelIdFile;
const downloadPath = await NTQQFileApi.downloadFileForModelId(peer, modelId, '');
const downloadPath = await this.core.apis.FileApi.downloadFileForModelId(peer, modelId, '');
const res: GetFileResponse = {
file: downloadPath,
url: downloadPath,
@@ -83,9 +80,9 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
}
//搜索名字模式
const searchResult = (await NTQQFileApi.searchForFile([payload.file]));
const searchResult = (await this.core.apis.FileApi.searchForFile([payload.file]));
if (searchResult) {
const downloadPath = await NTQQFileApi.downloadFileById(searchResult.id, parseInt(searchResult.fileSize));
const downloadPath = await this.core.apis.FileApi.downloadFileById(searchResult.id, parseInt(searchResult.fileSize));
const res: GetFileResponse = {
file: downloadPath,
url: downloadPath,

View File

@@ -21,14 +21,13 @@ export class GetGroupFileList extends BaseAction<Payload, { FileList: Array<any>
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.MsgApi;
let param = {};
if (payload.folder_id) {
param = {
folderId: payload.folder_id.toString(),
};
}
const ret = await NTQQMsgApi.getGroupFileList(payload.group_id.toString(), {
const ret = await this.core.apis.MsgApi.getGroupFileList(payload.group_id.toString(), {
sortType: 1,
fileCount: +payload.file_count,
startIndex: +payload.start_index,

View File

@@ -18,7 +18,6 @@ export class SetGroupFileFolder extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
return (await NTQQGroupApi.CreatGroupFileFolder(payload.group_id.toString(), payload.folder_name)).resultWithGroupItem;
return (await this.core.apis.GroupApi.CreatGroupFileFolder(payload.group_id.toString(), payload.folder_name)).resultWithGroupItem;
}
}

View File

@@ -19,7 +19,6 @@ export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<any> {
const NTQQMsgApi = this.core.apis.MsgApi;
const msgId = payload.message_id || payload.id;
if (!msgId) {
throw Error('message_id is required');
@@ -29,7 +28,7 @@ export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> {
if (!rootMsg) {
throw Error('msg not found');
}
const data = await NTQQMsgApi.getMultiMsg(rootMsg.Peer, rootMsg.MsgId, rootMsg.MsgId);
const data = await this.core.apis.MsgApi.getMultiMsg(rootMsg.Peer, rootMsg.MsgId, rootMsg.MsgId);
if (!data || data.result !== 0) {
throw Error('找不到相关的聊天记录' + data?.errMsg);
}

View File

@@ -27,21 +27,17 @@ export default class GetFriendMsgHistory extends BaseAction<Payload, Response> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<Response> {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
const NTQQFriendApi = this.core.apis.FriendApi;
//处理参数
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
const MsgCount = +(payload.count ?? 20);
const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder;
if (!uid) throw `记录${payload.user_id}不存在`;
const friend = await NTQQFriendApi.isBuddy(uid);
const friend = await this.core.apis.FriendApi.isBuddy(uid);
const peer = { chatType: friend ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: uid };
const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0');
//拉取消息
const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0';
const msgList = hasMessageSeq ?
(await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await NTQQMsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList;
(await this.core.apis.MsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await this.core.apis.MsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList;
if (msgList.length === 0) throw `消息${payload.message_seq}不存在`;
//翻转消息
if (isReverseOrder) msgList.reverse();

View File

@@ -22,7 +22,6 @@ export class GetGroupHonorInfo extends BaseAction<Payload, Array<any>> {
if (!payload.type) {
payload.type = WebHonorType.ALL;
}
const NTQQWebApi = this.core.apis.WebApi;
return await NTQQWebApi.getGroupHonorInfo(payload.group_id.toString(), payload.type);
return await this.core.apis.WebApi.getGroupHonorInfo(payload.group_id.toString(), payload.type);
}
}

View File

@@ -27,7 +27,6 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<Response> {
const NTQQMsgApi = this.core.apis.MsgApi;
//处理参数
const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder;
const MsgCount = +(payload.count ?? 20);
@@ -36,7 +35,7 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
//拉取消息
const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0';
const msgList = hasMessageSeq ?
(await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await NTQQMsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList;
(await this.core.apis.MsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await this.core.apis.MsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList;
if (msgList.length === 0) throw `消息${payload.message_seq}不存在`;
//翻转消息
if (isReverseOrder) msgList.reverse();

View File

@@ -15,8 +15,7 @@ export class GetOnlineClient extends BaseAction<void, Array<any>> {
async _handle(payload: void) {
//注册监听
const NTQQSystemApi = this.core.apis.SystemApi;
NTQQSystemApi.getOnlineDev();
this.core.apis.SystemApi.getOnlineDev();
await sleep(500);
return [];

View File

@@ -19,10 +19,9 @@ export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11Use
actionName = ActionName.GoCQHTTP_GetStrangerInfo;
async _handle(payload: Payload): Promise<OB11User> {
const NTQQUserApi = this.core.apis.UserApi;
const user_id = payload.user_id.toString();
const extendData = await NTQQUserApi.getUserDetailInfoByUinV2(user_id);
const uid = (await NTQQUserApi.getUidByUinV2(user_id))!;
const extendData = await this.core.apis.UserApi.getUserDetailInfoByUinV2(user_id);
const uid = (await this.core.apis.UserApi.getUidByUinV2(user_id))!;
if (!uid || uid.indexOf('*') != -1) {
return {
...extendData.detail.simpleInfo.coreInfo,
@@ -38,7 +37,7 @@ export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11Use
login_days: 0,
};
}
const data = { ...extendData, ...(await NTQQUserApi.getUserDetailInfo(uid)) };
const data = { ...extendData, ...(await this.core.apis.UserApi.getUserDetailInfo(uid)) };
return OB11Entities.stranger(data);
}
}

View File

@@ -22,7 +22,6 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
actionName = ActionName.GoCQHTTP_SendGroupNotice;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
let UploadImage: { id: string, width: number, height: number } | undefined = undefined;
if (payload.image) {
//公告图逻辑
@@ -38,7 +37,7 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
throw `群公告${payload.image}设置失败,获取资源失败`;
}
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ImageUploadResult = await NTQQGroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path);
const ImageUploadResult = await this.core.apis.GroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path);
if (ImageUploadResult.errCode != 0) {
throw `群公告${payload.image}设置失败,图片上传失败`;
}
@@ -50,7 +49,7 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
}
const noticePinned = +(payload.pinned ?? 0);
const noticeConfirmRequired = +(payload.confirm_required ?? 0);
const publishGroupBulletinResult = await NTQQGroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, noticePinned, noticeConfirmRequired);
const publishGroupBulletinResult = await this.core.apis.GroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, noticePinned, noticeConfirmRequired);
if (publishGroupBulletinResult.result != 0) {
throw `设置群公告失败,错误信息:${publishGroupBulletinResult.errMsg}`;

View File

@@ -25,14 +25,13 @@ export default class SetGroupPortrait extends BaseAction<Payload, any> {
}
async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.core.apis.GroupApi;
const { path, isLocal, errMsg, success } = (await uri2local(this.core.NapCatTempPath, payload.file));
const { path, isLocal, success } = (await uri2local(this.core.NapCatTempPath, payload.file));
if (!success) {
throw `头像${payload.file}设置失败,file字段可能格式不正确`;
}
if (path) {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQGroupApi.setGroupAvatar(payload.group_id.toString(), path) as any;
const ret = await this.core.apis.GroupApi.setGroupAvatar(payload.group_id.toString(), path) as any;
if (!isLocal) {
fs.unlink(path, () => {
});

View File

@@ -19,10 +19,9 @@ export class SetQQProfile extends BaseAction<Payload, any | null> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const self = this.core.selfInfo;
const OldProfile = await NTQQUserApi.getUserDetailInfo(self.uid);
return await NTQQUserApi.modifySelfProfile({
const OldProfile = await this.core.apis.UserApi.getUserDetailInfo(self.uid);
return await this.core.apis.UserApi.modifySelfProfile({
nick: payload.nickname,
longNick: (payload?.personal_note ?? OldProfile?.longNick) || '',
sex: parseInt(payload?.sex ? payload?.sex.toString() : OldProfile?.sex!.toString()),

View File

@@ -22,14 +22,12 @@ export default class GoCQHTTPUploadPrivateFile extends BaseAction<Payload, null>
payloadSchema = SchemaData;
async getPeer(payload: Payload): Promise<Peer> {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQFriendApi = this.core.apis.FriendApi;
if (payload.user_id) {
const peerUid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const peerUid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!peerUid) {
throw `私聊${payload.user_id}不存在`;
}
const isBuddy = await NTQQFriendApi.isBuddy(peerUid);
const isBuddy = await this.core.apis.FriendApi.isBuddy(peerUid);
return { chatType: isBuddy ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid };
}
throw new Error('缺少参数 user_id');

View File

@@ -18,16 +18,14 @@ export default class DelEssenceMsg extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.core.apis.GroupApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(+payload.message_id);
const NTQQWebApi = this.core.apis.WebApi;
if (!msg) {
const data = NTQQGroupApi.essenceLRU.getValue(+payload.message_id);
const data = this.core.apis.GroupApi.essenceLRU.getValue(+payload.message_id);
if(!data) throw new Error('消息不存在');
const { msg_seq, msg_random, group_id } = JSON.parse(data) as { msg_seq: string, msg_random: string, group_id: string };
return await NTQQGroupApi.removeGroupEssenceBySeq(group_id, msg_seq, msg_random);
return await this.core.apis.GroupApi.removeGroupEssenceBySeq(group_id, msg_seq, msg_random);
}
return await NTQQGroupApi.removeGroupEssence(
return await this.core.apis.GroupApi.removeGroupEssence(
msg.Peer.peerUid,
msg.MsgId,
);

View File

@@ -19,9 +19,8 @@ export class DelGroupNotice extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
const group = payload.group_id.toString();
const noticeId = payload.notice_id;
return await NTQQGroupApi.deleteGroupBulletin(group, noticeId);
return await this.core.apis.GroupApi.deleteGroupBulletin(group, noticeId);
}
}

View File

@@ -31,9 +31,7 @@ export class GetGroupEssence extends BaseAction<Payload, any> {
}
async _handle(payload: Payload) {
const NTQQWebApi = this.core.apis.WebApi;
const NTQQGroupApi = this.core.apis.GroupApi;
const msglist = (await NTQQWebApi.getGroupEssenceMsgAll(payload.group_id.toString())).flatMap((e) => e.data.msg_list);
const msglist = (await this.core.apis.WebApi.getGroupEssenceMsgAll(payload.group_id.toString())).flatMap((e) => e.data.msg_list);
if (!msglist) {
throw new Error('获取失败');
}
@@ -65,7 +63,7 @@ export class GetGroupEssence extends BaseAction<Payload, any> {
//设置第一个bit为0 保证shortId为正数
hash[0] &= 0x7f;
const shortId = hash.readInt32BE(0);
NTQQGroupApi.essenceLRU.set(shortId, msgTempData);
this.core.apis.GroupApi.essenceLRU.set(shortId, msgTempData);
return {
msg_seq: msg.msg_seq,
msg_random: msg.msg_random,

View File

@@ -16,21 +16,19 @@ export class GetGroupIgnoredNotifies extends BaseAction<void, any> {
actionName = ActionName.GetGroupIgnoredNotifies;
async _handle(payload: void) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQGroupApi = this.core.apis.GroupApi;
const ignoredNotifies = await NTQQGroupApi.getSingleScreenNotifies(true, 10);
const ignoredNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(true, 10);
const retData: any = {
join_requests: await Promise.all(
ignoredNotifies
.filter(notify => notify.type === 7)
.map(async SSNotify => ({
request_id: SSNotify.seq,
requester_uin: await NTQQUserApi.getUinByUidV2(SSNotify.user1?.uid),
requester_uin: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1?.uid),
requester_nick: SSNotify.user1?.nickName,
group_id: SSNotify.group?.groupCode,
group_name: SSNotify.group?.groupName,
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
actor: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
}))),
};

View File

@@ -19,8 +19,7 @@ class GetGroupInfo extends BaseAction<Payload, OB11Group> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
const group = (await NTQQGroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString());
const group = (await this.core.apis.GroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString());
if (!group) throw `${payload.group_id}不存在`;
return OB11Entities.group(group);
}

View File

@@ -2,7 +2,6 @@ import { OB11Group } from '@/onebot';
import { OB11Entities } from '@/onebot/entities';
import BaseAction from '../BaseAction';
import { ActionName } from '../types';
import { Group } from '@/core/entities';
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
// no_cache get时传字符串
const SchemaData = {
@@ -19,9 +18,9 @@ class GetGroupList extends BaseAction<Payload, OB11Group[]> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
const groupList: Group[] = await NTQQGroupApi.getGroups(typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache);
return OB11Entities.groups(groupList);
return OB11Entities.groups(
await this.core.apis.GroupApi.getGroups(
typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache));
}
}

View File

@@ -22,27 +22,25 @@ class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQGroupApi = this.core.apis.GroupApi;
const isNocache = typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache;
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error(`Uin2Uid Error ${payload.user_id}不存在`);
const [member, info] = await Promise.allSettled([
NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache),
NTQQUserApi.getUserDetailInfo(uid),
this.core.apis.GroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache),
this.core.apis.UserApi.getUserDetailInfo(uid),
]);
if (member.status !== 'fulfilled') throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在 ${member.reason}`);
if (member.status !== 'fulfilled') throw new Error(`群(${payload.group_id})成员${payload.user_id}获取失败 ${member.reason}`);
if (!member.value) throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在`);
if (info.status === 'fulfilled') {
this.core.context.logger.logDebug('群成员详细信息结果', info.value);
Object.assign(member, info.value);
Object.assign(member.value, info.value);
} else {
this.core.context.logger.logDebug(`获取群成员详细信息失败, 只能返回基础信息 ${info.reason}`);
}
const date = Math.round(Date.now() / 1000);
const retMember = OB11Entities.groupMember(payload.group_id.toString(), member.value as GroupMember);
const Member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), retMember.user_id);
retMember.last_sent_time = parseInt(Member?.lastSpeakTime || date.toString());
retMember.join_time = parseInt(Member?.joinTime || date.toString());
retMember.last_sent_time = parseInt(Member?.lastSpeakTime ?? date.toString());
retMember.join_time = parseInt(Member?.joinTime ?? date.toString());
return retMember;
}
}

View File

@@ -20,9 +20,7 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQWebApi = this.core.apis.WebApi;
const groupMembers = await NTQQGroupApi.getGroupMembersV2(payload.group_id.toString());
const groupMembers = await this.core.apis.GroupApi.getGroupMembersV2(payload.group_id.toString());
const groupMembersArr = Array.from(groupMembers.values());
let _groupMembers = groupMembersArr.map(item => {
@@ -48,7 +46,7 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
});
if (isPrivilege) {
const webGroupMembers = await NTQQWebApi.getGroupMembers(payload.group_id.toString());
const webGroupMembers = await this.core.apis.WebApi.getGroupMembers(payload.group_id.toString());
for (let i = 0, len = webGroupMembers.length; i < len; i++) {
if (!webGroupMembers[i]?.uin) {
continue;

View File

@@ -34,10 +34,8 @@ export class GetGroupNotice extends BaseAction<Payload, GroupNotice[]> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQWebApi = this.core.apis.WebApi;
const group = payload.group_id.toString();
const ret = await NTQQWebApi.getGroupNotice(group);
const ret = await this.core.apis.WebApi.getGroupNotice(group);
if (!ret) {
throw new Error('获取公告失败');
}

View File

@@ -18,12 +18,11 @@ export default class SetEssenceMsg extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.core.apis.GroupApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
if (!msg) {
throw new Error('msg not found');
}
return await NTQQGroupApi.addGroupEssence(
return await this.core.apis.GroupApi.addGroupEssence(
msg.Peer.peerUid,
msg.MsgId,
);

View File

@@ -20,10 +20,9 @@ export default class SetGroupAddRequest extends BaseAction<Payload, null> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi;
const flag = payload.flag.toString();
const approve = payload.approve?.toString() !== 'false';
await NTQQGroupApi.handleGroupRequest(flag,
await this.core.apis.GroupApi.handleGroupRequest(flag,
approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject,
payload.reason ?? ' ',
);

View File

@@ -21,11 +21,9 @@ export default class SetGroupAdmin extends BaseAction<Payload, null> {
async _handle(payload: Payload): Promise<null> {
const enable = typeof payload.enable === 'string' ? payload.enable === 'true' : !!payload.enable;
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('get Uid Error');
await NTQQGroupApi.setMemberRole(payload.group_id.toString(), uid, enable ? GroupMemberRole.admin : GroupMemberRole.normal);
await this.core.apis.GroupApi.setMemberRole(payload.group_id.toString(), uid, enable ? GroupMemberRole.admin : GroupMemberRole.normal);
return null;
}
}

View File

@@ -19,11 +19,9 @@ export default class SetGroupBan extends BaseAction<Payload, null> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('uid error');
await NTQQGroupApi.banMember(payload.group_id.toString(),
await this.core.apis.GroupApi.banMember(payload.group_id.toString(),
[{ uid: uid, timeStamp: parseInt(payload.duration.toString()) }]);
return null;
}

View File

@@ -19,9 +19,8 @@ export default class SetGroupCard extends BaseAction<Payload, null> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi;
const member = await NTQQGroupApi.getGroupMember(payload.group_id.toString(), payload.user_id.toString());
member && await NTQQGroupApi.setMemberCard(payload.group_id.toString(), member.uid, payload.card || '');
const member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), payload.user_id.toString());
if (member) await this.core.apis.GroupApi.setMemberCard(payload.group_id.toString(), member.uid, payload.card || '');
return null;
}
}

View File

@@ -20,12 +20,10 @@ export default class SetGroupKick extends BaseAction<Payload, null> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const rejectReq = payload.reject_add_request?.toString() == 'true';
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('get Uid Error');
await NTQQGroupApi.kickMember(payload.group_id.toString(), [uid], rejectReq);
await this.core.apis.GroupApi.kickMember(payload.group_id.toString(), [uid], rejectReq);
return null;
}
}

View File

@@ -17,7 +17,6 @@ export default class SetGroupLeave extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.core.apis.GroupApi;
await NTQQGroupApi.quitGroup(payload.group_id.toString());
await this.core.apis.GroupApi.quitGroup(payload.group_id.toString());
}
}

View File

@@ -17,8 +17,7 @@ export default class SetGroupName extends BaseAction<Payload, null> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi;
await NTQQGroupApi.setGroupName(payload.group_id.toString(), payload.group_name);
await this.core.apis.GroupApi.setGroupName(payload.group_id.toString(), payload.group_name);
return null;
}
}

View File

@@ -19,8 +19,7 @@ export default class SetGroupWholeBan extends BaseAction<Payload, null> {
async _handle(payload: Payload): Promise<null> {
const enable = payload.enable?.toString() !== 'false';
const NTQQGroupApi = this.core.apis.GroupApi;
await NTQQGroupApi.banGroup(payload.group_id.toString(), enable);
await this.core.apis.GroupApi.banGroup(payload.group_id.toString(), enable);
return null;
}
}

View File

@@ -23,7 +23,6 @@ class DeleteMsg extends BaseAction<Payload, void> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.MsgApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(Number(payload.message_id));
if (msg) {
const ret = this.core.eventWrapper.registerListen(
@@ -34,7 +33,7 @@ class DeleteMsg extends BaseAction<Payload, void> {
).catch(() => new Promise<undefined>((resolve) => {
resolve(undefined);
}));
await NTQQMsgApi.recallMsg(msg.Peer, [msg.MsgId]);
await this.core.apis.MsgApi.recallMsg(msg.Peer, [msg.MsgId]);
const data = await ret;
if (!data) {
//throw new Error('Recall failed');

View File

@@ -18,9 +18,8 @@ type Payload = FromSchema<typeof SchemaData>;
class ForwardSingleMsg extends BaseAction<Payload, null> {
protected async getTargetPeer(payload: Payload): Promise<Peer> {
const NTQQUserApi = this.core.apis.UserApi;
if (payload.user_id) {
const peerUid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const peerUid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!peerUid) {
throw new Error(`无法找到私聊对象${payload.user_id}`);
}
@@ -30,13 +29,12 @@ class ForwardSingleMsg extends BaseAction<Payload, null> {
}
async _handle(payload: Payload): Promise<null> {
const NTQQMsgApi = this.core.apis.MsgApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
if (!msg) {
throw new Error(`无法找到消息${payload.message_id}`);
}
const peer = await this.getTargetPeer(payload);
const ret = await NTQQMsgApi.forwardMsg(msg.Peer,
const ret = await this.core.apis.MsgApi.forwardMsg(msg.Peer,
peer,
[msg.MsgId],
);

View File

@@ -22,7 +22,6 @@ class GetMsg extends BaseAction<Payload, OB11Message> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.MsgApi;
// log("history msg ids", Object.keys(msgHistory));
if (!payload.message_id) {
throw Error('参数message_id不能为空');
@@ -33,7 +32,7 @@ class GetMsg extends BaseAction<Payload, OB11Message> {
throw new Error('消息不存在');
}
const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType };
const msg = await NTQQMsgApi.getMsgsByMsgId(
const msg = await this.core.apis.MsgApi.getMsgsByMsgId(
peer,
[msgIdWithPeer?.MsgId || payload.message_id.toString()]);
const retMsg = await this.obContext.apis.MsgApi.parseMessage(msg.msgList[0], 'array');

View File

@@ -15,14 +15,12 @@ type PlayloadType = FromSchema<typeof SchemaData>;
class MarkMsgAsRead extends BaseAction<PlayloadType, null> {
async getPeer(payload: PlayloadType): Promise<Peer> {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQFriendApi = this.core.apis.FriendApi;
if (payload.user_id) {
const peerUid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const peerUid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!peerUid) {
throw `私聊${payload.user_id}不存在`;
}
const isBuddy = await NTQQFriendApi.isBuddy(peerUid);
const isBuddy = await this.core.apis.FriendApi.isBuddy(peerUid);
return { chatType: isBuddy ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid };
}
if (!payload.group_id) {
@@ -32,9 +30,7 @@ class MarkMsgAsRead extends BaseAction<PlayloadType, null> {
}
async _handle(payload: PlayloadType): Promise<null> {
const NTQQMsgApi = this.core.apis.MsgApi;
// 调用API
const ret = await NTQQMsgApi.setMsgRead(await this.getPeer(payload));
const ret = await this.core.apis.MsgApi.setMsgRead(await this.getPeer(payload));
if (ret.result != 0) {
throw new Error('设置已读失败,' + ret.errMsg);
}
@@ -70,8 +66,7 @@ export class MarkAllMsgAsRead extends BaseAction<Payload, null> {
actionName = ActionName._MarkAllMsgAsRead;
async _handle(payload: Payload): Promise<null> {
const NTQQMsgApi = this.core.apis.MsgApi;
await NTQQMsgApi.markallMsgAsRead();
await this.core.apis.MsgApi.markAllMsgAsRead();
return null;
}
}

View File

@@ -34,9 +34,6 @@ export async function createContext(core: NapCatCore, payload: OB11PostSendMsg,
// 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 NTQQFriendApi = core.apis.FriendApi;
const NTQQUserApi = core.apis.UserApi;
const NTQQMsgApi = core.apis.MsgApi;
if ((contextMode === ContextMode.Group || contextMode === ContextMode.Normal) && payload.group_id) {
return {
chatType: ChatType.KCHATTYPEGROUP,
@@ -44,11 +41,11 @@ export async function createContext(core: NapCatCore, payload: OB11PostSendMsg,
};
}
if ((contextMode === ContextMode.Private || contextMode === ContextMode.Normal) && payload.user_id) {
const Uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
const Uid = await core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!Uid) throw new Error('无法获取用户信息');
const isBuddy = await NTQQFriendApi.isBuddy(Uid);
const isBuddy = await core.apis.FriendApi.isBuddy(Uid);
if (!isBuddy) {
const ret = await NTQQMsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, Uid);
const ret = await core.apis.MsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, Uid);
if (ret.tmpChatInfo?.groupCode) {
return {
chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP,
@@ -139,7 +136,6 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
}
private async handleForwardedNodes(destPeer: Peer, messageNodes: OB11MessageNode[]): Promise<RawMessage | null> {
const NTQQMsgApi = this.core.apis.MsgApi;
const selfPeer = {
chatType: ChatType.KCHATTYPEC2C,
peerUid: this.core.selfInfo.uid,
@@ -206,7 +202,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
logger.logError('转发消息失败,未找到消息', msgId);
continue;
}
const nodeMsg = (await NTQQMsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0];
const nodeMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0];
srcPeer = srcPeer ?? { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid };
if (srcPeer.peerUid !== nodeMsg.peerUid) {
needSendSelf = true;
@@ -230,7 +226,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
if (retMsgIds.length === 0) throw Error('转发消息失败,生成节点为空');
try {
logger.logDebug('开发转发', srcPeer, destPeer, retMsgIds);
return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, retMsgIds);
return await this.core.apis.MsgApi.multiForwardMsg(srcPeer!, destPeer, retMsgIds);
} catch (e) {
logger.logError('forward failed', e);
return null;
@@ -243,9 +239,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
peerUid: this.core.selfInfo.uid,
};
const logger = this.core.context.logger;
const NTQQMsgApi = this.core.apis.MsgApi;
//msg 为待克隆消息
const sendElements: SendMessageElement[] = [];
for (const element of msg.elements) {
@@ -256,7 +250,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
logger.logDebug('需要clone的消息无法解析将会忽略掉', msg);
}
try {
return await NTQQMsgApi.sendMsg(selfPeer, sendElements, true);
return await this.core.apis.MsgApi.sendMsg(selfPeer, sendElements, true);
} catch (e) {
logger.logError(e, '克隆转发消息失败,将忽略本条消息', msg);
}

View File

@@ -19,7 +19,6 @@ export class SetMsgEmojiLike extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.MsgApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
if (!msg) {
throw new Error('msg not found');
@@ -27,10 +26,10 @@ export class SetMsgEmojiLike extends BaseAction<Payload, any> {
if (!payload.emoji_id) {
throw new Error('emojiId not found');
}
const msgData = (await NTQQMsgApi.getMsgsByMsgId(msg.Peer, [msg.MsgId])).msgList;
const msgData = (await this.core.apis.MsgApi.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);
return await this.core.apis.MsgApi.setEmojiLike(msg.Peer, msgData[0].msgSeq, payload.emoji_id.toString(), true);
}
}

View File

@@ -22,52 +22,10 @@ export class GetCookies extends BaseAction<Payload, Response> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQWebApi = this.core.apis.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);
const cookiesObject = await this.core.apis.UserApi.getCookies(payload.domain);
//把获取到的cookiesObject转换成 k=v; 格式字符串拼接在一起
const cookies = Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const bkn = cookiesObject?.skey ? NTQQWebApi.getBknFromCookie(cookiesObject) : '';
const bkn = cookiesObject?.skey ? this.core.apis.WebApi.getBknFromCookie(cookiesObject) : '';
return { cookies, bkn };
}
}

View File

@@ -19,7 +19,6 @@ export default class GetFriendList extends BaseAction<Payload, OB11User[]> {
async _handle(payload: Payload) {
//全新逻辑
const NTQQFriendApi = this.core.apis.FriendApi;
return OB11Entities.friendsV2(await NTQQFriendApi.getBuddyV2(typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache));
return OB11Entities.friendsV2(await this.core.apis.FriendApi.getBuddyV2(typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache));
}
}

View File

@@ -16,11 +16,9 @@ export default class GetRecentContact extends BaseAction<Payload, any> {
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
const ret = await NTQQUserApi.getRecentContactListSnapShot(+(payload.count || 10));
const ret = await this.core.apis.UserApi.getRecentContactListSnapShot(+(payload.count || 10));
return await Promise.all(ret.info.changedList.map(async (t) => {
const FastMsg = await NTQQMsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]);
const FastMsg = await this.core.apis.MsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]);
if (FastMsg.msgList.length > 0) {
//扩展ret.info.changedList
const lastestMsg = await this.obContext.apis.MsgApi.parseMessage(FastMsg.msgList[0], 'array');

View File

@@ -18,11 +18,10 @@ export default class SendLike extends BaseAction<Payload, null> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> {
const NTQQUserApi = this.core.apis.UserApi;
//logDebug('点赞参数', payload);
const qq = payload.user_id.toString();
const uid: string = await NTQQUserApi.getUidByUinV2(qq) || '';
const result = await NTQQUserApi.like(uid, parseInt(payload.times?.toString()) || 1);
const uid: string = await this.core.apis.UserApi.getUidByUinV2(qq) || '';
const result = await this.core.apis.UserApi.like(uid, parseInt(payload.times?.toString()) || 1);
//logDebug('点赞结果', result);
if (result.result !== 0) {
throw `点赞失败 ${result.errMsg}`;

View File

@@ -19,9 +19,8 @@ export default class SetFriendAddRequest extends BaseAction<Payload, null> {
payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> {
const NTQQFriendApi = this.core.apis.FriendApi;
const approve = payload.approve?.toString() !== 'false';
await NTQQFriendApi.handleFriendRequest(payload.flag, approve);
await this.core.apis.FriendApi.handleFriendRequest(payload.flag, approve);
return null;
}
}

View File

@@ -14,7 +14,6 @@ export class OneBotFriendApi {
//使用前预先判断 busiId 1061
async parsePrivatePokeEvent(grayTipElement: GrayTipElement) {
const NTQQUserApi = this.core.apis.UserApi;
const json = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr);
let pokedetail: any[] = json.items;
//筛选item带有uid的元素
@@ -23,8 +22,8 @@ export class OneBotFriendApi {
if (pokedetail.length == 2) {
return new OB11FriendPokeEvent(
this.core,
parseInt((await NTQQUserApi.getUinByUidV2(pokedetail[0].uid))!),
parseInt((await NTQQUserApi.getUinByUidV2(pokedetail[1].uid))!),
parseInt((await this.core.apis.UserApi.getUinByUidV2(pokedetail[0].uid))!),
parseInt((await this.core.apis.UserApi.getUinByUidV2(pokedetail[1].uid))!),
pokedetail,
);
}

View File

@@ -30,16 +30,13 @@ export class OneBotGroupApi {
}
async parseGroupEvent(msg: RawMessage) {
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
const logger = this.core.context.logger;
if (msg.chatType !== ChatType.KCHATTYPEGROUP) {
return;
}
//log("group msg", msg);
if (msg.senderUin && msg.senderUin !== '0') {
const member = await NTQQGroupApi.getGroupMember(msg.peerUid, msg.senderUin);
const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUid, msg.senderUin);
if (member && member.cardName !== msg.sendMemberName) {
const newCardName = msg.sendMemberName || '';
const event = new OB11GroupCardEvent(this.core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName);
@@ -58,7 +55,7 @@ export class OneBotGroupApi {
const BanEvent = await this.obContext.apis.GroupApi.parseGroupBanEvent(msg.peerUid, element.grayTipElement);
if (BanEvent) return BanEvent;
} else if (groupElement.type == TipGroupElementType.kicked) {
NTQQGroupApi.quitGroup(msg.peerUid).then();
this.core.apis.GroupApi.quitGroup(msg.peerUid).then();
try {
const KickEvent = await this.obContext.apis.GroupApi.parseGroupKickEvent(msg.peerUid, element.grayTipElement);
if (KickEvent) return KickEvent;
@@ -110,8 +107,8 @@ export class OneBotGroupApi {
return new OB11GroupPokeEvent(
this.core,
parseInt(msg.peerUid),
parseInt((await NTQQUserApi.getUinByUidV2(poke_uid[0].uid))!),
parseInt((await NTQQUserApi.getUinByUidV2(poke_uid[1].uid))!),
parseInt((await this.core.apis.UserApi.getUinByUidV2(poke_uid[0].uid))!),
parseInt((await this.core.apis.UserApi.getUinByUidV2(poke_uid[1].uid))!),
pokedetail,
);
}
@@ -127,7 +124,7 @@ export class OneBotGroupApi {
chatType: ChatType.KCHATTYPEGROUP,
peerUid: Group,
};
const msgData = await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true);
const msgData = await this.core.apis.MsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true);
const msgList = (await this.core.apis.WebApi.getGroupEssenceMsgAll(Group)).flatMap((e) => e.data.msg_list);
const realMsg = msgList.find((e) => e.msg_seq.toString() == msgSeq);
return new OB11GroupEssenceEvent(
@@ -158,7 +155,6 @@ export class OneBotGroupApi {
async parseGroupBanEvent(GroupCode: string, grayTipElement: GrayTipElement) {
const groupElement = grayTipElement?.groupElement;
const NTQQGroupApi = this.core.apis.GroupApi;
if (!groupElement?.shutUp) return undefined;
const memberUid = groupElement.shutUp!.member.uid;
const adminUid = groupElement.shutUp!.admin.uid;
@@ -166,14 +162,14 @@ export class OneBotGroupApi {
let duration = parseInt(groupElement.shutUp!.duration);
const subType: 'ban' | 'lift_ban' = duration > 0 ? 'ban' : 'lift_ban';
if (memberUid) {
memberUin = (await NTQQGroupApi.getGroupMember(GroupCode, memberUid))?.uin || '';
memberUin = (await this.core.apis.GroupApi.getGroupMember(GroupCode, memberUid))?.uin || '';
} else {
memberUin = '0'; // 0表示全员禁言
if (duration > 0) {
duration = -1;
}
}
const adminUin = (await NTQQGroupApi.getGroupMember(GroupCode, adminUid))?.uin;
const adminUin = (await this.core.apis.GroupApi.getGroupMember(GroupCode, adminUid))?.uin;
if (memberUin && adminUin) {
return new OB11GroupBanEvent(
this.core,
@@ -215,12 +211,11 @@ export class OneBotGroupApi {
}
async parseGroupMemberIncreaseEvent(GroupCode: string, grayTipElement: GrayTipElement) {
const NTQQGroupApi = this.core.apis.GroupApi;
const groupElement = grayTipElement?.groupElement;
if (!groupElement) return undefined;
const member = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.memberUid);
const member = await this.core.apis.GroupApi.getGroupMember(GroupCode, groupElement.memberUid);
const memberUin = member?.uin;
const adminMember = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.adminUid);
const adminMember = await this.core.apis.GroupApi.getGroupMember(GroupCode, groupElement.adminUid);
if (memberUin) {
const operatorUin = adminMember?.uin || memberUin;
return new OB11GroupIncreaseEvent(
@@ -235,11 +230,9 @@ export class OneBotGroupApi {
}
async parseGroupKickEvent(GroupCode: string, grayTipElement: GrayTipElement) {
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const groupElement = grayTipElement?.groupElement;
if (!groupElement) return undefined;
const adminUin = (await NTQQGroupApi.getGroupMember(GroupCode, groupElement.adminUid))?.uin || (await NTQQUserApi.getUidByUinV2(groupElement.adminUid));
const adminUin = (await this.core.apis.GroupApi.getGroupMember(GroupCode, groupElement.adminUid))?.uin || (await this.core.apis.UserApi.getUidByUinV2(groupElement.adminUid));
if (adminUin) {
return new OB11GroupDecreaseEvent(
this.core,

View File

@@ -106,12 +106,13 @@ export class OneBotMsgApi {
peerUid: msg.peerUid,
guildId: '',
};
const encodedFileId = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId);
return {
type: OB11MessageDataType.image,
data: {
file: element.fileName,
file: encodedFileId,
sub_type: element.picSubType,
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
file_id: encodedFileId,
url: await this.core.apis.FileApi.getImageUrl(element),
file_size: element.fileSize,
},
@@ -212,7 +213,6 @@ export class OneBotMsgApi {
},
replyElement: async (element, msg) => {
const NTQQMsgApi = this.core.apis.MsgApi;
const records = msg.records.find(msgRecord => msgRecord.msgId === element?.sourceMsgIdInRecords);
const peer = {
chatType: msg.chatType,
@@ -237,17 +237,17 @@ export class OneBotMsgApi {
let replyMsg: RawMessage | undefined;
// Attempt 1
replyMsg = (await NTQQMsgApi.getMsgsBySeqAndCount(peer,element.replayMsgSeq, 1, true, true))
replyMsg = (await this.core.apis.MsgApi.getMsgsBySeqAndCount(peer,element.replayMsgSeq, 1, true, true))
.msgList
.find(msg => msg.msgRandom === records.msgRandom);
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
// Attempt 2
replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replayMsgSeq)).msgList[0];
replyMsg = (await this.core.apis.MsgApi.getSingleMsg(peer, element.replayMsgSeq)).msgList[0];
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
// Attempt 3
const replyMsgList = (await NTQQMsgApi.getMsgExBySeq(peer, records.msgSeq)).msgList;
const replyMsgList = (await this.core.apis.MsgApi.getMsgExBySeq(peer, records.msgSeq)).msgList;
if (replyMsgList.length < 1) {
this.core.context.logger.logError('回复消息消息验证失败', element.replayMsgSeq);
return null;
@@ -261,20 +261,19 @@ export class OneBotMsgApi {
},
videoElement: async (element, msg, elementWrapper) => {
const NTQQFileApi = this.core.apis.FileApi;
const peer = {
chatType: msg.chatType,
peerUid: msg.peerUid,
guildId: '',
};
//读取视频链接并兜底
let videoUrlWrappers: Awaited<ReturnType<typeof NTQQFileApi.getVideoUrl>> | undefined;
let videoUrlWrappers: Awaited<ReturnType<typeof this.core.apis.FileApi.getVideoUrl>> | undefined;
if (msg.peerUin === '284840486') {
//TODO: 合并消息内部 应该进行特殊处理 可能需要重写peer 待测试与研究 Mlikiowa Tagged
}
try {
videoUrlWrappers = await NTQQFileApi.getVideoUrl({
videoUrlWrappers = await this.core.apis.FileApi.getVideoUrl({
chatType: msg.chatType,
peerUid: msg.peerUid,
guildId: '0',
@@ -300,7 +299,7 @@ export class OneBotMsgApi {
videoDownUrl = element.filePath;
}
await NTQQFileApi.addFileCache(
await this.core.apis.FileApi.addFileCache(
{
peerUid: msg.peerUid,
chatType: msg.chatType,
@@ -359,7 +358,6 @@ export class OneBotMsgApi {
},
multiForwardMsgElement: async (_, msg) => {
const NTQQMsgApi = this.core.apis.MsgApi;
const message_data: OB11MessageForward = {
data: {} as any,
type: OB11MessageDataType.forward,
@@ -376,7 +374,7 @@ export class OneBotMsgApi {
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;
const multiMsgs = (await this.core.apis.MsgApi.getMultiMsg(parentMsgPeer, msg.parentMsgIdList[0], msg.msgId))?.msgList;
//拉取下级消息
if (!multiMsgs) return null;
//拉取失败则跳过
@@ -446,15 +444,13 @@ export class OneBotMsgApi {
if (!context.peer || context.peer.chatType == ChatType.KCHATTYPEC2C) return undefined;
if (atQQ === 'all') return at(atQQ, atQQ, AtType.atAll, '全体成员');
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const atMember = await NTQQGroupApi.getGroupMember(context.peer.peerUid, atQQ);
const atMember = await this.core.apis.GroupApi.getGroupMember(context.peer.peerUid, atQQ);
if (atMember) {
return at(atQQ, atMember.uid, AtType.atUser, atMember.nick || atMember.cardName);
}
const uid = await NTQQUserApi.getUidByUinV2(`${atQQ}`);
const uid = await this.core.apis.UserApi.getUidByUinV2(`${atQQ}`);
if (!uid) throw new Error('Get Uid Error');
const info = await NTQQUserApi.getUserDetailInfo(uid);
const info = await this.core.apis.UserApi.getUserDetailInfo(uid);
return at(atQQ, uid, AtType.atUser, info.nick || '');
},
@@ -464,8 +460,7 @@ export class OneBotMsgApi {
this.core.context.logger.logWarn('回复消息不存在', id);
return undefined;
}
const NTQQMsgApi = this.core.apis.MsgApi;
const replyMsg = (await NTQQMsgApi.getMsgsByMsgId(
const replyMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(
replyMsgM.Peer, [replyMsgM.MsgId])).msgList[0];
return replyMsg ?
{
@@ -710,9 +705,6 @@ export class OneBotMsgApi {
if (msg.senderUin == '0' || msg.senderUin == '') return;
if (msg.peerUin == '0' || msg.peerUin == '') return;
//跳过空消息
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
const resMsg: OB11Message = {
self_id: parseInt(this.core.selfInfo.uin),
user_id: parseInt(msg.senderUin!),
@@ -736,18 +728,18 @@ export class OneBotMsgApi {
if (msg.chatType == ChatType.KCHATTYPEGROUP) {
resMsg.sub_type = 'normal'; // 这里go-cqhttp是group而onebot11标准是normal, 蛋疼
resMsg.group_id = parseInt(msg.peerUin);
let member = await NTQQGroupApi.getGroupMember(msg.peerUin, msg.senderUin);
if (!member) member = await NTQQGroupApi.getGroupMember(msg.peerUin, msg.senderUin);
let member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin);
if (!member) member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin);
if (member) {
resMsg.sender.role = OB11Entities.groupMemberRole(member.role);
resMsg.sender.nickname = member.nick;
}
} else if (msg.chatType == ChatType.KCHATTYPEC2C) {
resMsg.sub_type = 'friend';
resMsg.sender.nickname = (await NTQQUserApi.getUserDetailInfo(msg.senderUid)).nick;
resMsg.sender.nickname = (await this.core.apis.UserApi.getUserDetailInfo(msg.senderUid)).nick;
} else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) {
resMsg.sub_type = 'group';
const ret = await NTQQMsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid);
const ret = await this.core.apis.MsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid);
if (ret.result === 0) {
resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode);
resMsg.sender.nickname = ret.tmpChatInfo!.fromNick;

View File

@@ -77,7 +77,6 @@ export class NapCatOneBot11Adapter {
}
async InitOneBot() {
const NTQQUserApi = this.core.apis.UserApi;
const selfInfo = this.core.selfInfo;
const ob11Config = this.configLoader.configData;
@@ -87,7 +86,7 @@ export class NapCatOneBot11Adapter {
WebSocket服务 ${ob11Config.ws.enable ? '已启动' : '未启动'}, ${ob11Config.ws.host}:${ob11Config.ws.port}
WebSocket反向服务 ${ob11Config.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${ob11Config.reverseWs.urls}`;
NTQQUserApi.getUserDetailInfo(selfInfo.uid).then(user => {
this.core.apis.UserApi.getUserDetailInfo(selfInfo.uid).then(user => {
selfInfo.nick = user.nick;
this.context.logger.setLogSelfInfo(selfInfo);
}).catch(this.context.logger.logError);
@@ -341,12 +340,6 @@ export class NapCatOneBot11Adapter {
this.core.apis.FriendApi.clearBuddyReqUnreadCnt();
for (let i = 0; i < reqs.unreadNums; i++) {
const req = reqs.buddyReqs[i];
//req.isBuddy === false是单向好友 null为常规情况
// if (req.isBuddy === false && ) {
// const NTQQFriendApi = this.core.apis.FriendApi;
// await NTQQFriendApi.handleFriendRequest(req.friendUid + '|' + req.reqTime, true);
// }
if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
continue;
}

View File

@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
SettingItem(
'<span id="napcat-update-title">Napcat</span>',
undefined,
SettingButton('V2.2.28', 'napcat-update-button', 'secondary'),
SettingButton('V2.2.31', 'napcat-update-button', 'secondary'),
),
]),
SettingList([

View File

@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
SettingItem(
'<span id="napcat-update-title">Napcat</span>',
void 0,
SettingButton("V2.2.28", "napcat-update-button", "secondary")
SettingButton("V2.2.31", "napcat-update-button", "secondary")
)
]),
SettingList([