Skip to content

Commit

Permalink
Callautomation/release/beta2 features (#37485)
Browse files Browse the repository at this point in the history
Beta 2 features implementation of PMA BETA2_2023_06_15_preview contract:

SendDtmf
DtmfSubscription
PlayTTS
PlaySSML
Recognize Choices
Recognize Freeform
Mute
BYO Cogsvc changes for Answer/CreateCall
  • Loading branch information
abhishesingh-msft authored and vivekmore-msft committed Aug 6, 2023
1 parent 44012d1 commit f2ffcf8
Show file tree
Hide file tree
Showing 112 changed files with 4,422 additions and 551 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Release History

## 1.1.0-beta.1 (Unreleased)
- Play and recognize supports TTS and SSML source prompts.
- Recognize supports choices and freeform speech.
- Start/Stop continuous DTMF recognition by subscribing/unsubscribing to tones.
- Send DTMF tones to a participant in the call.
- Mute participants in the call.

### Features Added

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,12 @@ private AnswerCallRequestInternal CreateAnswerCallRequest(AnswerCallOptions opti
{
AnswerCallRequestInternal request = new AnswerCallRequestInternal(options.IncomingCallContext, options.CallbackUri.AbsoluteUri);

// Add custom cognitive service domain name
if (options.AzureCognitiveServicesEndpointUri != null)
{
request.AzureCognitiveServicesEndpointUrl = options.AzureCognitiveServicesEndpointUri.AbsoluteUri;
}

request.AnsweredBy = Source == null ? null : new CommunicationUserIdentifierModel(Source.Id);
request.OperationContext = options.OperationContext;

Expand Down Expand Up @@ -615,6 +621,12 @@ private CreateCallRequestInternal CreateCallRequest(CreateCallOptions options)
Source = Source == null ? null : new CommunicationUserIdentifierModel(Source.Id),
};

// Add custom cognitive service domain name
if (options.AzureCognitiveServicesEndpointUri != null)
{
request.AzureCognitiveServicesEndpointUrl = options.AzureCognitiveServicesEndpointUri.AbsoluteUri;
}

request.OperationContext = options.OperationContext;

return request;
Expand All @@ -633,6 +645,12 @@ private CreateCallRequestInternal CreateCallRequest(CreateGroupCallOptions optio
Source = Source == null ? null : new CommunicationUserIdentifierModel(Source.Id),
};

// Add custom cognitive service domain name
if (options.AzureCognitiveServicesEndpointUri != null)
{
request.AzureCognitiveServicesEndpointUrl = options.AzureCognitiveServicesEndpointUri.AbsoluteUri;
}

request.OperationContext = options.OperationContext;
return request;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class CallAutomationClientOptions : ClientOptions
/// <summary>
/// The latest version of the CallAutomation service.
/// </summary>
internal const ServiceVersion LatestVersion = ServiceVersion.V2023_03_06;
internal const ServiceVersion LatestVersion = ServiceVersion.V2023_06_15_Preview;

internal string ApiVersion { get; }

Expand All @@ -33,6 +33,7 @@ public CallAutomationClientOptions(ServiceVersion version = LatestVersion)
ApiVersion = version switch
{
ServiceVersion.V2023_03_06 => "2023-03-06",
ServiceVersion.V2023_06_15_Preview => "2023-06-15-preview",
_ => throw new ArgumentOutOfRangeException(nameof(version)),
};
}
Expand All @@ -46,7 +47,11 @@ public enum ServiceVersion
/// The GA1 of the CallAutomation service.
/// </summary>
#pragma warning disable CA1707 // Identifiers should not contain underscores
V2023_03_06 = 1
V2023_03_06 = 1,
/// <summary>
/// The beta2 of the CallAutomation service.
/// </summary>
V2023_06_15_Preview = 2
#pragma warning restore CA1707 // Identifiers should not contain underscores
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Azure.Communication.CallAutomation
{
/// <summary><see cref="SendDtmfEventResult"/> is returned from WaitForEvent of <see cref="SendDtmfResult"/>.</summary>
public class SendDtmfEventResult
{
/// <summary>
/// Indicates whether the returned event is considered successful or not.
/// </summary>
public bool IsSuccess { get; internal set; }

/// <summary>
/// <see cref="SendDtmfCompleted"/> event will be returned once the dtmf tones have been sent successfully.
/// </summary>
public SendDtmfCompleted SuccessResult { get; }

/// <summary>
/// <see cref="SendDtmfFailed"/> event will be returned if send dtmf tones completed unsuccessfully.
/// </summary>
public SendDtmfFailed FailureResult { get; }

internal SendDtmfEventResult(bool isSuccess, SendDtmfCompleted successResult, SendDtmfFailed failureResult)
{
IsSuccess = isSuccess;
SuccessResult = successResult;
FailureResult = failureResult;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -656,5 +656,113 @@ public virtual CallMedia GetCallMedia()
throw;
}
}

/// <summary>
/// Mute participant from the call.
/// Only Acs Users are currently supported.
/// </summary>
/// <param name="targetParticipant">Participant to mute.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
/// <exception cref="ArgumentNullException"> <paramref name="targetParticipant"/> is null. </exception>
/// <returns>A Response containing MuteParticipantsResponse.</returns>
public virtual Response<MuteParticipantsResult> MuteParticipants(CommunicationIdentifier targetParticipant, CancellationToken cancellationToken = default)
{
var options = new MuteParticipantsOptions(new List<CommunicationIdentifier> { targetParticipant });

return MuteParticipants(options, cancellationToken);
}

/// <summary>
/// Mute participants from the call.
/// Only Acs Users are currently supported.
/// </summary>
/// <param name="options">Options for the MuteParticipant operation.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
/// <exception cref="ArgumentNullException"> <paramref name="options"/> is null. </exception>
/// <returns>A Response containing MuteParticipantsResponse. </returns>
public virtual Response<MuteParticipantsResult> MuteParticipants(MuteParticipantsOptions options, CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(CallConnection)}.{nameof(MuteParticipants)}");
scope.Start();
try
{
if (options == null)
throw new ArgumentNullException(nameof(options));

MuteParticipantsRequestInternal request = new MuteParticipantsRequestInternal(
options.TargetParticipants.Select(participant => CommunicationIdentifierSerializer.Serialize(participant)));
var repeatabilityHeaders = new RepeatabilityHeaders();

request.OperationContext = options.OperationContext;

return RestClient.Mute(
CallConnectionId,
request,
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.RepeatabilityFirstSent,
cancellationToken);
}
catch (Exception ex)
{
scope.Failed(ex);
throw;
}
}

/// <summary>
/// Mute participants on the call.
/// Only Acs Users are currently supported.
/// </summary>
/// <param name="targetParticipant">Participants to mute.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="ArgumentNullException"> <paramref name="targetParticipant"/> is null. </exception>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
/// <returns></returns>
public async virtual Task<Response<MuteParticipantsResult>> MuteParticipantsAsync(CommunicationIdentifier targetParticipant, CancellationToken cancellationToken = default)
{
var options = new MuteParticipantsOptions(new List<CommunicationIdentifier> { targetParticipant });

return await MuteParticipantsAsync(options, cancellationToken).ConfigureAwait(false);
}

/// <summary>
/// Mute participants on the call.
/// </summary>
/// <param name="options">Options for the MuteParticipant operation.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="ArgumentNullException"> <paramref name="options"/> is null. </exception>
/// <exception cref="ArgumentException"> <paramref name="options"/> OperationContext is too long. </exception>
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
/// <returns></returns>
public async virtual Task<Response<MuteParticipantsResult>> MuteParticipantsAsync(MuteParticipantsOptions options, CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(CallConnection)}.{nameof(MuteParticipants)}");
scope.Start();
try
{
if (options == null)
throw new ArgumentNullException(nameof(options));

MuteParticipantsRequestInternal request = new MuteParticipantsRequestInternal(
options.TargetParticipants.Select(participant => CommunicationIdentifierSerializer.Serialize(participant)));
var repeatabilityHeaders = new RepeatabilityHeaders();

request.OperationContext = options.OperationContext;

return await RestClient.MuteAsync(
CallConnectionId,
request,
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.RepeatabilityFirstSent,
cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
scope.Failed(ex);
throw;
}
}
}
}
Loading

0 comments on commit f2ffcf8

Please sign in to comment.