This commit is contained in:
linyuchen
2024-04-15 00:09:08 +08:00
parent b2061347a5
commit 14e6c6d9a6
218 changed files with 8465 additions and 5 deletions

View File

@@ -0,0 +1,73 @@
import BaseAction from '../BaseAction';
import { ActionName } from '../types';
import fs from 'fs';
import { join as joinPath } from 'node:path';
import { calculateFileMD5, getTempDir, httpDownload } from '@/common/utils/file';
import { v4 as uuid4 } from 'uuid';
interface Payload {
thread_count?: number;
url?: string;
base64?: string;
name?: string;
headers?: string | string[];
}
interface FileResponse {
file: string;
}
export default class GoCQHTTPDownloadFile extends BaseAction<Payload, FileResponse> {
actionName = ActionName.GoCQHTTP_DownloadFile;
protected async _handle(payload: Payload): Promise<FileResponse> {
const isRandomName = !payload.name;
const name = payload.name || uuid4();
const filePath = joinPath(getTempDir(), name);
if (payload.base64) {
fs.writeFileSync(filePath, payload.base64, 'base64');
} else if (payload.url) {
const headers = this.getHeaders(payload.headers);
const buffer = await httpDownload({ url: payload.url, headers: headers });
fs.writeFileSync(filePath, Buffer.from(buffer), 'binary');
} else {
throw new Error('不存在任何文件, 无法下载');
}
if (fs.existsSync(filePath)) {
if (isRandomName) {
// 默认实现要名称未填写时文件名为文件 md5
const md5 = await calculateFileMD5(filePath);
const newPath = joinPath(getTempDir(), md5);
fs.renameSync(filePath, newPath);
return { file: newPath };
}
return { file: filePath };
} else {
throw new Error('文件写入失败, 检查权限');
}
}
getHeaders(headersIn?: string | string[]): Record<string, string> {
const headers: Record<string, string> = {};
if (typeof headersIn == 'string') {
headersIn = headersIn.split('[\\r\\n]');
}
if (Array.isArray(headersIn)) {
for (const headerItem of headersIn) {
const spilt = headerItem.indexOf('=');
if (spilt < 0) {
headers[headerItem] = '';
} else {
const key = headerItem.substring(0, spilt);
headers[key] = headerItem.substring(0, spilt + 1);
}
}
}
if (!headers['Content-Type']) {
headers['Content-Type'] = 'application/octet-stream';
}
return headers;
}
}

View File

@@ -0,0 +1,43 @@
import BaseAction from '../BaseAction';
import { OB11ForwardMessage, OB11Message, OB11MessageData } from '../../types';
import { NTQQMsgApi } from '@/core/qqnt/apis';
import { dbUtil } from '@/common/utils/db';
import { OB11Constructor } from '../../constructor';
import { ActionName } from '../types';
interface Payload {
message_id: string; // long msg id
}
interface Response {
messages: (OB11Message & { content: OB11MessageData })[];
}
export class GoCQHTTGetForwardMsgAction extends BaseAction<Payload, any> {
actionName = ActionName.GoCQHTTP_GetForwardMsg;
protected async _handle(payload: Payload): Promise<any> {
const rootMsg = await dbUtil.getMsgByLongId(payload.message_id);
if (!rootMsg) {
throw Error('msg not found');
}
const data = await NTQQMsgApi.getMultiMsg({
chatType: rootMsg.chatType,
peerUid: rootMsg.peerUid
}, rootMsg.msgId, rootMsg.msgId);
if (!data || data.result !== 0) {
throw Error('找不到相关的聊天记录' + data?.errMsg);
}
const msgList = data.msgList;
const messages = await Promise.all(msgList.map(async msg => {
const resMsg = await OB11Constructor.message(msg);
resMsg.message_id = await dbUtil.addMsg(msg);
return resMsg;
}));
messages.map(msg => {
(<OB11ForwardMessage>msg).content = msg.message;
delete (<any>msg).message;
});
return {messages};
}
}

View File

@@ -0,0 +1,43 @@
import BaseAction from '../BaseAction';
import { OB11Message, OB11User } from '../../types';
import { getGroup, groups } from '@/common/data';
import { ActionName } from '../types';
import { ChatType } from '@/core/qqnt/entities';
import { dbUtil } from '@/common/utils/db';
import { NTQQMsgApi } from '@/core/qqnt/apis/msg';
import { OB11Constructor } from '../../constructor';
interface Payload {
group_id: number
message_seq: number,
count: number
}
interface Response {
messages: OB11Message[];
}
export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Response> {
actionName = ActionName.GoCQHTTP_GetGroupMsgHistory;
protected async _handle(payload: Payload): Promise<Response> {
const group = await getGroup(payload.group_id.toString());
if (!group) {
throw `${payload.group_id}不存在`;
}
const startMsgId = (await dbUtil.getMsgByShortId(payload.message_seq))?.msgId || '0';
// log("startMsgId", startMsgId)
const historyResult = (await NTQQMsgApi.getMsgHistory({
chatType: ChatType.group,
peerUid: group.groupCode
}, startMsgId, parseInt(payload.count?.toString()) || 20));
console.log(historyResult);
const msgList = historyResult.msgList;
await Promise.all(msgList.map(async msg => {
msg.id = await dbUtil.addMsg(msg);
}));
const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(msg)));
return { 'messages': ob11MsgList };
}
}

View File

@@ -0,0 +1,22 @@
import BaseAction from '../BaseAction';
import { OB11User } from '../../types';
import { getUidByUin, uid2UinMap } from '@/common/data';
import { OB11Constructor } from '../../constructor';
import { ActionName } from '../types';
import { NTQQUserApi } from '@/core/qqnt/apis/user';
import { log } from '@/common/utils/log';
export default class GoCQHTTPGetStrangerInfo extends BaseAction<{ user_id: number }, OB11User> {
actionName = ActionName.GoCQHTTP_GetStrangerInfo;
protected async _handle(payload: { user_id: number }): Promise<OB11User> {
const user_id = payload.user_id.toString();
log('uidMaps', uid2UinMap);
const uid = getUidByUin(user_id);
if (!uid) {
throw new Error('查无此人');
}
return OB11Constructor.stranger(await NTQQUserApi.getUserDetailInfo(uid));
}
}

View File

@@ -0,0 +1,20 @@
import SendMsg, { convertMessage2List } from '../msg/SendMsg';
import { OB11PostSendMsg } from '../../types';
import { ActionName } from '../types';
export class GoCQHTTPSendForwardMsg extends SendMsg {
actionName = ActionName.GoCQHTTP_SendForwardMsg;
protected async check(payload: OB11PostSendMsg) {
if (payload.messages) payload.message = convertMessage2List(payload.messages);
return super.check(payload);
}
}
export class GoCQHTTPSendPrivateForwardMsg extends GoCQHTTPSendForwardMsg {
actionName = ActionName.GoCQHTTP_SendPrivateForwardMsg;
}
export class GoCQHTTPSendGroupForwardMsg extends GoCQHTTPSendForwardMsg {
actionName = ActionName.GoCQHTTP_SendGroupForwardMsg;
}

View File

@@ -0,0 +1,37 @@
import BaseAction from '../BaseAction';
import { getGroup } from '@/common/data';
import { ActionName } from '../types';
import { SendMsgElementConstructor } from '@/core/qqnt/entities/constructor';
import { ChatType, SendFileElement } from '@/core/qqnt/entities';
import fs from 'fs';
import { NTQQMsgApi } from '@/core/qqnt/apis/msg';
import { uri2local } from '@/common/utils/file';
interface Payload {
group_id: number;
file: string;
name: string;
folder: string;
}
export default class GoCQHTTPUploadGroupFile extends BaseAction<Payload, null> {
actionName = ActionName.GoCQHTTP_UploadGroupFile;
protected async _handle(payload: Payload): Promise<null> {
const group = await getGroup(payload.group_id.toString());
if (!group) {
throw new Error(`群组${payload.group_id}不存在`);
}
let file = payload.file;
if (fs.existsSync(file)) {
file = `file://${file}`;
}
const downloadResult = await uri2local(file);
if (downloadResult.errMsg) {
throw new Error(downloadResult.errMsg);
}
const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(downloadResult.path, payload.name);
await NTQQMsgApi.sendMsg({ chatType: ChatType.group, peerUid: group.groupCode }, [sendFileEle]);
return null;
}
}