diff --git a/sdk/communication/communication-call-automation/src/callAutomationClient.ts b/sdk/communication/communication-call-automation/src/callAutomationClient.ts index a22a8b066d8f..f48b0114dbc5 100644 --- a/sdk/communication/communication-call-automation/src/callAutomationClient.ts +++ b/sdk/communication/communication-call-automation/src/callAutomationClient.ts @@ -339,6 +339,9 @@ export class CallAutomationClient { operationContext: operationContext, callbackUri: callbackUrl, answeredBy: this.sourceIdentity, + customCallingContext: this.createCustomCallingContextInternal( + options.customCallingContext!, + ), }; const optionsInternal = { ...operationOptions, diff --git a/sdk/communication/communication-call-automation/src/models/options.ts b/sdk/communication/communication-call-automation/src/models/options.ts index e0ea30e60516..fed1efb4f3d8 100644 --- a/sdk/communication/communication-call-automation/src/models/options.ts +++ b/sdk/communication/communication-call-automation/src/models/options.ts @@ -144,6 +144,8 @@ export interface AnswerCallOptions extends OperationOptions { transcriptionOptions?: TranscriptionOptions; /** The operation context. */ operationContext?: string; + /** The Custom Context. */ + customCallingContext?: CustomCallingContext; } /** diff --git a/sdk/communication/communication-call-automation/test/node/callAutomationClient.live.spec.ts b/sdk/communication/communication-call-automation/test/node/callAutomationClient.live.spec.ts index 6290834543f9..a96e6c6feba2 100644 --- a/sdk/communication/communication-call-automation/test/node/callAutomationClient.live.spec.ts +++ b/sdk/communication/communication-call-automation/test/node/callAutomationClient.live.spec.ts @@ -112,6 +112,54 @@ describe("Call Automation Main Client Live Tests", { skip: !isNodeLike }, () => assert.isDefined(callDisconnectedEvent); }); + it("answer call with custom context and hangup", { timeout: 60000 }, async (ctx) => { + const fullTitle: string | undefined = + ctx.task.suite && ctx.task.suite.name && ctx.task.name + ? `${ctx.task.suite.name} ${ctx.task.name}` + : undefined; + + testName = fullTitle ? fullTitle.replace(/ /g, "_") : "answer_call_with_custom_context_and_hang_up"; + await loadPersistedEvents(testName); + + const callInvite: CallInvite = { targetParticipant: testUser2 }; + const uniqueId = await serviceBusWithNewCall(testUser, testUser2); + const callBackUrl: string = dispatcherCallback + `?q=${uniqueId}`; + const createCallOption: CreateCallOptions = { operationContext: "operationContextCreateCall" }; + + const result = await callerCallAutomationClient.createCall( + callInvite, + callBackUrl, + createCallOption, + ); + const incomingCallContext = await waitForIncomingCallContext(uniqueId, 8000); + const callConnectionId: string = result.callConnectionProperties.callConnectionId + ? result.callConnectionProperties.callConnectionId + : ""; + assert.isDefined(incomingCallContext); + + if (incomingCallContext) { + const answerCallOptions: AnswerCallOptions = { + operationContext: "operationContextAnswerCall", + customCallingContext : [{ kind: "voip", key: "foo", value: "bar" }] + }; + await receiverCallAutomationClient.answerCall( + incomingCallContext, + callBackUrl, + answerCallOptions, + ); + } + + const callConnectedEvent = await waitForEvent("CallConnected", callConnectionId, 8000); + + assert.isDefined(callConnectedEvent); + callConnection = result.callConnection; + + await callConnection.hangUp(true); + + const callDisconnectedEvent = await waitForEvent("CallDisconnected", callConnectionId, 8000); + assert.isDefined(callDisconnectedEvent); + }); + it("Reject call", { timeout: 60000 }, async (ctx) => { const fullTitle: string | undefined = ctx.task.suite && ctx.task.suite.name && ctx.task.name diff --git a/sdk/communication/communication-call-automation/test/node/callAutomationClient.spec.ts b/sdk/communication/communication-call-automation/test/node/callAutomationClient.spec.ts index 6967e13ffc6f..bd32d8252359 100644 --- a/sdk/communication/communication-call-automation/test/node/callAutomationClient.spec.ts +++ b/sdk/communication/communication-call-automation/test/node/callAutomationClient.spec.ts @@ -13,7 +13,7 @@ import type { CommunicationIdentifier, MicrosoftTeamsAppIdentifier, } from "@azure/communication-common"; -import type { CallInvite, CallConnection } from "../../src/index.js"; +import type { CallInvite, CallConnection, AnswerCallOptions } from "../../src/index.js"; import type { AnswerCallEventResult, CreateCallEventResult, @@ -185,6 +185,30 @@ describe("Call Automation Client Unit Tests", () => { assert.equal(result, answerCallResultMock); }); + it("AnswerCall with custom context", async () => { + // mocks + const answerCallResultMock: AnswerCallResult = { + callConnectionProperties: {} as CallConnectionProperties, + callConnection: {} as CallConnection, + waitForEventProcessor: async () => { + return {} as AnswerCallEventResult; + }, + }; + vi.spyOn(client, "answerCall").mockResolvedValue(answerCallResultMock); + const answerCallOptions: AnswerCallOptions = { + operationContext: "operationContextAnswerCall", + customCallingContext : [{ kind: "voip", key: "foo", value: "bar" }] + }; + const promiseResult = client.answerCall(CALL_INCOMING_CALL_CONTEXT, CALL_CALLBACK_URL, answerCallOptions); + + // asserts + const result = await promiseResult; + + assert.isNotNull(result); + expect(client.answerCall).toHaveBeenCalledWith(CALL_INCOMING_CALL_CONTEXT, CALL_CALLBACK_URL); + assert.equal(result, answerCallResultMock); + }); + it("RedirectCall", async () => { // mocks vi.spyOn(client, "redirectCall").mockReturnValue(