Skip to content

Callautomation/release/beta3 #50764

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 8 commits into
base: main
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
85 changes: 26 additions & 59 deletions sdk/communication/Azure.Communication.CallAutomation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,77 +1,44 @@
# Release History

## 1.5.0-beta.1 (Unreleased)
## 1.2.0-beta.1 (Unreleased)

### Features Added

- Added support for post-call processing options, including summarization and transcription.
- The StartRecording function now accepts the PauseOnStart parameter.
- Added support for CreateCallFailed and AnswerCallFailed events.
- Enabled audio streaming support for various APIs such as CreateCall, AnswerCall, CreateGroupCall, and ConnectCall.
- Receive events for audio streaming, including MediaStreamStarted, MediaStreamStopped, and MediaStreamFailed.
- Enhanced media streaming with bidirectional capabilities, supporting audio formats in both directions. Currently, it supports sample rates of 24kHz and 16kHz.
- Added support to manage rooms, server calls, and group calls using the ConnectAPI.
- Receive events for CallConnected and ConnectFailed.
- Added support for ConnectAPI to enable streaming and real-time transcription.
- Added the ability to hold and unhold participants.
- Ability to hold participants with a play source.
- The new InterruptAudioAnnounce API now allows for the interruption of hold audio
- With the InterruptHoldAudio option in PlayOptions, it is now possible to interrupt the hold audio.
- Events now include ResultInformation, which provides more details on the success or failure of the events.
- Added support for Teams multipersona users in add participant, transfer, and redirect scenarios in OPS calls
- Added ability to send custom calling context when answering calls
- Added TeamsAppSource for use when creating outbound OPS calls
- Recording with the call connection ID is now supported. OPS calls can be recorded using the call connection ID.
- Added a backup identifier of the Cognitive Service resource for the call
- Added Incomingcall event to support incoming call notification for Teams multipersona users
- Added StartRecordingFailed event to indicate when the start recording API is unable to initiate the recording.

### Breaking Changes

### Bugs Fixed
- Media streaming with AudioFormat default Pcm24kMono is removed and changed to null if AudioFormat is not passed.

### Other Changes
- Introduced audio streaming data parsing capabilities.
- Note: The ordering of the events input parameters has been changed. This modification won't affect existing code, but if you have used unit tests for the events, you may need to update the parameter order accordingly.

## 1.4.0-beta.1 (2024-11-22)

### Features Added

- Added support for ConnectAPI to enable streaming and real-time transcription
- Enhanced media streaming with bidirectional capabilities, enabling support for audio formats in both directions. Currently, it supports sample rates of 24kHz and 16kHz

### Other Changes

- Introduced audio streaming and transcription data parsing capabilities.

## 1.3.0 (2024-11-22)

### Features Added

- Support multiple play sources for Play and Recognize
- Support for PlayStarted event in Play/Recognize
- Hold and Unhold the participant
- CallDisconnected now includes more information on why the call has ended
- Support to manage the rooms/servercall/group call using connect API
- Expose original PSTN number target from incoming call event in call connection properties
- Support for VoIP to PSTN transfer scenario

### Other Changes

- Added CreateCallFailed event to signify when create call API fails to establish a call
- Added AnswerFailed event to signify when answer call API fails to answer a call

## 1.3.0-beta.2 (2024-10-28)

### Features Added

- Added CreateCallFailed event to signify when create call API fails to establish a call

## 1.3.0-beta.1 (2024-08-02)

### Features Added

- Support multiple play sources for Play and Recognize
- Support for PlayStarted event in Play/Recognize
- Support for the real time transcription
- Monetization for real-time transcription and audio streaming
- Hold and Unhold the participant
- Support to manage the rooms/servercall/group call using connect API
- Support for the audio streaming
- Expose original PSTN number target from incoming call event in call connection properties
- Support for VoIP to PSTN transfer scenario

## 1.2.0 (2024-04-15)

### Features Added
### Breaking Changes

- Support for Bring Your Own Storage recording option
- Support for PauseOnStart recording option
- Support for Recording state change with new recording kind's
### Bugs Fixed

### Other Changes

- Support for MicrosoftTeamsAppIdentifier CommunicationIdentifier

## 1.1.0 (2023-11-23)

### Features Added
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "net",
"TagPrefix": "net/communication/Azure.Communication.CallAutomation",
"Tag": "net/communication/Azure.Communication.CallAutomation_9cd8b0cf91"
"Tag": "net/communication/Azure.Communication.CallAutomation_767cc097e7"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Microsoft Azure Communication Call Automation quickstart - https://learn.microsoft.com/azure/communication-services/quickstarts/voice-video-calling/callflows-for-customer-interactions?pivots=programming-language-csharp
</Description>
<AssemblyTitle>Azure Communication CallAutomation Service</AssemblyTitle>
<Version>1.5.0-beta.1</Version>
<Version>1.2.0-beta.1</Version>
<!--The ApiCompatVersion is managed automatically and should not generally be modified manually.-->
<PackageTags>Microsoft Azure Communication CallAutomation Service;Microsoft;Azure;Azure Communication Service;Azure Communication CallAutomation Service;Calling;Communication;$(PackageCommonTags)</PackageTags>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
Expand All @@ -21,6 +21,7 @@
<Compile Include="..\..\Shared\src\ClientOptionsExtensions.cs" LinkBase="Shared\Communication" />
<Compile Include="..\..\Shared\src\HMACAuthenticationPolicy.cs" LinkBase="Shared\Communication" />
<Compile Include="..\..\Shared\src\CommunicationIdentifierSerializer.cs" LinkBase="Shared\Communication" />
<Compile Include="..\..\Shared\src\CommunicationIdentifierSerializer_2025_06_30.cs" LinkBase="Shared\Communication" />
<Compile Include="$(AzureCoreSharedSources)ArrayBufferWriter.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)AzureResourceProviderNamespaceAttribute.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)ConnectionString.cs" LinkBase="Shared" />
Expand All @@ -30,6 +31,7 @@
<ItemGroup>
<PackageReference Include="Azure.Core" />
<PackageReference Include="Azure.Communication.Common" />
<PackageReference Include="System.Text.Json" />
</ItemGroup>
<ItemGroup>
<Folder Include="Generated\" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Azure.Core.Pipeline;
using Azure.Communication.Pipeline;
using System.Collections.Generic;
using System.Net;

namespace Azure.Communication.CallAutomation
{
Expand Down Expand Up @@ -253,14 +254,13 @@ private AnswerCallRequestInternal CreateAnswerCallRequest(AnswerCallOptions opti
};
}

request.MediaStreamingOptions = CreateMediaStreamingOptionsInternal(options.MediaStreamingOptions);
request.TranscriptionOptions = CreateTranscriptionOptionsInternal(options.TranscriptionOptions);
request.TranscriptionConfiguration = CreateTranscriptionOptionsInternal(options.TranscriptionOptions);
request.MediaStreamingConfiguration = CreateMediaStreamingOptionsInternal(options.MediaStreamingOptions);
request.AnsweredBy = Source == null ? null : new CommunicationUserIdentifierModel(Source.Id);
request.OperationContext = options.OperationContext;
request.CustomCallingContext = new CustomCallingContextInternal(
options.CustomCallingContext?.VoipHeaders ?? new ChangeTrackingDictionary<string, string>(),
options.CustomCallingContext?.SipHeaders ?? new ChangeTrackingDictionary<string, string>(),
CustomCallContextHelpers.CreateTeamsPhoneCallDetailsInternal(options.CustomCallingContext?.TeamsPhoneCallDetails));
options.CustomCallingContext?.SipHeaders ?? new ChangeTrackingDictionary<string, string>());

return request;
}
Expand Down Expand Up @@ -293,12 +293,7 @@ public virtual async Task<Response> RedirectCallAsync(RedirectCallOptions option
if (options == null)
throw new ArgumentNullException(nameof(options));

RedirectCallRequestInternal request = new RedirectCallRequestInternal(options.IncomingCallContext, CommunicationIdentifierSerializer.Serialize(options.CallInvite.Target));

request.CustomCallingContext = new CustomCallingContextInternal(
options.CallInvite?.CustomCallingContext?.VoipHeaders == null ? new ChangeTrackingDictionary<string, string>() : options.CallInvite?.CustomCallingContext?.VoipHeaders,
options.CallInvite?.CustomCallingContext?.SipHeaders == null ? new ChangeTrackingDictionary<string, string>() : options.CallInvite?.CustomCallingContext?.SipHeaders,
CustomCallContextHelpers.CreateTeamsPhoneCallDetailsInternal(options.CallInvite?.CustomCallingContext?.TeamsPhoneCallDetails));
RedirectCallRequestInternal request = new RedirectCallRequestInternal(options.IncomingCallContext, CommunicationIdentifierSerializer_2025_06_30.Serialize(options.CallInvite.Target));

return await AzureCommunicationServicesRestClient.RedirectCallAsync(request, cancellationToken).ConfigureAwait(false);
}
Expand Down Expand Up @@ -337,12 +332,7 @@ public virtual Response RedirectCall(RedirectCallOptions options, CancellationTo
if (options == null)
throw new ArgumentNullException(nameof(options));

RedirectCallRequestInternal request = new RedirectCallRequestInternal(options.IncomingCallContext, CommunicationIdentifierSerializer.Serialize(options.CallInvite.Target));

request.CustomCallingContext = new CustomCallingContextInternal(
options.CallInvite?.CustomCallingContext?.VoipHeaders == null ? new ChangeTrackingDictionary<string, string>() : options.CallInvite.CustomCallingContext.VoipHeaders,
options.CallInvite?.CustomCallingContext?.SipHeaders == null ? new ChangeTrackingDictionary<string, string>() : options.CallInvite.CustomCallingContext.SipHeaders,
CustomCallContextHelpers.CreateTeamsPhoneCallDetailsInternal(options.CallInvite?.CustomCallingContext?.TeamsPhoneCallDetails));
RedirectCallRequestInternal request = new RedirectCallRequestInternal(options.IncomingCallContext, CommunicationIdentifierSerializer_2025_06_30.Serialize(options.CallInvite.Target));

return AzureCommunicationServicesRestClient.RedirectCall(request, cancellationToken);
}
Expand Down Expand Up @@ -717,10 +707,11 @@ public virtual Response<ConnectCallResult> ConnectCall(ConnectCallOptions connec
throw;
}
}

private CreateCallRequestInternal CreateCallRequest(CreateCallOptions options)
{
CreateCallRequestInternal request = new(
targets: new List<CommunicationIdentifierModel>() { { CommunicationIdentifierSerializer.Serialize(options.CallInvite.Target) } },
targets: new List<CommunicationIdentifierModel>() { { CommunicationIdentifierSerializer_2025_06_30.Serialize(options.CallInvite.Target) } },
callbackUri: options.CallbackUri.AbsoluteUri)
{
SourceCallerIdNumber = options?.CallInvite?.SourceCallerIdNumber == null
Expand All @@ -731,11 +722,6 @@ private CreateCallRequestInternal CreateCallRequest(CreateCallOptions options)
TeamsAppSource = options.TeamsAppSource == null ? null : new MicrosoftTeamsAppIdentifierModel(options.TeamsAppSource.AppId),
};

request.CustomCallingContext = new CustomCallingContextInternal(
options.CallInvite?.CustomCallingContext?.VoipHeaders == null ? new ChangeTrackingDictionary<string, string>() : options.CallInvite?.CustomCallingContext?.VoipHeaders,
options.CallInvite?.CustomCallingContext?.SipHeaders == null ? new ChangeTrackingDictionary<string, string>() : options.CallInvite.CustomCallingContext.SipHeaders,
CustomCallContextHelpers.CreateTeamsPhoneCallDetailsInternal(options.CallInvite?.CustomCallingContext?.TeamsPhoneCallDetails));

// Add CallIntelligenceOptions such as custom cognitive service domain name
string cognitiveServicesEndpoint = options.CallIntelligenceOptions?.CognitiveServicesEndpoint?.AbsoluteUri;
string backupCognitiveServicesEndpoint = options.CallIntelligenceOptions?.BackupCognitiveServicesEndpoint?.AbsoluteUri;
Expand All @@ -749,31 +735,26 @@ private CreateCallRequestInternal CreateCallRequest(CreateCallOptions options)
}

request.OperationContext = options.OperationContext;
request.MediaStreamingOptions = CreateMediaStreamingOptionsInternal(options.MediaStreamingOptions);
request.TranscriptionOptions = CreateTranscriptionOptionsInternal(options.TranscriptionOptions);
request.TranscriptionConfiguration = CreateTranscriptionOptionsInternal(options.TranscriptionOptions);
request.MediaStreamingConfiguration = CreateMediaStreamingOptionsInternal(options.MediaStreamingOptions);

return request;
}

private CreateCallRequestInternal CreateCallRequest(CreateGroupCallOptions options)
{
CreateCallRequestInternal request = new(
targets: options.Targets.Select(t => CommunicationIdentifierSerializer.Serialize(t)),
targets: options.Targets.Select(t => CommunicationIdentifierSerializer_2025_06_30.Serialize(t)),
callbackUri: options.CallbackUri.AbsoluteUri)
{
SourceCallerIdNumber = options?.SourceCallerIdNumber == null
? null
: new PhoneNumberIdentifierModel(options?.SourceCallerIdNumber?.PhoneNumber),
SourceDisplayName = options?.SourceDisplayName,
Source = Source == null ? null : new CommunicationUserIdentifierModel(Source.Id),
TeamsAppSource = options.TeamsAppSource == null ? null : new MicrosoftTeamsAppIdentifierModel(options.TeamsAppSource.AppId)
TeamsAppSource = options.TeamsAppSource == null ? null : new MicrosoftTeamsAppIdentifierModel(options.TeamsAppSource.AppId),
};

request.CustomCallingContext = new CustomCallingContextInternal(
options.CustomCallingContext?.VoipHeaders == null ? new ChangeTrackingDictionary<string, string>() : options.CustomCallingContext?.VoipHeaders,
options.CustomCallingContext?.SipHeaders == null ? new ChangeTrackingDictionary<string, string>() : options.CustomCallingContext?.SipHeaders,
CustomCallContextHelpers.CreateTeamsPhoneCallDetailsInternal(options.CustomCallingContext?.TeamsPhoneCallDetails));

// Add CallIntelligenceOptions such as custom cognitive service domain name
string cognitiveServicesEndpoint = options.CallIntelligenceOptions?.CognitiveServicesEndpoint?.AbsoluteUri;
string backupCognitiveServicesEndpoint = options.CallIntelligenceOptions?.BackupCognitiveServicesEndpoint?.AbsoluteUri;
Expand All @@ -787,8 +768,8 @@ private CreateCallRequestInternal CreateCallRequest(CreateGroupCallOptions optio
}

request.OperationContext = options.OperationContext;
request.MediaStreamingOptions = CreateMediaStreamingOptionsInternal(options.MediaStreamingOptions);
request.TranscriptionOptions = CreateTranscriptionOptionsInternal(options.TranscriptionOptions);
request.TranscriptionConfiguration = CreateTranscriptionOptionsInternal(options.TranscriptionOptions);
request.MediaStreamingConfiguration = CreateMediaStreamingOptionsInternal(options.MediaStreamingOptions);

return request;
}
Expand All @@ -798,9 +779,10 @@ private ConnectRequestInternal ConnectRequest(ConnectCallOptions options)
CallLocatorInternal callLocatorInternal = CallLocatorSerializer.Serialize(options.CallLocator);
ConnectRequestInternal connectRequest = new ConnectRequestInternal(callLocatorInternal, options.CallbackUri?.AbsoluteUri);
connectRequest.OperationContext = options.OperationContext;
connectRequest.MediaStreamingOptions = CreateMediaStreamingOptionsInternal(options.MediaStreamingOptions);
connectRequest.TranscriptionOptions = CreateTranscriptionOptionsInternal(options.TranscriptionOptions);
connectRequest.MediaStreamingConfiguration = CreateMediaStreamingOptionsInternal(options.MediaStreamingOptions);
connectRequest.TranscriptionConfiguration = CreateTranscriptionOptionsInternal(options.TranscriptionOptions);

// Add CallIntelligenceOptions such as custom cognitive service domain name
string cognitiveServicesEndpoint = options.CallIntelligenceOptions?.CognitiveServicesEndpoint?.AbsoluteUri;
string backupCognitiveServicesEndpoint = options.CallIntelligenceOptions?.BackupCognitiveServicesEndpoint?.AbsoluteUri;
if (!string.IsNullOrWhiteSpace(cognitiveServicesEndpoint))
Expand Down Expand Up @@ -828,24 +810,21 @@ private static bool IsValidHttpsUri(Uri uri)
return Uri.IsWellFormedUriString(uriString, UriKind.Absolute) && new Uri(uriString).Scheme == Uri.UriSchemeHttps;
}

private static MediaStreamingOptionsInternal CreateMediaStreamingOptionsInternal(MediaStreamingOptions configuration)
private static TranscriptionOptionsInternal CreateTranscriptionOptionsInternal(TranscriptionOptions configuration)
{
return configuration == default
? default
: new MediaStreamingOptionsInternal(configuration.TransportUri.AbsoluteUri, configuration.MediaStreamingTransport,
configuration.MediaStreamingContent, configuration.MediaStreamingAudioChannel, configuration.StartMediaStreaming,
configuration.EnableBidirectional, configuration.AudioFormat);
: new TranscriptionOptionsInternal(configuration.TransportUrl.AbsoluteUri, configuration.TranscriptionTransport, configuration.Locale,
configuration.StartTranscription);
}
private static TranscriptionOptionsInternal CreateTranscriptionOptionsInternal(TranscriptionOptions configuration)

private static MediaStreamingOptionsInternal CreateMediaStreamingOptionsInternal(MediaStreamingOptions configuration)
{
return configuration == default
? default
: new TranscriptionOptionsInternal(configuration.TransportUrl.AbsoluteUri, configuration.TranscriptionTransport, configuration.Locale,
configuration.StartTranscription.GetValueOrDefault())
{
EnableIntermediateResults = configuration.EnableIntermediateResults,
SpeechRecognitionModelEndpointId = configuration.SpeechRecognitionModelEndpointId
};
: new MediaStreamingOptionsInternal(configuration.TransportUri.AbsoluteUri, configuration.MediaStreamingTransport,
configuration.MediaStreamingContent, configuration.MediaStreamingAudioChannel, configuration.StartMediaStreaming,
configuration.EnableBidirectional, configuration.AudioFormat);
}

/// <summary> Initializes a new instance of CallConnection. <see cref="CallConnection"/>.</summary>
Expand Down
Loading