Add RichType to IRichMessage
This commit is contained in:
parent
d7bba4522a
commit
8cc1094469
|
|
@ -0,0 +1,6 @@
|
|||
namespace BotSharp.Abstraction.Messaging;
|
||||
|
||||
public interface IRichContentService
|
||||
{
|
||||
List<IRichMessage> ConvertToMessages(string content);
|
||||
}
|
||||
|
|
@ -3,4 +3,5 @@ namespace BotSharp.Abstraction.Messaging;
|
|||
public interface IRichMessage
|
||||
{
|
||||
string Text { get; set; }
|
||||
string RichType => "text";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
||||
public class QuickReplyElement
|
||||
{
|
||||
public class QuickReplyElement
|
||||
{
|
||||
[JsonPropertyName("content_type")]
|
||||
public string ContentType { get; set; } = "text";
|
||||
[JsonPropertyName("content_type")]
|
||||
public string ContentType { get; set; } = "text";
|
||||
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string? Payload { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string? Payload { get; set; }
|
||||
|
||||
[JsonPropertyName("image_url")]
|
||||
public string? ImageUrl { get; set; }
|
||||
}
|
||||
[JsonPropertyName("image_url")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? ImageUrl { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
||||
{
|
||||
public class QuickReplyMessage : IRichMessage
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
|
||||
[JsonPropertyName("quick_replies")]
|
||||
public List<QuickReplyElement> QuickReplies { get; set; } = new List<QuickReplyElement>();
|
||||
}
|
||||
public class QuickReplyMessage : IRichMessage
|
||||
{
|
||||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => "quick_reply";
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("quick_replies")]
|
||||
public List<QuickReplyElement> QuickReplies { get; set; } = new List<QuickReplyElement>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
||||
public class Recipient
|
||||
{
|
||||
public class Recipient
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
}
|
||||
public string Id { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
|
||||
public class RichContent<T> where T : IRichMessage
|
||||
{
|
||||
public class RichContent<T> where T : IRichMessage
|
||||
{
|
||||
public Recipient Recipient { get; set; } = new Recipient();
|
||||
/// <summary>
|
||||
/// RESPONSE
|
||||
/// </summary>
|
||||
[JsonPropertyName("messaging_type")]
|
||||
public string MessagingType => "RESPONSE";
|
||||
public T Message { get; set; }
|
||||
}
|
||||
public Recipient Recipient { get; set; } = new Recipient();
|
||||
/// <summary>
|
||||
/// RESPONSE
|
||||
/// </summary>
|
||||
[JsonPropertyName("messaging_type")]
|
||||
public string MessagingType => "RESPONSE";
|
||||
public T Message { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent
|
||||
public class SenderActionMessage
|
||||
{
|
||||
public class SenderActionMessage
|
||||
{
|
||||
/*
|
||||
* Requests to display sender action should only include the sender_action parameter and the recipient object.
|
||||
* All other Send API properties, such as text and templates, should be sent in a separate request.
|
||||
*/
|
||||
public Recipient Recipient { get; set; } = new Recipient();
|
||||
/*
|
||||
* Requests to display sender action should only include the sender_action parameter and the recipient object.
|
||||
* All other Send API properties, such as text and templates, should be sent in a separate request.
|
||||
*/
|
||||
public Recipient Recipient { get; set; } = new Recipient();
|
||||
|
||||
[JsonPropertyName("sender_action")]
|
||||
public string SenderAction { get; set; } = string.Empty;
|
||||
}
|
||||
[JsonPropertyName("sender_action")]
|
||||
public string SenderAction { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,35 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template;
|
||||
|
||||
/// <summary>
|
||||
/// https://developers.facebook.com/docs/messenger-platform/send-messages/buttons
|
||||
/// </summary>
|
||||
public class ButtonTemplateMessage : IRichMessage, ITemplateMessage
|
||||
{
|
||||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => "button_template";
|
||||
|
||||
[JsonPropertyName("text")]
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("template_type")]
|
||||
public string TemplateType => "button";
|
||||
|
||||
[JsonPropertyName("buttons")]
|
||||
public ButtonElement[] Buttons { get; set; } = new ButtonElement[0];
|
||||
}
|
||||
|
||||
public class ButtonElement
|
||||
{
|
||||
/// <summary>
|
||||
/// https://developers.facebook.com/docs/messenger-platform/send-messages/buttons
|
||||
/// web_url, postback, phone_number
|
||||
/// </summary>
|
||||
public class ButtonTemplateMessage : IRichMessage
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = "web_url";
|
||||
|
||||
[JsonPropertyName("template_type")]
|
||||
public string TemplateType => "button";
|
||||
public List<ButtonElement> Buttons { get; set; } = new List<ButtonElement>();
|
||||
}
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Url { get; set; }
|
||||
|
||||
public class ButtonElement
|
||||
{
|
||||
/// <summary>
|
||||
/// web_url, postback, phone_number
|
||||
/// </summary>
|
||||
public string Type { get; set; } = "web_url";
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Payload { get; set; }
|
||||
|
||||
[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;
|
||||
}
|
||||
public string Title { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template;
|
|||
/// </summary>
|
||||
public class CouponTemplateMessage : IRichMessage, ITemplateMessage
|
||||
{
|
||||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => "coupon_template";
|
||||
[JsonIgnore]
|
||||
public string Text { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template;
|
||||
|
||||
public class GenericTemplateMessage : TemplateMessageBase<GenericElement>, IRichMessage, ITemplateMessage
|
||||
public class GenericTemplateMessage : IRichMessage, ITemplateMessage
|
||||
{
|
||||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => "generic_template";
|
||||
|
||||
[JsonIgnore]
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("template_type")]
|
||||
public override string TemplateType => "generic";
|
||||
public string TemplateType => "generic";
|
||||
}
|
||||
|
||||
public class GenericElement
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
|
||||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template;
|
||||
|
||||
public class MultiSelectTemplateMessage : IRichMessage, ITemplateMessage
|
||||
{
|
||||
public class MultiSelectTemplateMessage : IRichMessage
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => "multi-select_template";
|
||||
|
||||
[JsonPropertyName("template_type")]
|
||||
public string TemplateType => "multi-select";
|
||||
public List<OptionElement> Options { get; set; } = new List<OptionElement>();
|
||||
}
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
public class OptionElement
|
||||
{
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public string? Payload { get; set; }
|
||||
}
|
||||
[JsonPropertyName("template_type")]
|
||||
public string TemplateType => "multi-select";
|
||||
public List<OptionElement> Options { get; set; } = new List<OptionElement>();
|
||||
}
|
||||
|
||||
public class OptionElement
|
||||
{
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public string? Payload { get; set; }
|
||||
}
|
||||
|
|
@ -1,9 +1,15 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template;
|
||||
|
||||
public class ProductTemplateMessage : TemplateMessageBase<ProductElement>, IRichMessage
|
||||
public class ProductTemplateMessage : IRichMessage, ITemplateMessage
|
||||
{
|
||||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => "generic_template";
|
||||
|
||||
[JsonIgnore]
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("template_type")]
|
||||
public override string TemplateType => "product";
|
||||
public string TemplateType => "product";
|
||||
}
|
||||
|
||||
public class ProductElement
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
|
||||
{
|
||||
public class TemplateMessageBase<T>
|
||||
{
|
||||
[JsonIgnore]
|
||||
public string Text { get; set; }
|
||||
|
||||
[JsonPropertyName("template_type")]
|
||||
public virtual string TemplateType => string.Empty;
|
||||
public T[] Elements { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@ namespace BotSharp.Abstraction.Messaging.Models.RichContent;
|
|||
|
||||
public class TextMessage : IRichMessage
|
||||
{
|
||||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => "text";
|
||||
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
public TextMessage(string text)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ using BotSharp.Abstraction.MLTasks.Settings;
|
|||
using BotSharp.Abstraction.Planning;
|
||||
using BotSharp.Core.Planning;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using static Dapper.SqlMapper;
|
||||
using BotSharp.Abstraction.Messaging;
|
||||
using BotSharp.Core.Messaging;
|
||||
|
||||
namespace BotSharp.Core;
|
||||
|
||||
|
|
@ -98,6 +99,9 @@ public static class BotSharpCoreExtensions
|
|||
|
||||
services.AddScoped<IAgentHook, RoutingAgentHook>();
|
||||
|
||||
// Rich content messaging
|
||||
services.AddScoped<IRichContentService, RichContentService>();
|
||||
|
||||
// Evaluation
|
||||
var evalSetting = new EvaluatorSetting();
|
||||
config.Bind("Evaluator", evalSetting);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
using BotSharp.Abstraction.Messaging;
|
||||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
|
||||
namespace BotSharp.Core.Messaging;
|
||||
|
||||
public class RichContentService : IRichContentService
|
||||
{
|
||||
public List<IRichMessage> ConvertToMessages(string content)
|
||||
{
|
||||
var messages = new List<IRichMessage>();
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
var tempMessages = JsonSerializer.Deserialize<JsonDocument[]>(content, options);
|
||||
|
||||
foreach (var m in tempMessages)
|
||||
{
|
||||
var richType = "text";
|
||||
if (m.RootElement.TryGetProperty("rich_type", out var element))
|
||||
{
|
||||
richType = element.GetString();
|
||||
}
|
||||
|
||||
if (richType == "text")
|
||||
{
|
||||
messages.Add(JsonSerializer.Deserialize<TextMessage>(m.RootElement.ToString(), options));
|
||||
}
|
||||
else if (richType == "quick_reply")
|
||||
{
|
||||
messages.Add(JsonSerializer.Deserialize<QuickReplyMessage>(m.RootElement.ToString(), options));
|
||||
}
|
||||
}
|
||||
|
||||
return messages.ToList();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using BotSharp.Abstraction.Messaging;
|
||||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
|
|
@ -27,10 +28,8 @@ public class ChatHubConversationHook : ConversationHookBase
|
|||
var welcomeTemplate = agent.Templates.FirstOrDefault(x => x.Name == "welcome");
|
||||
if (welcomeTemplate != null)
|
||||
{
|
||||
var messages = JsonSerializer.Deserialize<TextMessage[]>(welcomeTemplate.Content, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
var richContentService = _services.GetRequiredService<IRichContentService>();
|
||||
var messages = richContentService.ConvertToMessages(welcomeTemplate.Content);
|
||||
|
||||
foreach (var message in messages)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
|
|||
/// </summary>
|
||||
public class AttachmentMessage : IRichMessage
|
||||
{
|
||||
[JsonPropertyName("rich_type")]
|
||||
public string RichType => "attachment";
|
||||
|
||||
[JsonIgnore]
|
||||
public string Text { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
using System.Text.Json.Serialization.Metadata;
|
||||
|
||||
namespace BotSharp.Plugin.MetaMessenger.Services;
|
||||
|
||||
public static class ConditionalSerialization
|
||||
{
|
||||
/// <summary>
|
||||
/// https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-7/#example-conditional-serialization
|
||||
/// </summary>
|
||||
/// <param name="typeInfo"></param>
|
||||
public static void IgnoreRichType(JsonTypeInfo typeInfo)
|
||||
{
|
||||
if (typeInfo.Type.GetInterface(nameof(IRichMessage)) == null)
|
||||
return;
|
||||
|
||||
foreach (JsonPropertyInfo propertyInfo in typeInfo.Properties)
|
||||
{
|
||||
if (propertyInfo.Name == "rich_type")
|
||||
{
|
||||
propertyInfo.ShouldSerialize = static (obj, value) => false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ using BotSharp.Abstraction.Agents.Enums;
|
|||
using BotSharp.Abstraction.Conversations.Enums;
|
||||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
using BotSharp.Abstraction.Utilities;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
|
||||
namespace BotSharp.Plugin.MetaMessenger.Services;
|
||||
|
||||
|
|
@ -19,7 +20,11 @@ public class MessageHandleService
|
|||
Converters =
|
||||
{
|
||||
new RichContentJsonConverter(),
|
||||
new TemplateMessageJsonConverter()
|
||||
new TemplateMessageJsonConverter(),
|
||||
},
|
||||
TypeInfoResolver = new DefaultJsonTypeInfoResolver
|
||||
{
|
||||
Modifiers = { ConditionalSerialization.IgnoreRichType }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue