diff --git a/Lagrange.Core/Common/Interface/Api/OperationExt.cs b/Lagrange.Core/Common/Interface/Api/OperationExt.cs index b5f2cffc8..e0f7e1bd5 100644 --- a/Lagrange.Core/Common/Interface/Api/OperationExt.cs +++ b/Lagrange.Core/Common/Interface/Api/OperationExt.cs @@ -293,4 +293,7 @@ public static Task UploadImage(this BotContext bot, ImageEntity entity) public static Task<(int Retcode, string Message)> SetPinGroup(this BotContext bot, uint uin, bool isPin) => bot.ContextCollection.Business.OperationLogic.SetPinGroup(uin, isPin); + + public static Task FetchPrivateFSDownload(this BotContext bot, string fileId, string fileHash, uint userId) + => bot.ContextCollection.Business.OperationLogic.FetchPrivateFSDownload(fileId, fileHash, userId); } \ No newline at end of file diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs index 55b1dbb37..e7e94836c 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs @@ -222,6 +222,15 @@ public async Task FetchGroupFSDownload(uint groupUin, string fileId) var events = await Collection.Business.SendEvent(groupFSDownloadEvent); return $"{((GroupFSDownloadEvent)events[0]).FileUrl}{fileId}"; } + + public async Task FetchPrivateFSDownload(string fileId, string fileHash, uint userId) + { + var uid = await Collection.Business.CachingLogic.ResolveUid(null, userId); + if (uid == null) return "false"; + var privateFSDownloadEvent = FileDownloadEvent.Create(fileId, fileHash, uid, uid); + var events = await Collection.Business.SendEvent(privateFSDownloadEvent); + return $"{((FileDownloadEvent)events[0]).FileUrl}"; + } public async Task<(int, string)> GroupFSMove(uint groupUin, string fileId, string parentDirectory, string targetDirectory) { diff --git a/Lagrange.OneBot/Core/Entity/Action/OneBotGetPrivateFile.cs b/Lagrange.OneBot/Core/Entity/Action/OneBotGetPrivateFile.cs new file mode 100644 index 000000000..a2d62f1e1 --- /dev/null +++ b/Lagrange.OneBot/Core/Entity/Action/OneBotGetPrivateFile.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace Lagrange.OneBot.Core.Entity.Action; + +[Serializable] +public class OneBotGetPrivateFile +{ + [JsonPropertyName("user_id")] public uint UserId { get; set; } + + [JsonPropertyName("file_hash")] public required string FileHash { get; set; } + + [JsonPropertyName("file_id")] public required string FileId { get; set; } +} \ No newline at end of file diff --git a/Lagrange.OneBot/Core/Entity/Notify/OneBotPrivateFile.cs b/Lagrange.OneBot/Core/Entity/Notify/OneBotPrivateFile.cs index c41785cc1..2988e60f4 100644 --- a/Lagrange.OneBot/Core/Entity/Notify/OneBotPrivateFile.cs +++ b/Lagrange.OneBot/Core/Entity/Notify/OneBotPrivateFile.cs @@ -3,9 +3,26 @@ namespace Lagrange.OneBot.Core.Entity.Notify; [Serializable] -public class OneBotPrivateFile(uint selfId, uint userId, OneBotFileInfo fileInfo) : OneBotNotify(selfId, "offline_file") +public class OneBotPrivateFile(uint selfId, uint userId, OneBotPrivateFileInfo fileInfo) : OneBotNotify(selfId, "offline_file") { [JsonPropertyName("user_id")] public uint UserId { get; set; } = userId; - [JsonPropertyName("file")] public OneBotFileInfo Info { get; set; } = fileInfo; + [JsonPropertyName("file")] public OneBotPrivateFileInfo Info { get; set; } = fileInfo; +} + + + +[Serializable] + +public class OneBotPrivateFileInfo(string id, string name, ulong size, string url, string hash) +{ + [JsonPropertyName("id")] public string Id { get; set; } = id; + + [JsonPropertyName("name")] public string Name { get; set; } = name; + + [JsonPropertyName("size")] public ulong Size { get; set; } = size; + + [JsonPropertyName("url")] public string Url { get; set; } = url; + + [JsonPropertyName("file_hash")] public string FileHash { get; set; } = hash; } \ No newline at end of file diff --git a/Lagrange.OneBot/Core/Notify/NotifyService.cs b/Lagrange.OneBot/Core/Notify/NotifyService.cs index 85eef152f..4f401ac3e 100644 --- a/Lagrange.OneBot/Core/Notify/NotifyService.cs +++ b/Lagrange.OneBot/Core/Notify/NotifyService.cs @@ -28,7 +28,7 @@ public void RegisterEvents() { if (@event.Chain.GetEntity() is { FileUrl: { } url } file) { - var fileInfo = new OneBotFileInfo(file.FileId ?? "", file.FileName, (ulong)file.FileSize, url); + var fileInfo = new OneBotPrivateFileInfo(file.FileUuid ?? "", file.FileName, (ulong)file.FileSize, url, file.FileHash ?? ""); await service.SendJsonAsync(new OneBotPrivateFile(bot.BotUin, @event.Chain.FriendUin, fileInfo)); } }; diff --git a/Lagrange.OneBot/Core/Operation/File/PrivateFSOperations.cs b/Lagrange.OneBot/Core/Operation/File/PrivateFSOperations.cs new file mode 100644 index 000000000..b3af61b0a --- /dev/null +++ b/Lagrange.OneBot/Core/Operation/File/PrivateFSOperations.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Lagrange.Core; +using Lagrange.Core.Common.Interface.Api; +using Lagrange.OneBot.Core.Entity.Action; +using Lagrange.OneBot.Core.Operation.Converters; + +namespace Lagrange.OneBot.Core.Operation.File; + +[Operation("get_private_file_url")] +public class GetPrivateFileUrlOperation : IOperation +{ + public async Task HandleOperation(BotContext context, JsonNode? payload) + { + if (payload.Deserialize(SerializerOptions.DefaultOptions) is { } url) + { + string raw = await context.FetchPrivateFSDownload(url.FileId, url.FileHash, url.UserId); + return new OneBotResult(new JsonObject { { "url", raw } }, 0, "ok"); + } + + throw new Exception(); + } +} \ No newline at end of file