Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions BotSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down
37 changes: 31 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
19 changes: 19 additions & 0 deletions src/Plugins/BotSharp.Plugin.Twilio/BotSharp.Plugin.Twilio.csproj
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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;
}
}
9 changes: 9 additions & 0 deletions src/Plugins/BotSharp.Plugin.Twilio/Settings/TwilioSetting.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
16 changes: 16 additions & 0 deletions src/Plugins/BotSharp.Plugin.Twilio/TwilioPlugin.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
17 changes: 17 additions & 0 deletions src/Plugins/BotSharp.Plugin.Twilio/Using.cs
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions src/WebStarter/WebStarter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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>
8 changes: 8 additions & 0 deletions src/WebStarter/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@
"PageAccessToken": ""
},

"Twilio": {
"PhoneNumber": "+1",
"AccountSID": "",
"AuthToken": "",
"CallbackHost": "https://"
},

"Database": {
"Default": "FileRepository",
"TablePrefix": "BotSharp",
Expand Down Expand Up @@ -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",
Expand Down