Add more template rich message.

This commit is contained in:
Haiping Chen 2023-11-24 17:26:33 -06:00
parent be88bfa121
commit a1bc56b481
45 changed files with 358 additions and 261 deletions

View file

@ -1,5 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Messaging.Models;
using BotSharp.Abstraction.Messaging;
using BotSharp.Abstraction.Messaging.Models.RichContent;
namespace BotSharp.Abstraction.Conversations.Models;
@ -45,7 +45,7 @@ public class RoleDialogModel : ITrackableMessage
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public object Data { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public RichContent<IMessageTemplate>? RichContent { get; set; }
public RichContent<IRichMessage>? RichContent { get; set; }
/// <summary>
/// Stop conversation completion

View file

@ -0,0 +1,6 @@
namespace BotSharp.Abstraction.Messaging;
public interface IRichMessage
{
string Text { get; set; }
}

View file

@ -0,0 +1,7 @@
namespace BotSharp.Abstraction.Messaging;
public interface ITemplateMessage
{
[JsonPropertyName("template_type")]
string TemplateType => string.Empty;
}

View file

@ -1,6 +0,0 @@
namespace BotSharp.Abstraction.Messaging.Models;
public interface IMessageTemplate
{
string Text { get; set; }
}

View file

@ -0,0 +1,15 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
public class ElementAction
{
public string Type { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Url { get; set; }
[JsonPropertyName("webview_height_ratio")]
public string WebViewHeightRatio { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Payload { get; set; }
}

View file

@ -0,0 +1,17 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
/// <summary>
/// https://developers.facebook.com/docs/messenger-platform/send-messages/buttons
/// </summary>
public class ElementButton
{
public string Type { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Url { get; set; }
public string Title { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Payload { get; set; }
}

View file

@ -4,11 +4,12 @@ namespace BotSharp.Abstraction.Messaging.Models.RichContent
public class QuickReplyElement
{
[JsonPropertyName("content_type")]
public string ContentType { get; set; } = string.Empty;
public string ContentType { get; set; } = "text";
public string Title { get; set; } = string.Empty;
public string? Payload { get; set; }
[JsonPropertyName("image_url")]
public string? ImageUrl { get; set; }
public string? PostBackUrl { get; set; }
}
}

View file

@ -1,7 +1,6 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent
{
public class QuickReplyMessage : IMessageTemplate
public class QuickReplyMessage : IRichMessage
{
public string Text { get; set; } = string.Empty;

View file

@ -1,6 +1,6 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent
{
public class RichContent<T> where T : IMessageTemplate
public class RichContent<T> where T : IRichMessage
{
public Recipient Recipient { get; set; } = new Recipient();
/// <summary>

View file

@ -1,7 +1,6 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
{
public class ButtonTemplate : IMessageTemplate
public class ButtonTemplateMessage : IRichMessage
{
public string Text { get; set; } = string.Empty;

View file

@ -1,10 +0,0 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
{
public class CommonTemplate<T>
{
[JsonPropertyName("template_type")]
public string TemplateType { get; set; } = string.Empty;
public T Elements { get; set; }
}
}

View file

@ -0,0 +1,34 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template;
/// <summary>
/// Coupon Template
/// https://developers.facebook.com/docs/messenger-platform/send-messages/template/coupon
/// </summary>
public class CouponTemplateMessage : IRichMessage, ITemplateMessage
{
[JsonIgnore]
public string Text { get; set; }
public string Title { get; set; }
public string Subtitle { get; set; }
[JsonPropertyName("template_type")]
public string TemplateType => "coupon";
[JsonPropertyName("coupon_code")]
public string CouponCode { get; set; }
[JsonPropertyName("coupon_url")]
public string CouponUrl { get; set; }
[JsonPropertyName("coupon_url_button_title")]
public string CouponUrlButtonTitle { get; set; } = "Shop now";
[JsonPropertyName("coupon_pre_message")]
public string CouponPreMessage { get; set; } = "Here's a deal just for you!";
[JsonPropertyName("image_url")]
public string ImageUrl { get; set; }
[JsonPropertyName("payload")]
public string Payload { get; set; }
}

View file

@ -0,0 +1,18 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template;
public class GenericTemplateMessage : TemplateMessageBase<GenericElement>, IRichMessage, ITemplateMessage
{
[JsonPropertyName("template_type")]
public override string TemplateType => "generic";
}
public class GenericElement
{
public string Title { get; set; }
public string Subtitle { get; set; }
[JsonPropertyName("image_url")]
public string ImageUrl { get; set; }
[JsonPropertyName("default_action")]
public ElementAction DefaultAction { get; set; }
public ElementButton[] Buttons { get; set; }
}

View file

@ -1,7 +1,6 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template
{
public class MultiSelectTemplate : IMessageTemplate
public class MultiSelectTemplateMessage : IRichMessage
{
public string Text { get; set; } = string.Empty;

View file

@ -0,0 +1,11 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent.Template;
public class ProductTemplateMessage : TemplateMessageBase<ProductElement>, IRichMessage
{
public override string TemplateType => "product";
}
public class ProductElement
{
public string Id { get; set; }
}

View file

@ -0,0 +1,12 @@
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; }
}
}

View file

@ -1,7 +1,11 @@
namespace BotSharp.Abstraction.Messaging.Models.RichContent;
public class TextMessage : IMessageTemplate
public class TextMessage : IRichMessage
{
public string Text { get; set; } = string.Empty;
public TextMessage(string text)
{
Text = text;
}
}

View file

@ -1,16 +0,0 @@
using System.Text.Json;
namespace BotSharp.Abstraction.Messaging.Models;
public class RichContentJsonConverter : JsonConverter<IMessageTemplate>
{
public override IMessageTemplate? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, IMessageTemplate value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, value.GetType(), options);
}
}

View file

@ -0,0 +1,16 @@
using System.Text.Json;
namespace BotSharp.Abstraction.Messaging;
public class RichContentJsonConverter : JsonConverter<IRichMessage>
{
public override IRichMessage? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, IRichMessage value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, value.GetType(), options);
}
}

View file

@ -0,0 +1,16 @@
using System.Text.Json;
namespace BotSharp.Abstraction.Messaging;
public class TemplateMessageJsonConverter : JsonConverter<ITemplateMessage>
{
public override ITemplateMessage? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, ITemplateMessage value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, value.GetType(), options);
}
}

View file

@ -1,5 +1,5 @@
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Messaging.Models;
using BotSharp.Abstraction.Messaging;
using BotSharp.Abstraction.Messaging.Models.RichContent;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
@ -104,7 +104,7 @@ public partial class ConversationService
// Process rich content
if (response.RichContent != null &&
response.RichContent is RichContent<IMessageTemplate> template &&
response.RichContent is RichContent<IRichMessage> template &&
string.IsNullOrEmpty(template.Message.Text))
{
template.Message.Text = response.Content;
@ -112,10 +112,10 @@ public partial class ConversationService
// Only read content from RichContent for UI rendering. When richContent is null, create a basic text message for richContent.
var state = _services.GetRequiredService<IConversationStateService>();
response.RichContent = response.RichContent ?? new RichContent<IMessageTemplate>
response.RichContent = response.RichContent ?? new RichContent<IRichMessage>
{
Recipient = new Recipient { Id = state.GetConversationId() },
Message = new TextMessage { Text = response.Content }
Message = new TextMessage(response.Content)
};
var hooks = _services.GetServices<IConversationHook>().ToList();

View file

@ -5,7 +5,7 @@
<LangVersion>$(LangVersion)</LangVersion>
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<GenerateDocumentationFile>GenerateDocumentationFile</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>

View file

@ -1,21 +1,7 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Conversations;
using BotSharp.Plugin.MetaMessenger.GraphAPIs;
using BotSharp.Plugin.MetaMessenger.MessagingModels;
using BotSharp.Plugin.MetaMessenger.Settings;
using BotSharp.Plugin.MetaMessenger.WebhookModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Refit;
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.MetaMessenger.Controllers;
@ -41,7 +27,7 @@ public class WebhookController : ControllerBase
[FromQuery(Name = "hub.challenge")] string challenge,
[FromRoute] string agentId)
{
Console.WriteLine(agentId);
Console.WriteLine($"Verificate {mode} {token} {challenge} {agentId}");
return challenge;
}
@ -64,103 +50,32 @@ public class WebhookController : ControllerBase
// https://developers.facebook.com/docs/messenger-platform/webhooks#verification-requests
try
{
string senderId = "";
string message = "";
// received message
if (req.Entry[0].Messaging[0].Message != null)
{
var reply = new QuickReplyMessage();
var senderId = req.Entry[0].Messaging[0].Sender.Id;
var input = req.Entry[0].Messaging[0].Message.Text;
var setting = _services.GetRequiredService<MetaMessengerSetting>();
var messenger = _services.GetRequiredService<IMessengerGraphAPI>();
var jsonOpt = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
var recipient = JsonSerializer.Serialize(new { Id = senderId }, jsonOpt);
// Marking seen
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = recipient,
SenderAction = SenderActionEnum.MarkSeen
});
// Typing on
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = recipient,
SenderAction = SenderActionEnum.TypingOn
});
// Go to LLM
var conv = _services.GetRequiredService<IConversationService>();
conv.SetConversationId(senderId, new List<string>
{
"channel=messenger"
});
var result = await conv.SendMessage(agentId, new RoleDialogModel("user", input), async msg =>
{
reply.Text = msg.Content;
}, async functionExecuting =>
{
/*await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt),
Message = JsonSerializer.Serialize(new { Text = "I'm pulling the relevent information, please wait a second ..." }, jsonOpt)
});*/
}, async functionExecuted =>
{
// Render structured data
if (functionExecuted.Data != null)
{
// validate data format
var json = JsonSerializer.Serialize(functionExecuted.Data, jsonOpt);
try
{
var parsed = JsonSerializer.Deserialize<QuickReplyMessageItem[]>(json, jsonOpt);
if (parsed.Length > 0)
{
reply.QuickReplies = parsed;
}
}
catch(Exception ex)
{
_logger.LogError(ex, ex.Message);
}
}
});
// Response to user
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = recipient,
Message = JsonSerializer.Serialize(reply, jsonOpt)
});
// Typing off
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = recipient,
SenderAction = SenderActionEnum.TypingOff
});
senderId = req.Entry[0].Messaging[0].Sender.Id;
message = req.Entry[0].Messaging[0].Message.Text;
}
else if (req.Entry[0].Messaging[0].Postback != null)
{
senderId = req.Entry[0].Messaging[0].Sender.Id;
message = req.Entry[0].Messaging[0].Postback.Payload;
}
var handler = _services.GetRequiredService<MessageHandleService>();
await handler.Handle(senderId, agentId, message);
}
catch (ApiException ex)
{
Console.WriteLine(ex.Content);
_logger.LogError(ex.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
_logger.LogError(ex.ToString());
}
return Ok(new WebhookResponse

View file

@ -1,11 +1,5 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using BotSharp.Plugin.MetaMessenger.Settings;
namespace BotSharp.Plugin.MetaMessenger.GraphAPIs;

View file

@ -1,9 +1,4 @@
using BotSharp.Plugin.MetaMessenger.MessagingModels;
using Refit;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace BotSharp.Plugin.MetaMessenger.GraphAPIs;

View file

@ -1,5 +0,0 @@
namespace BotSharp.Plugin.MetaMessenger.Interfaces;
public interface IResponseMessage
{
}

View file

@ -1,11 +0,0 @@
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
public class AttachementPayload
{
[JsonPropertyName("template_type")]
public string TemplateType { get; set; }
public string Text { get; set; }
public ButtonItem[] Buttons { get; set; }
}

View file

@ -2,6 +2,7 @@ namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
public class AttachmentBody
{
[JsonPropertyName("type")]
public string Type { get; set; } = "template";
public AttachementPayload Payload { get; set; }
public ITemplateMessage Payload { get; set; }
}

View file

@ -1,13 +1,13 @@
using BotSharp.Plugin.MetaMessenger.Interfaces;
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
/// <summary>
/// https://developers.facebook.com/docs/messenger-platform/send-messages/templates
/// </summary>
public class TemplateMessage : IResponseMessage
public class AttachmentMessage : IRichMessage
{
[JsonIgnore]
public string Text { get; set; }
[JsonPropertyName("attachment")]
public AttachmentBody Attachment { get; set; }
}

View file

@ -1,18 +0,0 @@
using BotSharp.Plugin.MetaMessenger.Interfaces;
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
/// <summary>
/// Quick Replies
/// https://developers.facebook.com/docs/messenger-platform/send-messages/quick-replies
/// </summary>
public class QuickReplyMessage : IResponseMessage
{
[JsonPropertyName("text")]
public string Text { get; set; }
[JsonPropertyName("quick_replies")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public QuickReplyMessageItem[]? QuickReplies { get; set; }
}

View file

@ -1,18 +0,0 @@
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
public class QuickReplyMessageItem
{
[JsonPropertyName("content_type")]
public string ContentType { get; set; } = "text";
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("payload")]
public string Payload { get; set; }
[JsonPropertyName("image_url")]
public string ImageUrl { get; set; }
}

View file

@ -1,5 +1,3 @@
using System.Runtime.Serialization;
namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
public enum SenderActionEnum

View file

@ -27,4 +27,10 @@ public class SendingMessageRequest
[AliasAs("sender_action")]
public SenderActionEnum? SenderAction { get; set; }
public SendingMessageRequest(string token, string recipient)
{
AccessToken = token;
Recipient = recipient;
}
}

View file

@ -1,8 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
public class SendingMessageResponse

View file

@ -1,13 +1,4 @@
using BotSharp.Abstraction.Plugins;
using BotSharp.Plugin.MetaMessenger.GraphAPIs;
using BotSharp.Plugin.MetaMessenger.Settings;
using BotSharp.Abstraction.Utilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Refit;
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger;
@ -35,6 +26,8 @@ public class MetaMessengerPlugin : IBotSharpPlugin
var setting = sp.GetRequiredService<MetaMessengerSetting>();
c.BaseAddress = new Uri($"{setting.Endpoint}");
});
//.AddHttpMessageHandler<AuthHeaderHandler>();
//.AddHttpMessageHandler<AuthHeaderHandler>();
services.AddScoped<MessageHandleService>();
}
}

View file

@ -0,0 +1,107 @@
using BotSharp.Abstraction.Messaging.Models.RichContent;
namespace BotSharp.Plugin.MetaMessenger.Services;
public class MessageHandleService
{
private readonly IServiceProvider _services;
private JsonSerializerOptions _serializerOptions;
public MessageHandleService(IServiceProvider services)
{
_services = services;
_serializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters =
{
new RichContentJsonConverter(),
new TemplateMessageJsonConverter()
}
};
}
public async Task Handle(string sender, string agentId, string message)
{
var setting = _services.GetRequiredService<MetaMessengerSetting>();
var messenger = _services.GetRequiredService<IMessengerGraphAPI>();
var recipient = JsonSerializer.Serialize(new { Id = sender }, _serializerOptions);
// Marking seen
await messenger.SendMessage(setting.ApiVersion, setting.PageId,
new SendingMessageRequest(setting.PageAccessToken, recipient)
{
SenderAction = SenderActionEnum.MarkSeen
});
// Typing on
await messenger.SendMessage(setting.ApiVersion, setting.PageId,
new SendingMessageRequest(setting.PageAccessToken, recipient)
{
SenderAction = SenderActionEnum.TypingOn
});
// Go to LLM
var conv = _services.GetRequiredService<IConversationService>();
conv.SetConversationId(sender, new List<string>
{
"channel=messenger"
});
var replies = new List<IRichMessage>();
var result = await conv.SendMessage(agentId, new RoleDialogModel("user", message), async msg =>
{
if (!string.IsNullOrEmpty(msg.Content))
{
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);
// Response to user
foreach(var reply in replies)
{
await messenger.SendMessage(setting.ApiVersion, setting.PageId,
new SendingMessageRequest(setting.PageAccessToken, recipient)
{
Message = JsonSerializer.Serialize(reply, _serializerOptions)
});
Thread.Sleep(500);
}
// Typing off
await messenger.SendMessage(setting.ApiVersion, setting.PageId,
new SendingMessageRequest(setting.PageAccessToken, recipient)
{
SenderAction = SenderActionEnum.TypingOff
});
}
}

View file

@ -0,0 +1,22 @@
global using System;
global using System.IO;
global using System.Text.Json;
global using System.Threading;
global using System.Threading.Tasks;
global using System.Collections.Generic;
global using System.Runtime.Serialization;
global using System.Text.Json.Serialization;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Configuration;
global using BotSharp.Abstraction.Plugins;
global using BotSharp.Plugin.MetaMessenger.GraphAPIs;
global using BotSharp.Plugin.MetaMessenger.Settings;
global using BotSharp.Abstraction.Utilities;
global using BotSharp.Plugin.MetaMessenger.Services;
global using BotSharp.Plugin.MetaMessenger.WebhookModels;
global using BotSharp.Plugin.MetaMessenger.MessagingModels;
global using BotSharp.Abstraction.Messaging;
global using BotSharp.Abstraction.Conversations.Models;
global using BotSharp.Abstraction.Conversations;
global using BotSharp.Abstraction.Messaging.Models.RichContent.Template;

View file

@ -5,5 +5,6 @@ public class WebhookMessage
public WebhookMessageUser Sender { get; set; }
public WebhookMessageUser Recipient { get; set; }
public WebhookMessageBody Message { get; set; }
public WebhookMessagePostback Postback { get; set; }
public long TimeStamp { get; set; }
}

View file

@ -1,8 +1,4 @@
using BotSharp.Plugin.MetaMessenger.MessagingModels;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
using BotSharp.Abstraction.Messaging.Models.RichContent;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
@ -10,7 +6,11 @@ public class WebhookMessageBody
{
[JsonPropertyName("mid")]
public string Id { get;set; }
[JsonPropertyName("text")]
public string Text { get;set; }
[JsonPropertyName("quick_reply")]
public QuickReplyMessageItem QuickReply { get;set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public QuickReplyMessage QuickReply { get;set; }
}

View file

@ -0,0 +1,10 @@
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookMessagePostback
{
public string Title { get; set; }
public string Payload { get; set; }
[JsonPropertyName("mid")]
public string Id { get; set; }
}

View file

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookMessageUser

View file

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookObject

View file

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookRequest

View file

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookResponse

View file

@ -1,3 +1,4 @@
using BotSharp.Abstraction.Messaging;
using BotSharp.Abstraction.Users;
using BotSharp.Core;
using BotSharp.Core.Users.Services;
@ -8,7 +9,12 @@ using System.Text;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new RichContentJsonConverter());
options.JsonSerializerOptions.Converters.Add(new TemplateMessageJsonConverter());
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();