Merge with upstream

This commit is contained in:
Haiping Chen 2024-09-09 12:39:37 -05:00
commit c71c44692a
7 changed files with 27 additions and 17 deletions

View file

@ -7,4 +7,9 @@ public class KeyValue
[JsonPropertyName("value")]
public string Value { get; set; }
public override string ToString()
{
return $"Key: {Key}, Value: {Value}";
}
}

View file

@ -23,15 +23,4 @@ public class ConversationFilter
/// Check whether each key in the list is in the conversation states and its value equals to target value if not empty
/// </summary>
public IEnumerable<KeyValue> States { get; set; } = new List<KeyValue>();
}
public class KeyValue
{
public string Key { get; set; }
public string? Value { get; set; }
public override string ToString()
{
return $"Key: {Key}, Value: {Value}";
}
}

View file

@ -1,11 +1,9 @@
using Azure.Messaging;
using BotSharp.Abstraction.Files;
using BotSharp.Core.Infrastructures;
using BotSharp.Plugin.Twilio.Models;
using BotSharp.Plugin.Twilio.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using Twilio.Http;
namespace BotSharp.Plugin.Twilio.Controllers;
@ -109,14 +107,14 @@ public class TwilioVoiceController : TwilioController
else
{
response = twilio.ReturnInstructions(null, $"twilio/voice/{conversationId}/receive/{seqNum}?states={states}&attempts={++attempts}", true);
}
}
}
return TwiML(response);
}
[ValidateRequest]
[HttpPost("twilio/voice/{conversationId}/reply/{seqNum}")]
public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversationId, [FromRoute] int seqNum,
public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversationId, [FromRoute] int seqNum,
[FromQuery] string states, VoiceRequest request)
{
var nextSeqNum = seqNum + 1;
@ -166,7 +164,7 @@ public class TwilioVoiceController : TwilioController
}
else
{
response = twilio.ReturnInstructions(new List<string>
response = twilio.ReturnInstructions(new List<string>
{
$"twilio/hold-on-long-{Random.Shared.Next(1, 9)}.mp3",
$"twilio/typing-{Random.Shared.Next(1, 4)}.mp3"
@ -175,7 +173,11 @@ public class TwilioVoiceController : TwilioController
}
else
{
if (reply.ConversationEnd)
if (reply.HumanIntervationNeeded)
{
response = twilio.DialCsrAgent($"twilio/voice/speeches/{conversationId}/{reply.SpeechFileName}");
}
else if (reply.ConversationEnd)
{
response = twilio.HangUp($"twilio/voice/speeches/{conversationId}/{reply.SpeechFileName}");
}

View file

@ -3,6 +3,7 @@ namespace BotSharp.Plugin.Twilio.Models
public class AssistantMessage
{
public bool ConversationEnd { get; set; }
public bool HumanIntervationNeeded { get; set; }
public string Content { get; set; }
public string MessageId { get; set; }
public string SpeechFileName { get; set; }

View file

@ -86,6 +86,7 @@ namespace BotSharp.Plugin.Twilio.Services
reply = new AssistantMessage()
{
ConversationEnd = msg.Instruction?.ConversationEnd ?? false,
HumanIntervationNeeded = string.Equals("human_intervention_needed", msg.FunctionName),
Content = msg.Content,
MessageId = msg.MessageId
};

View file

@ -133,6 +133,17 @@ public class TwilioService
return response;
}
public VoiceResponse DialCsrAgent(string speechPath)
{
var response = new VoiceResponse();
if (!string.IsNullOrEmpty(speechPath))
{
response.Play(new Uri($"{_settings.CallbackHost}/{speechPath}"));
}
response.Dial(_settings.CsrAgentNumber);
return response;
}
public VoiceResponse HoldOn(int interval, string message = null)
{
var twilioSetting = _services.GetRequiredService<TwilioSetting>();

View file

@ -10,4 +10,5 @@ public class TwilioSetting
public string ApiSecret { get; set; }
public string CallbackHost { get; set; }
public string AgentId { get; set; }
public string CsrAgentNumber { get; set; }
}