feat: get_private_file_url

This commit is contained in:
手瓜一十雪
2025-02-18 16:51:51 +08:00
parent 6b3bfa1ee9
commit 95ea761b2d
5 changed files with 65 additions and 18 deletions

View File

@@ -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);

View 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!');
}
}

View File

@@ -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];

View File

@@ -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

View File

@@ -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: {