Add Twilio plugin.

This commit is contained in:
hchen 2023-11-09 14:02:57 -06:00
parent ad606e6710
commit 74259ee6bc
9 changed files with 227 additions and 6 deletions

View file

@ -63,6 +63,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.MongoStorag
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.GoogleAI", "src\Plugins\BotSharp.Plugin.GoogleAI\BotSharp.Plugin.GoogleAI.csproj", "{8BC29F8A-78D6-422C-B522-10687ADC38ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.Twilio", "src\Plugins\BotSharp.Plugin.Twilio\BotSharp.Plugin.Twilio.csproj", "{E627F1E3-BE03-443A-83A2-86A855A278EB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -223,6 +225,14 @@ Global
{8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|Any CPU.Build.0 = Release|Any CPU
{8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|x64.ActiveCfg = Release|Any CPU
{8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|x64.Build.0 = Release|Any CPU
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Debug|x64.ActiveCfg = Debug|Any CPU
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Debug|x64.Build.0 = Debug|Any CPU
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Release|Any CPU.Build.0 = Release|Any CPU
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Release|x64.ActiveCfg = Release|Any CPU
{E627F1E3-BE03-443A-83A2-86A855A278EB}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -254,6 +264,7 @@ Global
{5CD330E1-9E5A-4112-8346-6E31CA98EF78} = {2635EC9B-2E5F-4313-AC21-0B847F31F36C}
{DB3DE37B-1208-4ED3-9615-A52AD0AAD69C} = {5CD330E1-9E5A-4112-8346-6E31CA98EF78}
{8BC29F8A-78D6-422C-B522-10687ADC38ED} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
{E627F1E3-BE03-443A-83A2-86A855A278EB} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}

View file

@ -39,14 +39,39 @@ It's written in C# running on .Net Core that is full cross-platform framework, t
```
2. Run UI project, reference to [Chatbot UI](src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md).
### Extension Libraries
### Plugins
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.
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:
* Chatbot UI connector.
* A channel module of BotSharp for Facebook Messenger.
* A channel module of BotSharp for Tencent Wechat.
* A channel module of BotSharp for Telegram.
#### Data Storages
- BotSharp.Plugin.MongoStorage
#### LLMs
- BotSharp.Plugin.AzureOpenAI
- BotSharp.Plugin.GoogleAI
- BotSharp.Plugin.MetaAI
- BotSharp.Plugin.HuggingFace
- BotSharp.Plugin.LLamaSharp
#### Messaging / Channel
- BotSharp.OpenAPI
- BotSharp.Plugin.MetaMessenger
- BotSharp.Plugin.Twilio
- BotSharp.Plugin.WeChat
#### RAGS
- BotSharp.Plugin.KnowledgeBase
- BotSharp.Plugin.Qdrant
#### Visions
- BotSharp.Plugin.PaddleSharp
#### Tools
- BotSharp.Plugin.RoutingSpeeder
- BotSharp.Plugin.PizzaBot
#### UIs
- BotSharp.Plugin.ChatbotUI
### Documents

View file

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>$(LangVersion)</LangVersion>
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Twilio.AspNet.Common" Version="8.0.2" />
<PackageReference Include="Twilio.AspNet.Core" Version="8.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Infrastructure\BotSharp.Abstraction\BotSharp.Abstraction.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,115 @@
using BotSharp.Abstraction.Conversations;
using BotSharp.Plugin.Twilio.Settings;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System;
using Twilio.AspNet.Common;
using Twilio.AspNet.Core;
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using BotSharp.Abstraction.Routing.Settings;
using Twilio.Http;
using Twilio.TwiML.Messaging;
using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Conversations.Models;
namespace BotSharp.Plugin.Twilio.Controllers;
[AllowAnonymous]
public class TwilioVoiceController : TwilioController
{
private readonly TwilioSetting _settings;
private readonly IServiceProvider _services;
public TwilioVoiceController(TwilioSetting settings, IServiceProvider services)
{
_settings = settings;
_services = services;
}
[HttpPost("/twilio/voice/welcome")]
public async Task<TwiMLResult> StartConversation(VoiceRequest request)
{
string sessionId = $"TwilioVoice_{request.CallSid}";
var response = ReturnInstructions("Hello, how may I help you?");
return TwiML(response);
}
[HttpPost("/twilio/voice/{agentId}")]
public async Task<TwiMLResult> ReceivedVoiceMessage([FromRoute] string agentId, VoiceRequest input)
{
string sessionId = $"TwilioVoice_{input.CallSid}";
var conv = _services.GetRequiredService<IConversationService>();
conv.SetConversationId(sessionId, new List<string>
{
"channel=phone",
$"calling_phone={input.DialCallSid}"
});
VoiceResponse response = default;
var result = await conv.SendMessage(agentId, new RoleDialogModel(AgentRole.User, input.SpeechResult), async msg =>
{
response = HangUp(msg.Content);
}, async functionExecuting =>
{
}, async functionExecuted =>
{
});
return TwiML(response);
}
private VoiceResponse ReturnInstructions(string message)
{
var routingSetting = _services.GetRequiredService<RoutingSettings>();
var response = new VoiceResponse();
var gather = new Gather()
{
Input = new List<Gather.InputEnum>()
{
Gather.InputEnum.Speech
},
Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}")
};
gather.Say(message);
response.Append(gather);
return response;
}
private VoiceResponse HangUp(string message)
{
var response = new VoiceResponse();
if (!string.IsNullOrEmpty(message))
{
response.Say(message);
}
response.Hangup();
return response;
}
private VoiceResponse HoldOn(int interval, string message = null)
{
var routingSetting = _services.GetRequiredService<RoutingSettings>();
var response = new VoiceResponse();
var gather = new Gather()
{
Input = new List<Gather.InputEnum>() { Gather.InputEnum.Speech },
Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}"),
ActionOnEmptyResult = true
};
if (!string.IsNullOrEmpty(message))
{
gather.Say(message);
}
gather.Pause(interval);
response.Append(gather);
return response;
}
}

View file

@ -0,0 +1,9 @@
namespace BotSharp.Plugin.Twilio.Settings;
public class TwilioSetting
{
public string PhoneNumber { get; set; }
public string AccountSID { get; set; }
public string AuthToken { get; set; }
public string CallbackHost { get; set; }
}

View file

@ -0,0 +1,16 @@
using BotSharp.Abstraction.Plugins;
using BotSharp.Plugin.Twilio.Settings;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace BotSharp.Plugin.Twilio;
public class TwilioPlugin : IBotSharpPlugin
{
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
var setting = new TwilioSetting();
config.Bind("Twilio", setting);
services.AddSingleton(setting);
}
}

View file

@ -0,0 +1,17 @@
global using System;
global using System.Collections.Generic;
global using System.Text;
global using System.Threading.Tasks;
global using System.Linq;
global using System.Text.Json;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.Logging;
global using BotSharp.Abstraction.Functions;
global using BotSharp.Abstraction.Functions.Models;
global using BotSharp.Abstraction.Agents.Enums;
global using BotSharp.Abstraction.Models;
global using BotSharp.Abstraction.Agents;
global using BotSharp.Abstraction.Conversations;
global using BotSharp.Abstraction.Plugins;
global using BotSharp.Abstraction.Conversations.Models;

View file

@ -63,6 +63,7 @@
<ItemGroup>
<ProjectReference Include="..\..\tests\BotSharp.Plugin.PizzaBot\BotSharp.Plugin.PizzaBot.csproj" />
<ProjectReference Include="..\Plugins\BotSharp.Plugin.Twilio\BotSharp.Plugin.Twilio.csproj" />
</ItemGroup>
</Project>

View file

@ -89,6 +89,13 @@
"PageAccessToken": ""
},
"Twilio": {
"PhoneNumber": "+1",
"AccountSID": "",
"AuthToken": "",
"CallbackHost": "https://"
},
"Database": {
"Default": "FileRepository",
"TablePrefix": "BotSharp",
@ -132,6 +139,7 @@
"BotSharp.Plugin.AzureOpenAI",
"BotSharp.Plugin.GoogleAI",
"BotSharp.Plugin.MetaAI",
// "BotSharp.Plugin.Twilio",
"BotSharp.Plugin.HuggingFace",
"BotSharp.Plugin.LLamaSharp",
"BotSharp.Plugin.KnowledgeBase",