Skip to content

Added dtmf data in streaming data parser and added unit test. #49992

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: callautomation/release/ga5
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ public CallAutomationClient(Uri endpoint, TokenCredential credential, CallAutoma
Argument.CheckNotNull(credential, nameof(credential)),
options ?? new CallAutomationClientOptions())
{ }

/// <summary> Initializes a new instance of <see cref="CallAutomationClient"/> with custom PMA endpoint.</summary>
/// <param name="pmaEndpoint">Endpoint for PMA</param>
/// <param name="connectionString">Connection string acquired from the Azure Communication Services resource.</param>
/// <param name="options">Client option exposing <see cref="ClientOptions.Diagnostics"/>, <see cref="ClientOptions.Retry"/>, <see cref="ClientOptions.Transport"/>, etc.</param>
public CallAutomationClient(Uri pmaEndpoint, string connectionString, CallAutomationClientOptions options = default)
: this(
pmaEndpoint,
options ?? new CallAutomationClientOptions(),
ConnectionString.Parse(connectionString))
{ }
#endregion

#region private constructors
Expand All @@ -73,6 +84,13 @@ private CallAutomationClient(string endpoint, TokenCredential tokenCredential, C
: this(new Uri(endpoint), options.BuildHttpPipeline(tokenCredential), options)
{ }

private CallAutomationClient(Uri endpoint, CallAutomationClientOptions options, ConnectionString connectionString)
: this(
endpoint: endpoint,
httpPipeline: options.CustomBuildHttpPipeline(connectionString),
options: options)
{ }

private CallAutomationClient(Uri endpoint, HttpPipeline httpPipeline, CallAutomationClientOptions options)
{
_pipeline = httpPipeline;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.Communication.CallAutomation
{
/// <summary>
/// Streaming dtmf data.
/// </summary>
public class DtmfData : StreamingData
{
/// <summary>
/// The dtmf data, encoded as a base64 string
/// </summary>
/// <param name="data"></param>
public DtmfData(string data)
{
Data = data;
}

internal DtmfData(string data, DateTime timestamp, string participantId)
{
Data = !string.IsNullOrWhiteSpace(data) ? data : default;
Timestamp = timestamp;
if (participantId != null)
{
Participant = CommunicationIdentifier.FromRawId(participantId);
}
}

/// <summary>
/// The dtmf data in base64 byte.
/// </summary>
public string Data { get; }

/// <summary>
/// The timestamp indicating when the media content was received by the bot,
/// or if the bot is sending media, the timestamp of when the media was sourced.
/// The format is ISO 8601 (yyyy-mm-ddThh:mm).
/// </summary>
public DateTimeOffset Timestamp { get; }

/// <summary>
/// The raw ID of the participant.
/// </summary>
public CommunicationIdentifier Participant { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Text.Json.Serialization;

namespace Azure.Communication.CallAutomation
{
/// <summary>
/// Streaming dtmf.
/// </summary>
internal class DtmfDataInternal
{
/// <summary>
/// The dtmf data in base64 string.
/// </summary>
[JsonPropertyName("data")]
public string Data { get; set; }

/// <summary>
/// The timestamp of thwn the media was sourced.
/// </summary>
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; }

/// <summary>
/// Participant ID.
/// </summary>
[JsonPropertyName("participantRawID")]
public string ParticipantRawId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,16 @@ private static StreamingData ParseStreamingData(string base64Data)

#endregion

#region Dtmf
case "DtmfData":
DtmfDataInternal dtmfInternal = JsonSerializer.Deserialize<DtmfDataInternal>(streamingData.GetProperty("dtmfData").ToString());
return new DtmfData(dtmfInternal.Data, dtmfInternal.Timestamp, dtmfInternal.ParticipantRawId);
#endregion

#region Transcription
case "TranscriptionMetadata":
return JsonSerializer.Deserialize<TranscriptionMetadata>(streamingData.GetProperty("transcriptionMetadata").ToString());
TranscriptionMetaDataInternal transcriptionMetadata = JsonSerializer.Deserialize<TranscriptionMetaDataInternal>(streamingData.GetProperty("transcriptionMetadata").ToString());
return new TranscriptionMetadata(transcriptionMetadata);

case "TranscriptionData":
TranscriptionDataInternal transcriptionDataInternal = JsonSerializer.Deserialize<TranscriptionDataInternal>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public enum StreamingDataKind
/// <summary>
/// Transcription metadata type
/// </summary>
TranscriptionMetadata
TranscriptionMetadata,
/// <summary>
/// Dtmf data type
/// </summary>
DtmfData,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Text.Json.Serialization;

namespace Azure.Communication.CallAutomation
{
internal class TranscriptionMetaDataInternal
{
/// <summary>
/// Transcription Subscription Id.
/// </summary>
[JsonPropertyName("subscriptionId")]
public string TranscriptionSubscriptionId { get; set; }

/// <summary>
/// The target locale in which the translated text needs to be
/// </summary>
[JsonPropertyName("locale")]
public string Locale { get; set; }

/// <summary>
/// call connection Id.
/// </summary>
[JsonPropertyName("callConnectionId")]
public string CallConnectionId { get; set; }

/// <summary>
/// correlation Id.
/// </summary>
[JsonPropertyName("correlationId")]
public string CorrelationId { get; set; }

/// <summary>
/// The custom speech recognition model endpoint id
/// </summary>
[JsonPropertyName("speechRecognitionModelEndpointId")]
public string SpeechRecognitionModelEndpointId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ namespace Azure.Communication.CallAutomation
/// </summary>
public class TranscriptionMetadata : StreamingData
{
internal TranscriptionMetadata(TranscriptionMetaDataInternal metaData)
{
TranscriptionSubscriptionId = metaData.TranscriptionSubscriptionId;
Locale = metaData.Locale;
CallConnectionId = metaData.CallConnectionId;
CorrelationId = metaData.CorrelationId;
SpeechRecognitionModelEndpointId = metaData.SpeechRecognitionModelEndpointId;
}
/// <summary>
/// Transcription Subscription Id.
/// </summary>
Expand All @@ -33,5 +41,11 @@ public class TranscriptionMetadata : StreamingData
/// </summary>
[JsonPropertyName("correlationId")]
public string CorrelationId { get; internal set; }

/// <summary>
/// The custom speech recognition model endpoint id
/// </summary>
[JsonPropertyName("speechRecognitionModelEndpointId")]
public string SpeechRecognitionModelEndpointId { get; internal set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,31 @@ private static void ValidateAudioData(AudioData streamingAudio)
Assert.AreEqual("participantId", streamingAudio.Participant.RawId);
Assert.IsFalse(streamingAudio.IsSilent);
}
private static void ValidateAudioDataNoParticipant(AudioData streamingAudio)
#endregion

#region DTMF
[Test]
public void ParseDtmfData_Test()
{
Assert.IsNotNull(streamingAudio);
Assert.AreEqual(Convert.FromBase64String("AQIDBAU="), streamingAudio.Data);
Assert.AreEqual(2022, streamingAudio.Timestamp.Year);
Assert.IsNull(streamingAudio.Participant);
Assert.IsFalse(streamingAudio.IsSilent);
string dtmfJson = "{"
+ "\"kind\": \"DtmfData\","
+ "\"dtmfData\": {"
+ "\"data\": \"5\","
+ "\"timestamp\": \"2022-08-23T11:48:05Z\","
+ "\"participantRawID\": \"participantId\""
+ "}"
+ "}";

DtmfData streamingDtmf = (DtmfData)StreamingData.Parse(dtmfJson);
ValidateDtmfData(streamingDtmf);
}
private static void ValidateDtmfData(DtmfData streamingDtmf)
{
Assert.IsNotNull(streamingDtmf);
Assert.AreEqual("5", streamingDtmf.Data);
Assert.AreEqual(2022, streamingDtmf.Timestamp.Year);
Assert.IsTrue(streamingDtmf.Participant is CommunicationIdentifier);
Assert.AreEqual("participantId", streamingDtmf.Participant.RawId);
}
#endregion

Expand All @@ -88,7 +106,8 @@ public void ParseTranscriptionMetadata_Test()
"\"subscriptionId\":\"subscriptionId\"," +
"\"locale\":\"en-US\"," +
"\"callConnectionId\":\"callConnectionId\"," +
"\"correlationId\":\"correlationId\"" +
"\"correlationId\":\"correlationId\"," +
"\"speechRecognitionModelEndpointId\":\"speechRecognitionModelEndpointId\"" +
"}" +
"}";

Expand Down Expand Up @@ -154,6 +173,7 @@ private static void ValidateTranscriptionMetadata(TranscriptionMetadata transcri
Assert.AreEqual("en-US", transcriptionMetadata.Locale);
Assert.AreEqual("callConnectionId", transcriptionMetadata.CallConnectionId);
Assert.AreEqual("correlationId", transcriptionMetadata.CorrelationId);
Assert.AreEqual("speechRecognitionModelEndpointId", transcriptionMetadata.SpeechRecognitionModelEndpointId);
}

private static void ValidateTranscriptionDataWithWordsNull(TranscriptionData transcription)
Expand Down