save file to directory
This commit is contained in:
parent
991582372d
commit
2f08a13f05
|
|
@ -3,4 +3,5 @@ namespace BotSharp.Abstraction.Conversations;
|
|||
public interface IConversationAttachmentService
|
||||
{
|
||||
string GetDirectory(string conversationId);
|
||||
void SaveConversationFiles(List<BotSharpFile> files);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,4 +9,6 @@ public class IncomingMessageModel : MessageConfig
|
|||
/// Postback message
|
||||
/// </summary>
|
||||
public PostbackMessageModel? Postback { get; set; }
|
||||
|
||||
public List<BotSharpFile> Files { get; set; } = new List<BotSharpFile>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ public class RoleDialogModel : ITrackableMessage
|
|||
|
||||
public FunctionCallFromLlm Instruction { get; set; }
|
||||
|
||||
public List<BotSharpFile> Files { get; set; } = new List<BotSharpFile>();
|
||||
|
||||
private RoleDialogModel()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
namespace BotSharp.Abstraction.Files.Models;
|
||||
|
||||
public class BotSharpFile
|
||||
{
|
||||
[JsonPropertyName("conversation_id")]
|
||||
public string ConversationId { get; set; }
|
||||
|
||||
[JsonPropertyName("message_id")]
|
||||
public string MessageId { get; set; }
|
||||
|
||||
[JsonPropertyName("file_name")]
|
||||
public string FileName { get; set; }
|
||||
|
||||
[JsonPropertyName("file_data")]
|
||||
public string FileData { get; set; }
|
||||
|
||||
[JsonPropertyName("content_type")]
|
||||
public string ContentType { get; set; }
|
||||
|
||||
[JsonPropertyName("file_size")]
|
||||
public int FileSize { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -14,4 +14,5 @@ global using BotSharp.Abstraction.Models;
|
|||
global using BotSharp.Abstraction.Routing.Models;
|
||||
global using BotSharp.Abstraction.Routing.Planning;
|
||||
global using BotSharp.Abstraction.Templating;
|
||||
global using BotSharp.Abstraction.Translation.Attributes;
|
||||
global using BotSharp.Abstraction.Translation.Attributes;
|
||||
global using BotSharp.Abstraction.Files.Models;
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using System.IO;
|
||||
using System.IO.Enumeration;
|
||||
using System.Threading;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
||||
|
|
@ -7,6 +8,10 @@ public class ConversationAttachmentService : IConversationAttachmentService
|
|||
{
|
||||
private readonly BotSharpDatabaseSettings _dbSettings;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly string _baseDir;
|
||||
|
||||
private const string CONVERSATION_FOLDER = "conversations";
|
||||
private const string FILE_FOLDER = "files";
|
||||
|
||||
public ConversationAttachmentService(
|
||||
BotSharpDatabaseSettings dbSettings,
|
||||
|
|
@ -14,15 +19,107 @@ public class ConversationAttachmentService : IConversationAttachmentService
|
|||
{
|
||||
_dbSettings = dbSettings;
|
||||
_services = services;
|
||||
_baseDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dbSettings.FileRepository);
|
||||
}
|
||||
|
||||
public string GetDirectory(string conversationId)
|
||||
{
|
||||
var dir = Path.Combine(_dbSettings.FileRepository, "conversations", conversationId, "attachments");
|
||||
var dir = Path.Combine(_dbSettings.FileRepository, CONVERSATION_FOLDER, conversationId, "attachments");
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
public string GetConversationFileDirectory(string conversationId)
|
||||
{
|
||||
var dir = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER);
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
public void SaveConversationFiles(List<BotSharpFile> files)
|
||||
{
|
||||
if (files.IsNullOrEmpty()) return;
|
||||
|
||||
var converationId = files.First().ConversationId;
|
||||
var dir = GetConversationFileDirectory(converationId);
|
||||
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
if (string.IsNullOrEmpty(file.ConversationId)
|
||||
|| string.IsNullOrEmpty(file.MessageId)
|
||||
|| string.IsNullOrEmpty(file.FileData))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var fileType = GetFileType(file.FileData);
|
||||
var bytes = GetFileBytes(file.FileData);
|
||||
var parsedFormat = ParseFileFormat(fileType);
|
||||
if (string.IsNullOrEmpty(parsedFormat))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var fileName = $"{file.MessageId}-{i+1}{parsedFormat}";
|
||||
Thread.Sleep(100);
|
||||
File.WriteAllBytes(Path.Combine(dir, fileName), bytes);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFileType(string data)
|
||||
{
|
||||
if (string.IsNullOrEmpty(data))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var startIdx = data.IndexOf(':');
|
||||
var endIdx = data.IndexOf(';');
|
||||
var fileType = data.Substring(startIdx + 1, endIdx - startIdx - 1);
|
||||
return fileType;
|
||||
}
|
||||
|
||||
private byte[] GetFileBytes(string data)
|
||||
{
|
||||
if (string.IsNullOrEmpty(data))
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
var startIdx = data.IndexOf(',');
|
||||
var base64Str = data.Substring(startIdx + 1);
|
||||
return Convert.FromBase64String(base64Str);
|
||||
}
|
||||
|
||||
private string ParseFileFormat(string type)
|
||||
{
|
||||
var parsed = string.Empty;
|
||||
switch (type)
|
||||
{
|
||||
case "image/png":
|
||||
parsed = ".png";
|
||||
break;
|
||||
case "image/jpeg":
|
||||
case "image/jpg":
|
||||
parsed = ".jpeg";
|
||||
break;
|
||||
case "application/pdf":
|
||||
parsed = ".pdf";
|
||||
break;
|
||||
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
||||
parsed = ".xlsx";
|
||||
break;
|
||||
case "text/plain":
|
||||
parsed = ".txt";
|
||||
break;
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Messaging;
|
||||
using BotSharp.Abstraction.Messaging.Enums;
|
||||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
using BotSharp.Abstraction.Routing.Settings;
|
||||
using System.Drawing;
|
||||
|
|
@ -141,6 +142,13 @@ public partial class ConversationService
|
|||
Message = new TextMessage(response.SecondaryContent ?? response.Content)
|
||||
};
|
||||
|
||||
response.RichContent = new RichContent<IRichMessage>
|
||||
{
|
||||
Recipient = new Recipient { Id = state.GetConversationId() },
|
||||
Editor = EditorTypeEnum.File,
|
||||
Message = new TextMessage(response.SecondaryContent ?? response.Content)
|
||||
};
|
||||
|
||||
// Patch return function name
|
||||
if (response.PostbackFunctionName != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public class ConversationStorage : IConversationStorage
|
|||
{
|
||||
var agentId = dialog.CurrentAgentId;
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var attachment = _services.GetRequiredService<IConversationAttachmentService>();
|
||||
var dialogElements = new List<DialogElement>();
|
||||
|
||||
// Prevent duplicate record to be inserted
|
||||
|
|
@ -76,6 +77,8 @@ public class ConversationStorage : IConversationStorage
|
|||
}
|
||||
|
||||
db.AppendConversationDialogs(conversationId, dialogElements);
|
||||
attachment.SaveConversationFiles(dialog.Files);
|
||||
dialog.Files.Clear();
|
||||
}
|
||||
|
||||
public List<RoleDialogModel> GetDialogs(string conversationId)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ global using BotSharp.Abstraction.Functions.Models;
|
|||
global using BotSharp.Abstraction.Repositories;
|
||||
global using BotSharp.Abstraction.Repositories.Filters;
|
||||
global using BotSharp.Abstraction.Translation;
|
||||
global using BotSharp.Abstraction.Files.Models;
|
||||
global using BotSharp.Core.Repository;
|
||||
global using BotSharp.Core.Routing;
|
||||
global using BotSharp.Core.Agents.Services;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,10 @@ public class ConversationController : ControllerBase
|
|||
await conv.TruncateConversation(conversationId, input.TruncateMessageId);
|
||||
}
|
||||
|
||||
var inputMsg = new RoleDialogModel(AgentRole.User, input.Text);
|
||||
var inputMsg = new RoleDialogModel(AgentRole.User, input.Text)
|
||||
{
|
||||
Files = input.Files
|
||||
};
|
||||
var routing = _services.GetRequiredService<IRoutingService>();
|
||||
routing.Context.SetMessageId(conversationId, inputMsg.MessageId);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue