Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
06f22eb
ga5 changes
v-dharmarajv May 9, 2025
f5cebcd
ga5 api changes
v-dharmarajv May 13, 2025
a7a071d
Made GA5 changes and recorded the live tests. (#45409)
v-pivamshi May 20, 2025
4c30693
Addressing arb comments
v-dharmarajv May 21, 2025
cf508ed
Added the parser for the dtmf data. (#45347)
v-pivamshi May 21, 2025
6300665
updating the white space difference
v-dharmarajv May 21, 2025
a34f372
addressing the arb comments
v-dharmarajv May 21, 2025
3beae7c
GA5 Javadoc Issues (#45432)
v-saasomani May 21, 2025
47bb9e9
Re-recorded tests and fixed linting issues (unused imports). (#45448)
v-saasomani May 22, 2025
99dccc2
updating java missing fields
v-dharmarajv May 22, 2025
0baee07
Merge branch 'callautomation/release/ga5' of https://github.com/Azure…
v-dharmarajv May 22, 2025
50ad4c7
lint errors
v-dharmarajv May 22, 2025
6fafaf3
moving transport url
v-dharmarajv May 23, 2025
0b8acfa
Addressing the ARB Comments
v-dharmarajv May 27, 2025
2fe8f65
addressing the arb comments
v-dharmarajv May 27, 2025
b83c48e
addressing all arb comments
v-dharmarajv May 27, 2025
e5964c9
merge from main
v-dharmarajv May 27, 2025
1a568e4
updating the transcription and media streaming options
v-dharmarajv May 28, 2025
2a11acf
Fixed Javadoc issues + updated ga5 version. (#45496)
v-saasomani May 28, 2025
0722329
Fixing the lint errors
v-dharmarajv May 28, 2025
f0b6caa
fixing the lint error
v-dharmarajv May 28, 2025
f2faa81
updating the changelog
v-dharmarajv May 30, 2025
c8f0c56
merge from main
v-dharmarajv Jun 3, 2025
2e374f3
Updating the changelog and release date
v-dharmarajv Jun 4, 2025
adcf1bb
Created feature branch off of callautomation/release/ga5. Updated to …
v-saasomani Jun 4, 2025
0141709
Ran recorded tests. Fixed timeout issue with waiting for incomingCall…
v-saasomani Jun 16, 2025
c319bb9
merging from main
v-dharmarajv Jun 23, 2025
1d871a8
adding teams extension user id
v-dharmarajv Jun 23, 2025
789d7ee
ga6 version
v-dharmarajv Jun 23, 2025
320d949
changelog update
v-dharmarajv Jun 23, 2025
fc8a861
moving the sipheaderprefix to extendable enum
v-dharmarajv Jun 23, 2025
68497db
setting callconnection id to recording request
v-dharmarajv Jul 7, 2025
46890d9
merging from main
v-dharmarajv Jul 10, 2025
db98550
updating the ga version
v-dharmarajv Jul 10, 2025
9143398
Increment package versions for core releases (#45876)
azure-sdk Jun 30, 2025
a408c48
Increment package versions for patch releases (#45841)
jairmyree Jun 26, 2025
a4d4c1f
latest from main autorest version
v-dharmarajv Jul 10, 2025
0aa988b
apispec endpoint from the main
v-dharmarajv Jul 10, 2025
9086a08
Fixing the build issues
v-dharmarajv Jul 11, 2025
5c81e17
cherry pickign the changes
v-dharmarajv Jul 11, 2025
4005a5e
adding recorded test
v-dharmarajv Jul 12, 2025
0ebacb5
pushing latest record file
v-dharmarajv Jul 12, 2025
569ff47
removing the public contructor as per the comments
v-dharmarajv Jul 12, 2025
05e0493
removing tests which are added mistaken
v-dharmarajv Jul 14, 2025
58e5649
Merging from main
v-dharmarajv Jul 14, 2025
819831c
updating the release date for the ga6
v-dharmarajv Jul 25, 2025
a231ded
changelog update
v-dharmarajv Jul 29, 2025
a8a72be
removing the release date
v-dharmarajv Jul 29, 2025
ab59789
reverting version beta until finalize the release date
v-dharmarajv Jul 30, 2025
a356468
merge from main
v-dharmarajv Jul 30, 2025
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 @@ -4,11 +4,11 @@

### Features Added

### Breaking Changes

### Bugs Fixed

### Other Changes
- Added support for Teams multipersona users in create call, add participant, transfer, and redirect scenarios in OPS 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 StartRecordingFailed event to indicate when the start recording API is unable to initiate the recording.
- Adds support for SIP headers prefixed with 'X-' and 'X-MS-Custom-' within the CustomCallingContext.

## 1.4.1 (2025-06-19)

Expand Down
57 changes: 1 addition & 56 deletions sdk/communication/azure-communication-callautomation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This package contains a Java SDK for Azure Communication Call Automation Service
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-communication-callautomation</artifactId>
<version>1.4.1</version>
<version>1.5.0</version>
</dependency>
```

Expand All @@ -41,61 +41,6 @@ This is the restart of Call Automation Service. It is renamed to Call Automation

`CallAutomationEventParser` provides the functionality to handle events from the ACS resource.

## Examples

### Handle Mid-Connection events with CallAutomation's EventProcessor

To easily handle mid-connection events, Call Automation's SDK provides easier way to handle these events.
Take a look at `CallAutomationEventProcessor`. This will ensure correlation between call and events more easily.

```Java
@RestController
public class ActionController {
// Controller implementation...

@RequestMapping(value = "/api/events", method = POST)
public ResponseEntity<?> handleCallEvents(@RequestBody String requestBody) {
try {
CallAutomationAsyncClient client = getCallAutomationAsyncClient();
client.getEventProcessor().processEvents(requestBody);

return new ResponseEntity<>(HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
```

`processEvents` is required for EventProcessor to work.
After event is being consumed by EventProcessor, you can start using its feature.

See below for example: where you are making a call with `CreateCall`, and wait for `CallConnected` event of the call.

```Java
public class commandClass {
// Class implementation...

public void createCallCommand() {
CallAutomationAsyncClient client = getCallAutomationAsyncClient(); // Should be the same instance as the one used in the example above.
String callbackUrl = "<YOUR_CALL_BACK_URL>";
CallInvite callInvite = new CallInvite(new CommunicationUserIdentifier("<TARGET_USER_ID>"));
CreateCallResult result = client.createCall(callInvite, callbackUrl).block();

try {
// This will wait until CallConnected event is arrived or Timesout!
CreateCallEventResult eventResult = result.waitForEventProcessorAsync(Duration.ofSeconds(30)).block();
CallConnected returnedEvent = eventResult.successResult();
} catch (Exception e) {
// Timeout exception happend!
// Call likely was never answered.
}
}
}
```

If timeout was not set when calling "waitForEventProcessorAsync", the default timeout is 4 minutes.

## Troubleshooting

If you receive a CommunicationErrorException with the message: "Action is invalid when call is not in Established state." This usually means the call has ended. This can occur if the participants all leave
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "java",
"TagPrefix": "java/communication/azure-communication-callautomation",
"Tag": "java/communication/azure-communication-callautomation_33108318f9"
"Tag": "java/communication/azure-communication-callautomation_89c8cc481e"
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version> <!-- {x-version-update;org.hamcrest:hamcrest-all;external_dependency} -->
<version>1.3</version>
<!-- {x-version-update;org.hamcrest:hamcrest-all;external_dependency} -->
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.azure.communication.callautomation.implementation.converters.CommunicationIdentifierConverter;
import com.azure.communication.callautomation.implementation.converters.CommunicationUserIdentifierConverter;
import com.azure.communication.callautomation.implementation.converters.PhoneNumberIdentifierConverter;
import com.azure.communication.callautomation.implementation.converters.MicrosoftTeamsAppIdentifierConverter;
import com.azure.communication.callautomation.implementation.models.AnswerCallRequestInternal;
import com.azure.communication.callautomation.implementation.models.AudioFormatInternal;
import com.azure.communication.callautomation.implementation.models.CallIntelligenceOptionsInternal;
Expand Down Expand Up @@ -239,6 +240,11 @@ private CreateCallRequestInternal getCreateCallRequestInternal(CreateCallOptions
request.setTranscriptionOptions(transcriptionOptionsInternal);
}

if (createCallOptions.getTeamsAppSource() != null) {
request
.setTeamsAppSource(MicrosoftTeamsAppIdentifierConverter.convert(createCallOptions.getTeamsAppSource()));
}

return request;
}

Expand Down Expand Up @@ -278,6 +284,11 @@ private CreateCallRequestInternal getCreateCallRequestInternal(CreateGroupCallOp
request.setTranscriptionOptions(transcriptionOptionsInternal);
}

if (createCallGroupOptions.getTeamsAppSource() != null) {
request.setTeamsAppSource(
MicrosoftTeamsAppIdentifierConverter.convert(createCallGroupOptions.getTeamsAppSource()));
}

return request;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ public enum CallAutomationServiceVersion implements ServiceVersion {
/**
* Service version {@code 2025-05-15}.
*/
V2025_05_15("2025-05-15");
V2025_05_15("2025-05-15"),
/**
* Service version {@code 2025-06-15}.
*/
V2025_06_15("2025-06-15");

private final String version;

Expand All @@ -55,6 +59,6 @@ public String getVersion() {
* @return The latest {@link CallAutomationServiceVersion} object.
*/
public static CallAutomationServiceVersion getLatest() {
return V2025_05_15;
return V2025_06_15;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.azure.communication.common.MicrosoftTeamsAppIdentifier;
import com.azure.communication.common.MicrosoftTeamsUserIdentifier;
import com.azure.communication.common.PhoneNumberIdentifier;
import com.azure.communication.common.TeamsExtensionUserIdentifier;
import com.azure.core.annotation.ReturnType;
import com.azure.core.annotation.ServiceMethod;
import com.azure.core.exception.HttpResponseException;
Expand Down Expand Up @@ -259,6 +260,10 @@ public Mono<TransferCallResult> transferCallToParticipant(CommunicationIdentifie
return transferCallToParticipantWithResponse(
new TransferCallToParticipantOptions((MicrosoftTeamsAppIdentifier) targetParticipant))
.flatMap(FluxUtil::toMono);
} else if (targetParticipant instanceof TeamsExtensionUserIdentifier) {
return transferCallToParticipantWithResponse(
new TransferCallToParticipantOptions((TeamsExtensionUserIdentifier) targetParticipant))
.flatMap(FluxUtil::toMono);
} else {
throw logger.logExceptionAsError(new IllegalArgumentException("targetParticipant type is invalid."));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ private StartCallRecordingRequestInternal getStartCallRecordingRequest(StartReco
if (options.isPauseOnStart() != null) {
request.setPauseOnStart(options.isPauseOnStart());
}
if (options.getCallConnectionId() != null) {
request.setCallConnectionId(options.getCallConnectionId());
}
return request;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public AzureCommunicationCallAutomationServiceImplBuilder retryPolicy(RetryPolic
public AzureCommunicationCallAutomationServiceImpl buildClient() {
this.validateClient();
HttpPipeline localPipeline = (pipeline != null) ? pipeline : createHttpPipeline();
String localApiVersion = (apiVersion != null) ? apiVersion : "2025-05-15";
String localApiVersion = (apiVersion != null) ? apiVersion : "2025-06-15";
SerializerAdapter localSerializerAdapter
= (serializerAdapter != null) ? serializerAdapter : JacksonAdapter.createDefaultSerializerAdapter();
AzureCommunicationCallAutomationServiceImpl client = new AzureCommunicationCallAutomationServiceImpl(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public final class CallRecordingsImpl {
@ServiceInterface(name = "AzureCommunicationCallAutomationServiceCallRecordings")
public interface CallRecordingsService {
@Post("/calling/recordings")
@ExpectedResponses({ 200 })
@ExpectedResponses({ 200, 202 })
@UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
Mono<Response<RecordingStateResponseInternal>> startRecording(@HostParam("endpoint") String endpoint,
@QueryParam("api-version") String apiVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
import com.azure.communication.callautomation.implementation.models.MicrosoftTeamsAppIdentifierModel;
import com.azure.communication.callautomation.implementation.models.MicrosoftTeamsUserIdentifierModel;
import com.azure.communication.callautomation.implementation.models.PhoneNumberIdentifierModel;
import com.azure.communication.callautomation.implementation.models.TeamsExtensionUserIdentifierModel;
import com.azure.communication.common.CommunicationCloudEnvironment;
import com.azure.communication.common.CommunicationIdentifier;
import com.azure.communication.common.CommunicationUserIdentifier;
import com.azure.communication.common.MicrosoftTeamsAppIdentifier;
import com.azure.communication.common.MicrosoftTeamsUserIdentifier;
import com.azure.communication.common.PhoneNumberIdentifier;
import com.azure.communication.common.TeamsExtensionUserIdentifier;
import com.azure.communication.common.UnknownIdentifier;

import java.util.ArrayList;
Expand Down Expand Up @@ -66,6 +68,25 @@ public static CommunicationIdentifier convert(CommunicationIdentifierModel ident
CommunicationCloudEnvironment.fromString(teamsUserIdentifierModel.getCloud().toString()));
}

if (kind == CommunicationIdentifierModelKind.TEAMS_EXTENSION_USER
&& identifier.getTeamsExtensionUser() != null) {
TeamsExtensionUserIdentifierModel teamsExtensionUserIdentifierModel = identifier.getTeamsExtensionUser();
Objects.requireNonNull(teamsExtensionUserIdentifierModel.getUserId(),
"'UserID' of the CommunicationIdentifierModel cannot be null.");
Objects.requireNonNull(teamsExtensionUserIdentifierModel.getResourceId(),
"'ResourceId' of the CommunicationIdentifierModel cannot be null.");
Objects.requireNonNull(teamsExtensionUserIdentifierModel.getTenantId(),
"'TenantId' of the CommunicationIdentifierModel cannot be null.");
Objects.requireNonNull(teamsExtensionUserIdentifierModel.getCloud(),
"'Cloud' of the CommunicationIdentifierModel cannot be null.");
Objects.requireNonNull(rawId, "'RawID' of the CommunicationIdentifierModel cannot be null.");
return new TeamsExtensionUserIdentifier(teamsExtensionUserIdentifierModel.getUserId(),
teamsExtensionUserIdentifierModel.getTenantId(), teamsExtensionUserIdentifierModel.getResourceId())
.setRawId(rawId)
.setCloudEnvironment(CommunicationCloudEnvironment
.fromString(teamsExtensionUserIdentifierModel.getCloud().toString()));
}

if (kind == CommunicationIdentifierModelKind.MICROSOFT_TEAMS_APP && identifier.getMicrosoftTeamsApp() != null) {
MicrosoftTeamsAppIdentifierModel teamsUserIdentifierModel = identifier.getMicrosoftTeamsApp();
Objects.requireNonNull(teamsUserIdentifierModel.getAppId(),
Expand Down Expand Up @@ -122,6 +143,17 @@ public static CommunicationIdentifierModel convert(CommunicationIdentifier ident
.fromString(teamsAppIdentifier.getCloudEnvironment().toString())));
}

if (identifier instanceof TeamsExtensionUserIdentifier) {
TeamsExtensionUserIdentifier teamsExtensionUserIdentifier = (TeamsExtensionUserIdentifier) identifier;
return new CommunicationIdentifierModel().setRawId(teamsExtensionUserIdentifier.getRawId())
.setTeamsExtensionUser(
new TeamsExtensionUserIdentifierModel().setResourceId(teamsExtensionUserIdentifier.getResourceId())
.setUserId(teamsExtensionUserIdentifier.getUserId())
.setTenantId(teamsExtensionUserIdentifier.getTenantId())
.setCloud(CommunicationCloudEnvironmentModel
.fromString(teamsExtensionUserIdentifier.getCloudEnvironment().toString())));
}

if (identifier instanceof UnknownIdentifier) {
UnknownIdentifier unknownIdentifier = (UnknownIdentifier) identifier;
return new CommunicationIdentifierModel().setRawId(unknownIdentifier.getId());
Expand Down Expand Up @@ -171,6 +203,9 @@ private static CommunicationIdentifierModelKind extractKind(CommunicationIdentif
if (identifier.getMicrosoftTeamsApp() != null) {
return CommunicationIdentifierModelKind.MICROSOFT_TEAMS_APP;
}
if (identifier.getTeamsExtensionUser() != null) {
return CommunicationIdentifierModelKind.TEAMS_EXTENSION_USER;
}
return CommunicationIdentifierModelKind.UNKNOWN;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ public final class CommunicationIdentifierModel implements JsonSerializable<Comm
@Generated
private MicrosoftTeamsAppIdentifierModel microsoftTeamsApp;

/*
* The Microsoft Teams Extension user.
*/
@Generated
private TeamsExtensionUserIdentifierModel teamsExtensionUser;

/**
* Creates an instance of CommunicationIdentifierModel class.
*/
Expand Down Expand Up @@ -194,6 +200,28 @@ public CommunicationIdentifierModel setMicrosoftTeamsApp(MicrosoftTeamsAppIdenti
return this;
}

/**
* Get the teamsExtensionUser property: The Microsoft Teams Extension user.
*
* @return the teamsExtensionUser value.
*/
@Generated
public TeamsExtensionUserIdentifierModel getTeamsExtensionUser() {
return this.teamsExtensionUser;
}

/**
* Set the teamsExtensionUser property: The Microsoft Teams Extension user.
*
* @param teamsExtensionUser the teamsExtensionUser value to set.
* @return the CommunicationIdentifierModel object itself.
*/
@Generated
public CommunicationIdentifierModel setTeamsExtensionUser(TeamsExtensionUserIdentifierModel teamsExtensionUser) {
this.teamsExtensionUser = teamsExtensionUser;
return this;
}

/**
* {@inheritDoc}
*/
Expand All @@ -207,6 +235,7 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException {
jsonWriter.writeJsonField("phoneNumber", this.phoneNumber);
jsonWriter.writeJsonField("microsoftTeamsUser", this.microsoftTeamsUser);
jsonWriter.writeJsonField("microsoftTeamsApp", this.microsoftTeamsApp);
jsonWriter.writeJsonField("teamsExtensionUser", this.teamsExtensionUser);
return jsonWriter.writeEndObject();
}

Expand Down Expand Up @@ -242,6 +271,9 @@ public static CommunicationIdentifierModel fromJson(JsonReader jsonReader) throw
} else if ("microsoftTeamsApp".equals(fieldName)) {
deserializedCommunicationIdentifierModel.microsoftTeamsApp
= MicrosoftTeamsAppIdentifierModel.fromJson(reader);
} else if ("teamsExtensionUser".equals(fieldName)) {
deserializedCommunicationIdentifierModel.teamsExtensionUser
= TeamsExtensionUserIdentifierModel.fromJson(reader);
} else {
reader.skipChildren();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public final class CommunicationIdentifierModelKind extends ExpandableStringEnum
@Generated
public static final CommunicationIdentifierModelKind MICROSOFT_TEAMS_APP = fromString("microsoftTeamsApp");

/**
* Static value teamsExtensionUser for CommunicationIdentifierModelKind.
*/
@Generated
public static final CommunicationIdentifierModelKind TEAMS_EXTENSION_USER = fromString("teamsExtensionUser");

/**
* Creates a new instance of CommunicationIdentifierModelKind value.
*
Expand Down
Loading