mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
feat: get_private_file_url
This commit is contained in:
@@ -1,22 +1,22 @@
|
|||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import {PacketContext} from '@/core/packet/context/packetContext';
|
import { PacketContext } from '@/core/packet/context/packetContext';
|
||||||
import * as trans from '@/core/packet/transformer';
|
import * as trans from '@/core/packet/transformer';
|
||||||
import {PacketMsg} from '@/core/packet/message/message';
|
import { PacketMsg } from '@/core/packet/message/message';
|
||||||
import {
|
import {
|
||||||
PacketMsgFileElement,
|
PacketMsgFileElement,
|
||||||
PacketMsgPicElement,
|
PacketMsgPicElement,
|
||||||
PacketMsgPttElement,
|
PacketMsgPttElement,
|
||||||
PacketMsgVideoElement
|
PacketMsgVideoElement
|
||||||
} from '@/core/packet/message/element';
|
} from '@/core/packet/message/element';
|
||||||
import {ChatType, MsgSourceType, NTMsgType, RawMessage} from '@/core';
|
import { ChatType, MsgSourceType, NTMsgType, RawMessage } from '@/core';
|
||||||
import {MiniAppRawData, MiniAppReqParams} from '@/core/packet/entities/miniApp';
|
import { MiniAppRawData, MiniAppReqParams } from '@/core/packet/entities/miniApp';
|
||||||
import {AIVoiceChatType} from '@/core/packet/entities/aiChat';
|
import { AIVoiceChatType } from '@/core/packet/entities/aiChat';
|
||||||
import {NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg} from '@napneko/nap-proto-core';
|
import { NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
||||||
import {IndexNode, LongMsgResult, MsgInfo} from '@/core/packet/transformer/proto';
|
import { IndexNode, LongMsgResult, MsgInfo } from '@/core/packet/transformer/proto';
|
||||||
import {OidbPacket} from '@/core/packet/transformer/base';
|
import { OidbPacket } from '@/core/packet/transformer/base';
|
||||||
import {ImageOcrResult} from '@/core/packet/entities/ocrResult';
|
import { ImageOcrResult } from '@/core/packet/entities/ocrResult';
|
||||||
import {gunzipSync} from 'zlib';
|
import { gunzipSync } from 'zlib';
|
||||||
import {PacketMsgConverter} from '@/core/packet/message/converter';
|
import { PacketMsgConverter } from '@/core/packet/message/converter';
|
||||||
|
|
||||||
export class PacketOperationContext {
|
export class PacketOperationContext {
|
||||||
private readonly context: PacketContext;
|
private readonly context: PacketContext;
|
||||||
@@ -59,10 +59,10 @@ export class PacketOperationContext {
|
|||||||
const res = trans.GetStrangerInfo.parse(resp);
|
const res = trans.GetStrangerInfo.parse(resp);
|
||||||
const extBigInt = BigInt(res.data.status.value);
|
const extBigInt = BigInt(res.data.status.value);
|
||||||
if (extBigInt <= 10n) {
|
if (extBigInt <= 10n) {
|
||||||
return {status: Number(extBigInt) * 10, ext_status: 0};
|
return { status: Number(extBigInt) * 10, ext_status: 0 };
|
||||||
}
|
}
|
||||||
status = Number((extBigInt & 0xff00n) + ((extBigInt >> 16n) & 0xffn));
|
status = Number((extBigInt & 0xff00n) + ((extBigInt >> 16n) & 0xffn));
|
||||||
return {status: 10, ext_status: status};
|
return { status: 10, ext_status: status };
|
||||||
} catch {
|
} catch {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -79,13 +79,13 @@ export class PacketOperationContext {
|
|||||||
const reqList = msg.flatMap(m =>
|
const reqList = msg.flatMap(m =>
|
||||||
m.msg.map(e => {
|
m.msg.map(e => {
|
||||||
if (e instanceof PacketMsgPicElement) {
|
if (e instanceof PacketMsgPicElement) {
|
||||||
return this.context.highway.uploadImage({chatType, peerUid}, e);
|
return this.context.highway.uploadImage({ chatType, peerUid }, e);
|
||||||
} else if (e instanceof PacketMsgVideoElement) {
|
} else if (e instanceof PacketMsgVideoElement) {
|
||||||
return this.context.highway.uploadVideo({chatType, peerUid}, e);
|
return this.context.highway.uploadVideo({ chatType, peerUid }, e);
|
||||||
} else if (e instanceof PacketMsgPttElement) {
|
} else if (e instanceof PacketMsgPttElement) {
|
||||||
return this.context.highway.uploadPtt({chatType, peerUid}, e);
|
return this.context.highway.uploadPtt({ chatType, peerUid }, e);
|
||||||
} else if (e instanceof PacketMsgFileElement) {
|
} else if (e instanceof PacketMsgFileElement) {
|
||||||
return this.context.highway.uploadFile({chatType, peerUid}, e);
|
return this.context.highway.uploadFile({ chatType, peerUid }, e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}).filter(Boolean)
|
}).filter(Boolean)
|
||||||
@@ -160,6 +160,12 @@ export class PacketOperationContext {
|
|||||||
const res = trans.DownloadGroupFile.parse(resp);
|
const res = trans.DownloadGroupFile.parse(resp);
|
||||||
return `https://${res.download.downloadDns}/ftn_handler/${Buffer.from(res.download.downloadUrl).toString('hex')}/?fname=`;
|
return `https://${res.download.downloadDns}/ftn_handler/${Buffer.from(res.download.downloadUrl).toString('hex')}/?fname=`;
|
||||||
}
|
}
|
||||||
|
async GetPrivateFileUrl(self_id: string, fileUUID: string, md5: string) {
|
||||||
|
const req = trans.DownloadPrivateFile.build(self_id, fileUUID, md5);
|
||||||
|
const resp = await this.context.client.sendOidbPacket(req, true);
|
||||||
|
const res = trans.DownloadPrivateFile.parse(resp);
|
||||||
|
return `http://${res.body?.result?.server}:${res.body?.result?.port}${res.body?.result?.url?.slice(8)}&isthumb=0`;
|
||||||
|
}
|
||||||
|
|
||||||
async GetGroupPttUrl(groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>) {
|
async GetGroupPttUrl(groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>) {
|
||||||
const req = trans.DownloadGroupPtt.build(groupUin, node);
|
const req = trans.DownloadGroupPtt.build(groupUin, node);
|
||||||
|
38
src/onebot/action/file/GetPrivateFileUrl.ts
Normal file
38
src/onebot/action/file/GetPrivateFileUrl.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { ActionName } from '@/onebot/action/router';
|
||||||
|
import { FileNapCatOneBotUUID } from '@/common/file-uuid';
|
||||||
|
import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus';
|
||||||
|
import { Static, Type } from '@sinclair/typebox';
|
||||||
|
|
||||||
|
const SchemaData = Type.Object({
|
||||||
|
file_id: Type.String(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Payload = Static<typeof SchemaData>;
|
||||||
|
|
||||||
|
interface GetPrivateFileUrlResponse {
|
||||||
|
url?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GetPrivateFileUrl extends GetPacketStatusDepends<Payload, GetPrivateFileUrlResponse> {
|
||||||
|
override actionName = ActionName.NapCat_GetPrivateFileUrl;
|
||||||
|
override payloadSchema = SchemaData;
|
||||||
|
|
||||||
|
async _handle(payload: Payload) {
|
||||||
|
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id);
|
||||||
|
|
||||||
|
if (contextMsgFile?.fileUUID && contextMsgFile.msgId) {
|
||||||
|
let msg = await this.core.apis.MsgApi.getMsgsByMsgId(contextMsgFile.peer, [contextMsgFile.msgId]);
|
||||||
|
let self_id = this.core.selfInfo.uid;
|
||||||
|
let file_hash = msg.msgList[0]?.elements.map(ele => ele.fileElement?.file10MMd5)[0];
|
||||||
|
console.log(file_hash,msg)
|
||||||
|
if (file_hash) {
|
||||||
|
return {
|
||||||
|
url: await this.core.apis.PacketApi.pkt.operation.GetPrivateFileUrl(self_id, contextMsgFile.fileUUID, file_hash)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
console.log(contextMsgFile);
|
||||||
|
throw new Error('real fileUUID not found!');
|
||||||
|
}
|
||||||
|
}
|
@@ -106,6 +106,7 @@ import { SendPoke } from '@/onebot/action/packet/SendPoke';
|
|||||||
import { SetDiyOnlineStatus } from './extends/SetDiyOnlineStatus';
|
import { SetDiyOnlineStatus } from './extends/SetDiyOnlineStatus';
|
||||||
import { BotExit } from './extends/BotExit';
|
import { BotExit } from './extends/BotExit';
|
||||||
import { ClickInlineKeyboardButton } from './extends/ClickInlineKeyboardButton';
|
import { ClickInlineKeyboardButton } from './extends/ClickInlineKeyboardButton';
|
||||||
|
import { GetPrivateFileUrl } from './file/GetPrivateFileUrl';
|
||||||
|
|
||||||
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
||||||
|
|
||||||
@@ -225,6 +226,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo
|
|||||||
new GetGroupSystemMsg(obContext, core),
|
new GetGroupSystemMsg(obContext, core),
|
||||||
new BotExit(obContext, core),
|
new BotExit(obContext, core),
|
||||||
new ClickInlineKeyboardButton(obContext, core),
|
new ClickInlineKeyboardButton(obContext, core),
|
||||||
|
new GetPrivateFileUrl(obContext,core)
|
||||||
];
|
];
|
||||||
|
|
||||||
type HandlerUnion = typeof actionHandlers[number];
|
type HandlerUnion = typeof actionHandlers[number];
|
||||||
|
@@ -10,6 +10,7 @@ export interface InvalidCheckResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ActionName = {
|
export const ActionName = {
|
||||||
|
NapCat_GetPrivateFileUrl: 'get_private_file_url',
|
||||||
ClickInlineKeyboardButton: 'click_inline_keyboard_button',
|
ClickInlineKeyboardButton: 'click_inline_keyboard_button',
|
||||||
GetUnidirectionalFriendList: 'get_unidirectional_friend_list',
|
GetUnidirectionalFriendList: 'get_unidirectional_friend_list',
|
||||||
// onebot 11
|
// onebot 11
|
||||||
|
@@ -148,7 +148,7 @@ export class OneBotMsgApi {
|
|||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
};
|
};
|
||||||
const file = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileName);
|
const file = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileUuid);
|
||||||
return {
|
return {
|
||||||
type: OB11MessageDataType.file,
|
type: OB11MessageDataType.file,
|
||||||
data: {
|
data: {
|
||||||
|
Reference in New Issue
Block a user