Skip to content

Commit 84ae258

Browse files
authored
Merge pull request #610 from hchen2020/master
fix bug of twilio
2 parents 74da640 + 91a221a commit 84ae258

File tree

4 files changed

+59
-46
lines changed

4 files changed

+59
-46
lines changed

src/Infrastructure/BotSharp.Logger/Hooks/RateLimitConversationHook.cs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BotSharp.Abstraction.Agents.Enums;
2+
using BotSharp.Abstraction.Conversations.Enums;
23
using BotSharp.Abstraction.Repositories.Filters;
34
using BotSharp.Abstraction.Users;
45

@@ -47,20 +48,26 @@ public override async Task OnMessageReceived(RoleDialogModel message)
4748
}
4849
}
4950

51+
var states = _services.GetRequiredService<IConversationStateService>();
52+
var channel = states.GetState("channel");
53+
5054
// Check the number of conversations
51-
var user = _services.GetRequiredService<IUserIdentity>();
52-
var convService = _services.GetRequiredService<IConversationService>();
53-
var results = await convService.GetConversations(new ConversationFilter
55+
if (channel != ConversationChannel.Phone && channel != ConversationChannel.Email)
5456
{
55-
UserId = user.Id,
56-
StartTime = DateTime.UtcNow.AddHours(-24),
57-
});
57+
var user = _services.GetRequiredService<IUserIdentity>();
58+
var convService = _services.GetRequiredService<IConversationService>();
59+
var results = await convService.GetConversations(new ConversationFilter
60+
{
61+
UserId = user.Id,
62+
StartTime = DateTime.UtcNow.AddHours(-24),
63+
});
5864

59-
if (results.Count > rateLimit.MaxConversationPerDay)
60-
{
61-
message.Content = $"The number of conversations you have exceeds the system maximum of {rateLimit.MaxConversationPerDay}";
62-
message.StopCompletion = true;
63-
return;
65+
if (results.Count > rateLimit.MaxConversationPerDay)
66+
{
67+
message.Content = $"The number of conversations you have exceeds the system maximum of {rateLimit.MaxConversationPerDay}";
68+
message.StopCompletion = true;
69+
return;
70+
}
6471
}
6572
}
6673
}

src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using BotSharp.Plugin.Twilio.Services;
55
using Microsoft.AspNetCore.Http;
66
using Microsoft.AspNetCore.Mvc;
7+
using Twilio.Http;
78

89
namespace BotSharp.Plugin.Twilio.Controllers;
910

@@ -35,7 +36,7 @@ public TwiMLResult InitiateConversation(VoiceRequest request, [FromQuery] string
3536
string conversationId = $"TwilioVoice_{request.CallSid}";
3637
var twilio = _services.GetRequiredService<TwilioService>();
3738
var url = $"twilio/voice/{conversationId}/receive/0?states={states}";
38-
var response = twilio.ReturnInstructions("twilio/welcome.mp3", url, true);
39+
var response = twilio.ReturnInstructions(new List<string> { "twilio/welcome.mp3" }, url, true);
3940
return TwiML(response);
4041
}
4142

@@ -53,17 +54,10 @@ public async Task<TwiMLResult> ReceiveCallerMessage([FromRoute] string conversat
5354
messages.Add(text);
5455
await sessionManager.StageCallerMessageAsync(conversationId, seqNum, text);
5556
}
57+
5658
VoiceResponse response;
57-
if (messages.Count == 0 && seqNum == 0)
58-
{
59-
response = twilio.ReturnInstructions("twilio/welcome.mp3", $"twilio/voice/{conversationId}/receive/{seqNum}?states={states}", true, timeout: 2);
60-
}
61-
else
59+
if (messages.Any())
6260
{
63-
if (messages.Count == 0)
64-
{
65-
messages = await sessionManager.RetrieveStagedCallerMessagesAsync(conversationId, seqNum - 1);
66-
}
6761
var messageContent = string.Join("\r\n", messages);
6862
var callerMessage = new CallerMessage()
6963
{
@@ -82,15 +76,21 @@ public async Task<TwiMLResult> ReceiveCallerMessage([FromRoute] string conversat
8276
}
8377
await messageQueue.EnqueueAsync(callerMessage);
8478

85-
int audioIndex = Random.Shared.Next(1, 5);
86-
response = twilio.ReturnInstructions($"twilio/hold-on-{audioIndex}.mp3", $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}", true, 1);
79+
response = new VoiceResponse()
80+
.Redirect(new Uri($"{_settings.CallbackHost}/twilio/voice/{conversationId}/reply/{seqNum}?states={states}"), HttpMethod.Post);
81+
}
82+
else
83+
{
84+
response = twilio.ReturnInstructions(null, $"twilio/voice/{conversationId}/receive/{seqNum}?states={states}", true);
8785
}
86+
8887
return TwiML(response);
8988
}
9089

9190
[ValidateRequest]
9291
[HttpPost("twilio/voice/{conversationId}/reply/{seqNum}")]
93-
public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversationId, [FromRoute] int seqNum, [FromQuery] string states, VoiceRequest request)
92+
public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversationId, [FromRoute] int seqNum,
93+
[FromQuery] string states, [FromQuery] string play, VoiceRequest request)
9494
{
9595
var nextSeqNum = seqNum + 1;
9696
var sessionManager = _services.GetRequiredService<ITwilioSessionManager>();
@@ -106,25 +106,33 @@ public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversatio
106106
var indication = await sessionManager.GetReplyIndicationAsync(conversationId, seqNum);
107107
if (indication != null)
108108
{
109-
string speechPath;
110-
if (indication.StartsWith('#'))
109+
var speechPaths = new List<string>();
110+
foreach (var text in indication.Split('|'))
111111
{
112-
speechPath = $"twilio/{indication.Substring(1)}";
112+
var seg = text.Trim();
113+
if (seg.StartsWith('#'))
114+
{
115+
speechPaths.Add($"twilio/{seg.Substring(1)}.mp3");
116+
}
117+
else
118+
{
119+
var textToSpeechService = CompletionProvider.GetTextToSpeech(_services, "openai", "tts-1");
120+
var fileService = _services.GetRequiredService<IFileStorageService>();
121+
var data = await textToSpeechService.GenerateSpeechFromTextAsync(seg);
122+
var fileName = $"indication_{seqNum}.mp3";
123+
await fileService.SaveSpeechFileAsync(conversationId, fileName, data);
124+
speechPaths.Add($"twilio/voice/speeches/{conversationId}/{fileName}");
125+
}
113126
}
114-
else
115-
{
116-
var textToSpeechService = CompletionProvider.GetTextToSpeech(_services, "openai", "tts-1");
117-
var fileService = _services.GetRequiredService<IFileStorageService>();
118-
var data = await textToSpeechService.GenerateSpeechFromTextAsync(indication);
119-
var fileName = $"indication_{seqNum}.mp3";
120-
await fileService.SaveSpeechFileAsync(conversationId, fileName, data);
121-
speechPath = $"twilio/voice/speeches/{conversationId}/{fileName}";
122-
}
123-
response = twilio.ReturnInstructions(speechPath, $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}", true, 2);
127+
response = twilio.ReturnInstructions(speechPaths, $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}", true);
124128
}
125129
else
126130
{
127-
response = twilio.ReturnInstructions(null, $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}", true, 1);
131+
response = twilio.ReturnInstructions(new List<string>
132+
{
133+
$"twilio/hold-on-{Random.Shared.Next(1, 5)}.mp3",
134+
$"twilio/typing-{Random.Shared.Next(2, 4)}.mp3"
135+
}, $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}", true);
128136
}
129137
}
130138
else
@@ -135,7 +143,7 @@ public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversatio
135143
}
136144
else
137145
{
138-
response = twilio.ReturnInstructions($"twilio/voice/speeches/{conversationId}/{reply.SpeechFileName}", $"twilio/voice/{conversationId}/receive/{nextSeqNum}?states={states}", true);
146+
response = twilio.ReturnInstructions(new List<string> { $"twilio/voice/speeches/{conversationId}/{reply.SpeechFileName}" }, $"twilio/voice/{conversationId}/receive/{nextSeqNum}?states={states}", true);
139147
}
140148

141149
}

src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private async Task ProcessUserMessageAsync(CallerMessage message)
8282
{
8383
reply = new AssistantMessage()
8484
{
85-
ConversationEnd = msg.Instruction.ConversationEnd,
85+
ConversationEnd = msg.Instruction?.ConversationEnd ?? false,
8686
Content = msg.Content,
8787
MessageId = msg.MessageId
8888
};

src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public VoiceResponse ReturnInstructions(string message)
6464
return response;
6565
}
6666

67-
public VoiceResponse ReturnInstructions(string speechPath, string callbackPath, bool actionOnEmptyResult, int timeout = 3)
67+
public VoiceResponse ReturnInstructions(List<string> speechPaths, string callbackPath, bool actionOnEmptyResult, int timeout = 2)
6868
{
6969
var response = new VoiceResponse();
7070
var gather = new Gather()
@@ -80,13 +80,11 @@ public VoiceResponse ReturnInstructions(string speechPath, string callbackPath,
8080
Timeout = timeout > 0 ? timeout : 3,
8181
ActionOnEmptyResult = actionOnEmptyResult
8282
};
83-
if (!string.IsNullOrEmpty(speechPath))
83+
if (speechPaths != null && speechPaths.Any())
8484
{
85-
gather.Play(new Uri($"{_settings.CallbackHost}/{speechPath}"));
86-
if (speechPath.Contains("hold-on-"))
85+
foreach (var speechPath in speechPaths)
8786
{
88-
int audioIndex = Random.Shared.Next(1, 4);
89-
gather.Play(new Uri($"{_settings.CallbackHost}/twilio/typing-{audioIndex}.mp3"));
87+
gather.Play(new Uri($"{_settings.CallbackHost}/{speechPath}"));
9088
}
9189
}
9290
response.Append(gather);

0 commit comments

Comments
 (0)