From 51bca39dd63ce5e9b43824de3ef2a9268ae86557 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Mon, 4 Nov 2024 12:12:40 -0600 Subject: [PATCH] add chat file download --- .../Files/Models/FileInformation.cs | 9 +++++++- .../Services/AgentService.CreateAgent.cs | 2 +- .../LocalFileStorageService.Conversation.cs | 1 + .../Controllers/ConversationController.cs | 21 +++++++++++++++++++ .../ViewModels/Files/MessageFileViewModel.cs | 7 ++++++- .../WebSocketsMiddleware.cs | 1 + .../TencentCosService.Conversation.cs | 1 + 7 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Files/Models/FileInformation.cs b/src/Infrastructure/BotSharp.Abstraction/Files/Models/FileInformation.cs index fe767e163..f8dd9449b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Files/Models/FileInformation.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Files/Models/FileInformation.cs @@ -3,7 +3,7 @@ namespace BotSharp.Abstraction.Files.Models; public class FileInformation { /// - /// External file url + /// External file url for display /// [JsonPropertyName("file_url")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -35,4 +35,11 @@ public class FileInformation [JsonPropertyName("file_extension")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? FileExtension { get; set; } = string.Empty; + + /// + /// External file url for download + /// + [JsonPropertyName("file_download_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? FileDownloadUrl { get; set; } = string.Empty; } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs index 4f020a78c..df10ac4b8 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs @@ -34,7 +34,7 @@ public async Task CreateAgent(Agent agent) { UserId = user.Id, AgentId = agentRecord.Id, - Actions = new List { UserAction.Edit }, + Actions = new List { UserAction.Edit, UserAction.Chat }, CreatedTime = DateTime.UtcNow, UpdatedTime = DateTime.UtcNow } diff --git a/src/Infrastructure/BotSharp.Core/Files/Services/Storage/LocalFileStorageService.Conversation.cs b/src/Infrastructure/BotSharp.Core/Files/Services/Storage/LocalFileStorageService.Conversation.cs index 44bfb9f1a..d296e0b39 100644 --- a/src/Infrastructure/BotSharp.Core/Files/Services/Storage/LocalFileStorageService.Conversation.cs +++ b/src/Infrastructure/BotSharp.Core/Files/Services/Storage/LocalFileStorageService.Conversation.cs @@ -69,6 +69,7 @@ public IEnumerable GetMessageFiles(string conversationId, IEnu { MessageId = messageId, FileUrl = $"/conversation/{conversationId}/message/{messageId}/{source}/file/{index}/{fileName}", + FileDownloadUrl = $"/conversation/{conversationId}/message/{messageId}/{source}/file/{index}/{fileName}/download", FileStorageUrl = file, FileName = fileName, FileExtension = fileExtension, diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs index 19f6241f7..b7391be70 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs @@ -1,6 +1,7 @@ using Azure; using BotSharp.Abstraction.Files.Constants; using BotSharp.Abstraction.Files.Enums; +using BotSharp.Abstraction.Files.Utilities; using BotSharp.Abstraction.Options; using BotSharp.Abstraction.Routing; using BotSharp.Abstraction.Users.Enums; @@ -488,6 +489,26 @@ public IActionResult GetMessageFile([FromRoute] string conversationId, [FromRout } return BuildFileResult(file); } + + [HttpGet("/conversation/{conversationId}/message/{messageId}/{source}/file/{index}/{fileName}/download")] + public IActionResult DownloadMessageFile([FromRoute] string conversationId, [FromRoute] string messageId, [FromRoute] string source, [FromRoute] string index, [FromRoute] string fileName) + { + var fileStorage = _services.GetRequiredService(); + var file = fileStorage.GetMessageFile(conversationId, messageId, source, index, fileName); + if (string.IsNullOrEmpty(file)) + { + return NotFound(); + } + + var fName = file.Split(Path.DirectorySeparatorChar).Last(); + var contentType = FileUtility.GetFileContentType(fName); + var stream = System.IO.File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read); + var bytes = new byte[stream.Length]; + stream.Read(bytes, 0, (int)stream.Length); + stream.Position = 0; + + return new FileStreamResult(stream, contentType) { FileDownloadName = fName }; + } #endregion #region Private methods diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Files/MessageFileViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Files/MessageFileViewModel.cs index 787ab1472..fa8ebab61 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Files/MessageFileViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Files/MessageFileViewModel.cs @@ -19,6 +19,10 @@ public class MessageFileViewModel [JsonPropertyName("file_source")] public string FileSource { get; set; } + [JsonPropertyName("file_download_url")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? FileDownloadUrl { get; set; } + public MessageFileViewModel() { @@ -32,7 +36,8 @@ public static MessageFileViewModel Transform(MessageFileModel model) FileName = model.FileName, FileExtension = model.FileExtension, ContentType = model.ContentType, - FileSource = model.FileSource + FileSource = model.FileSource, + FileDownloadUrl = model.FileDownloadUrl }; } } diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/WebSocketsMiddleware.cs b/src/Plugins/BotSharp.Plugin.ChatHub/WebSocketsMiddleware.cs index ff986be61..47c646b7a 100644 --- a/src/Plugins/BotSharp.Plugin.ChatHub/WebSocketsMiddleware.cs +++ b/src/Plugins/BotSharp.Plugin.ChatHub/WebSocketsMiddleware.cs @@ -37,6 +37,7 @@ private bool VerifyGetRequest(HttpRequest request) var regexes = new List { new Regex(@"/conversation/(.*?)/message/(.*?)/(.*?)/file/(.*?)/(.*?)", RegexOptions.IgnoreCase), + new Regex(@"/conversation/(.*?)/message/(.*?)/(.*?)/file/(.*?)/(.*?)/download", RegexOptions.IgnoreCase), new Regex(@"/user/avatar", RegexOptions.IgnoreCase), new Regex(@"/knowledge/document/(.*?)/file/(.*?)", RegexOptions.IgnoreCase) }; diff --git a/src/Plugins/BotSharp.Plugin.TencentCos/Services/TencentCosService.Conversation.cs b/src/Plugins/BotSharp.Plugin.TencentCos/Services/TencentCosService.Conversation.cs index 844afb654..69cda8caa 100644 --- a/src/Plugins/BotSharp.Plugin.TencentCos/Services/TencentCosService.Conversation.cs +++ b/src/Plugins/BotSharp.Plugin.TencentCos/Services/TencentCosService.Conversation.cs @@ -66,6 +66,7 @@ public IEnumerable GetMessageFiles(string conversationId, IEnu { MessageId = messageId, FileUrl = BuilFileUrl(file), + FileDownloadUrl = BuilFileUrl(file), FileStorageUrl = file, FileName = fileName, FileExtension = fileExtension,