diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs index 859e34ffe..8863d64e0 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs @@ -54,17 +54,24 @@ public async Task ReceiveCallerMessage([FromRoute] string conversat var twilio = _services.GetRequiredService(); var messageQueue = _services.GetRequiredService(); var sessionManager = _services.GetRequiredService(); - var url = $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}"; var messages = await sessionManager.RetrieveStagedCallerMessagesAsync(conversationId, seqNum); if (!string.IsNullOrWhiteSpace(request.SpeechResult)) { messages.Add(request.SpeechResult); + await sessionManager.StageCallerMessageAsync(conversationId, seqNum, request.SpeechResult); } - var messageContent = string.Join("\r\n", messages); VoiceResponse response; - if (!string.IsNullOrWhiteSpace(messageContent)) + if (messages.Count == 0 && seqNum == 0) + { + response = twilio.ReturnInstructions("twilio/welcome.mp3", $"twilio/voice/{conversationId}/receive/{seqNum}?states={states}", true); + } + else { - + if (messages.Count == 0) + { + messages = await sessionManager.RetrieveStagedCallerMessagesAsync(conversationId, seqNum - 1); + } + var messageContent = string.Join("\r\n", messages); var callerMessage = new CallerMessage() { ConversationId = conversationId, @@ -81,12 +88,7 @@ public async Task ReceiveCallerMessage([FromRoute] string conversat } } await messageQueue.EnqueueAsync(callerMessage); - response = twilio.ReturnInstructions(null, url, true, 1); - } - else - { - var speechPath = seqNum > 0 ? $"twilio/voice/speeches/{conversationId}/{seqNum - 1}.mp3" : "twilio/welcome.mp3"; - response = twilio.ReturnInstructions(speechPath, $"twilio/voice/{conversationId}/receive/{seqNum}?states={states}", true); + response = twilio.ReturnInstructions(null, $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}", true, 1); } return TwiML(response); } @@ -108,12 +110,21 @@ public async Task ReplyCallerMessage([FromRoute] string conversatio var indication = await sessionManager.GetReplyIndicationAsync(conversationId, seqNum); if (indication != null) { - var textToSpeechService = CompletionProvider.GetTextToSpeech(_services, "openai", "tts-1"); - var fileService = _services.GetRequiredService(); - var data = await textToSpeechService.GenerateSpeechFromTextAsync(indication); - var fileName = $"indication_{seqNum}.mp3"; - await fileService.SaveSpeechFileAsync(conversationId, fileName, data); - response = twilio.ReturnInstructions($"twilio/voice/speeches/{conversationId}/{fileName}", $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}", true, 2); + string speechPath; + if (indication.StartsWith('#')) + { + speechPath = $"twilio/{indication.Substring(1)}"; + } + else + { + var textToSpeechService = CompletionProvider.GetTextToSpeech(_services, "openai", "tts-1"); + var fileService = _services.GetRequiredService(); + var data = await textToSpeechService.GenerateSpeechFromTextAsync(indication); + var fileName = $"indication_{seqNum}.mp3"; + await fileService.SaveSpeechFileAsync(conversationId, fileName, data); + speechPath = $"twilio/voice/speeches/{conversationId}/{fileName}"; + } + response = twilio.ReturnInstructions(speechPath, $"twilio/voice/{conversationId}/reply/{seqNum}?states={states}", true, 2); } else { @@ -125,7 +136,7 @@ public async Task ReplyCallerMessage([FromRoute] string conversatio var textToSpeechService = CompletionProvider.GetTextToSpeech(_services, "openai", "tts-1"); var fileService = _services.GetRequiredService(); var data = await textToSpeechService.GenerateSpeechFromTextAsync(reply.Content); - var fileName = $"reply_{seqNum}.mp3"; + var fileName = $"reply_{reply.MessageId ?? seqNum.ToString()}.mp3"; await fileService.SaveSpeechFileAsync(conversationId, fileName, data); if (reply.ConversationEnd) { diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Models/AssistantMessage.cs b/src/Plugins/BotSharp.Plugin.Twilio/Models/AssistantMessage.cs index f9a83613c..560658474 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Models/AssistantMessage.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Models/AssistantMessage.cs @@ -4,5 +4,6 @@ public class AssistantMessage { public bool ConversationEnd { get; set; } public string Content { get; set; } + public string MessageId { get; set; } } } diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs index a84ce5d95..92345bde8 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs @@ -80,7 +80,8 @@ private async Task ProcessUserMessageAsync(CallerMessage message) reply = new AssistantMessage() { ConversationEnd = msg.Instruction.ConversationEnd, - Content = msg.Content + Content = msg.Content, + MessageId = msg.MessageId }; }, async msg =>