Messenger platform.

This commit is contained in:
hchen 2023-08-04 17:07:44 -05:00
parent 0547d13799
commit 67de32b07c
18 changed files with 338 additions and 25 deletions

View file

@ -25,8 +25,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.HuggingFace
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.ChatbotUI", "src\Plugins\BotSharp.Plugin.ChatbotUI\BotSharp.Plugin.ChatbotUI.csproj", "{68C7C9E9-496B-4004-A1F8-75FFB8C06C76}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.ChatbotUI", "src\Plugins\BotSharp.Plugin.ChatbotUI\BotSharp.Plugin.ChatbotUI.csproj", "{68C7C9E9-496B-4004-A1F8-75FFB8C06C76}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.FacebookMessenger", "src\Plugins\BotSharp.Plugin.FacebookMessenger\BotSharp.Plugin.FacebookMessenger.csproj", "{0149F6C2-4CF8-4904-A545-54F3278BEA74}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.WeChat", "src\Plugins\BotSharp.Plugin.WeChat\BotSharp.Plugin.WeChat.csproj", "{2323A7A3-E938-488D-A57E-638638054BC4}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.WeChat", "src\Plugins\BotSharp.Plugin.WeChat\BotSharp.Plugin.WeChat.csproj", "{2323A7A3-E938-488D-A57E-638638054BC4}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}"
@ -43,6 +41,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Visions", "Visions", "{B797
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.PaddleSharp", "src\Plugins\BotSharp.Plugin.PaddleSharp\BotSharp.Plugin.PaddleSharp.csproj", "{0308FBFD-57EB-4709-9AE4-A80D516AD84D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.PaddleSharp", "src\Plugins\BotSharp.Plugin.PaddleSharp\BotSharp.Plugin.PaddleSharp.csproj", "{0308FBFD-57EB-4709-9AE4-A80D516AD84D}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.MetaMessenger", "src\Plugins\BotSharp.Plugin.MetaMessenger\BotSharp.Plugin.MetaMessenger.csproj", "{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -125,18 +125,6 @@ Global
{68C7C9E9-496B-4004-A1F8-75FFB8C06C76}.Release|Any CPU.Build.0 = Release|Any CPU {68C7C9E9-496B-4004-A1F8-75FFB8C06C76}.Release|Any CPU.Build.0 = Release|Any CPU
{68C7C9E9-496B-4004-A1F8-75FFB8C06C76}.Release|x64.ActiveCfg = Release|Any CPU {68C7C9E9-496B-4004-A1F8-75FFB8C06C76}.Release|x64.ActiveCfg = Release|Any CPU
{68C7C9E9-496B-4004-A1F8-75FFB8C06C76}.Release|x64.Build.0 = Release|Any CPU {68C7C9E9-496B-4004-A1F8-75FFB8C06C76}.Release|x64.Build.0 = Release|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.Debug|x64.ActiveCfg = Debug|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.Debug|x64.Build.0 = Debug|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.GPU|Any CPU.ActiveCfg = Release|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.GPU|Any CPU.Build.0 = Release|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.GPU|x64.ActiveCfg = Release|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.GPU|x64.Build.0 = Release|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.Release|Any CPU.Build.0 = Release|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.Release|x64.ActiveCfg = Release|Any CPU
{0149F6C2-4CF8-4904-A545-54F3278BEA74}.Release|x64.Build.0 = Release|Any CPU
{2323A7A3-E938-488D-A57E-638638054BC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2323A7A3-E938-488D-A57E-638638054BC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2323A7A3-E938-488D-A57E-638638054BC4}.Debug|Any CPU.Build.0 = Debug|Any CPU {2323A7A3-E938-488D-A57E-638638054BC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2323A7A3-E938-488D-A57E-638638054BC4}.Debug|x64.ActiveCfg = Debug|Any CPU {2323A7A3-E938-488D-A57E-638638054BC4}.Debug|x64.ActiveCfg = Debug|Any CPU
@ -197,6 +185,18 @@ Global
{0308FBFD-57EB-4709-9AE4-A80D516AD84D}.Release|Any CPU.Build.0 = Release|Any CPU {0308FBFD-57EB-4709-9AE4-A80D516AD84D}.Release|Any CPU.Build.0 = Release|Any CPU
{0308FBFD-57EB-4709-9AE4-A80D516AD84D}.Release|x64.ActiveCfg = Release|Any CPU {0308FBFD-57EB-4709-9AE4-A80D516AD84D}.Release|x64.ActiveCfg = Release|Any CPU
{0308FBFD-57EB-4709-9AE4-A80D516AD84D}.Release|x64.Build.0 = Release|Any CPU {0308FBFD-57EB-4709-9AE4-A80D516AD84D}.Release|x64.Build.0 = Release|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.Debug|x64.ActiveCfg = Debug|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.Debug|x64.Build.0 = Debug|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.GPU|Any CPU.Build.0 = Debug|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.GPU|x64.ActiveCfg = Debug|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.GPU|x64.Build.0 = Debug|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.Release|Any CPU.Build.0 = Release|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.Release|x64.ActiveCfg = Release|Any CPU
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -210,7 +210,6 @@ Global
{3EAB9CF3-0F47-4BFB-8BAC-8ADFF24AD899} = {D5293208-2BEF-42FC-A64C-5954F61720BA} {3EAB9CF3-0F47-4BFB-8BAC-8ADFF24AD899} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
{57806BAF-7736-425A-B499-13A2A2DF1E63} = {D5293208-2BEF-42FC-A64C-5954F61720BA} {57806BAF-7736-425A-B499-13A2A2DF1E63} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
{68C7C9E9-496B-4004-A1F8-75FFB8C06C76} = {42226933-0A0D-48E8-85EC-AFE773A1F841} {68C7C9E9-496B-4004-A1F8-75FFB8C06C76} = {42226933-0A0D-48E8-85EC-AFE773A1F841}
{0149F6C2-4CF8-4904-A545-54F3278BEA74} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00}
{2323A7A3-E938-488D-A57E-638638054BC4} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00} {2323A7A3-E938-488D-A57E-638638054BC4} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00}
{0B6E1D7F-ABDE-47F6-8B2D-4483C2CFF2D6} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC} {0B6E1D7F-ABDE-47F6-8B2D-4483C2CFF2D6} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}
{6D8D18A9-86D7-455E-81EC-9682C30AB7E7} = {D5293208-2BEF-42FC-A64C-5954F61720BA} {6D8D18A9-86D7-455E-81EC-9682C30AB7E7} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
@ -218,6 +217,7 @@ Global
{FE2E6CC1-EB80-4518-B3A3-CB373EDA6A83} = {53E7CD86-0D19-40D9-A0FA-AB4613837E89} {FE2E6CC1-EB80-4518-B3A3-CB373EDA6A83} = {53E7CD86-0D19-40D9-A0FA-AB4613837E89}
{B797EC3E-B5B9-4047-A6C8-6D330B7C6763} = {2635EC9B-2E5F-4313-AC21-0B847F31F36C} {B797EC3E-B5B9-4047-A6C8-6D330B7C6763} = {2635EC9B-2E5F-4313-AC21-0B847F31F36C}
{0308FBFD-57EB-4709-9AE4-A80D516AD84D} = {B797EC3E-B5B9-4047-A6C8-6D330B7C6763} {0308FBFD-57EB-4709-9AE4-A80D516AD84D} = {B797EC3E-B5B9-4047-A6C8-6D330B7C6763}
{8300F66D-9EB8-438A-BF0F-70DFBE07D9DE} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}

View file

@ -10,6 +10,6 @@ public interface IConversationService
Task DeleteConversation(string id); Task DeleteConversation(string id);
Task<bool> SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, Func<RoleDialogModel, Task> onMessageReceived); Task<bool> SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, Func<RoleDialogModel, Task> onMessageReceived);
Task<bool> SendMessage(string agentId, string conversationId, List<RoleDialogModel> wholeDialogs, Func<RoleDialogModel, Task> onMessageReceived); Task<bool> SendMessage(string agentId, string conversationId, List<RoleDialogModel> wholeDialogs, Func<RoleDialogModel, Task> onMessageReceived);
List<RoleDialogModel> GetDialogHistory(string agentId, string conversationId); List<RoleDialogModel> GetDialogHistory(string agentId, string conversationId, int lastCount = 20);
Task CleanHistory(string agentId); Task CleanHistory(string agentId);
} }

View file

@ -170,8 +170,9 @@ public class ConversationService : IConversationService
throw new NotImplementedException(); throw new NotImplementedException();
} }
public List<RoleDialogModel> GetDialogHistory(string agentId, string conversationId) public List<RoleDialogModel> GetDialogHistory(string agentId, string conversationId, int lastCount = 20)
{ {
return _storage.GetDialogs(agentId, conversationId); var dialogs = _storage.GetDialogs(agentId, conversationId);
return dialogs.TakeLast(lastCount).ToList();
} }
} }

View file

@ -1,7 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>10</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Infrastructure\BotSharp.Abstraction\BotSharp.Abstraction.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Refit.HttpClientFactory" Version="7.0.0" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,98 @@
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;
namespace BotSharp.Plugin.MetaMessenger.Controllers;
/// <summary>
/// This controller is used to receive Wehbook from Messenger platform
/// https://developers.facebook.com/docs/graph-api/webhooks/
/// </summary>
[AllowAnonymous]
public class WebhookController : ControllerBase
{
private readonly IServiceProvider _services;
public WebhookController(IServiceProvider services)
{
_services = services;
}
[HttpGet("/webhook")]
public string Verificate([FromQuery(Name = "hub.mode")] string mode,
[FromQuery(Name = "hub.verify_token")] string token,
[FromQuery(Name = "hub.challenge")] string challenge)
{
return challenge;
}
/// <summary>
/// https://developers.facebook.com/docs/messenger-platform/webhooks
/// </summary>
/// <returns></returns>
[HttpPost("/webhook")]
public async Task<ActionResult<WebhookResponse>> Messages()
{
using var stream = new StreamReader(Request.Body);
var body = await stream.ReadToEndAsync();
var req = JsonSerializer.Deserialize<WebhookRequest>(body, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
});
// TODO validate request
// https://developers.facebook.com/docs/messenger-platform/webhooks#verification-requests
try
{
// received message
if (req.Entry[0].Messaging[0].Message != null)
{
var conv = _services.GetRequiredService<IConversationService>();
string content = "";
var sessionId = req.Entry[0].Messaging[0].Sender.Id;
var input = req.Entry[0].Messaging[0].Message.Text;
var result = await conv.SendMessage("", sessionId, new RoleDialogModel("user", input), async msg =>
{
content = msg.Content;
});
var setting = _services.GetRequiredService<MetaMessengerSetting>();
var messenger = _services.GetRequiredService<IMessengerGraphAPI>();
var jsonOpt = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt),
Message = JsonSerializer.Serialize(new { Text = content }, jsonOpt)
});
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return Ok(new WebhookResponse
{
Success = true
});
}
}

View file

@ -0,0 +1,30 @@
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;
public class AuthHeaderHandler : DelegatingHandler
{
private readonly IHttpContextAccessor _context;
private readonly MetaMessengerSetting _settings;
public AuthHeaderHandler(IHttpContextAccessor context,
MetaMessengerSetting settings)
{
_context = context;
_settings = settings;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// request.Headers.Add("Authorization", _settings.PageAccessToken);
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
}

View file

@ -0,0 +1,20 @@
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;
public interface IMessengerGraphAPI
{
/// <summary>
/// https://developers.facebook.com/docs/messenger-platform/reference/send-api
/// </summary>
/// <example>
/// /v17.0/104435566084134/messages?recipient={'id':'6610279455689235'}&messaging_type=RESPONSE&message={'text':'hello,world'}&access_token=
/// </example>
[Post("/{apiVer}/{pageId}/messages")]
Task<SendingMessageResponse> SendMessage(string apiVer, string pageId, [Query] SendingMessageRequest request);
}

View file

@ -0,0 +1,27 @@
using Refit;
namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
/// <summary>
/// https://developers.facebook.com/docs/messenger-platform/reference/send-api#parameters
/// </summary>
public class SendingMessageRequest
{
/// <example>
/// {'id':'6610279455689235'}
/// </example>
[AliasAs("recipient")]
public string Recipient { get; set; }
/// <example>
/// {'text':'hello,world'}
/// </example>
[AliasAs("message")]
public string Message { get; set; }
[AliasAs("access_token")]
public string AccessToken { get; set; }
[AliasAs("messaging_type")]
public string MessagingType { get; set; } = "RESPONSE";
}

View file

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.MetaMessenger.MessagingModels;
public class SendingMessageResponse
{
[JsonPropertyName("recipient_id")]
public string RecipientId { get; set; }
[JsonPropertyName("message_id")]
public string MessageId { get; set; }
}

View file

@ -0,0 +1,38 @@
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;
/// <summary>
/// https://developers.facebook.com/docs/messenger-platform/overview
/// </summary>
public class MetaMessengerPlugin : IBotSharpPlugin
{
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
var settings = new MetaMessengerSetting();
config.Bind("MetaMessenger", settings);
services.AddSingleton(x =>
{
Console.WriteLine($"Loaded MetaMessenger settings: {settings.Endpoint}/{settings.ApiVersion} {settings.PageId} {settings.PageAccessToken.SubstringMax(4)}");
return settings;
});
// services.AddScoped<AuthHeaderHandler>();
services.AddRefitClient<IMessengerGraphAPI>()
.ConfigureHttpClient((sp, c) =>
{
var setting = sp.GetRequiredService<MetaMessengerSetting>();
c.BaseAddress = new Uri($"{setting.Endpoint}");
});
//.AddHttpMessageHandler<AuthHeaderHandler>();
}
}

View file

@ -0,0 +1,9 @@
namespace BotSharp.Plugin.MetaMessenger.Settings;
public class MetaMessengerSetting
{
public string Endpoint { get; set; }
public string ApiVersion { get; set; }
public string PageId { get; set; }
public string PageAccessToken { get; set; }
}

View file

@ -0,0 +1,9 @@
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookMessage
{
public WebhookMessageUser Sender { get; set; }
public WebhookMessageUser Recipient { get; set; }
public WebhookMessageBody Message { get; set; }
public long TimeStamp { get; set; }
}

View file

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookMessageBody
{
[JsonPropertyName("mid")]
public string Id { get;set; }
public string Text { get;set; }
}

View file

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookMessageUser
{
public string Id { get; set; }
}

View file

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookObject
{
public string Id { get; set; }
public long Time { get; set; }
public List<WebhookMessage> Messaging { get; set; }
}

View file

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookRequest
{
public string Object { get;set; }
public List<WebhookObject> Entry { get;set; }
}

View file

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Plugin.MetaMessenger.WebhookModels;
public class WebhookResponse
{
public bool Success { get; set; }
}