mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6024cabb69 | ||
![]() |
08446e648e | ||
![]() |
14af7a3572 | ||
![]() |
cdc4275f81 | ||
![]() |
a9ade98315 | ||
![]() |
f3ae6fa70f | ||
![]() |
8f465e376e | ||
![]() |
adc366a959 | ||
![]() |
b176fa66d4 | ||
![]() |
7b7609a068 | ||
![]() |
136e27d655 | ||
![]() |
e3ca5df713 | ||
![]() |
bda32f3e8f | ||
![]() |
a7c6e45a92 | ||
![]() |
7c20ca9b64 | ||
![]() |
a201461eff | ||
![]() |
e5d9df37c5 | ||
![]() |
106fbaf086 | ||
![]() |
a0024c98d5 | ||
![]() |
684a702638 | ||
![]() |
aec4a009d1 | ||
![]() |
822af575c9 | ||
![]() |
485efa7d44 | ||
![]() |
3d09d45423 | ||
![]() |
4c69c6d9fd | ||
![]() |
920a41acef | ||
![]() |
0cf13a284c | ||
![]() |
a89cdef436 | ||
![]() |
881d88f4ad | ||
![]() |
a72c96f56d | ||
![]() |
bc8235b209 | ||
![]() |
0087495749 | ||
![]() |
9560afd4a7 | ||
![]() |
56ec8559a0 | ||
![]() |
99ca79ac7d | ||
![]() |
24564f4c74 | ||
![]() |
212c802a1e | ||
![]() |
984b5d6c40 | ||
![]() |
0e3a4191a9 | ||
![]() |
570a34bca5 | ||
![]() |
c9a0c29286 | ||
![]() |
b5f804ec22 | ||
![]() |
dadbb83271 | ||
![]() |
dcf0a06217 | ||
![]() |
3b5e6553cd | ||
![]() |
509390af20 | ||
![]() |
9ad511a9c0 | ||
![]() |
89c102513d |
17
README.md
17
README.md
@@ -3,36 +3,33 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
---
|
---
|
||||||
## To Be Continued
|
## 欢迎回来
|
||||||
当前版本 (v2.1.x) 请使用内核构建版本(版本号最后的五位数)为 27187 以上的 PC NTQQ 运行。
|
NapCatQQ (aka 猫猫框架) 是现代化的基于 NTQQ 的 Bot 协议端实现。
|
||||||
|
|
||||||
## 项目介绍
|
## 猫猫技能
|
||||||
NapCatQQ 是现代化的基于 NTQQ 的 Bot 协议端实现。
|
|
||||||
|
|
||||||
## 项目优势
|
|
||||||
- [x] **多种启动方式**:支持以无头、LiteLoader 插件、仅 QQ GUI 三种方式启动
|
- [x] **多种启动方式**:支持以无头、LiteLoader 插件、仅 QQ GUI 三种方式启动
|
||||||
- [x] **低占用**:无头模式占用资源极低,适合在服务器上运行
|
- [x] **低占用**:无头模式占用资源极低,适合在服务器上运行
|
||||||
- [x] **超多接口**:在实现大部分Onebot接口上扩展了一套私有API
|
- [x] **超多接口**:在实现大部分Onebot接口上扩展了一套私有API
|
||||||
- [x] **WebUI**:自带 WebUI 支持,远程管理更加便捷
|
- [x] **WebUI**:自带 WebUI 支持,远程管理更加便捷
|
||||||
|
|
||||||
## 如何使用
|
## 使用猫猫
|
||||||
|
|
||||||
可前往 [Release](https://github.com/NapNeko/NapCatQQ/releases/) 页面下载最新版本
|
可前往 [Release](https://github.com/NapNeko/NapCatQQ/releases/) 页面下载最新版本
|
||||||
|
|
||||||
**首次使用**请务必前往[官方文档](https://napneko.github.io/)查看使用教程。
|
**首次使用**请务必前往[官方文档](https://napneko.github.io/)查看使用教程。
|
||||||
|
|
||||||
## 相关链接
|
## 回家旅途
|
||||||
[QQ Group](https://qm.qq.com/q/VfjAq5HIMS)
|
[QQ Group](https://qm.qq.com/q/VfjAq5HIMS)
|
||||||
|
|
||||||
[Telegram Link](https://t.me/+nLZEnpne-pQ1OWFl)
|
[Telegram Link](https://t.me/+nLZEnpne-pQ1OWFl)
|
||||||
|
|
||||||
## 鸣谢名单
|
## 猫猫朋友
|
||||||
感谢 [LLOneBot](https://github.com/LLOneBot/LLOneBot) 提供初始版本基础
|
感谢 [LLOneBot](https://github.com/LLOneBot/LLOneBot) 提供初始版本基础
|
||||||
|
|
||||||
感谢 [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持
|
感谢 [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 使用许可
|
## 约法三章
|
||||||
|
|
||||||
任何使用本仓库代码的地方,都应当严格遵守[本仓库开源许可](./LICENSE)。**此外,禁止任何项目未经授权二次分发或基于 NapCat 代码开发。**
|
任何使用本仓库代码的地方,都应当严格遵守[本仓库开源许可](./LICENSE)。**此外,禁止任何项目未经授权二次分发或基于 NapCat 代码开发。**
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"name": "NapCatQQ",
|
"name": "NapCatQQ",
|
||||||
"slug": "NapCat.Framework",
|
"slug": "NapCat.Framework",
|
||||||
"description": "高性能的 OneBot 11 协议实现",
|
"description": "高性能的 OneBot 11 协议实现",
|
||||||
"version": "2.2.4",
|
"version": "2.2.8",
|
||||||
"icon": "./logo.png",
|
"icon": "./logo.png",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"name": "napcat",
|
"name": "napcat",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.2.4",
|
"version": "2.2.8",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:framework": "vite build --mode framework",
|
"build:framework": "vite build --mode framework",
|
||||||
"build:shell": "vite build --mode shell",
|
"build:shell": "vite build --mode shell",
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { NodeIQQNTWrapperSession } from '@/core/wrapper/wrapper';
|
import { NodeIQQNTWrapperSession } from '@/core/wrapper/wrapper';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
|
|
||||||
interface Internal_MapKey {
|
interface InternalMapKey {
|
||||||
timeout: number;
|
timeout: number;
|
||||||
createtime: number;
|
createtime: number;
|
||||||
func: (...arg: any[]) => any;
|
func: (...arg: any[]) => any;
|
||||||
@@ -11,14 +11,14 @@ interface Internal_MapKey {
|
|||||||
export type ListenerClassBase = Record<string, string>;
|
export type ListenerClassBase = Record<string, string>;
|
||||||
|
|
||||||
export interface ListenerIBase {
|
export interface ListenerIBase {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-new
|
|
||||||
new(listener: any): ListenerClassBase;
|
new(listener: any): ListenerClassBase;
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LegacyNTEventWrapper {
|
export class LegacyNTEventWrapper {
|
||||||
private WrapperSession: NodeIQQNTWrapperSession | undefined; //WrapperSession
|
private WrapperSession: NodeIQQNTWrapperSession | undefined; //WrapperSession
|
||||||
private listenerManager: Map<string, ListenerClassBase> = new Map<string, ListenerClassBase>(); //ListenerName-Unique -> Listener实例
|
private listenerManager: Map<string, ListenerClassBase> = new Map<string, ListenerClassBase>(); //ListenerName-Unique -> Listener实例
|
||||||
private EventTask = new Map<string, Map<string, Map<string, Internal_MapKey>>>(); //tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func}
|
private EventTask = new Map<string, Map<string, Map<string, InternalMapKey>>>(); //tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
wrapperSession: NodeIQQNTWrapperSession
|
wrapperSession: NodeIQQNTWrapperSession
|
||||||
@@ -27,17 +27,15 @@ export class LegacyNTEventWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createProxyDispatch(ListenerMainName: string) {
|
createProxyDispatch(ListenerMainName: string) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
const dispatcherListenerFunc = this.dispatcherListener.bind(this);
|
||||||
const current = this;
|
|
||||||
return new Proxy(
|
return new Proxy(
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
get(target: any, prop: any, receiver: any) {
|
get(target: any, prop: any, receiver: any) {
|
||||||
// console.log('get', prop, typeof target[prop]);
|
|
||||||
if (typeof target[prop] === 'undefined') {
|
if (typeof target[prop] === 'undefined') {
|
||||||
// 如果方法不存在,返回一个函数,这个函数调用existentMethod
|
// 如果方法不存在,返回一个函数,这个函数调用existentMethod
|
||||||
return (...args: any[]) => {
|
return (...args: any[]) => {
|
||||||
current.dispatcherListener.apply(current, [ListenerMainName, prop, ...args]).then();
|
dispatcherListenerFunc(ListenerMainName, prop, ...args).then();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// 如果方法存在,正常返回
|
// 如果方法存在,正常返回
|
||||||
@@ -55,8 +53,6 @@ export class LegacyNTEventWrapper {
|
|||||||
if (eventNameArr.length > 1) {
|
if (eventNameArr.length > 1) {
|
||||||
const serviceName = 'get' + eventNameArr[0].replace('NodeIKernel', '');
|
const serviceName = 'get' + eventNameArr[0].replace('NodeIKernel', '');
|
||||||
const eventName = eventNameArr[1];
|
const eventName = eventNameArr[1];
|
||||||
//getNodeIKernelGroupListener,GroupService
|
|
||||||
//console.log('2', eventName);
|
|
||||||
const services = (this.WrapperSession as unknown as eventType)[serviceName]();
|
const services = (this.WrapperSession as unknown as eventType)[serviceName]();
|
||||||
let event = services[eventName];
|
let event = services[eventName];
|
||||||
//重新绑定this
|
//重新绑定this
|
||||||
@@ -84,16 +80,14 @@ export class LegacyNTEventWrapper {
|
|||||||
|
|
||||||
//统一回调清理事件
|
//统一回调清理事件
|
||||||
async dispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: any[]) {
|
async dispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: any[]) {
|
||||||
//console.log("[EventDispatcher]",ListenerMainName, ListenerSubName, ...args);
|
|
||||||
this.EventTask.get(ListenerMainName)
|
this.EventTask.get(ListenerMainName)
|
||||||
?.get(ListenerSubName)
|
?.get(ListenerSubName)
|
||||||
?.forEach((task, uuid) => {
|
?.forEach((task, uuid) => {
|
||||||
//console.log(task.func, uuid, task.createtime, task.timeout);
|
|
||||||
if (task.createtime + task.timeout < Date.now()) {
|
if (task.createtime + task.timeout < Date.now()) {
|
||||||
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.delete(uuid);
|
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.delete(uuid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (task.checker && task.checker(...args)) {
|
if (task?.checker?.(...args)) {
|
||||||
task.func(...args);
|
task.func(...args);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -162,7 +156,88 @@ export class LegacyNTEventWrapper {
|
|||||||
this.createListenerFunction(ListenerMainName);
|
this.createListenerFunction(ListenerMainName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
async CallNormalEventV2<
|
||||||
|
EventType extends (...args: any[]) => Promise<any>,
|
||||||
|
ListenerType extends (...args: any[]) => void
|
||||||
|
>(
|
||||||
|
EventName = '',
|
||||||
|
ListenerName = '',
|
||||||
|
waitTimes = 1,
|
||||||
|
timeout: number = 3000,
|
||||||
|
checkerEvent: (ret: Awaited<ReturnType<EventType>>) => boolean = () => true,
|
||||||
|
checkerListener: (...args: Parameters<ListenerType>) => boolean = () => true,
|
||||||
|
...args: Parameters<EventType>
|
||||||
|
) {
|
||||||
|
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(
|
||||||
|
async (resolve, reject) => {
|
||||||
|
const id = randomUUID();
|
||||||
|
let complete = 0;
|
||||||
|
let retData: Parameters<ListenerType> | undefined = undefined;
|
||||||
|
let retEvent: any = {};
|
||||||
|
const databack = () => {
|
||||||
|
if (complete == 0) {
|
||||||
|
reject(
|
||||||
|
new Error(
|
||||||
|
'Timeout: NTEvent EventName:' +
|
||||||
|
EventName +
|
||||||
|
' ListenerName:' +
|
||||||
|
ListenerName +
|
||||||
|
' EventRet:\n' +
|
||||||
|
JSON.stringify(retEvent, null, 4) +
|
||||||
|
'\n',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
resolve([retEvent as Awaited<ReturnType<EventType>>, ...retData!]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ListenerNameList = ListenerName.split('/');
|
||||||
|
const ListenerMainName = ListenerNameList[0];
|
||||||
|
const ListenerSubName = ListenerNameList[1];
|
||||||
|
|
||||||
|
const Timeouter = setTimeout(databack, timeout);
|
||||||
|
|
||||||
|
const eventCallbak = {
|
||||||
|
timeout: timeout,
|
||||||
|
createtime: Date.now(),
|
||||||
|
checker: checkerListener,
|
||||||
|
func: (...args: any[]) => {
|
||||||
|
complete++;
|
||||||
|
retData = args as Parameters<ListenerType>;
|
||||||
|
if (complete >= waitTimes) {
|
||||||
|
clearTimeout(Timeouter);
|
||||||
|
databack();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (!this.EventTask.get(ListenerMainName)) {
|
||||||
|
this.EventTask.set(ListenerMainName, new Map());
|
||||||
|
}
|
||||||
|
if (!this.EventTask.get(ListenerMainName)?.get(ListenerSubName)) {
|
||||||
|
this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map());
|
||||||
|
}
|
||||||
|
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak);
|
||||||
|
this.createListenerFunction(ListenerMainName);
|
||||||
|
const EventFunc = this.createEventFunction<EventType>(EventName);
|
||||||
|
retEvent = await EventFunc!(...(args as any[]));
|
||||||
|
if (!checkerEvent(retEvent)) {
|
||||||
|
clearTimeout(Timeouter);
|
||||||
|
reject(
|
||||||
|
new Error(
|
||||||
|
'EventChecker Failed: NTEvent EventName:' +
|
||||||
|
EventName +
|
||||||
|
' ListenerName:' +
|
||||||
|
ListenerName +
|
||||||
|
' EventRet:\n' +
|
||||||
|
JSON.stringify(retEvent, null, 4) +
|
||||||
|
'\n',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
async CallNormalEvent<
|
async CallNormalEvent<
|
||||||
EventType extends (...args: any[]) => Promise<any>,
|
EventType extends (...args: any[]) => Promise<any>,
|
||||||
ListenerType extends (...args: any[]) => void
|
ListenerType extends (...args: any[]) => void
|
||||||
@@ -232,28 +307,3 @@ export class LegacyNTEventWrapper {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 示例代码 快速创建事件
|
|
||||||
// let NTEvent = new NTEventWrapper();
|
|
||||||
// let TestEvent = NTEvent.CreatEventFunction<(force: boolean) => Promise<Number>>('NodeIKernelProfileLikeService/GetTest');
|
|
||||||
// if (TestEvent) {
|
|
||||||
// TestEvent(true);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 示例代码 快速创建监听Listener类
|
|
||||||
// let NTEvent = new NTEventWrapper();
|
|
||||||
// NTEvent.CreatListenerFunction<NodeIKernelMsgListener>('NodeIKernelMsgListener', 'core')
|
|
||||||
|
|
||||||
// 调用接口
|
|
||||||
//let NTEvent = new NTEventWrapper();
|
|
||||||
//let ret = await NTEvent.CallNormalEvent<(force: boolean) => Promise<Number>, (data1: string, data2: number) => void>('NodeIKernelProfileLikeService/GetTest', 'NodeIKernelMsgListener/onAddSendMsg', 1, 3000, true);
|
|
||||||
|
|
||||||
// 注册监听 解除监听
|
|
||||||
// NTEventDispatch.RigisterListener('NodeIKernelMsgListener/onAddSendMsg','core',cb);
|
|
||||||
// NTEventDispatch.UnRigisterListener('NodeIKernelMsgListener/onAddSendMsg','core');
|
|
||||||
|
|
||||||
// let GetTest = NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode);
|
|
||||||
// GetTest('test');
|
|
||||||
|
|
||||||
// always模式
|
|
||||||
// NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode,(...args:any[])=>{ console.log(args) });
|
|
||||||
|
@@ -124,14 +124,7 @@ export class NTEventChannel extends EventEmitter {
|
|||||||
EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
|
EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
|
||||||
return new Promise<Awaited<ReturnType<EventType>>>(async (resolve, reject) => {
|
return new Promise<Awaited<ReturnType<EventType>>>(async (resolve, reject) => {
|
||||||
const EventFunc = this.createEventFunction<EventType>(EventName);
|
const EventFunc = this.createEventFunction<EventType>(EventName);
|
||||||
let complete = false;
|
|
||||||
const Timeouter = setTimeout(() => {
|
|
||||||
if (!complete) {
|
|
||||||
reject(new Error('NTEvent EventName:' + EventName + ' timeout'));
|
|
||||||
}
|
|
||||||
}, timeout);
|
|
||||||
const retData = await EventFunc!(...args);
|
const retData = await EventFunc!(...args);
|
||||||
complete = true;
|
|
||||||
resolve(retData);
|
resolve(retData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@ import path, { dirname } from 'path';
|
|||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
export const napcat_version = '2.2.4';
|
export const napcat_version = '2.2.8';
|
||||||
|
|
||||||
export class NapCatPathWrapper {
|
export class NapCatPathWrapper {
|
||||||
binaryPath: string;
|
binaryPath: string;
|
||||||
|
@@ -53,7 +53,7 @@ export abstract class ConfigBase<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
save(newConfigData: T = this.configData as T) {
|
save(newConfigData: T = this.configData) {
|
||||||
const logger = this.coreContext.context.logger;
|
const logger = this.coreContext.context.logger;
|
||||||
const selfInfo = this.coreContext.selfInfo;
|
const selfInfo = this.coreContext.selfInfo;
|
||||||
this.configData = newConfigData;
|
this.configData = newConfigData;
|
||||||
|
@@ -46,7 +46,7 @@ export class QQBasicInfoWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requireMinNTQQBuild(buildStr: string) {
|
requireMinNTQQBuild(buildStr: string) {
|
||||||
const currentBuild = parseInt(this.getQQBuildStr() || '0');
|
const currentBuild = +(this.getQQBuildStr() ?? '0');
|
||||||
if (currentBuild == 0) throw new Error('QQBuildStr获取失败');
|
if (currentBuild == 0) throw new Error('QQBuildStr获取失败');
|
||||||
return currentBuild >= parseInt(buildStr);
|
return currentBuild >= parseInt(buildStr);
|
||||||
}
|
}
|
||||||
@@ -77,5 +77,3 @@ export class QQBasicInfoWrapper {
|
|||||||
return { appid: systemPlatform === 'linux' ? '537240795' : '537240709', qua: this.getQUAInternal() };
|
return { appid: systemPlatform === 'linux' ? '537240795' : '537240709', qua: this.getQUAInternal() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export let QQBasicInfo: QQBasicInfoWrapper | undefined;
|
|
||||||
|
@@ -4,6 +4,7 @@ import crypto, { randomUUID } from 'crypto';
|
|||||||
import util from 'util';
|
import util from 'util';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import * as fileType from 'file-type';
|
import * as fileType from 'file-type';
|
||||||
|
import { solveAsyncProblem, solveProblem } from './helper';
|
||||||
|
|
||||||
export function isGIF(path: string) {
|
export function isGIF(path: string) {
|
||||||
const buffer = Buffer.alloc(4);
|
const buffer = Buffer.alloc(4);
|
||||||
@@ -185,25 +186,28 @@ export enum FileUriType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function checkUriType(Uri: string) {
|
export async function checkUriType(Uri: string) {
|
||||||
//先判断是否是本地文件
|
|
||||||
try {
|
const LocalFileRet = await solveProblem((uri: string) => {
|
||||||
if (fs.existsSync(Uri)) return { Uri: Uri, Type: FileUriType.Local };
|
if (fs.existsSync(uri)) {
|
||||||
} catch (error) {
|
return { Uri: uri, Type: FileUriType.Local };
|
||||||
}
|
}
|
||||||
try {
|
return undefined;
|
||||||
|
}, Uri);
|
||||||
|
if (LocalFileRet) return LocalFileRet;
|
||||||
|
|
||||||
|
const OtherFileRet = await solveProblem((uri: string) => {
|
||||||
//再判断是否是Http
|
//再判断是否是Http
|
||||||
if (Uri.startsWith('http://') || Uri.startsWith('https://')) {
|
if (uri.startsWith('http://') || uri.startsWith('https://')) {
|
||||||
return { Uri: Uri, Type: FileUriType.Remote };
|
return { Uri: uri, Type: FileUriType.Remote };
|
||||||
}
|
}
|
||||||
//再判断是否是Base64
|
//再判断是否是Base64
|
||||||
if (Uri.startsWith('base64://')) {
|
if (uri.startsWith('base64://')) {
|
||||||
return { Uri: Uri, Type: FileUriType.Base64 };
|
return { Uri: uri, Type: FileUriType.Base64 };
|
||||||
}
|
}
|
||||||
if (Uri.startsWith('file://')) {
|
if (uri.startsWith('file://')) {
|
||||||
let pathname: string;
|
|
||||||
let filePath: string;
|
let filePath: string;
|
||||||
// await fs.copyFile(url.pathname, filePath);
|
// await fs.copyFile(url.pathname, filePath);
|
||||||
pathname = decodeURIComponent(new URL(Uri).pathname);
|
const pathname = decodeURIComponent(new URL(uri).pathname);
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
filePath = pathname.slice(1);
|
filePath = pathname.slice(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -211,8 +215,9 @@ export async function checkUriType(Uri: string) {
|
|||||||
}
|
}
|
||||||
return { Uri: filePath, Type: FileUriType.Local };
|
return { Uri: filePath, Type: FileUriType.Local };
|
||||||
}
|
}
|
||||||
} catch (error) {
|
}, Uri);
|
||||||
}
|
if (OtherFileRet) return OtherFileRet;
|
||||||
|
|
||||||
return { Uri: Uri, Type: FileUriType.Unknown };
|
return { Uri: Uri, Type: FileUriType.Unknown };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +237,7 @@ export async function uri2local(dir: string, uri: string, filename: string | und
|
|||||||
//接下来都要有文件名
|
//接下来都要有文件名
|
||||||
if (!filename) filename = randomUUID();
|
if (!filename) filename = randomUUID();
|
||||||
//解析Http和Https协议
|
//解析Http和Https协议
|
||||||
|
|
||||||
if (UriType == FileUriType.Remote) {
|
if (UriType == FileUriType.Remote) {
|
||||||
const pathInfo = path.parse(decodeURIComponent(new URL(HandledUri).pathname));
|
const pathInfo = path.parse(decodeURIComponent(new URL(HandledUri).pathname));
|
||||||
if (pathInfo.name) {
|
if (pathInfo.name) {
|
||||||
|
@@ -3,8 +3,28 @@ import fs from 'fs';
|
|||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import { QQLevel } from '@/core';
|
import { QQLevel } from '@/core';
|
||||||
|
|
||||||
//下面这个类是用于将uid+msgid合并的类
|
export async function solveProblem<T extends (...arg: any[]) => any>(func: T, ...args: Parameters<T>): Promise<ReturnType<T> | undefined> {
|
||||||
|
return new Promise<ReturnType<T> | undefined>((resolve) => {
|
||||||
|
try {
|
||||||
|
const result = func(...args);
|
||||||
|
resolve(result);
|
||||||
|
} catch (e) {
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function solveAsyncProblem<T extends (...args: any[]) => Promise<any>>(func: T, ...args: Parameters<T>): Promise<Awaited<ReturnType<T>> | undefined> {
|
||||||
|
return new Promise<Awaited<ReturnType<T>> | undefined>(async (resolve) => {
|
||||||
|
try {
|
||||||
|
const result = await func(...args);
|
||||||
|
resolve(result);
|
||||||
|
} catch (e) {
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//下面这个类是用于将uid+msgid合并的类
|
||||||
export class UUIDConverter {
|
export class UUIDConverter {
|
||||||
static encode(highStr: string, lowStr: string): string {
|
static encode(highStr: string, lowStr: string): string {
|
||||||
const high = BigInt(highStr);
|
const high = BigInt(highStr);
|
||||||
|
@@ -3,7 +3,6 @@ import { LogWrapper } from './log';
|
|||||||
export function proxyHandlerOf(logger: LogWrapper) {
|
export function proxyHandlerOf(logger: LogWrapper) {
|
||||||
return {
|
return {
|
||||||
get(target: any, prop: any, receiver: any) {
|
get(target: any, prop: any, receiver: any) {
|
||||||
// console.log('get', prop, typeof target[prop]);
|
|
||||||
if (typeof target[prop] === 'undefined') {
|
if (typeof target[prop] === 'undefined') {
|
||||||
// 如果方法不存在,返回一个函数,这个函数调用existentMethod
|
// 如果方法不存在,返回一个函数,这个函数调用existentMethod
|
||||||
return (..._args: unknown[]) => {
|
return (..._args: unknown[]) => {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Friend, FriendV2, User } from '@/core/entities';
|
import { Friend, FriendV2, User } from '@/core/entities';
|
||||||
import { BuddyListReqType, InstanceContext, NapCatCore, NodeIKernelProfileService, OnBuddyChangeParams } from '@/core';
|
import { BuddyListReqType, InstanceContext, NapCatCore, NodeIKernelBuddyListener, NodeIKernelBuddyService, NodeIKernelProfileService, OnBuddyChangeParams } from '@/core';
|
||||||
import { LimitedHashTable } from '@/common/utils/MessageUnique';
|
import { LimitedHashTable } from '@/common/utils/MessageUnique';
|
||||||
|
|
||||||
export class NTQQFriendApi {
|
export class NTQQFriendApi {
|
||||||
@@ -70,29 +70,19 @@ export class NTQQFriendApi {
|
|||||||
async isBuddy(uid: string) {
|
async isBuddy(uid: string) {
|
||||||
return this.context.session.getBuddyService().isBuddy(uid);
|
return this.context.session.getBuddyService().isBuddy(uid);
|
||||||
}
|
}
|
||||||
|
async clearBuddyReqUnreadCnt() {
|
||||||
/**
|
return this.context.session.getBuddyService().clearBuddyReqUnreadCnt();
|
||||||
* @deprecated
|
}
|
||||||
* @param forced
|
async getBuddyReq() {
|
||||||
* @returns
|
const [, ret] = await this.core.eventWrapper.CallNormalEventV2<
|
||||||
*/
|
NodeIKernelBuddyService['getBuddyReq'],
|
||||||
async getFriends(forced = false): Promise<User[]> {
|
NodeIKernelBuddyListener['onBuddyReqChange']
|
||||||
const [_retData, _BuddyArg] = await this.core.eventWrapper.CallNormalEvent<(force: boolean) => Promise<any>, (arg: OnBuddyChangeParams) => void>
|
>(
|
||||||
(
|
'NodeIKernelBuddyService/getBuddyReq',
|
||||||
'NodeIKernelBuddyService/getBuddyList',
|
'NodeIKernelBuddyListener/onBuddyReqChange',
|
||||||
'NodeIKernelBuddyListener/onBuddyListChange',
|
|
||||||
1,
|
1,
|
||||||
5000,
|
5000);
|
||||||
() => true,
|
return ret;
|
||||||
forced,
|
|
||||||
);
|
|
||||||
const friends: User[] = [];
|
|
||||||
for (const categoryItem of _BuddyArg) {
|
|
||||||
for (const friend of categoryItem.buddyList) {
|
|
||||||
friends.push(friend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return friends;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleFriendRequest(flag: string, accept: boolean) {
|
async handleFriendRequest(flag: string, accept: boolean) {
|
||||||
|
@@ -7,12 +7,14 @@ import {
|
|||||||
GroupNotify,
|
GroupNotify,
|
||||||
GroupRequestOperateTypes,
|
GroupRequestOperateTypes,
|
||||||
InstanceContext,
|
InstanceContext,
|
||||||
|
KickMemberInfo,
|
||||||
|
kickMemberV2Req,
|
||||||
MemberExtSourceType,
|
MemberExtSourceType,
|
||||||
NapCatCore,
|
NapCatCore,
|
||||||
NodeIKernelGroupListener,
|
NodeIKernelGroupListener,
|
||||||
NodeIKernelGroupService,
|
NodeIKernelGroupService,
|
||||||
} from '@/core';
|
} from '@/core';
|
||||||
import { isNumeric, runAllWithTimeout } from '@/common/utils/helper';
|
import { isNumeric, runAllWithTimeout, sleep } from '@/common/utils/helper';
|
||||||
|
|
||||||
export class NTQQGroupApi {
|
export class NTQQGroupApi {
|
||||||
context: InstanceContext;
|
context: InstanceContext;
|
||||||
@@ -23,7 +25,9 @@ export class NTQQGroupApi {
|
|||||||
constructor(context: InstanceContext, core: NapCatCore) {
|
constructor(context: InstanceContext, core: NapCatCore) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.core = core;
|
this.core = core;
|
||||||
this.initCache().then().catch(context.logger.logError);
|
sleep(1000).then(() => {
|
||||||
|
this.initCache().then().catch(context.logger.logError);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
async initCache() {
|
async initCache() {
|
||||||
this.groups = await this.getGroups();
|
this.groups = await this.getGroups();
|
||||||
@@ -219,7 +223,21 @@ export class NTQQGroupApi {
|
|||||||
// GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
|
// GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
|
||||||
return this.context.session.getGroupService().addGroupEssence(param);
|
return this.context.session.getGroupService().addGroupEssence(param);
|
||||||
}
|
}
|
||||||
|
async kickMemberV2Inner(param: kickMemberV2Req) {
|
||||||
|
return this.context.session.getGroupService().kickMemberV2(param);
|
||||||
|
}
|
||||||
|
async deleteGroupBulletin(GroupCode: string, feedId: 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, feedId);
|
||||||
|
}
|
||||||
|
async quitGroupV2(GroupCode: string, needDeleteLocalMsg: boolean) {
|
||||||
|
const param = {
|
||||||
|
groupCode: GroupCode,
|
||||||
|
needDeleteLocalMsg: needDeleteLocalMsg
|
||||||
|
};
|
||||||
|
//应该是直接返回不需要Listener的 未经测试 需测试再发布
|
||||||
|
return this.context.session.getGroupService().quitGroupV2(param);
|
||||||
|
}
|
||||||
async removeGroupEssence(GroupCode: string, msgId: string) {
|
async removeGroupEssence(GroupCode: string, msgId: string) {
|
||||||
// 代码没测过
|
// 代码没测过
|
||||||
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
|
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
|
||||||
@@ -253,10 +271,7 @@ export class NTQQGroupApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getGroupMemberV2(GroupCode: string, uid: string, forced = false) {
|
async getGroupMemberV2(GroupCode: string, uid: string, forced = false) {
|
||||||
//type ListenerType = NodeIKernelGroupListener['onMemberInfoChange'];
|
|
||||||
type EventType = NodeIKernelGroupService['getMemberInfo'];
|
type EventType = NodeIKernelGroupService['getMemberInfo'];
|
||||||
// NTEventDispatch.CreatListenerFunction('NodeIKernelGroupListener/onGroupMemberInfoUpdate',
|
|
||||||
//return napCatCore.session.getGroupService().getMemberInfo(GroupCode, [uid], forced);
|
|
||||||
const Listener = this.core.eventWrapper.RegisterListen<(params: any) => void>
|
const Listener = this.core.eventWrapper.RegisterListen<(params: any) => void>
|
||||||
(
|
(
|
||||||
'NodeIKernelGroupListener/onMemberInfoChange',
|
'NodeIKernelGroupListener/onMemberInfoChange',
|
||||||
@@ -278,20 +293,6 @@ export class NTQQGroupApi {
|
|||||||
member = members.get(uid);
|
member = members.get(uid);
|
||||||
}
|
}
|
||||||
return member;
|
return member;
|
||||||
|
|
||||||
// 原本的方法: (no_cache 下效率很高, cache 下效率一致)
|
|
||||||
// const [, , , _members] = await this.core.eventWrapper.CallNormalEvent<EventType, ListenerType>
|
|
||||||
// (
|
|
||||||
// 'NodeIKernelGroupService/getMemberInfo',
|
|
||||||
// 'NodeIKernelGroupListener/onMemberInfoChange',
|
|
||||||
// 1,
|
|
||||||
// 5000,
|
|
||||||
// (groupCode: string, changeType: number, members: Map<string, GroupMember>) => {
|
|
||||||
// return groupCode == GroupCode && members.has(uid);
|
|
||||||
// },
|
|
||||||
// GroupCode, [uid], forced,
|
|
||||||
// );
|
|
||||||
// return _members.get(uid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGroupMembers(groupQQ: string, num = 3000): Promise<Map<string, GroupMember>> {
|
async getGroupMembers(groupQQ: string, num = 3000): Promise<Map<string, GroupMember>> {
|
||||||
@@ -299,10 +300,10 @@ export class NTQQGroupApi {
|
|||||||
const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow');
|
const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow');
|
||||||
const result = await groupService.getNextMemberList(sceneId!, undefined, num);
|
const result = await groupService.getNextMemberList(sceneId!, undefined, num);
|
||||||
if (result.errCode !== 0) {
|
if (result.errCode !== 0) {
|
||||||
throw ('获取群成员列表出错,' + result.errMsg);
|
throw new Error('获取群成员列表出错,' + result.errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
//logDebug(`获取群(${groupQQ})成员列表结果:`, `finish: ${result.result.finish}`); //, Array.from(result.result.infos.values()));
|
this.context.logger.logDebug(`获取群(${groupQQ})成员列表结果:`, `members: ${result.result.infos.size}`); //, Array.from(result.result.infos.values()));
|
||||||
return result.result.infos;
|
return result.result.infos;
|
||||||
/*
|
/*
|
||||||
console.log(sceneId);
|
console.log(sceneId);
|
||||||
|
@@ -3,6 +3,7 @@ import { NodeIKernelProfileListener } from '@/core/listeners';
|
|||||||
import { RequestUtil } from '@/common/utils/request';
|
import { RequestUtil } from '@/common/utils/request';
|
||||||
import { NodeIKernelProfileService, ProfileBizType, UserDetailSource } from '@/core/services';
|
import { NodeIKernelProfileService, ProfileBizType, UserDetailSource } from '@/core/services';
|
||||||
import { InstanceContext, NapCatCore } from '..';
|
import { InstanceContext, NapCatCore } from '..';
|
||||||
|
import { solveAsyncProblem } from '@/common/utils/helper';
|
||||||
|
|
||||||
export class NTQQUserApi {
|
export class NTQQUserApi {
|
||||||
context: InstanceContext;
|
context: InstanceContext;
|
||||||
@@ -128,12 +129,9 @@ export class NTQQUserApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getUserDetailInfo(uid: string): Promise<User> {
|
async getUserDetailInfo(uid: string): Promise<User> {
|
||||||
try {
|
const retUser = await solveAsyncProblem(async (uid) => this.fetchUserDetailInfo(uid, UserDetailSource.KDB));
|
||||||
const retUser = await this.fetchUserDetailInfo(uid, UserDetailSource.KDB);
|
if (retUser && retUser.uin !== '0') {
|
||||||
if (retUser.uin !== '0') {
|
return retUser;
|
||||||
return retUser;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
}
|
}
|
||||||
this.context.logger.logDebug('[NapCat] [Mark] getUserDetailInfo Mode1 Failed.');
|
this.context.logger.logDebug('[NapCat] [Mark] getUserDetailInfo Mode1 Failed.');
|
||||||
return this.fetchUserDetailInfo(uid, UserDetailSource.KSERVER);
|
return this.fetchUserDetailInfo(uid, UserDetailSource.KSERVER);
|
||||||
|
@@ -20,14 +20,13 @@ export class NTQQWebApi {
|
|||||||
|
|
||||||
async shareDigest(groupCode: string, msgSeq: string, msgRandom: string, targetGroupCode: string) {
|
async shareDigest(groupCode: string, msgSeq: string, msgRandom: string, targetGroupCode: string) {
|
||||||
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
||||||
const url = `https://qun.qq.com/cgi-bin/group_digest/share_digest?${
|
const url = `https://qun.qq.com/cgi-bin/group_digest/share_digest?${new URLSearchParams({
|
||||||
new URLSearchParams({
|
bkn: this.getBknFromCookie(cookieObject),
|
||||||
bkn: this.getBknFromCookie(cookieObject),
|
group_code: groupCode,
|
||||||
group_code: groupCode,
|
msg_seq: msgSeq,
|
||||||
msg_seq: msgSeq,
|
msg_random: msgRandom,
|
||||||
msg_random: msgRandom,
|
target_group_code: targetGroupCode,
|
||||||
target_group_code: targetGroupCode,
|
}).toString()
|
||||||
}).toString()
|
|
||||||
}`;
|
}`;
|
||||||
try {
|
try {
|
||||||
return RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
|
return RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
|
||||||
@@ -38,13 +37,12 @@ export class NTQQWebApi {
|
|||||||
|
|
||||||
async getGroupEssenceMsg(GroupCode: string, page_start: string) {
|
async getGroupEssenceMsg(GroupCode: string, page_start: string) {
|
||||||
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
||||||
const url = `https://qun.qq.com/cgi-bin/group_digest/digest_list?${
|
const url = `https://qun.qq.com/cgi-bin/group_digest/digest_list?${new URLSearchParams({
|
||||||
new URLSearchParams({
|
bkn: this.getBknFromCookie(cookieObject),
|
||||||
bkn: this.getBknFromCookie(cookieObject),
|
group_code: GroupCode,
|
||||||
group_code: GroupCode,
|
page_start,
|
||||||
page_start,
|
page_limit: '20',
|
||||||
page_limit: '20',
|
}).toString()
|
||||||
}).toString()
|
|
||||||
}`;
|
}`;
|
||||||
let ret;
|
let ret;
|
||||||
try {
|
try {
|
||||||
@@ -65,14 +63,13 @@ export class NTQQWebApi {
|
|||||||
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
||||||
const retList: Promise<WebApiGroupMemberRet>[] = [];
|
const retList: Promise<WebApiGroupMemberRet>[] = [];
|
||||||
const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>
|
const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>
|
||||||
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${
|
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({
|
||||||
new URLSearchParams({
|
st: '0',
|
||||||
st: '0',
|
end: '40',
|
||||||
end: '40',
|
sort: '1',
|
||||||
sort: '1',
|
gc: GroupCode,
|
||||||
gc: GroupCode,
|
bkn: this.getBknFromCookie(cookieObject),
|
||||||
bkn: this.getBknFromCookie(cookieObject),
|
}).toString()
|
||||||
}).toString()
|
|
||||||
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
|
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
|
||||||
if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) {
|
if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) {
|
||||||
return [];
|
return [];
|
||||||
@@ -86,14 +83,13 @@ export class NTQQWebApi {
|
|||||||
//遍历批量请求
|
//遍历批量请求
|
||||||
for (let i = 2; i <= PageNum; i++) {
|
for (let i = 2; i <= PageNum; i++) {
|
||||||
const ret = RequestUtil.HttpGetJson<WebApiGroupMemberRet>
|
const ret = RequestUtil.HttpGetJson<WebApiGroupMemberRet>
|
||||||
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${
|
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({
|
||||||
new URLSearchParams({
|
st: ((i - 1) * 40).toString(),
|
||||||
st: ((i - 1) * 40).toString(),
|
end: (i * 40).toString(),
|
||||||
end: (i * 40).toString(),
|
sort: '1',
|
||||||
sort: '1',
|
gc: GroupCode,
|
||||||
gc: GroupCode,
|
bkn: this.getBknFromCookie(cookieObject),
|
||||||
bkn: this.getBknFromCookie(cookieObject),
|
}).toString()
|
||||||
}).toString()
|
|
||||||
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
|
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
|
||||||
retList.push(ret);
|
retList.push(ret);
|
||||||
}
|
}
|
||||||
@@ -127,15 +123,14 @@ export class NTQQWebApi {
|
|||||||
let ret: any = undefined;
|
let ret: any = undefined;
|
||||||
try {
|
try {
|
||||||
ret = await RequestUtil.HttpGetJson<any>
|
ret = await RequestUtil.HttpGetJson<any>
|
||||||
(`https://web.qun.qq.com/cgi-bin/announce/add_qun_notice${
|
(`https://web.qun.qq.com/cgi-bin/announce/add_qun_notice${new URLSearchParams({
|
||||||
new URLSearchParams({
|
bkn: this.getBknFromCookie(cookieObject),
|
||||||
bkn: this.getBknFromCookie(cookieObject),
|
qid: GroupCode,
|
||||||
qid: GroupCode,
|
text: Content,
|
||||||
text: Content,
|
pinned: '0',
|
||||||
pinned: '0',
|
type: '1',
|
||||||
type: '1',
|
settings: '{"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}',
|
||||||
settings: '{"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}',
|
}).toString()
|
||||||
}).toString()
|
|
||||||
}`, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
|
}`, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
|
||||||
return ret;
|
return ret;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -147,15 +142,10 @@ export class NTQQWebApi {
|
|||||||
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
||||||
let ret: WebApiGroupNoticeRet | undefined = undefined;
|
let ret: WebApiGroupNoticeRet | undefined = undefined;
|
||||||
try {
|
try {
|
||||||
ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(`https://web.qun.qq.com/cgi-bin/announce/get_t_list?${
|
const url = 'https://web.qun.qq.com/cgi-bin/announce/get_t_list?bkn=' +
|
||||||
new URLSearchParams({
|
this.getBknFromCookie(cookieObject) + '&qid=' + GroupCode + '&ft=23&ni=1&n=1&i=1&log_read=1&platform=1&s=-1&n=20';
|
||||||
bkn: this.getBknFromCookie(cookieObject),
|
|
||||||
qid: GroupCode,
|
ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
|
||||||
type: '1',
|
|
||||||
start: '0',
|
|
||||||
num: '1',
|
|
||||||
}).toString()
|
|
||||||
}`, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
|
|
||||||
if (ret?.ec !== 0) {
|
if (ret?.ec !== 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -168,11 +158,10 @@ export class NTQQWebApi {
|
|||||||
async getGroupHonorInfo(groupCode: string, getType: WebHonorType) {
|
async getGroupHonorInfo(groupCode: string, getType: WebHonorType) {
|
||||||
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
|
||||||
const getDataInternal = async (Internal_groupCode: string, Internal_type: number) => {
|
const getDataInternal = async (Internal_groupCode: string, Internal_type: number) => {
|
||||||
const url = `https://qun.qq.com/interactive/honorlist?${
|
const url = `https://qun.qq.com/interactive/honorlist?${new URLSearchParams({
|
||||||
new URLSearchParams({
|
gc: Internal_groupCode,
|
||||||
gc: Internal_groupCode,
|
type: Internal_type.toString(),
|
||||||
type: Internal_type.toString(),
|
}).toString()
|
||||||
}).toString()
|
|
||||||
}`;
|
}`;
|
||||||
let resJson;
|
let resJson;
|
||||||
try {
|
try {
|
||||||
|
@@ -197,12 +197,12 @@ export class NapCatCore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.context.session.getGroupService().addKernelGroupListener(
|
this.context.session.getGroupService().addKernelGroupListener(
|
||||||
proxiedListenerOf(profileListener, this.context.logger) as any
|
proxiedListenerOf(groupListener, this.context.logger) as any
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
checkAdminEvent(groupCode: string, memberNew: GroupMember, memberOld: GroupMember | undefined): boolean {
|
checkAdminEvent(groupCode: string, memberNew: GroupMember, memberOld: GroupMember | undefined): boolean {
|
||||||
if (memberNew.role !== memberOld?.role) {
|
if (memberNew.role !== memberOld?.role) {
|
||||||
this.context.logger.log(`群 ${groupCode} ${memberNew.nick} 角色变更为 ${memberNew.role === 3 ? '管理员' : '群员'}`);
|
this.context.logger.logDebug(`群 ${groupCode} ${memberNew.nick} 角色变更为 ${memberNew.role === 3 ? '管理员' : '群员'}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,5 +1,17 @@
|
|||||||
import { QQLevel, Sex, User } from './user';
|
import { QQLevel, Sex, User } from './user';
|
||||||
|
export interface KickMemberInfo {
|
||||||
|
optFlag: number,
|
||||||
|
optOperate: number,
|
||||||
|
optMemberUid: string,
|
||||||
|
optBytesMsg: string,
|
||||||
|
}
|
||||||
|
export interface kickMemberV2Req{
|
||||||
|
groupCode: string,
|
||||||
|
kickFlag: number,
|
||||||
|
kickList: Array<KickMemberInfo>,
|
||||||
|
kickListUids: Array<string>,
|
||||||
|
kickMsg: string
|
||||||
|
}
|
||||||
export enum GroupListUpdateType {
|
export enum GroupListUpdateType {
|
||||||
REFRESHALL,
|
REFRESHALL,
|
||||||
GETALL,
|
GETALL,
|
||||||
|
@@ -848,41 +848,6 @@ export interface MultiForwardMsgElement {
|
|||||||
resId: string;
|
resId: string;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
}
|
}
|
||||||
export enum NTSubMsgType {
|
|
||||||
KMSGSUBTYPEARKGROUPANNOUNCE = 3,
|
|
||||||
KMSGSUBTYPEARKGROUPANNOUNCECONFIRMREQUIRED = 4,
|
|
||||||
KMSGSUBTYPEARKGROUPGIFTATME = 5,
|
|
||||||
KMSGSUBTYPEARKGROUPTASKATALL = 6,
|
|
||||||
KMSGSUBTYPEARKMULTIMSG = 7,
|
|
||||||
KMSGSUBTYPEARKNORMAL = 0,
|
|
||||||
KMSGSUBTYPEARKTENCENTDOCFROMMINIAPP = 1,
|
|
||||||
KMSGSUBTYPEARKTENCENTDOCFROMPLUSPANEL = 2,
|
|
||||||
KMSGSUBTYPEEMOTICON = 15,
|
|
||||||
KMSGSUBTYPEFILEAPP = 11,
|
|
||||||
KMSGSUBTYPEFILEAUDIO = 3,
|
|
||||||
KMSGSUBTYPEFILEDOC = 4,
|
|
||||||
KMSGSUBTYPEFILEEXCEL = 6,
|
|
||||||
KMSGSUBTYPEFILEFOLDER = 13,
|
|
||||||
KMSGSUBTYPEFILEHTML = 10,
|
|
||||||
KMSGSUBTYPEFILEIPA = 14,
|
|
||||||
KMSGSUBTYPEFILENORMAL = 0,
|
|
||||||
KMSGSUBTYPEFILEPDF = 7,
|
|
||||||
KMSGSUBTYPEFILEPIC = 1,
|
|
||||||
KMSGSUBTYPEFILEPPT = 5,
|
|
||||||
KMSGSUBTYPEFILEPSD = 12,
|
|
||||||
KMSGSUBTYPEFILETXT = 8,
|
|
||||||
KMSGSUBTYPEFILEVIDEO = 2,
|
|
||||||
KMSGSUBTYPEFILEZIP = 9,
|
|
||||||
KMSGSUBTYPELINK = 5,
|
|
||||||
KMSGSUBTYPEMARKETFACE = 1,
|
|
||||||
KMSGSUBTYPEMIXEMOTICON = 7,
|
|
||||||
KMSGSUBTYPEMIXFACE = 3,
|
|
||||||
KMSGSUBTYPEMIXMARKETFACE = 2,
|
|
||||||
KMSGSUBTYPEMIXPIC = 1,
|
|
||||||
KMSGSUBTYPEMIXREPLY = 4,
|
|
||||||
KMSGSUBTYPEMIXTEXT = 0,
|
|
||||||
KMSGSUBTYPETENCENTDOC = 6
|
|
||||||
}
|
|
||||||
export enum SendStatusType {
|
export enum SendStatusType {
|
||||||
KSEND_STATUS_FAILED = 0,
|
KSEND_STATUS_FAILED = 0,
|
||||||
KSEND_STATUS_SENDING = 1,
|
KSEND_STATUS_SENDING = 1,
|
||||||
@@ -914,7 +879,7 @@ export interface RawMessage {
|
|||||||
|
|
||||||
msgType: NTMsgType;
|
msgType: NTMsgType;
|
||||||
|
|
||||||
subMsgType: NTSubMsgType;
|
subMsgType: number;
|
||||||
|
|
||||||
senderUid: string;
|
senderUid: string;
|
||||||
|
|
||||||
|
@@ -1,40 +1,58 @@
|
|||||||
export enum GroupNotifyTypes {
|
export enum GroupNotifyMsgType {
|
||||||
INVITE_ME = 1,
|
UN_SPECIFIED,
|
||||||
INVITED_JOIN = 4, // 有人接受了邀请入群
|
INVITED_BY_MEMBER,
|
||||||
JOIN_REQUEST = 7,
|
REFUSE_INVITED,
|
||||||
ADMIN_SET = 8,
|
REFUSED_BY_ADMINI_STRATOR,
|
||||||
KICK_MEMBER = 9,
|
AGREED_TOJOIN_DIRECT,// 有人接受了邀请入群
|
||||||
MEMBER_EXIT = 11, // 主动退出
|
INVITED_NEED_ADMINI_STRATOR_PASS,
|
||||||
ADMIN_UNSET = 12,
|
AGREED_TO_JOIN_BY_ADMINI_STRATOR,
|
||||||
ADMIN_UNSET_OTHER = 13, // 其他人取消管理员
|
REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS,
|
||||||
|
SET_ADMIN,
|
||||||
|
KICK_MEMBER_NOTIFY_ADMIN,
|
||||||
|
KICK_MEMBER_NOTIFY_KICKED,
|
||||||
|
MEMBER_LEAVE_NOTIFY_ADMIN,// 主动退出
|
||||||
|
CANCEL_ADMIN_NOTIFY_CANCELED,
|
||||||
|
CANCEL_ADMIN_NOTIFY_ADMIN,// 其他人取消管理员
|
||||||
|
TRANSFER_GROUP_NOTIFY_OLDOWNER,
|
||||||
|
TRANSFER_GROUP_NOTIFY_ADMIN
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GroupNotifies {
|
export interface GroupNotifies {
|
||||||
doubt: boolean;
|
doubt: boolean;
|
||||||
nextStartSeq: string;
|
nextStartSeq: string;
|
||||||
notifies: GroupNotify[];
|
notifies: GroupNotify[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum GroupNotifyStatus {
|
export enum GroupNotifyMsgStatus {
|
||||||
IGNORE = 0,
|
KINIT,//初始化
|
||||||
WAIT_HANDLE = 1,
|
KUNHANDLE,//未处理
|
||||||
APPROVE = 2,
|
KAGREED,//同意
|
||||||
REJECT = 3
|
KREFUSED,//拒绝
|
||||||
|
KIGNORED//忽略
|
||||||
|
}
|
||||||
|
export enum GroupInviteStatus {
|
||||||
|
INIT,
|
||||||
|
WAIT_TO_APPROVE,
|
||||||
|
JOINED,
|
||||||
|
REFUSED_BY_ADMINI_STRATOR
|
||||||
|
}
|
||||||
|
export enum GroupInviteType {
|
||||||
|
BYBUDDY,
|
||||||
|
BYGROUPMEMBER,
|
||||||
|
BYDISCUSSMEMBER
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GroupNotify {
|
export interface GroupNotify {
|
||||||
time: number; // 自己添加的字段,时间戳,毫秒, 用于判断收到短时间内收到重复的notify
|
seq: string; // 通知序列号
|
||||||
seq: string; // 唯一标识符,转成数字再除以1000应该就是时间戳?
|
type: GroupNotifyMsgType;
|
||||||
type: GroupNotifyTypes;
|
status: GroupNotifyMsgStatus;
|
||||||
status: GroupNotifyStatus; // 0是已忽略?,1是未处理,2是已同意
|
|
||||||
group: { groupCode: string; groupName: string };
|
group: { groupCode: string; groupName: string };
|
||||||
user1: { uid: string; nickName: string }; // 被设置管理员的人
|
user1: { uid: string; nickName: string }; // 被设置管理员的人
|
||||||
user2: { uid: string; nickName: string }; // 操作者
|
user2: { uid: string; nickName: string }; // 操作者
|
||||||
actionUser: { uid: string; nickName: string }; //未知
|
actionUser: { uid: string; nickName: string }; //未知
|
||||||
actionTime: string;
|
actionTime: string;
|
||||||
invitationExt: {
|
invitationExt: {
|
||||||
srcType: number; // 0?未知
|
srcType: GroupInviteType; // 邀请来源
|
||||||
groupCode: string; waitStatus: number
|
groupCode: string;
|
||||||
|
waitStatus: GroupInviteStatus
|
||||||
};
|
};
|
||||||
postscript: string; // 加群用户填写的验证信息
|
postscript: string; // 加群用户填写的验证信息
|
||||||
repeatSeqs: [];
|
repeatSeqs: [];
|
||||||
@@ -64,6 +82,7 @@ export enum BuddyReqType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FriendRequest {
|
export interface FriendRequest {
|
||||||
|
isBuddy?: boolean;
|
||||||
isInitiator?: boolean;
|
isInitiator?: boolean;
|
||||||
isDecide: boolean;
|
isDecide: boolean;
|
||||||
friendUid: string;
|
friendUid: string;
|
||||||
|
@@ -43,4 +43,48 @@ export class ProfileListener implements IProfileListener {
|
|||||||
onStrangerRemarkChanged(...args: unknown[]) {
|
onStrangerRemarkChanged(...args: unknown[]) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMemberListChange(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onMemberInfoChange(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupListUpdate(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupAllInfoChange(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupDetailInfoChange(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupConfMemberChange(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupExtListUpdate(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupNotifiesUpdated(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupNotifiesUnreadCountUpdated(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupMemberLevelInfoChange(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onGroupBulletinChange(...args: unknown[]){
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -61,11 +61,11 @@ export interface NodeIKernelBuddyService {
|
|||||||
|
|
||||||
getBuddyReqUnreadCnt(): number;
|
getBuddyReqUnreadCnt(): number;
|
||||||
|
|
||||||
getBuddyReq(): unknown;
|
getBuddyReq(): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
delBuddyReq(uid: number): void;
|
delBuddyReq(uid: number): void;
|
||||||
|
|
||||||
clearBuddyReqUnreadCnt(): void;
|
clearBuddyReqUnreadCnt(): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
reqToAddFriends(uid: number, msg: string): void;
|
reqToAddFriends(uid: number, msg: string): void;
|
||||||
|
|
||||||
|
@@ -3,14 +3,18 @@ import {
|
|||||||
GroupExtParam,
|
GroupExtParam,
|
||||||
GroupMember,
|
GroupMember,
|
||||||
GroupMemberRole,
|
GroupMemberRole,
|
||||||
GroupNotifyTypes,
|
GroupNotifyMsgType,
|
||||||
GroupRequestOperateTypes,
|
GroupRequestOperateTypes,
|
||||||
|
kickMemberV2Req,
|
||||||
} from '@/core/entities';
|
} from '@/core/entities';
|
||||||
import { GeneralCallResult } from '@/core/services/common';
|
import { GeneralCallResult } from '@/core/services/common';
|
||||||
|
|
||||||
//高版本的接口不应该随意使用 使用应该严格进行pr审核 同时部分ipc中未出现的接口不要过于依赖 应该做好数据兜底
|
//高版本的接口不应该随意使用 使用应该严格进行pr审核 同时部分ipc中未出现的接口不要过于依赖 应该做好数据兜底
|
||||||
|
|
||||||
export interface NodeIKernelGroupService {
|
export interface NodeIKernelGroupService {
|
||||||
|
kickMemberV2(param: kickMemberV2Req): Promise<GeneralCallResult>;
|
||||||
|
quitGroupV2(param: { groupCode: string; needDeleteLocalMsg: boolean; }): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
getMemberCommonInfo(Req: {
|
getMemberCommonInfo(Req: {
|
||||||
groupCode: string,
|
groupCode: string,
|
||||||
startUin: string,
|
startUin: string,
|
||||||
@@ -96,7 +100,7 @@ export interface NodeIKernelGroupService {
|
|||||||
uid: string,
|
uid: string,
|
||||||
index: number//0
|
index: number//0
|
||||||
}>,
|
}>,
|
||||||
infos: {},
|
infos: unknown,
|
||||||
finish: true,
|
finish: true,
|
||||||
hasRobot: false
|
hasRobot: false
|
||||||
}
|
}
|
||||||
@@ -195,7 +199,7 @@ export interface NodeIKernelGroupService {
|
|||||||
operateType: GroupRequestOperateTypes, // 2 拒绝
|
operateType: GroupRequestOperateTypes, // 2 拒绝
|
||||||
targetMsg: {
|
targetMsg: {
|
||||||
seq: string, // 通知序列号
|
seq: string, // 通知序列号
|
||||||
type: GroupNotifyTypes,
|
type: GroupNotifyMsgType,
|
||||||
groupCode: string,
|
groupCode: string,
|
||||||
postscript: string
|
postscript: string
|
||||||
}
|
}
|
||||||
@@ -205,7 +209,7 @@ export interface NodeIKernelGroupService {
|
|||||||
|
|
||||||
getGroupBulletin(groupCode: string): unknown;
|
getGroupBulletin(groupCode: string): unknown;
|
||||||
|
|
||||||
deleteGroupBulletin(groupCode: string, seq: string): void;
|
deleteGroupBulletin(groupCode: string, seq: string, feedId: string): void;
|
||||||
|
|
||||||
publishGroupBulletin(groupCode: string, pskey: string, data: any): Promise<GeneralCallResult>;
|
publishGroupBulletin(groupCode: string, pskey: string, data: any): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
|
@@ -37,7 +37,7 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
recallMsg(peer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
|
recallMsg(peer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
addKernelMsgImportToolListener(arg: Object): unknown;
|
addKernelMsgImportToolListener(arg: unknown): unknown;
|
||||||
|
|
||||||
removeKernelMsgListener(args: unknown): unknown;
|
removeKernelMsgListener(args: unknown): unknown;
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
getOnLineDev(): void;
|
getOnLineDev(): void;
|
||||||
|
|
||||||
kickOffLine(DevInfo: Object): unknown;
|
kickOffLine(DevInfo: unknown): unknown;
|
||||||
|
|
||||||
setStatus(args: { status: number, extStatus: number, batteryStatus: number }): Promise<GeneralCallResult>;
|
setStatus(args: { status: number, extStatus: number, batteryStatus: number }): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
@@ -80,11 +80,11 @@ export interface NodeIKernelMsgService {
|
|||||||
// this.voipToken = bArr2;
|
// this.voipToken = bArr2;
|
||||||
// this.profileId = str;
|
// this.profileId = str;
|
||||||
|
|
||||||
setToken(arg: Object): unknown;
|
setToken(arg: unknown): unknown;
|
||||||
|
|
||||||
switchForeGround(): unknown;
|
switchForeGround(): unknown;
|
||||||
|
|
||||||
switchBackGround(arg: Object): unknown;
|
switchBackGround(arg: unknown): unknown;
|
||||||
|
|
||||||
//hex
|
//hex
|
||||||
setTokenForMqq(token: string): unknown;
|
setTokenForMqq(token: string): unknown;
|
||||||
@@ -384,7 +384,7 @@ export interface NodeIKernelMsgService {
|
|||||||
getFileThumbSavePath(...args: unknown[]): unknown;
|
getFileThumbSavePath(...args: unknown[]): unknown;
|
||||||
|
|
||||||
//猜测居多
|
//猜测居多
|
||||||
translatePtt2Text(MsgId: string, Peer: {}, MsgElement: {}): unknown;
|
translatePtt2Text(MsgId: string, Peer: Peer, MsgElement: unknown): unknown;
|
||||||
|
|
||||||
setPttPlayedState(...args: unknown[]): unknown;
|
setPttPlayedState(...args: unknown[]): unknown;
|
||||||
|
|
||||||
@@ -668,7 +668,7 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
recordEmoji(...args: unknown[]): unknown;
|
recordEmoji(...args: unknown[]): unknown;
|
||||||
|
|
||||||
fetchGetHitEmotionsByWord(args: Object): Promise<unknown>;//表情推荐?
|
fetchGetHitEmotionsByWord(args: unknown): Promise<unknown>;//表情推荐?
|
||||||
|
|
||||||
deleteAllRoamMsgs(...args: unknown[]): unknown;//漫游消息?
|
deleteAllRoamMsgs(...args: unknown[]): unknown;//漫游消息?
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { forceFetchClientKeyRetType } from './common';
|
import { ForceFetchClientKeyRetType } from './common';
|
||||||
|
|
||||||
export interface NodeIKernelTicketService {
|
export interface NodeIKernelTicketService {
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ export interface NodeIKernelTicketService {
|
|||||||
|
|
||||||
removeKernelTicketListener(listenerId: unknown): void;
|
removeKernelTicketListener(listenerId: unknown): void;
|
||||||
|
|
||||||
forceFetchClientKey(arg: string): Promise<forceFetchClientKeyRetType>;
|
forceFetchClientKey(arg: string): Promise<ForceFetchClientKeyRetType>;
|
||||||
|
|
||||||
isNull(): boolean;
|
isNull(): boolean;
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ export interface GeneralCallResult {
|
|||||||
errMsg: string
|
errMsg: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface forceFetchClientKeyRetType extends GeneralCallResult {
|
export interface ForceFetchClientKeyRetType extends GeneralCallResult {
|
||||||
url: string;
|
url: string;
|
||||||
keyIndex: string;
|
keyIndex: string;
|
||||||
clientKey: string;
|
clientKey: string;
|
||||||
|
@@ -69,9 +69,9 @@ export interface NodeQQNTWrapperUtil {
|
|||||||
|
|
||||||
genFileShaAndMd5Hex(path: string, unknown: number): unknown; //可能是错的
|
genFileShaAndMd5Hex(path: string, unknown: number): unknown; //可能是错的
|
||||||
|
|
||||||
setTraceInfo(unknown: Object): unknown;
|
setTraceInfo(unknown: unknown): unknown;
|
||||||
|
|
||||||
encodeOffLine(unknown: Object): unknown;
|
encodeOffLine(unknown: unknown): unknown;
|
||||||
|
|
||||||
decodeOffLine(arg: string): unknown; //可能是错的 传递hex
|
decodeOffLine(arg: string): unknown; //可能是错的 传递hex
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ export interface NodeQQNTWrapperUtil {
|
|||||||
|
|
||||||
runProcessArgs(arg0: string, arg1: { [key: string]: string }, arg2: boolean): unknown;
|
runProcessArgs(arg0: string, arg1: { [key: string]: string }, arg2: boolean): unknown;
|
||||||
|
|
||||||
calcThumbSize(arg0: number, arg1: number, arg2: Object): unknown;
|
calcThumbSize(arg0: number, arg1: number, arg2: unknown): unknown;
|
||||||
|
|
||||||
fullWordToHalfWord(arg0: string): unknown;
|
fullWordToHalfWord(arg0: string): unknown;
|
||||||
|
|
||||||
|
@@ -90,7 +90,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
this.CoreContext.context.logger.logDebug('GetFileBase Mode - 1 Error');
|
||||||
}
|
}
|
||||||
|
|
||||||
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import { OB11ForwardMessage, OB11Message, OB11MessageData } from '../../types';
|
import { OB11ForwardMessage, OB11Message, OB11MessageData } from '@/onebot';
|
||||||
import { OB11Constructor } from '@/onebot/helper/converter';
|
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||||
import { RawNTMsg2Onebot } from '@/onebot/helper';
|
|
||||||
|
|
||||||
const SchemaData = {
|
const SchemaData = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@@ -41,7 +39,8 @@ export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> {
|
|||||||
}
|
}
|
||||||
const msgList = data.msgList;
|
const msgList = data.msgList;
|
||||||
const messages = (await Promise.all(msgList.map(async msg => {
|
const messages = (await Promise.all(msgList.map(async msg => {
|
||||||
const resMsg = await RawNTMsg2Onebot(this.CoreContext, this.OneBotContext, msg);
|
const resMsg = await this.OneBotContext.apiContext.MsgApi
|
||||||
|
.parseMessage(msg);
|
||||||
if (!resMsg) return;
|
if (!resMsg) return;
|
||||||
resMsg.message_id = MessageUnique.createMsg({
|
resMsg.message_id = MessageUnique.createMsg({
|
||||||
guildId: '',
|
guildId: '',
|
||||||
|
@@ -1,11 +1,9 @@
|
|||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import { OB11Message } from '../../types';
|
import { OB11Message } from '@/onebot';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { ChatType, RawMessage } from '@/core/entities';
|
import { ChatType, RawMessage } from '@/core/entities';
|
||||||
import { OB11Constructor } from '@/onebot/helper/converter';
|
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||||
import { RawNTMsg2Onebot } from '@/onebot/helper';
|
|
||||||
|
|
||||||
interface Response {
|
interface Response {
|
||||||
messages: OB11Message[];
|
messages: OB11Message[];
|
||||||
@@ -54,7 +52,9 @@ export default class GetFriendMsgHistory extends BaseAction<Payload, Response> {
|
|||||||
msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);
|
msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);
|
||||||
}));
|
}));
|
||||||
//转换消息
|
//转换消息
|
||||||
const ob11MsgList = (await Promise.all(msgList.map(msg => RawNTMsg2Onebot(this.CoreContext, this.OneBotContext, msg)))).filter(msg => !!msg);
|
const ob11MsgList = (await Promise.all(
|
||||||
|
msgList.map(msg => this.OneBotContext.apiContext.MsgApi.parseMessage(msg)))
|
||||||
|
).filter(msg => msg !== undefined);
|
||||||
return { 'messages': ob11MsgList };
|
return { 'messages': ob11MsgList };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,9 @@
|
|||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import { OB11Message } from '../../types';
|
import { OB11Message } from '@/onebot';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { ChatType, Peer, RawMessage } from '@/core/entities';
|
import { ChatType, Peer, RawMessage } from '@/core/entities';
|
||||||
import { OB11Constructor } from '@/onebot/helper/converter';
|
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||||
import { RawNTMsg2Onebot } from '@/onebot/helper';
|
|
||||||
|
|
||||||
interface Response {
|
interface Response {
|
||||||
messages: OB11Message[];
|
messages: OB11Message[];
|
||||||
@@ -49,7 +47,9 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
//转换消息
|
//转换消息
|
||||||
const ob11MsgList = (await Promise.all(msgList.map(msg => RawNTMsg2Onebot(this.CoreContext, this.OneBotContext, msg)))).filter(msg => !!msg);
|
const ob11MsgList = (await Promise.all(
|
||||||
|
msgList.map(msg => this.OneBotContext.apiContext.MsgApi.parseMessage(msg)))
|
||||||
|
).filter(msg => msg !== undefined);
|
||||||
return { 'messages': ob11MsgList };
|
return { 'messages': ob11MsgList };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ export class SetQQProfile extends BaseAction<Payload, any | null> {
|
|||||||
const OldProfile = await NTQQUserApi.getUserDetailInfo(self.uid);
|
const OldProfile = await NTQQUserApi.getUserDetailInfo(self.uid);
|
||||||
const ret = await NTQQUserApi.modifySelfProfile({
|
const ret = await NTQQUserApi.modifySelfProfile({
|
||||||
nick: payload.nickname,
|
nick: payload.nickname,
|
||||||
longNick: payload?.personal_note ?? OldProfile?.longNick!,
|
longNick: (payload?.personal_note ?? OldProfile?.longNick) || '',
|
||||||
sex: parseInt(payload?.sex ? payload?.sex.toString() : OldProfile?.sex!.toString()),
|
sex: parseInt(payload?.sex ? payload?.sex.toString() : OldProfile?.sex!.toString()),
|
||||||
birthday: { birthday_year: OldProfile?.birthday_year!.toString(), birthday_month: OldProfile?.birthday_month!.toString(), birthday_day: OldProfile?.birthday_day!.toString() },
|
birthday: { birthday_year: OldProfile?.birthday_year!.toString(), birthday_month: OldProfile?.birthday_month!.toString(), birthday_day: OldProfile?.birthday_day!.toString() },
|
||||||
location: undefined,
|
location: undefined,
|
||||||
|
28
src/onebot/action/group/DelGroupNotice.ts
Normal file
28
src/onebot/action/group/DelGroupNotice.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { WebApiGroupNoticeFeed } from '@/core';
|
||||||
|
import BaseAction from '../BaseAction';
|
||||||
|
import { ActionName } from '../types';
|
||||||
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
|
|
||||||
|
|
||||||
|
const SchemaData = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
group_id: { type: ['number', 'string'] },
|
||||||
|
feed_id: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: ['group_id','feed_id'],
|
||||||
|
} as const satisfies JSONSchema;
|
||||||
|
|
||||||
|
type Payload = FromSchema<typeof SchemaData>;
|
||||||
|
|
||||||
|
export class DelGroupNotice extends BaseAction<Payload, any> {
|
||||||
|
actionName = ActionName.DelGroupNotice;
|
||||||
|
PayloadSchema = SchemaData;
|
||||||
|
|
||||||
|
async _handle(payload: Payload) {
|
||||||
|
const NTQQGroupApi = this.CoreContext.apis.GroupApi;
|
||||||
|
const group = payload.group_id.toString();
|
||||||
|
const feedId = payload.feed_id;
|
||||||
|
return await NTQQGroupApi.deleteGroupBulletin(group, feedId);
|
||||||
|
}
|
||||||
|
}
|
@@ -26,12 +26,12 @@ class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
|
|||||||
const NTQQGroupApi = this.CoreContext.apis.GroupApi;
|
const NTQQGroupApi = this.CoreContext.apis.GroupApi;
|
||||||
const isNocache = typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache;
|
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 NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
||||||
if (!uid) throw (`Uin2Uid Error ${payload.user_id}不存在`);
|
if (!uid) throw new Error (`Uin2Uid Error ${payload.user_id}不存在`);
|
||||||
const [member, info] = await Promise.allSettled([
|
const [member, info] = await Promise.allSettled([
|
||||||
NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache),
|
NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache),
|
||||||
NTQQUserApi.getUserDetailInfo(uid),
|
NTQQUserApi.getUserDetailInfo(uid),
|
||||||
]);
|
]);
|
||||||
if (member.status !== 'fulfilled') throw (`群(${payload.group_id})成员${payload.user_id}不存在 ${member.reason}`);
|
if (member.status !== 'fulfilled') throw new Error (`群(${payload.group_id})成员${payload.user_id}不存在 ${member.reason}`);
|
||||||
if (info.status === 'fulfilled') {
|
if (info.status === 'fulfilled') {
|
||||||
this.CoreContext.context.logger.logDebug("群成员详细信息结果", info.value);
|
this.CoreContext.context.logger.logDebug("群成员详细信息结果", info.value);
|
||||||
Object.assign(member, info.value);
|
Object.assign(member, info.value);
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { GroupNotifyMsgStatus } from '@/core';
|
||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
@@ -28,7 +29,7 @@ export class GetGroupSystemMsg extends BaseAction<void, any> {
|
|||||||
invitor_nick: SSNotify.user1?.nickName,
|
invitor_nick: SSNotify.user1?.nickName,
|
||||||
group_id: SSNotify.group?.groupCode,
|
group_id: SSNotify.group?.groupCode,
|
||||||
group_name: SSNotify.group?.groupName,
|
group_name: SSNotify.group?.groupName,
|
||||||
checked: SSNotify.status === 1 ? false : true,
|
checked: SSNotify.status === GroupNotifyMsgStatus.KUNHANDLE ? false : true,
|
||||||
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
||||||
});
|
});
|
||||||
} else if (SSNotify.type == 7) {
|
} else if (SSNotify.type == 7) {
|
||||||
@@ -38,7 +39,7 @@ export class GetGroupSystemMsg extends BaseAction<void, any> {
|
|||||||
requester_nick: SSNotify.user1?.nickName,
|
requester_nick: SSNotify.user1?.nickName,
|
||||||
group_id: SSNotify.group?.groupCode,
|
group_id: SSNotify.group?.groupCode,
|
||||||
group_name: SSNotify.group?.groupName,
|
group_name: SSNotify.group?.groupName,
|
||||||
checked: SSNotify.status === 1 ? false : true,
|
checked: SSNotify.status === GroupNotifyMsgStatus.KUNHANDLE ? false : true,
|
||||||
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -80,6 +80,7 @@ import GetGuildProfile from './guild/GetGuildProfile';
|
|||||||
import SetModelShow from './go-cqhttp/SetModelShow';
|
import SetModelShow from './go-cqhttp/SetModelShow';
|
||||||
import { SetInputStatus } from './extends/SetInputStatus';
|
import { SetInputStatus } from './extends/SetInputStatus';
|
||||||
import { GetCSRF } from './system/GetCSRF';
|
import { GetCSRF } from './system/GetCSRF';
|
||||||
|
import { DelGroupNotice } from './group/DelGroupNotice';
|
||||||
|
|
||||||
export type ActionMap = Map<string, BaseAction<any, any>>;
|
export type ActionMap = Map<string, BaseAction<any, any>>;
|
||||||
|
|
||||||
@@ -169,6 +170,7 @@ export function createActionMap(onebotContext: NapCatOneBot11Adapter, coreContex
|
|||||||
new SetModelShow(onebotContext, coreContext),
|
new SetModelShow(onebotContext, coreContext),
|
||||||
new SetInputStatus(onebotContext, coreContext),
|
new SetInputStatus(onebotContext, coreContext),
|
||||||
new GetCSRF(onebotContext, coreContext),
|
new GetCSRF(onebotContext, coreContext),
|
||||||
|
new DelGroupNotice(onebotContext, coreContext),
|
||||||
];
|
];
|
||||||
const actionMap = new Map();
|
const actionMap = new Map();
|
||||||
for (const action of actionHandlers) {
|
for (const action of actionHandlers) {
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
import { OB11Message } from '../../types';
|
import { OB11Message } from '@/onebot';
|
||||||
import { OB11Constructor } from '@/onebot/helper/converter';
|
|
||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||||
import { RawNTMsg2Onebot } from '@/onebot/helper';
|
|
||||||
|
|
||||||
|
|
||||||
export type ReturnDataType = OB11Message
|
export type ReturnDataType = OB11Message
|
||||||
@@ -32,19 +30,20 @@ class GetMsg extends BaseAction<Payload, OB11Message> {
|
|||||||
const MsgShortId = MessageUnique.getShortIdByMsgId(payload.message_id.toString());
|
const MsgShortId = MessageUnique.getShortIdByMsgId(payload.message_id.toString());
|
||||||
const msgIdWithPeer = MessageUnique.getMsgIdAndPeerByShortId(MsgShortId || parseInt(payload.message_id.toString()));
|
const msgIdWithPeer = MessageUnique.getMsgIdAndPeerByShortId(MsgShortId || parseInt(payload.message_id.toString()));
|
||||||
if (!msgIdWithPeer) {
|
if (!msgIdWithPeer) {
|
||||||
throw ('消息不存在');
|
throw new Error('消息不存在');
|
||||||
}
|
}
|
||||||
const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType };
|
const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType };
|
||||||
const msg = await NTQQMsgApi.getMsgsByMsgId(
|
const msg = await NTQQMsgApi.getMsgsByMsgId(
|
||||||
peer,
|
peer,
|
||||||
[msgIdWithPeer?.MsgId || payload.message_id.toString()]);
|
[msgIdWithPeer?.MsgId || payload.message_id.toString()]);
|
||||||
const retMsg = await RawNTMsg2Onebot(this.CoreContext, this.OneBotContext, msg.msgList[0], 'array');
|
const retMsg = await this.OneBotContext.apiContext.MsgApi.parseMessage(msg.msgList[0], 'array');
|
||||||
if (!retMsg) throw Error('消息为空');
|
if (!retMsg) throw Error('消息为空');
|
||||||
try {
|
try {
|
||||||
retMsg.message_id = MessageUnique.createMsg(peer, msg.msgList[0].msgId)!;
|
retMsg.message_id = MessageUnique.createMsg(peer, msg.msgList[0].msgId)!;
|
||||||
retMsg.message_seq = retMsg.message_id;
|
retMsg.message_seq = retMsg.message_id;
|
||||||
retMsg.real_id = retMsg.message_id;
|
retMsg.real_id = retMsg.message_id;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// ignored
|
||||||
}
|
}
|
||||||
return retMsg;
|
return retMsg;
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,7 @@ class MarkMsgAsRead extends BaseAction<PlayloadType, null> {
|
|||||||
// 调用API
|
// 调用API
|
||||||
const ret = await NTQQMsgApi.setMsgRead(await this.getPeer(payload));
|
const ret = await NTQQMsgApi.setMsgRead(await this.getPeer(payload));
|
||||||
if (ret.result != 0) {
|
if (ret.result != 0) {
|
||||||
throw ('设置已读失败,' + ret.errMsg);
|
throw new Error('设置已读失败,' + ret.errMsg);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -68,7 +68,7 @@ const _handlers: {
|
|||||||
}
|
}
|
||||||
const uid = await NTQQUserApi.getUidByUinV2(`${atQQ}`);
|
const uid = await NTQQUserApi.getUidByUinV2(`${atQQ}`);
|
||||||
if (!uid) throw new Error('Get Uid Error');
|
if (!uid) throw new Error('Get Uid Error');
|
||||||
let info = await NTQQUserApi.getUserDetailInfo(uid);
|
const info = await NTQQUserApi.getUserDetailInfo(uid);
|
||||||
return SendMsgElementConstructor.at(coreContext, atQQ, uid, AtType.atUser, info.nick || '');
|
return SendMsgElementConstructor.at(coreContext, atQQ, uid, AtType.atUser, info.nick || '');
|
||||||
},
|
},
|
||||||
[OB11MessageDataType.reply]: async (coreContext, obContext: NapCatOneBot11Adapter, { data: { id } }) => {
|
[OB11MessageDataType.reply]: async (coreContext, obContext: NapCatOneBot11Adapter, { data: { id } }) => {
|
||||||
@@ -171,7 +171,7 @@ const _handlers: {
|
|||||||
} else {
|
} else {
|
||||||
postData = data;
|
postData = data;
|
||||||
}
|
}
|
||||||
// Mlikiowa V2.2.4 Refactor Todo
|
// Mlikiowa V2.2.8 Refactor Todo
|
||||||
const signUrl = obContext.configLoader.configData.musicSignUrl;
|
const signUrl = obContext.configLoader.configData.musicSignUrl;
|
||||||
if (!signUrl) {
|
if (!signUrl) {
|
||||||
if (data.type === 'qq') {
|
if (data.type === 'qq') {
|
||||||
|
@@ -110,18 +110,21 @@ export async function handleForwardNode(coreContext: NapCatCore, obContext: NapC
|
|||||||
nodeMsgIds = nodeMsgArray.map(msg => msg.msgId);
|
nodeMsgIds = nodeMsgArray.map(msg => msg.msgId);
|
||||||
let retMsgIds: string[] = [];
|
let retMsgIds: string[] = [];
|
||||||
if (needSendSelf) {
|
if (needSendSelf) {
|
||||||
for (const [index, msg] of nodeMsgArray.entries()) {
|
for (const [, msg] of nodeMsgArray.entries()) {
|
||||||
if (msg.peerUid === coreContext.selfInfo.uid) continue;
|
if (msg.peerUid === coreContext.selfInfo.uid){
|
||||||
|
retMsgIds.push(msg.msgId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const ClonedMsg = await cloneMsg(coreContext, msg);
|
const ClonedMsg = await cloneMsg(coreContext, msg);
|
||||||
if (ClonedMsg) retMsgIds.push(ClonedMsg.msgId);
|
if (ClonedMsg) retMsgIds.push(ClonedMsg.msgId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
retMsgIds = nodeMsgIds;
|
retMsgIds = nodeMsgIds;
|
||||||
}
|
}
|
||||||
if (nodeMsgIds.length === 0) throw Error('转发消息失败,生成节点为空');
|
if (retMsgIds.length === 0) throw Error('转发消息失败,生成节点为空');
|
||||||
try {
|
try {
|
||||||
logger.logDebug('开发转发', srcPeer, destPeer, nodeMsgIds);
|
logger.logDebug('开发转发', srcPeer, destPeer, retMsgIds);
|
||||||
return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, nodeMsgIds);
|
return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, retMsgIds);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.logError('forward failed', e);
|
logger.logError('forward failed', e);
|
||||||
return null;
|
return null;
|
||||||
|
@@ -40,7 +40,7 @@ export async function sendMsg(coreContext: NapCatCore, peer: Peer, sendElements:
|
|||||||
const NTQQMsgApi = coreContext.apis.MsgApi;
|
const NTQQMsgApi = coreContext.apis.MsgApi;
|
||||||
const logger = coreContext.context.logger;
|
const logger = coreContext.context.logger;
|
||||||
if (!sendElements.length) {
|
if (!sendElements.length) {
|
||||||
throw ('消息体无法解析, 请检查是否发送了不支持的消息类型');
|
throw new Error ('消息体无法解析, 请检查是否发送了不支持的消息类型');
|
||||||
}
|
}
|
||||||
let totalSize = 0;
|
let totalSize = 0;
|
||||||
let timeout = 10000;
|
let timeout = 10000;
|
||||||
@@ -90,6 +90,7 @@ async function createContext(coreContext: NapCatCore, payload: OB11PostSendMsg,
|
|||||||
// This redundant design of Ob11 here should be blamed.
|
// This redundant design of Ob11 here should be blamed.
|
||||||
const NTQQFriendApi = coreContext.apis.FriendApi;
|
const NTQQFriendApi = coreContext.apis.FriendApi;
|
||||||
const NTQQUserApi = coreContext.apis.UserApi;
|
const NTQQUserApi = coreContext.apis.UserApi;
|
||||||
|
const NTQQMsgApi = coreContext.apis.MsgApi;
|
||||||
if ((contextMode === ContextMode.Group || contextMode === ContextMode.Normal) && payload.group_id) {
|
if ((contextMode === ContextMode.Group || contextMode === ContextMode.Normal) && payload.group_id) {
|
||||||
return {
|
return {
|
||||||
chatType: ChatType.KCHATTYPEGROUP,
|
chatType: ChatType.KCHATTYPEGROUP,
|
||||||
@@ -98,12 +99,34 @@ async function createContext(coreContext: NapCatCore, payload: OB11PostSendMsg,
|
|||||||
}
|
}
|
||||||
if ((contextMode === ContextMode.Private || contextMode === ContextMode.Normal) && payload.user_id) {
|
if ((contextMode === ContextMode.Private || contextMode === ContextMode.Normal) && payload.user_id) {
|
||||||
const Uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
const Uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
||||||
const isBuddy = await NTQQFriendApi.isBuddy(Uid!);
|
if (!Uid) throw '无法获取用户信息';
|
||||||
//console.log("[调试代码] UIN:", payload.user_id, " UID:", Uid, " IsBuddy:", isBuddy);
|
const isBuddy = await NTQQFriendApi.isBuddy(Uid);
|
||||||
|
if (!isBuddy) {
|
||||||
|
const ret = await NTQQMsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, Uid);
|
||||||
|
if (ret.tmpChatInfo?.groupCode) {
|
||||||
|
return {
|
||||||
|
chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP,
|
||||||
|
peerUid: Uid,
|
||||||
|
guildId: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (payload.group_id) {
|
||||||
|
return {
|
||||||
|
chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP,
|
||||||
|
peerUid: Uid,
|
||||||
|
guildId: payload.group_id.toString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
chatType: ChatType.KCHATTYPEC2C,
|
||||||
|
peerUid: Uid!,
|
||||||
|
guildId: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
chatType: isBuddy ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP,
|
chatType: ChatType.KCHATTYPEC2C,
|
||||||
peerUid: Uid!,
|
peerUid: Uid!,
|
||||||
guildId: payload.group_id?.toString() || '',
|
guildId: '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
throw '请指定 group_id 或 user_id';
|
throw '请指定 group_id 或 user_id';
|
||||||
@@ -135,7 +158,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
if (payload.user_id && payload.message_type !== 'group') {
|
if (payload.user_id && payload.message_type !== 'group') {
|
||||||
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
||||||
const isBuddy = await NTQQFriendApi.isBuddy(uid!);
|
const isBuddy = await NTQQFriendApi.isBuddy(uid!);
|
||||||
if (!isBuddy) {}
|
//if (!isBuddy) { }
|
||||||
}
|
}
|
||||||
return { valid: true };
|
return { valid: true };
|
||||||
}
|
}
|
||||||
|
@@ -109,4 +109,5 @@ export enum ActionName {
|
|||||||
SetModelShow = "_set_model_show",
|
SetModelShow = "_set_model_show",
|
||||||
SetInputStatus = "set_input_status",
|
SetInputStatus = "set_input_status",
|
||||||
GetCSRF = "get_csrf_token",
|
GetCSRF = "get_csrf_token",
|
||||||
|
DelGroupNotice = "_del_group_notice",
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { OB11Constructor } from '@/onebot/helper/converter';
|
|
||||||
import { RawNTMsg2Onebot } from '@/onebot/helper';
|
|
||||||
|
|
||||||
const SchemaData = {
|
const SchemaData = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@@ -21,11 +19,11 @@ export default class GetRecentContact extends BaseAction<Payload, any> {
|
|||||||
const NTQQUserApi = this.CoreContext.apis.UserApi;
|
const NTQQUserApi = this.CoreContext.apis.UserApi;
|
||||||
const NTQQMsgApi = this.CoreContext.apis.MsgApi;
|
const NTQQMsgApi = this.CoreContext.apis.MsgApi;
|
||||||
const ret = await NTQQUserApi.getRecentContactListSnapShot(parseInt((payload.count || 10).toString()));
|
const ret = await NTQQUserApi.getRecentContactListSnapShot(parseInt((payload.count || 10).toString()));
|
||||||
const data = await Promise.all(ret.info.changedList.map(async (t) => {
|
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 NTQQMsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]);
|
||||||
if (FastMsg.msgList.length > 0) {
|
if (FastMsg.msgList.length > 0) {
|
||||||
//扩展ret.info.changedList
|
//扩展ret.info.changedList
|
||||||
const lastestMsg = await RawNTMsg2Onebot(this.CoreContext, this.OneBotContext,FastMsg.msgList[0], 'array');
|
const lastestMsg = await this.OneBotContext.apiContext.MsgApi.parseMessage(FastMsg.msgList[0], 'array');
|
||||||
return {
|
return {
|
||||||
lastestMsg: lastestMsg,
|
lastestMsg: lastestMsg,
|
||||||
peerUin: t.peerUin,
|
peerUin: t.peerUin,
|
||||||
@@ -49,6 +47,5 @@ export default class GetRecentContact extends BaseAction<Payload, any> {
|
|||||||
peerName: t.peerName,
|
peerName: t.peerName,
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,7 +75,7 @@ export class OneBotGroupApi {
|
|||||||
const NTQQGroupApi = this.coreContext.apis.GroupApi;
|
const NTQQGroupApi = this.coreContext.apis.GroupApi;
|
||||||
const groupElement = grayTipElement?.groupElement;
|
const groupElement = grayTipElement?.groupElement;
|
||||||
if (!groupElement) return undefined;
|
if (!groupElement) return undefined;
|
||||||
const member = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.memberUid);
|
const member = await NTQQGroupApi.getGroupMemberV2(GroupCode, groupElement.memberUid);
|
||||||
const memberUin = member?.uin;
|
const memberUin = member?.uin;
|
||||||
const adminMember = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.adminUid);
|
const adminMember = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.adminUid);
|
||||||
if (memberUin) {
|
if (memberUin) {
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
import { UUIDConverter } from '@/common/utils/helper';
|
import { UUIDConverter } from '@/common/utils/helper';
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||||
import { AtType, FaceIndex, MessageElement, NapCatCore, RawMessage } from '@/core';
|
import { AtType, ChatType, FaceIndex, MessageElement, NapCatCore, RawMessage } from '@/core';
|
||||||
import { NapCatOneBot11Adapter, OB11MessageData, OB11MessageDataType } from '@/onebot';
|
import { NapCatOneBot11Adapter, OB11Message, OB11MessageData, OB11MessageDataType } from '@/onebot';
|
||||||
import { RawNTMsg2Onebot } from '../helper';
|
import { OB11Constructor } from '../helper';
|
||||||
|
import { EventType } from '@/onebot/event/OB11BaseEvent';
|
||||||
|
import { encodeCQCode } from '@/onebot/helper/cqcode';
|
||||||
|
|
||||||
export class OneBotMsgApi {
|
export class OneBotMsgApi {
|
||||||
obContext: NapCatOneBot11Adapter;
|
obContext: NapCatOneBot11Adapter;
|
||||||
@@ -12,11 +14,121 @@ export class OneBotMsgApi {
|
|||||||
this.obContext = obContext;
|
this.obContext = obContext;
|
||||||
this.coreContext = coreContext;
|
this.coreContext = coreContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async parseMessage(
|
||||||
|
msg: RawMessage,
|
||||||
|
messagePostFormat: string = this.obContext.configLoader.configData.messagePostFormat
|
||||||
|
) {
|
||||||
|
if (msg.senderUin == "0" || msg.senderUin == "") return;
|
||||||
|
if (msg.peerUin == "0" || msg.peerUin == "") return;
|
||||||
|
//跳过空消息
|
||||||
|
const NTQQGroupApi = this.coreContext.apis.GroupApi;
|
||||||
|
const NTQQUserApi = this.coreContext.apis.UserApi;
|
||||||
|
const NTQQMsgApi = this.coreContext.apis.MsgApi;
|
||||||
|
const resMsg: OB11Message = {
|
||||||
|
self_id: parseInt(this.coreContext.selfInfo.uin),
|
||||||
|
user_id: parseInt(msg.senderUin!),
|
||||||
|
time: parseInt(msg.msgTime) || Date.now(),
|
||||||
|
message_id: msg.id!,
|
||||||
|
message_seq: msg.id!,
|
||||||
|
real_id: msg.id!,
|
||||||
|
message_type: msg.chatType == ChatType.KCHATTYPEGROUP ? 'group' : 'private',
|
||||||
|
sender: {
|
||||||
|
user_id: parseInt(msg.senderUin || '0'),
|
||||||
|
nickname: msg.sendNickName,
|
||||||
|
card: msg.sendMemberName || '',
|
||||||
|
},
|
||||||
|
raw_message: '',
|
||||||
|
font: 14,
|
||||||
|
sub_type: 'friend',
|
||||||
|
message: messagePostFormat === 'string' ? '' : [],
|
||||||
|
message_format: messagePostFormat === 'string' ? 'string' : 'array',
|
||||||
|
post_type: this.coreContext.selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE,
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
if (member) {
|
||||||
|
resMsg.sender.role = OB11Constructor.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;
|
||||||
|
} else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) {
|
||||||
|
resMsg.sub_type = 'group';
|
||||||
|
const ret = await NTQQMsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid);
|
||||||
|
if (ret.result === 0) {
|
||||||
|
resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode);
|
||||||
|
resMsg.sender.nickname = ret.tmpChatInfo!.fromNick;
|
||||||
|
} else {
|
||||||
|
resMsg.group_id = 284840486; //兜底数据
|
||||||
|
resMsg.sender.nickname = "临时会话";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const element of msg.elements) {
|
||||||
|
let message_data: OB11MessageData = {
|
||||||
|
data: {} as any,
|
||||||
|
type: 'unknown' as any,
|
||||||
|
};
|
||||||
|
if (element.textElement && element.textElement?.atType !== AtType.notAt) {
|
||||||
|
const textAtMsgData = await this.obContext.apiContext.MsgApi.parseTextElemntWithAt(msg, element);
|
||||||
|
if (textAtMsgData) message_data = textAtMsgData;
|
||||||
|
} else if (element.textElement) {
|
||||||
|
const textMsgData = await this.obContext.apiContext.MsgApi.parseTextElement(msg, element);
|
||||||
|
if (textMsgData) message_data = textMsgData;
|
||||||
|
} else if (element.replyElement) {
|
||||||
|
const replyMsgData = await this.obContext.apiContext.MsgApi.parseReplyElement(msg, element);
|
||||||
|
if (replyMsgData) message_data = replyMsgData;
|
||||||
|
} else if (element.picElement) {
|
||||||
|
const PicMsgData = await this.obContext.apiContext.MsgApi.parsePicElement(msg, element);
|
||||||
|
if (PicMsgData) message_data = PicMsgData;
|
||||||
|
} else if (element.fileElement) {
|
||||||
|
const FileMsgData = await this.obContext.apiContext.MsgApi.parseFileElement(msg, element);
|
||||||
|
if (FileMsgData) message_data = FileMsgData;
|
||||||
|
} else if (element.videoElement) {
|
||||||
|
const videoMsgData = await this.obContext.apiContext.MsgApi.parseVideoElement(msg, element);
|
||||||
|
if (videoMsgData) message_data = videoMsgData;
|
||||||
|
} else if (element.pttElement) {
|
||||||
|
const pttMsgData = await this.obContext.apiContext.MsgApi.parsePTTElement(msg, element);
|
||||||
|
if (pttMsgData) message_data = pttMsgData;
|
||||||
|
} else if (element.arkElement) {
|
||||||
|
const arkMsgData = await this.obContext.apiContext.MsgApi.parseArkElement(msg, element);
|
||||||
|
if (arkMsgData) message_data = arkMsgData;
|
||||||
|
} else if (element.faceElement) {
|
||||||
|
const faceMsgData = await this.obContext.apiContext.MsgApi.parseFaceElement(msg, element);
|
||||||
|
if (faceMsgData) message_data = faceMsgData;
|
||||||
|
} else if (element.marketFaceElement) {
|
||||||
|
const marketFaceMsgData = await this.obContext.apiContext.MsgApi.parseMarketFaceElement(msg, element);
|
||||||
|
if (marketFaceMsgData) message_data = marketFaceMsgData;
|
||||||
|
} else if (element.markdownElement) {
|
||||||
|
message_data['type'] = OB11MessageDataType.markdown;
|
||||||
|
message_data['data']['data'] = element.markdownElement.content;
|
||||||
|
} else if (element.multiForwardMsgElement) {
|
||||||
|
const multiForwardMsgData = await this.obContext.apiContext.MsgApi.parseMultForwardElement(msg, element, messagePostFormat);
|
||||||
|
if (multiForwardMsgData) message_data = multiForwardMsgData;
|
||||||
|
}
|
||||||
|
if ((message_data.type as string) !== 'unknown' && message_data.data) {
|
||||||
|
const cqCode = encodeCQCode(message_data);
|
||||||
|
|
||||||
|
if (messagePostFormat === 'string') {
|
||||||
|
(resMsg.message as string) += cqCode;
|
||||||
|
} else (resMsg.message as OB11MessageData[]).push(message_data);
|
||||||
|
resMsg.raw_message += cqCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
resMsg.raw_message = resMsg.raw_message.trim();
|
||||||
|
return resMsg;
|
||||||
|
}
|
||||||
|
|
||||||
async parseFileElement(msg: RawMessage, element: MessageElement) {
|
async parseFileElement(msg: RawMessage, element: MessageElement) {
|
||||||
const fileElement = element.fileElement;
|
const fileElement = element.fileElement;
|
||||||
if (!fileElement) return undefined;
|
if (!fileElement) return undefined;
|
||||||
const NTQQFileApi = this.coreContext.apis.FileApi;
|
const NTQQFileApi = this.coreContext.apis.FileApi;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -46,12 +158,8 @@ export class OneBotMsgApi {
|
|||||||
const textElement = element.textElement;
|
const textElement = element.textElement;
|
||||||
if (!textElement) return undefined;
|
if (!textElement) return undefined;
|
||||||
const NTQQUserApi = this.coreContext.apis.UserApi;
|
const NTQQUserApi = this.coreContext.apis.UserApi;
|
||||||
let message_data: OB11MessageData = {
|
|
||||||
data: {} as any,
|
|
||||||
type: 'unknown' as any,
|
|
||||||
};
|
|
||||||
let qq: `${number}` | 'all';
|
let qq: `${number}` | 'all';
|
||||||
let name: string | undefined;
|
// let name: string | undefined;
|
||||||
if (textElement.atType == AtType.atAll) {
|
if (textElement.atType == AtType.atAll) {
|
||||||
qq = 'all';
|
qq = 'all';
|
||||||
} else {
|
} else {
|
||||||
@@ -62,22 +170,22 @@ export class OneBotMsgApi {
|
|||||||
}
|
}
|
||||||
if (atQQ) {
|
if (atQQ) {
|
||||||
qq = atQQ as `${number}`;
|
qq = atQQ as `${number}`;
|
||||||
name = content.replace('@', '');
|
// name = content.replace('@', '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
message_data = {
|
|
||||||
|
return {
|
||||||
type: OB11MessageDataType.at,
|
type: OB11MessageDataType.at,
|
||||||
data: {
|
data: {
|
||||||
qq: qq!,
|
qq: qq!,
|
||||||
name,
|
// name,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return message_data;
|
|
||||||
}
|
}
|
||||||
async parseTextElement(msg: RawMessage, element: MessageElement) {
|
async parseTextElement(msg: RawMessage, element: MessageElement) {
|
||||||
const textElement = element.textElement;
|
const textElement = element.textElement;
|
||||||
if (!textElement) return undefined;
|
if (!textElement) return undefined;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -98,7 +206,7 @@ export class OneBotMsgApi {
|
|||||||
const picElement = element.picElement;
|
const picElement = element.picElement;
|
||||||
if (!picElement) return undefined;
|
if (!picElement) return undefined;
|
||||||
const NTQQFileApi = this.coreContext.apis.FileApi;
|
const NTQQFileApi = this.coreContext.apis.FileApi;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -120,7 +228,7 @@ export class OneBotMsgApi {
|
|||||||
}
|
}
|
||||||
async parseMarketFaceElement(msg: RawMessage, element: MessageElement) {
|
async parseMarketFaceElement(msg: RawMessage, element: MessageElement) {
|
||||||
const NTQQFileApi = this.coreContext.apis.FileApi;
|
const NTQQFileApi = this.coreContext.apis.FileApi;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -149,7 +257,7 @@ export class OneBotMsgApi {
|
|||||||
const replyElement = element.replyElement;
|
const replyElement = element.replyElement;
|
||||||
if (!replyElement) return undefined;
|
if (!replyElement) return undefined;
|
||||||
const NTQQMsgApi = this.coreContext.apis.MsgApi;
|
const NTQQMsgApi = this.coreContext.apis.MsgApi;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -200,7 +308,7 @@ export class OneBotMsgApi {
|
|||||||
const videoElement = element.videoElement;
|
const videoElement = element.videoElement;
|
||||||
if (!videoElement) return undefined;
|
if (!videoElement) return undefined;
|
||||||
const NTQQFileApi = this.coreContext.apis.FileApi;
|
const NTQQFileApi = this.coreContext.apis.FileApi;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -261,7 +369,7 @@ export class OneBotMsgApi {
|
|||||||
const pttElement = element.pttElement;
|
const pttElement = element.pttElement;
|
||||||
if (!pttElement) return undefined;
|
if (!pttElement) return undefined;
|
||||||
const NTQQFileApi = this.coreContext.apis.FileApi;
|
const NTQQFileApi = this.coreContext.apis.FileApi;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -277,13 +385,13 @@ export class OneBotMsgApi {
|
|||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
},
|
},
|
||||||
msg.msgId,
|
msg.msgId,
|
||||||
msg.msgSeq,
|
msg.msgSeq,
|
||||||
msg.senderUid,
|
msg.senderUid,
|
||||||
element.elementId,
|
element.elementId,
|
||||||
element.elementType.toString(),
|
element.elementType.toString(),
|
||||||
pttElement.fileSize || '0',
|
pttElement.fileSize || '0',
|
||||||
pttElement.fileUuid || ''
|
pttElement.fileUuid || ''
|
||||||
);
|
);
|
||||||
//以uuid作为文件名
|
//以uuid作为文件名
|
||||||
return message_data;
|
return message_data;
|
||||||
@@ -291,7 +399,7 @@ export class OneBotMsgApi {
|
|||||||
async parseFaceElement(msg: RawMessage, element: MessageElement) {
|
async parseFaceElement(msg: RawMessage, element: MessageElement) {
|
||||||
const faceElement = element.faceElement;
|
const faceElement = element.faceElement;
|
||||||
if (!faceElement) return undefined;
|
if (!faceElement) return undefined;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -312,7 +420,7 @@ export class OneBotMsgApi {
|
|||||||
const NTQQMsgApi = this.coreContext.apis.MsgApi;
|
const NTQQMsgApi = this.coreContext.apis.MsgApi;
|
||||||
const faceElement = element.multiForwardMsgElement;
|
const faceElement = element.multiForwardMsgElement;
|
||||||
if (!faceElement) return undefined;
|
if (!faceElement) return undefined;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
@@ -339,7 +447,7 @@ export class OneBotMsgApi {
|
|||||||
MultiMsg.parentMsgPeer = ParentMsgPeer;
|
MultiMsg.parentMsgPeer = ParentMsgPeer;
|
||||||
MultiMsg.parentMsgIdList = msg.parentMsgIdList;
|
MultiMsg.parentMsgIdList = msg.parentMsgIdList;
|
||||||
MultiMsg.id = MessageUnique.createMsg(ParentMsgPeer, MultiMsg.msgId); //该ID仅用查看 无法调用
|
MultiMsg.id = MessageUnique.createMsg(ParentMsgPeer, MultiMsg.msgId); //该ID仅用查看 无法调用
|
||||||
const msgList = await RawNTMsg2Onebot(this.coreContext, this.obContext, MultiMsg, messagePostFormat);
|
const msgList = await this.parseMessage(MultiMsg, messagePostFormat);
|
||||||
if (!msgList) continue;
|
if (!msgList) continue;
|
||||||
message_data['data']['content'].push(msgList);
|
message_data['data']['content'].push(msgList);
|
||||||
//console.log("合并消息", msgList);
|
//console.log("合并消息", msgList);
|
||||||
@@ -349,7 +457,7 @@ export class OneBotMsgApi {
|
|||||||
async parseArkElement(msg: RawMessage, element: MessageElement) {
|
async parseArkElement(msg: RawMessage, element: MessageElement) {
|
||||||
const arkElement = element.arkElement;
|
const arkElement = element.arkElement;
|
||||||
if (!arkElement) return undefined;
|
if (!arkElement) return undefined;
|
||||||
let message_data: OB11MessageData = {
|
const message_data: OB11MessageData = {
|
||||||
data: {} as any,
|
data: {} as any,
|
||||||
type: 'unknown' as any,
|
type: 'unknown' as any,
|
||||||
};
|
};
|
||||||
|
@@ -94,7 +94,7 @@ export async function NT2GroupEvent(core: NapCatCore, obContext: NapCatOneBot11A
|
|||||||
if (emojiLikeEvent) return emojiLikeEvent;
|
if (emojiLikeEvent) return emojiLikeEvent;
|
||||||
}
|
}
|
||||||
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
|
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
|
||||||
const GroupIncreaseEvent = await obContext.apiContext.GroupApi.parseGroupMemberIncreaseEvent(msg.peerUid, element.grayTipElement);
|
const GroupIncreaseEvent = await obContext.apiContext.GroupApi.parseGroupIncreaseEvent(msg.peerUid, element.grayTipElement);
|
||||||
if (GroupIncreaseEvent) return GroupIncreaseEvent;
|
if (GroupIncreaseEvent) return GroupIncreaseEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
export * from './config';
|
export * from './config';
|
||||||
export * from './parseMessage';
|
|
||||||
export * from './converter';
|
export * from './converter';
|
||||||
export * from './quick';
|
export * from './quick';
|
||||||
export * from './genMessage';
|
export * from './genMessage';
|
||||||
export * from './event';
|
export * from './event';
|
||||||
|
@@ -1,117 +0,0 @@
|
|||||||
import { NapCatOneBot11Adapter, OB11Message, OB11MessageData, OB11MessageDataType } from '..';
|
|
||||||
import { AtType, ChatType, NapCatCore, RawMessage } from '@/core';
|
|
||||||
import { EventType } from '../event/OB11BaseEvent';
|
|
||||||
import { OB11Constructor } from './converter';
|
|
||||||
import { encodeCQCode } from './cqcode';
|
|
||||||
|
|
||||||
|
|
||||||
export async function RawNTMsg2Onebot(
|
|
||||||
core: NapCatCore,
|
|
||||||
obcore: NapCatOneBot11Adapter,
|
|
||||||
msg: RawMessage,
|
|
||||||
messagePostFormat: string = obcore.configLoader.configData.messagePostFormat
|
|
||||||
): Promise<OB11Message | undefined> {
|
|
||||||
if (msg.senderUin == "0" || msg.senderUin == "") return;
|
|
||||||
if (msg.peerUin == "0" || msg.peerUin == "") return;
|
|
||||||
//跳过空消息
|
|
||||||
const NTQQGroupApi = core.apis.GroupApi;
|
|
||||||
const NTQQUserApi = core.apis.UserApi;
|
|
||||||
const NTQQMsgApi = core.apis.MsgApi;
|
|
||||||
const resMsg: OB11Message = {
|
|
||||||
self_id: parseInt(core.selfInfo.uin),
|
|
||||||
user_id: parseInt(msg.senderUin!),
|
|
||||||
time: parseInt(msg.msgTime) || Date.now(),
|
|
||||||
message_id: msg.id!,
|
|
||||||
message_seq: msg.id!,
|
|
||||||
real_id: msg.id!,
|
|
||||||
message_type: msg.chatType == ChatType.KCHATTYPEGROUP ? 'group' : 'private',
|
|
||||||
sender: {
|
|
||||||
user_id: parseInt(msg.senderUin || '0'),
|
|
||||||
nickname: msg.sendNickName,
|
|
||||||
card: msg.sendMemberName || '',
|
|
||||||
},
|
|
||||||
raw_message: '',
|
|
||||||
font: 14,
|
|
||||||
sub_type: 'friend',
|
|
||||||
message: messagePostFormat === 'string' ? '' : [],
|
|
||||||
message_format: messagePostFormat === 'string' ? 'string' : 'array',
|
|
||||||
post_type: core.selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE,
|
|
||||||
};
|
|
||||||
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);
|
|
||||||
if (member) {
|
|
||||||
resMsg.sender.role = OB11Constructor.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;
|
|
||||||
} else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) {
|
|
||||||
resMsg.sub_type = 'group';
|
|
||||||
const ret = await NTQQMsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid);
|
|
||||||
if (ret.result === 0) {
|
|
||||||
resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode);
|
|
||||||
resMsg.sender.nickname = ret.tmpChatInfo!.fromNick;
|
|
||||||
} else {
|
|
||||||
resMsg.group_id = 284840486; //兜底数据
|
|
||||||
resMsg.sender.nickname = "临时会话";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const element of msg.elements) {
|
|
||||||
let message_data: OB11MessageData = {
|
|
||||||
data: {} as any,
|
|
||||||
type: 'unknown' as any,
|
|
||||||
};
|
|
||||||
if (element.textElement && element.textElement?.atType !== AtType.notAt) {
|
|
||||||
let textAtMsgData = await obcore.apiContext.MsgApi.parseTextElemntWithAt(msg, element);
|
|
||||||
if (textAtMsgData) message_data = textAtMsgData
|
|
||||||
} else if (element.textElement) {
|
|
||||||
let textMsgData = await obcore.apiContext.MsgApi.parseTextElement(msg, element);
|
|
||||||
if (textMsgData) message_data = textMsgData;
|
|
||||||
} else if (element.replyElement) {
|
|
||||||
let replyMsgData = await obcore.apiContext.MsgApi.parseReplyElement(msg, element);
|
|
||||||
if (replyMsgData) message_data = replyMsgData;
|
|
||||||
} else if (element.picElement) {
|
|
||||||
let PicMsgData = await obcore.apiContext.MsgApi.parsePicElement(msg, element);
|
|
||||||
if (PicMsgData) message_data = PicMsgData;
|
|
||||||
} else if (element.fileElement) {
|
|
||||||
let FileMsgData = await obcore.apiContext.MsgApi.parseFileElement(msg, element);
|
|
||||||
if (FileMsgData) message_data = FileMsgData;
|
|
||||||
} else if (element.videoElement) {
|
|
||||||
let videoMsgData = await obcore.apiContext.MsgApi.parseVideoElement(msg, element);
|
|
||||||
if (videoMsgData) message_data = videoMsgData;
|
|
||||||
} else if (element.pttElement) {
|
|
||||||
let pttMsgData = await obcore.apiContext.MsgApi.parsePTTElement(msg, element);
|
|
||||||
if (pttMsgData) message_data = pttMsgData;
|
|
||||||
} else if (element.arkElement) {
|
|
||||||
let arkMsgData = await obcore.apiContext.MsgApi.parseArkElement(msg, element);
|
|
||||||
if (arkMsgData) message_data = arkMsgData;
|
|
||||||
} else if (element.faceElement) {
|
|
||||||
let faceMsgData = await obcore.apiContext.MsgApi.parseFaceElement(msg, element);
|
|
||||||
if (faceMsgData) message_data = faceMsgData;
|
|
||||||
} else if (element.marketFaceElement) {
|
|
||||||
let marketFaceMsgData = await obcore.apiContext.MsgApi.parseMarketFaceElement(msg, element);
|
|
||||||
if (marketFaceMsgData) message_data = marketFaceMsgData;
|
|
||||||
} else if (element.markdownElement) {
|
|
||||||
message_data['type'] = OB11MessageDataType.markdown;
|
|
||||||
message_data['data']['data'] = element.markdownElement.content;
|
|
||||||
} else if (element.multiForwardMsgElement) {
|
|
||||||
let multiForwardMsgData = await obcore.apiContext.MsgApi.parseMultForwardElement(msg, element, messagePostFormat);
|
|
||||||
if (multiForwardMsgData) message_data = multiForwardMsgData;
|
|
||||||
}
|
|
||||||
if ((message_data.type as string) !== 'unknown' && message_data.data) {
|
|
||||||
const cqCode = encodeCQCode(message_data);
|
|
||||||
|
|
||||||
if (messagePostFormat === 'string') {
|
|
||||||
(resMsg.message as string) += cqCode;
|
|
||||||
} else (resMsg.message as OB11MessageData[]).push(message_data);
|
|
||||||
resMsg.raw_message += cqCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
resMsg.raw_message = resMsg.raw_message.trim();
|
|
||||||
return resMsg;
|
|
||||||
}
|
|
@@ -3,13 +3,14 @@ import {
|
|||||||
BuddyReqType,
|
BuddyReqType,
|
||||||
ChatType,
|
ChatType,
|
||||||
GroupListener,
|
GroupListener,
|
||||||
GroupNotifyTypes,
|
|
||||||
InstanceContext,
|
InstanceContext,
|
||||||
MsgListener,
|
MsgListener,
|
||||||
NapCatCore,
|
NapCatCore,
|
||||||
RawMessage,
|
RawMessage,
|
||||||
SendStatusType,
|
SendStatusType,
|
||||||
GroupMemberRole,
|
GroupMemberRole,
|
||||||
|
GroupNotifyMsgType,
|
||||||
|
GroupNotifyMsgStatus,
|
||||||
} from '@/core';
|
} from '@/core';
|
||||||
import { OB11Config, OB11ConfigLoader } from '@/onebot/helper/config';
|
import { OB11Config, OB11ConfigLoader } from '@/onebot/helper/config';
|
||||||
import { OneBotApiContextType } from '@/onebot/types';
|
import { OneBotApiContextType } from '@/onebot/types';
|
||||||
@@ -34,7 +35,7 @@ import { OB11GroupRequestEvent } from '@/onebot/event/request/OB11GroupRequest';
|
|||||||
import { OB11FriendRecallNoticeEvent } from '@/onebot/event/notice/OB11FriendRecallNoticeEvent';
|
import { OB11FriendRecallNoticeEvent } from '@/onebot/event/notice/OB11FriendRecallNoticeEvent';
|
||||||
import { OB11GroupRecallNoticeEvent } from '@/onebot/event/notice/OB11GroupRecallNoticeEvent';
|
import { OB11GroupRecallNoticeEvent } from '@/onebot/event/notice/OB11GroupRecallNoticeEvent';
|
||||||
import { LRUCache } from '@/common/utils/LRU';
|
import { LRUCache } from '@/common/utils/LRU';
|
||||||
import { NT2GroupEvent, NT2PrivateEvent, RawNTMsg2Onebot } from './helper';
|
import { NT2GroupEvent, NT2PrivateEvent } from './helper';
|
||||||
|
|
||||||
//OneBot实现类
|
//OneBot实现类
|
||||||
export class NapCatOneBot11Adapter {
|
export class NapCatOneBot11Adapter {
|
||||||
@@ -248,15 +249,16 @@ export class NapCatOneBot11Adapter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const msgIdSend = new LRUCache<string, boolean>(100);
|
const msgIdSend = new LRUCache<string, boolean>(100);
|
||||||
|
const recallMsgs = new LRUCache<string, boolean>(100);
|
||||||
msgListener.onMsgInfoListUpdate = async msgList => {
|
msgListener.onMsgInfoListUpdate = async msgList => {
|
||||||
this.emitRecallMsg(msgList)
|
this.emitRecallMsg(msgList, recallMsgs)
|
||||||
.catch(e => this.context.logger.logError('处理消息失败', e));
|
.catch(e => this.context.logger.logError('处理消息失败', e));
|
||||||
|
|
||||||
for (const msg of msgList.filter(e => e.senderUin == this.core.selfInfo.uin)) {
|
for (const msg of msgList.filter(e => e.senderUin == this.core.selfInfo.uin)) {
|
||||||
if (msg.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS && !msgIdSend.get(msg.msgId)) {
|
if (msg.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS && !msgIdSend.get(msg.msgId)) {
|
||||||
msgIdSend.put(msg.msgId, true);
|
msgIdSend.put(msg.msgId, true);
|
||||||
// 完成后再post
|
// 完成后再post
|
||||||
RawNTMsg2Onebot(this.core, this, msg)
|
this.apiContext.MsgApi.parseMessage(msg)
|
||||||
.then((ob11Msg) => {
|
.then((ob11Msg) => {
|
||||||
if (!ob11Msg) return;
|
if (!ob11Msg) return;
|
||||||
ob11Msg.target_id = parseInt(msg.peerUin);
|
ob11Msg.target_id = parseInt(msg.peerUin);
|
||||||
@@ -283,8 +285,16 @@ export class NapCatOneBot11Adapter {
|
|||||||
private initBuddyListener() {
|
private initBuddyListener() {
|
||||||
const buddyListener = new BuddyListener();
|
const buddyListener = new BuddyListener();
|
||||||
|
|
||||||
buddyListener.onBuddyReqChange = reqs => {
|
buddyListener.onBuddyReqChange = async reqs => {
|
||||||
reqs.buddyReqs.forEach(async req => {
|
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)) {
|
if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -299,7 +309,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.context.logger.logDebug('获取加好友者QQ号失败', e);
|
this.context.logger.logDebug('获取加好友者QQ号失败', e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.context.session.getBuddyService().addKernelBuddyListener(
|
this.context.session.getBuddyService().addKernelBuddyListener(
|
||||||
@@ -313,12 +323,11 @@ export class NapCatOneBot11Adapter {
|
|||||||
groupListener.onGroupNotifiesUpdated = async (_, notifies) => {
|
groupListener.onGroupNotifiesUpdated = async (_, notifies) => {
|
||||||
//console.log('ob11 onGroupNotifiesUpdated', notifies[0]);
|
//console.log('ob11 onGroupNotifiesUpdated', notifies[0]);
|
||||||
if (![
|
if (![
|
||||||
GroupNotifyTypes.ADMIN_SET,
|
GroupNotifyMsgType.SET_ADMIN,
|
||||||
GroupNotifyTypes.ADMIN_UNSET,
|
GroupNotifyMsgType.CANCEL_ADMIN_NOTIFY_CANCELED,
|
||||||
GroupNotifyTypes.ADMIN_UNSET_OTHER,
|
GroupNotifyMsgType.CANCEL_ADMIN_NOTIFY_ADMIN,
|
||||||
].includes(notifies[0]?.type)) {
|
].includes(notifies[0]?.type)) {
|
||||||
for (const notify of notifies) {
|
for (const notify of notifies) {
|
||||||
notify.time = Date.now();
|
|
||||||
const notifyTime = parseInt(notify.seq) / 1000 / 1000;
|
const notifyTime = parseInt(notify.seq) / 1000 / 1000;
|
||||||
// log(`群通知时间${notifyTime}`, `启动时间${this.bootTime}`);
|
// log(`群通知时间${notifyTime}`, `启动时间${this.bootTime}`);
|
||||||
if (notifyTime < this.bootTime) {
|
if (notifyTime < this.bootTime) {
|
||||||
@@ -329,9 +338,9 @@ export class NapCatOneBot11Adapter {
|
|||||||
this.context.logger.logDebug('收到群通知', notify);
|
this.context.logger.logDebug('收到群通知', notify);
|
||||||
|
|
||||||
if ([
|
if ([
|
||||||
GroupNotifyTypes.ADMIN_SET,
|
GroupNotifyMsgType.SET_ADMIN,
|
||||||
GroupNotifyTypes.ADMIN_UNSET,
|
GroupNotifyMsgType.CANCEL_ADMIN_NOTIFY_CANCELED,
|
||||||
GroupNotifyTypes.ADMIN_UNSET_OTHER,
|
GroupNotifyMsgType.CANCEL_ADMIN_NOTIFY_ADMIN,
|
||||||
].includes(notify.type)) {
|
].includes(notify.type)) {
|
||||||
const member1 = await this.core.apis.GroupApi.getGroupMember(notify.group.groupCode, notify.user1.uid);
|
const member1 = await this.core.apis.GroupApi.getGroupMember(notify.group.groupCode, notify.user1.uid);
|
||||||
this.context.logger.logDebug('有管理员变动通知');
|
this.context.logger.logDebug('有管理员变动通知');
|
||||||
@@ -340,20 +349,21 @@ export class NapCatOneBot11Adapter {
|
|||||||
this.context.logger.logDebug('开始获取变动的管理员');
|
this.context.logger.logDebug('开始获取变动的管理员');
|
||||||
if (member1) {
|
if (member1) {
|
||||||
this.context.logger.logDebug('变动管理员获取成功');
|
this.context.logger.logDebug('变动管理员获取成功');
|
||||||
// member1.role = notify.type == GroupNotifyTypes.ADMIN_SET ? GroupMemberRole.admin : GroupMemberRole.normal;
|
|
||||||
|
|
||||||
const groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent(
|
const groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent(
|
||||||
this.core,
|
this.core,
|
||||||
parseInt(notify.group.groupCode),
|
parseInt(notify.group.groupCode),
|
||||||
parseInt(member1.uin),
|
parseInt(member1.uin),
|
||||||
[GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes(notify.type) ? 'unset' : 'set',
|
[
|
||||||
|
GroupNotifyMsgType.CANCEL_ADMIN_NOTIFY_CANCELED,
|
||||||
|
GroupNotifyMsgType.CANCEL_ADMIN_NOTIFY_ADMIN
|
||||||
|
].includes(notify.type) ? 'unset' : 'set',
|
||||||
);
|
);
|
||||||
this.networkManager.emitEvent(groupAdminNoticeEvent)
|
this.networkManager.emitEvent(groupAdminNoticeEvent)
|
||||||
.catch(e => this.context.logger.logError('处理群管理员变动失败', e));
|
.catch(e => this.context.logger.logError('处理群管理员变动失败', e));
|
||||||
} else {
|
} else {
|
||||||
this.context.logger.logDebug('获取群通知的成员信息失败', notify, this.core.apis.GroupApi.getGroup(notify.group.groupCode));
|
this.context.logger.logDebug('获取群通知的成员信息失败', notify, this.core.apis.GroupApi.getGroup(notify.group.groupCode));
|
||||||
}
|
}
|
||||||
} else if (notify.type == GroupNotifyTypes.MEMBER_EXIT || notify.type == GroupNotifyTypes.KICK_MEMBER) {
|
} else if (notify.type == GroupNotifyMsgType.MEMBER_LEAVE_NOTIFY_ADMIN || notify.type == GroupNotifyMsgType.KICK_MEMBER_NOTIFY_ADMIN) {
|
||||||
this.context.logger.logDebug('有成员退出通知', notify);
|
this.context.logger.logDebug('有成员退出通知', notify);
|
||||||
const member1Uin = (await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid))!;
|
const member1Uin = (await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid))!;
|
||||||
let operatorId = member1Uin;
|
let operatorId = member1Uin;
|
||||||
@@ -377,8 +387,8 @@ export class NapCatOneBot11Adapter {
|
|||||||
.catch(e => this.context.logger.logError('处理群成员退出失败', e));
|
.catch(e => this.context.logger.logError('处理群成员退出失败', e));
|
||||||
// notify.status == 1 表示未处理 2表示处理完成
|
// notify.status == 1 表示未处理 2表示处理完成
|
||||||
} else if ([
|
} else if ([
|
||||||
GroupNotifyTypes.JOIN_REQUEST,
|
GroupNotifyMsgType.REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS,
|
||||||
].includes(notify.type) && notify.status == 1) {
|
].includes(notify.type) && notify.status == GroupNotifyMsgStatus.KUNHANDLE) {
|
||||||
this.context.logger.logDebug('有加群请求');
|
this.context.logger.logDebug('有加群请求');
|
||||||
try {
|
try {
|
||||||
let requestUin = (await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid))!;
|
let requestUin = (await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid))!;
|
||||||
@@ -398,7 +408,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.context.logger.logError('获取加群人QQ号失败 Uid:', notify.user1.uid, e);
|
this.context.logger.logError('获取加群人QQ号失败 Uid:', notify.user1.uid, e);
|
||||||
}
|
}
|
||||||
} else if (notify.type == GroupNotifyTypes.INVITE_ME && notify.status == 1) {
|
} else if (notify.type == GroupNotifyMsgType.INVITED_BY_MEMBER && notify.status == GroupNotifyMsgStatus.KUNHANDLE) {
|
||||||
this.context.logger.logDebug(`收到邀请我加群通知:${notify}`);
|
this.context.logger.logDebug(`收到邀请我加群通知:${notify}`);
|
||||||
const groupInviteEvent = new OB11GroupRequestEvent(
|
const groupInviteEvent = new OB11GroupRequestEvent(
|
||||||
this.core,
|
this.core,
|
||||||
@@ -446,7 +456,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
private async emitMsg(message: RawMessage) {
|
private async emitMsg(message: RawMessage) {
|
||||||
const { debug, reportSelfMessage, messagePostFormat } = this.configLoader.configData;
|
const { debug, reportSelfMessage, messagePostFormat } = this.configLoader.configData;
|
||||||
this.context.logger.logDebug('收到新消息 RawMessage', message);
|
this.context.logger.logDebug('收到新消息 RawMessage', message);
|
||||||
RawNTMsg2Onebot(this.core, this, message, messagePostFormat).then((ob11Msg) => {
|
this.apiContext.MsgApi.parseMessage(message, messagePostFormat).then((ob11Msg) => {
|
||||||
if (!ob11Msg) return;
|
if (!ob11Msg) return;
|
||||||
this.context.logger.logDebug('转化为 OB11Message', ob11Msg);
|
this.context.logger.logDebug('转化为 OB11Message', ob11Msg);
|
||||||
if (debug) {
|
if (debug) {
|
||||||
@@ -483,10 +493,11 @@ export class NapCatOneBot11Adapter {
|
|||||||
}).catch(e => this.context.logger.logError('constructPrivateEvent error: ', e));
|
}).catch(e => this.context.logger.logError('constructPrivateEvent error: ', e));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async emitRecallMsg(msgList: RawMessage[]) {
|
private async emitRecallMsg(msgList: RawMessage[], cache: LRUCache<string, boolean>) {
|
||||||
for (const message of msgList) {
|
for (const message of msgList) {
|
||||||
// log("message update", message.sendStatus, message.msgId, message.msgSeq)
|
// log("message update", message.sendStatus, message.msgId, message.msgSeq)
|
||||||
if (message.recallTime != '0') { //todo: 这个判断方法不太好,应该使用灰色消息元素来判断?
|
if (message.recallTime != '0' && !cache.get(message.msgId)) { //todo: 这个判断方法不太好,应该使用灰色消息元素来判断?
|
||||||
|
cache.put(message.msgId, true);
|
||||||
// 撤回消息上报
|
// 撤回消息上报
|
||||||
const oriMessageId = MessageUnique.getShortIdByMsgId(message.msgId);
|
const oriMessageId = MessageUnique.getShortIdByMsgId(message.msgId);
|
||||||
if (!oriMessageId) {
|
if (!oriMessageId) {
|
||||||
|
@@ -156,7 +156,7 @@ export interface OB11MessageCustomMusic {
|
|||||||
|
|
||||||
export interface OB11MessageJson {
|
export interface OB11MessageJson {
|
||||||
type: OB11MessageDataType.json;
|
type: OB11MessageDataType.json;
|
||||||
data: { config: { token: string } } & any;
|
data: { config: { token: string }, data: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OB11MessageDice {
|
export interface OB11MessageDice {
|
||||||
|
@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
|
|||||||
SettingItem(
|
SettingItem(
|
||||||
'<span id="napcat-update-title">Napcat</span>',
|
'<span id="napcat-update-title">Napcat</span>',
|
||||||
undefined,
|
undefined,
|
||||||
SettingButton('V2.2.4', 'napcat-update-button', 'secondary'),
|
SettingButton('V2.2.8', 'napcat-update-button', 'secondary'),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
|
|||||||
SettingItem(
|
SettingItem(
|
||||||
'<span id="napcat-update-title">Napcat</span>',
|
'<span id="napcat-update-title">Napcat</span>',
|
||||||
void 0,
|
void 0,
|
||||||
SettingButton("V2.2.4", "napcat-update-button", "secondary")
|
SettingButton("V2.2.8", "napcat-update-button", "secondary")
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
Reference in New Issue
Block a user