Skip to content

Commit 7caedab

Browse files
Callautomation/release/beta2 features (#37485)
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
1 parent 2eac7ff commit 7caedab

File tree

114 files changed

+4588
-550
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+4588
-550
lines changed

sdk/communication/Azure.Communication.CallAutomation/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Release History
22

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

510
### Features Added
611

sdk/communication/Azure.Communication.CallAutomation/api/Azure.Communication.CallAutomation.netstandard2.0.cs

Lines changed: 163 additions & 1 deletion
Large diffs are not rendered by default.

sdk/communication/Azure.Communication.CallAutomation/src/CallAutomationClient.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ private AnswerCallRequestInternal CreateAnswerCallRequest(AnswerCallOptions opti
209209
{
210210
AnswerCallRequestInternal request = new AnswerCallRequestInternal(options.IncomingCallContext, options.CallbackUri.AbsoluteUri);
211211

212+
// Add custom cognitive service domain name
213+
if (options.AzureCognitiveServicesEndpointUri != null)
214+
{
215+
request.AzureCognitiveServicesEndpointUrl = options.AzureCognitiveServicesEndpointUri.AbsoluteUri;
216+
}
217+
212218
request.AnsweredBy = Source == null ? null : new CommunicationUserIdentifierModel(Source.Id);
213219
request.OperationContext = options.OperationContext;
214220

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

624+
// Add custom cognitive service domain name
625+
if (options.AzureCognitiveServicesEndpointUri != null)
626+
{
627+
request.AzureCognitiveServicesEndpointUrl = options.AzureCognitiveServicesEndpointUri.AbsoluteUri;
628+
}
629+
618630
request.OperationContext = options.OperationContext;
619631

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

648+
// Add custom cognitive service domain name
649+
if (options.AzureCognitiveServicesEndpointUri != null)
650+
{
651+
request.AzureCognitiveServicesEndpointUrl = options.AzureCognitiveServicesEndpointUri.AbsoluteUri;
652+
}
653+
636654
request.OperationContext = options.OperationContext;
637655
return request;
638656
}

sdk/communication/Azure.Communication.CallAutomation/src/CallAutomationClientOptions.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class CallAutomationClientOptions : ClientOptions
1616
/// <summary>
1717
/// The latest version of the CallAutomation service.
1818
/// </summary>
19-
internal const ServiceVersion LatestVersion = ServiceVersion.V2023_03_06;
19+
internal const ServiceVersion LatestVersion = ServiceVersion.V2023_06_15_Preview;
2020

2121
internal string ApiVersion { get; }
2222

@@ -33,6 +33,7 @@ public CallAutomationClientOptions(ServiceVersion version = LatestVersion)
3333
ApiVersion = version switch
3434
{
3535
ServiceVersion.V2023_03_06 => "2023-03-06",
36+
ServiceVersion.V2023_06_15_Preview => "2023-06-15-preview",
3637
_ => throw new ArgumentOutOfRangeException(nameof(version)),
3738
};
3839
}
@@ -46,7 +47,11 @@ public enum ServiceVersion
4647
/// The GA1 of the CallAutomation service.
4748
/// </summary>
4849
#pragma warning disable CA1707 // Identifiers should not contain underscores
49-
V2023_03_06 = 1
50+
V2023_03_06 = 1,
51+
/// <summary>
52+
/// The beta2 of the CallAutomation service.
53+
/// </summary>
54+
V2023_06_15_Preview = 2
5055
#pragma warning restore CA1707 // Identifiers should not contain underscores
5156
}
5257
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
namespace Azure.Communication.CallAutomation
5+
{
6+
/// <summary><see cref="SendDtmfEventResult"/> is returned from WaitForEvent of <see cref="SendDtmfResult"/>.</summary>
7+
public class SendDtmfEventResult
8+
{
9+
/// <summary>
10+
/// Indicates whether the returned event is considered successful or not.
11+
/// </summary>
12+
public bool IsSuccess { get; internal set; }
13+
14+
/// <summary>
15+
/// <see cref="SendDtmfCompleted"/> event will be returned once the dtmf tones have been sent successfully.
16+
/// </summary>
17+
public SendDtmfCompleted SuccessResult { get; }
18+
19+
/// <summary>
20+
/// <see cref="SendDtmfFailed"/> event will be returned if send dtmf tones completed unsuccessfully.
21+
/// </summary>
22+
public SendDtmfFailed FailureResult { get; }
23+
24+
internal SendDtmfEventResult(bool isSuccess, SendDtmfCompleted successResult, SendDtmfFailed failureResult)
25+
{
26+
IsSuccess = isSuccess;
27+
SuccessResult = successResult;
28+
FailureResult = failureResult;
29+
}
30+
}
31+
}

sdk/communication/Azure.Communication.CallAutomation/src/CallConnection.cs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,5 +656,113 @@ public virtual CallMedia GetCallMedia()
656656
throw;
657657
}
658658
}
659+
660+
/// <summary>
661+
/// Mute participant from the call.
662+
/// Only Acs Users are currently supported.
663+
/// </summary>
664+
/// <param name="targetParticipant">Participant to mute.</param>
665+
/// <param name="cancellationToken">The cancellation token.</param>
666+
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
667+
/// <exception cref="ArgumentNullException"> <paramref name="targetParticipant"/> is null. </exception>
668+
/// <returns>A Response containing MuteParticipantsResponse.</returns>
669+
public virtual Response<MuteParticipantsResult> MuteParticipants(CommunicationIdentifier targetParticipant, CancellationToken cancellationToken = default)
670+
{
671+
var options = new MuteParticipantsOptions(new List<CommunicationIdentifier> { targetParticipant });
672+
673+
return MuteParticipants(options, cancellationToken);
674+
}
675+
676+
/// <summary>
677+
/// Mute participants from the call.
678+
/// Only Acs Users are currently supported.
679+
/// </summary>
680+
/// <param name="options">Options for the MuteParticipant operation.</param>
681+
/// <param name="cancellationToken">The cancellation token.</param>
682+
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
683+
/// <exception cref="ArgumentNullException"> <paramref name="options"/> is null. </exception>
684+
/// <returns>A Response containing MuteParticipantsResponse. </returns>
685+
public virtual Response<MuteParticipantsResult> MuteParticipants(MuteParticipantsOptions options, CancellationToken cancellationToken = default)
686+
{
687+
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(CallConnection)}.{nameof(MuteParticipants)}");
688+
scope.Start();
689+
try
690+
{
691+
if (options == null)
692+
throw new ArgumentNullException(nameof(options));
693+
694+
MuteParticipantsRequestInternal request = new MuteParticipantsRequestInternal(
695+
options.TargetParticipants.Select(participant => CommunicationIdentifierSerializer.Serialize(participant)));
696+
var repeatabilityHeaders = new RepeatabilityHeaders();
697+
698+
request.OperationContext = options.OperationContext;
699+
700+
return RestClient.Mute(
701+
CallConnectionId,
702+
request,
703+
repeatabilityHeaders.RepeatabilityRequestId,
704+
repeatabilityHeaders.RepeatabilityFirstSent,
705+
cancellationToken);
706+
}
707+
catch (Exception ex)
708+
{
709+
scope.Failed(ex);
710+
throw;
711+
}
712+
}
713+
714+
/// <summary>
715+
/// Mute participants on the call.
716+
/// Only Acs Users are currently supported.
717+
/// </summary>
718+
/// <param name="targetParticipant">Participants to mute.</param>
719+
/// <param name="cancellationToken">The cancellation token.</param>
720+
/// <exception cref="ArgumentNullException"> <paramref name="targetParticipant"/> is null. </exception>
721+
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
722+
/// <returns></returns>
723+
public async virtual Task<Response<MuteParticipantsResult>> MuteParticipantsAsync(CommunicationIdentifier targetParticipant, CancellationToken cancellationToken = default)
724+
{
725+
var options = new MuteParticipantsOptions(new List<CommunicationIdentifier> { targetParticipant });
726+
727+
return await MuteParticipantsAsync(options, cancellationToken).ConfigureAwait(false);
728+
}
729+
730+
/// <summary>
731+
/// Mute participants on the call.
732+
/// </summary>
733+
/// <param name="options">Options for the MuteParticipant operation.</param>
734+
/// <param name="cancellationToken">The cancellation token.</param>
735+
/// <exception cref="ArgumentNullException"> <paramref name="options"/> is null. </exception>
736+
/// <exception cref="ArgumentException"> <paramref name="options"/> OperationContext is too long. </exception>
737+
/// <exception cref="RequestFailedException">The server returned an error. See <see cref="Exception.Message"/> for details returned from the server.</exception>
738+
/// <returns></returns>
739+
public async virtual Task<Response<MuteParticipantsResult>> MuteParticipantsAsync(MuteParticipantsOptions options, CancellationToken cancellationToken = default)
740+
{
741+
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(CallConnection)}.{nameof(MuteParticipants)}");
742+
scope.Start();
743+
try
744+
{
745+
if (options == null)
746+
throw new ArgumentNullException(nameof(options));
747+
748+
MuteParticipantsRequestInternal request = new MuteParticipantsRequestInternal(
749+
options.TargetParticipants.Select(participant => CommunicationIdentifierSerializer.Serialize(participant)));
750+
var repeatabilityHeaders = new RepeatabilityHeaders();
751+
752+
request.OperationContext = options.OperationContext;
753+
754+
return await RestClient.MuteAsync(
755+
CallConnectionId,
756+
request,
757+
repeatabilityHeaders.RepeatabilityRequestId,
758+
repeatabilityHeaders.RepeatabilityFirstSent,
759+
cancellationToken).ConfigureAwait(false);
760+
}
761+
catch (Exception ex)
762+
{
763+
scope.Failed(ex);
764+
throw;
765+
}
766+
}
659767
}
660768
}

0 commit comments

Comments
 (0)