diff --git a/README.md b/README.md index 7ad13d60..470fd6f6 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ It's written in C# running on .Net Core that is full cross-platform framework, t * Build, test, evaluate and audit your LLM agent in one place. * Support different open source UI [Chatbot UI](src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md), [HuggingChat UI](src/Plugins/BotSharp.Plugin.HuggingFace/HuggingChat-UI.md). * Abstract standard Rich Content data structure. Integrate with popular message channels like Facebook Messenger, Slack and Telegram. +* Provide RESTful Open API and WebSocket real-time communication. ### Quick Started 1. Run backend service @@ -61,7 +62,7 @@ The core module is mainly composed of abstraction and framework function impleme BotSharp uses component design, the kernel is kept to a minimum, and business functions are implemented by external components. The modular design also allows contributors to better participate. Below are the bulit-in plugins: #### Data Storages -- BotSharp.Plugin.FileRepository +- BotSharp.Core.Repository - BotSharp.Plugin.MongoStorage #### LLMs diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplateMessage.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplateMessage.cs index 243c75b5..2ec5464e 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplateMessage.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplateMessage.cs @@ -1,5 +1,8 @@ namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template { + /// + /// https://developers.facebook.com/docs/messenger-platform/send-messages/buttons + /// public class ButtonTemplateMessage : IRichMessage { public string Text { get; set; } = string.Empty; @@ -11,8 +14,17 @@ namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template public class ButtonElement { - public string Type { get; set; } = string.Empty; + /// + /// web_url, postback, phone_number + /// + public string Type { get; set; } = "web_url"; + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Url { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Payload { get; set; } + public string Title { get; set; } = string.Empty; } } diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/Controllers/WebhookController.cs b/src/Plugins/BotSharp.Plugin.MetaMessenger/Controllers/WebhookController.cs index 883c1b2b..38fb1cfa 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/Controllers/WebhookController.cs +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/Controllers/WebhookController.cs @@ -57,7 +57,15 @@ public class WebhookController : ControllerBase if (req.Entry[0].Messaging[0].Message != null) { senderId = req.Entry[0].Messaging[0].Sender.Id; - message = req.Entry[0].Messaging[0].Message.Text; + + if (req.Entry[0].Messaging[0].Message.QuickReply != null) + { + message = req.Entry[0].Messaging[0].Message.QuickReply.Payload; + } + else + { + message = req.Entry[0].Messaging[0].Message.Text; + } } else if (req.Entry[0].Messaging[0].Postback != null) { diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/Services/MessageHandleService.cs b/src/Plugins/BotSharp.Plugin.MetaMessenger/Services/MessageHandleService.cs index a3c58021..465eca07 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/Services/MessageHandleService.cs +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/Services/MessageHandleService.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Messaging.Models.RichContent; +using BotSharp.Abstraction.Utilities; namespace BotSharp.Plugin.MetaMessenger.Services; @@ -53,35 +54,49 @@ public class MessageHandleService var replies = new List(); var result = await conv.SendMessage(agentId, new RoleDialogModel("user", message), async msg => { - if (!string.IsNullOrEmpty(msg.Content)) + if (msg.RichContent != null) + { + // Official API doesn't support to show extra content above the products + if (!string.IsNullOrEmpty(msg.RichContent.Message.Text) && + // avoid duplicated text + msg.RichContent.Message is not QuickReplyMessage) + { + replies.Add(new TextMessage(msg.RichContent.Message.Text)); + } + + if (msg.RichContent.Message is GenericTemplateMessage genericTemplate) + { + replies.Add(new AttachmentMessage + { + Attachment = new AttachmentBody + { + Payload = genericTemplate + } + }); + } + else if (msg.RichContent.Message is CouponTemplateMessage couponTemplate) + { + replies.Add(new AttachmentMessage + { + Attachment = new AttachmentBody + { + Payload = couponTemplate + } + }); + } + else if (msg.RichContent.Message is QuickReplyMessage quickReplyMessage) + { + replies.Add(quickReplyMessage); + } + else + { + replies.Add(msg.RichContent.Message); + } + } + else { replies.Add(new TextMessage(msg.Content)); } - - if (msg.RichContent.Message is GenericTemplateMessage genericTemplate) - { - replies.Add(new AttachmentMessage - { - Attachment = new AttachmentBody - { - Payload = genericTemplate - } - }); - } - else if (msg.RichContent.Message is CouponTemplateMessage couponTemplate) - { - replies.Add(new AttachmentMessage - { - Attachment = new AttachmentBody - { - Payload = couponTemplate - } - }); - } - else if (msg.RichContent.Message is not TextMessage) - { - replies.Add(msg.RichContent.Message); - } }, _ => Task.CompletedTask, _ => Task.CompletedTask); @@ -90,10 +105,10 @@ public class MessageHandleService foreach(var reply in replies) { await messenger.SendMessage(setting.ApiVersion, setting.PageId, - new SendingMessageRequest(setting.PageAccessToken, recipient) - { - Message = JsonSerializer.Serialize(reply, _serializerOptions) - }); + new SendingMessageRequest(setting.PageAccessToken, recipient) + { + Message = JsonSerializer.Serialize(reply, _serializerOptions) + }); Thread.Sleep(500); } diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/WebhookModels/WebhookMessageBody.cs b/src/Plugins/BotSharp.Plugin.MetaMessenger/WebhookModels/WebhookMessageBody.cs index 629a7746..06629680 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/WebhookModels/WebhookMessageBody.cs +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/WebhookModels/WebhookMessageBody.cs @@ -12,5 +12,5 @@ public class WebhookMessageBody [JsonPropertyName("quick_reply")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public QuickReplyMessage QuickReply { get;set; } + public WebhookMessagePostback QuickReply { get;set; } } diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/WebhookModels/WebhookMessagePostback.cs b/src/Plugins/BotSharp.Plugin.MetaMessenger/WebhookModels/WebhookMessagePostback.cs index cd0eff61..542319c1 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/WebhookModels/WebhookMessagePostback.cs +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/WebhookModels/WebhookMessagePostback.cs @@ -2,7 +2,9 @@ namespace BotSharp.Plugin.MetaMessenger.WebhookModels; public class WebhookMessagePostback { + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string Title { get; set; } + public string Payload { get; set; } [JsonPropertyName("mid")]