From c1d64314a148dff07e1fc3a91ecd42f8a4bee163 Mon Sep 17 00:00:00 2001 From: Bo Yin <103488@smsassist.com> Date: Tue, 14 Jan 2025 09:28:18 -0600 Subject: [PATCH 1/2] enable answering machine detection --- .../Controllers/TwilioVoiceController.cs | 5 ++++- src/Plugins/BotSharp.Plugin.Twilio/Models/CallerMessage.cs | 3 +++ .../Functions/HandleOutboundPhoneCallFn.cs | 3 ++- .../Services/TwilioMessageQueueService.cs | 4 ++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs index ef24298d3..7b5f9365e 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs @@ -126,9 +126,11 @@ public async Task ReceiveCallerMessage(ConversationalVoiceRequest r SeqNumber = request.SeqNum, Content = messageContent, Digits = request.Digits, - From = request.From, + From = string.Equals(request.Direction, "inbound") ? request.From : request.To, States = ParseStates(request.States) }; + callerMessage.RequestHeaders = new KeyValuePair[Request.Headers.Count]; + Request.Headers.CopyTo(callerMessage.RequestHeaders, 0); await messageQueue.EnqueueAsync(callerMessage); response = new VoiceResponse(); @@ -387,6 +389,7 @@ public TwiMLResult InitiateOutboundCall(VoiceRequest request, [Required][FromQue $"twilio/voice/speeches/{conversationId}/intial.mp3" } }; + string tag = Request.Form["AnsweredBy"]; var twilio = _services.GetRequiredService(); var response = twilio.ReturnNoninterruptedInstructions(instruction); return TwiML(response); diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Models/CallerMessage.cs b/src/Plugins/BotSharp.Plugin.Twilio/Models/CallerMessage.cs index c74addd0e..4b9c6a84e 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Models/CallerMessage.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Models/CallerMessage.cs @@ -1,3 +1,5 @@ +using Microsoft.Extensions.Primitives; + namespace BotSharp.Plugin.Twilio.Models { public class CallerMessage @@ -8,6 +10,7 @@ public class CallerMessage public string Digits { get; set; } public string From { get; set; } public Dictionary States { get; set; } = new(); + public KeyValuePair[] RequestHeaders { get; set; } public override string ToString() { diff --git a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/HandleOutboundPhoneCallFn.cs b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/HandleOutboundPhoneCallFn.cs index c9a6c923f..bdc05a615 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/HandleOutboundPhoneCallFn.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/HandleOutboundPhoneCallFn.cs @@ -92,7 +92,8 @@ public async Task Execute(RoleDialogModel message) var call = await CallResource.CreateAsync( url: new Uri($"{_twilioSetting.CallbackHost}/twilio/voice/init-call?conversationId={conversationId}"), to: new PhoneNumber(args.PhoneNumber), - from: new PhoneNumber(_twilioSetting.PhoneNumber)); + from: new PhoneNumber(_twilioSetting.PhoneNumber), + machineDetection: "DetectMessageEnd"); message.Content = $"The generated phone message: {args.InitialMessage}. \r\n[Conversation ID: {conversationId}]" ?? message.Content; message.StopCompletion = true; diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs index 0260320f8..5d7260959 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs @@ -65,6 +65,10 @@ private async Task ProcessUserMessageAsync(CallerMessage message) var httpContext = sp.GetRequiredService(); httpContext.HttpContext = new DefaultHttpContext(); httpContext.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); + foreach (var header in message.RequestHeaders) + { + httpContext.HttpContext.Request.Headers[header.Key] = header.Value; + } httpContext.HttpContext.Request.Headers["X-Twilio-BotSharp"] = "LOST"; AssistantMessage reply = null; From 065601ff2ee2634e7906646a02e902c10d9933e4 Mon Sep 17 00:00:00 2001 From: Bo Yin <103488@smsassist.com> Date: Tue, 14 Jan 2025 10:45:54 -0600 Subject: [PATCH 2/2] add answeredby tag --- .../Controllers/TwilioVoiceController.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs index 7b5f9365e..199e1e34a 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Files; using BotSharp.Abstraction.Infrastructures; +using BotSharp.Abstraction.Repositories; using BotSharp.Core.Infrastructures; using BotSharp.Plugin.Twilio.Interfaces; using BotSharp.Plugin.Twilio.Models; @@ -389,7 +390,9 @@ public TwiMLResult InitiateOutboundCall(VoiceRequest request, [Required][FromQue $"twilio/voice/speeches/{conversationId}/intial.mp3" } }; - string tag = Request.Form["AnsweredBy"]; + string tag = $"AnsweredBy: {Request.Form["AnsweredBy"]}"; + var db = _services.GetRequiredService(); + db.AppendConversationTags(conversationId, new List { tag }); var twilio = _services.GetRequiredService(); var response = twilio.ReturnNoninterruptedInstructions(instruction); return TwiML(response);