Skip to content

Commit 0cde479

Browse files
Juntuchen/js update (Azure#25543)
### Packages impacted by this PR ### Issues associated with this PR ### Describe the problem that is addressed by this PR ### What are the possible designs available to address the problem? If there are more than one possible design, why was the one in this PR chosen? ### Are there test cases added in this PR? _(If not, why?)_ ### Provide a list of related PRs _(if any)_ ### Command used to generate this PR:**_(Applicable only to SDK release request PRs)_ ### Checklists - [ ] Added impacted package name to the issue description - [ ] Does this PR needs any fixes in the SDK Generator?** _(If so, create an Issue in the [Autorest/typescript](https://github.com/Azure/autorest.typescript) repository and link it here)_ - [ ] Added a changelog (if necessary)
1 parent d39b4f7 commit 0cde479

File tree

7 files changed

+150
-67
lines changed

7 files changed

+150
-67
lines changed

sdk/communication/communication-call-automation/review/communication-call-automation.api.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ export class CallAutomationClient {
6464
constructor(connectionString: string, options?: CallAutomationClientOptions);
6565
constructor(endpoint: string, credential: KeyCredential, options?: CallAutomationClientOptions);
6666
constructor(endpoint: string, credential: TokenCredential, options?: CallAutomationClientOptions);
67-
answerCall(incomingCallContext: string, callbackUri: string, options?: AnswerCallOptions): Promise<AnswerCallResult>;
68-
createCall(target: CallInvite | CommunicationIdentifier[], callbackUri: string, options?: CreateCallOptions): Promise<CreateCallResult>;
67+
answerCall(incomingCallContext: string, callbackUrl: string, options?: AnswerCallOptions): Promise<AnswerCallResult>;
68+
createCall(target: CallInvite, callbackUrl: string, options?: CreateCallOptions): Promise<CreateCallResult>;
69+
createGroupCall(targets: CommunicationIdentifier[], callbackUrl: string, options?: CreateCallOptions): Promise<CreateCallResult>;
6970
getCallConnection(callConnectionId: string): CallConnection;
7071
getCallRecording(): CallRecording;
7172
getSourceIdentity(): CommunicationUserIdentifier | undefined;
@@ -84,7 +85,7 @@ export type CallAutomationEvent = AddParticipantSucceeded | AddParticipantFailed
8485
// @public
8586
export class CallAutomationEventParser {
8687
// (undocumented)
87-
parse(encodedEvents: string): Promise<CallAutomationEvent>;
88+
parse(encodedEvent: string): Promise<CallAutomationEvent>;
8889
// (undocumented)
8990
parse(encodedEvents: Record<string, unknown>): Promise<CallAutomationEvent>;
9091
}

sdk/communication/communication-call-automation/src/callAutomationClient.ts

Lines changed: 88 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
PhoneNumberIdentifierModelConverter,
3939
} from "./utli/converters";
4040
import { ContentDownloaderImpl } from "./contentDownloader";
41+
import { v4 as uuidv4 } from "uuid";
4142

4243
/**
4344
* Client options used to configure CallAutomation Client API requests.
@@ -159,48 +160,16 @@ export class CallAutomationClient {
159160
: undefined;
160161
}
161162

162-
/**
163-
* Create an outgoing call from source to target identities.
164-
* @param target - Either a single target or a group of target identities.
165-
* @param callbackUri - The callback url.
166-
* @param options - Additional request options contains createCallConnection api options.
167-
*/
168-
public async createCall(
169-
target: CallInvite | CommunicationIdentifier[],
170-
callbackUri: string,
171-
options: CreateCallOptions = {}
163+
private async createCallInternal(
164+
request: CreateCallRequest,
165+
options?: CreateCallOptions
172166
): Promise<CreateCallResult> {
173-
const request: CreateCallRequest = {
174-
sourceIdentity: this.sourceIdentity,
175-
targets:
176-
target instanceof CallInvite
177-
? [communicationIdentifierModelConverter(target.target)]
178-
: target.map((m) => communicationIdentifierModelConverter(m)),
179-
callbackUri: callbackUri,
180-
operationContext: options.operationContext,
181-
azureCognitiveServicesEndpointUrl: options.azureCognitiveServicesEndpointUrl,
182-
mediaStreamingConfiguration: options.mediaStreamingConfiguration,
183-
customContext: {
184-
sipHeaders:
185-
target instanceof CallInvite ? target.sipHeaders : options.sipHeaders ?? undefined,
186-
voipHeaders:
187-
target instanceof CallInvite ? target.voipHeaders : options.voipHeaders ?? undefined,
188-
},
189-
sourceCallerIdNumber:
190-
target instanceof CallInvite
191-
? PhoneNumberIdentifierModelConverter(target.sourceCallIdNumber)
192-
: options.sourceCallIdNumber
193-
? PhoneNumberIdentifierModelConverter(options.sourceCallIdNumber)
194-
: undefined,
195-
sourceDisplayName:
196-
target instanceof CallInvite
197-
? target.sourceDisplayName
198-
: options.sourceDisplayName
199-
? options.sourceDisplayName
200-
: undefined,
167+
const optionsInternal = {
168+
...options,
169+
repeatabilityFirstSent: new Date().toUTCString(),
170+
repeatabilityRequestID: uuidv4(),
201171
};
202-
203-
const result = await this.callAutomationApiClient.createCall(request, options);
172+
const result = await this.callAutomationApiClient.createCall(request, optionsInternal);
204173

205174
if (result?.callConnectionId) {
206175
const callConnectionPropertiesDto: CallConnectionProperties = {
@@ -229,25 +198,87 @@ export class CallAutomationClient {
229198
throw "callConnectionProperties / callConnectionId is missing in createCall result";
230199
}
231200

201+
/**
202+
* Create an outgoing call from source to a target identity.
203+
* @param target - A single target.
204+
* @param callbackUrl - The callback url.
205+
* @param options - Additional request options contains createCallConnection api options.
206+
*/
207+
public async createCall(
208+
target: CallInvite,
209+
callbackUrl: string,
210+
options: CreateCallOptions = {}
211+
): Promise<CreateCallResult> {
212+
const request: CreateCallRequest = {
213+
sourceIdentity: this.sourceIdentity,
214+
targets: [communicationIdentifierModelConverter(target.target)],
215+
callbackUri: callbackUrl,
216+
operationContext: options.operationContext,
217+
azureCognitiveServicesEndpointUrl: options.azureCognitiveServicesEndpointUrl,
218+
mediaStreamingConfiguration: options.mediaStreamingConfiguration,
219+
customContext: {
220+
sipHeaders: target.sipHeaders,
221+
voipHeaders: target.voipHeaders,
222+
},
223+
sourceCallerIdNumber: PhoneNumberIdentifierModelConverter(target.sourceCallIdNumber),
224+
sourceDisplayName: target.sourceDisplayName,
225+
};
226+
227+
return this.createCallInternal(request, options);
228+
}
229+
230+
/**
231+
* Create an outgoing call from source to a group of targets identities.
232+
* @param targets - A group of targets identities.
233+
* @param callbackUrl - The callback url.
234+
* @param options - Additional request options contains createCallConnection api options.
235+
*/
236+
public async createGroupCall(
237+
targets: CommunicationIdentifier[],
238+
callbackUrl: string,
239+
options: CreateCallOptions = {}
240+
): Promise<CreateCallResult> {
241+
const request: CreateCallRequest = {
242+
sourceIdentity: this.sourceIdentity,
243+
targets: targets.map((target) => communicationIdentifierModelConverter(target)),
244+
callbackUri: callbackUrl,
245+
operationContext: options.operationContext,
246+
azureCognitiveServicesEndpointUrl: options.azureCognitiveServicesEndpointUrl,
247+
mediaStreamingConfiguration: options.mediaStreamingConfiguration,
248+
customContext: {
249+
sipHeaders: options.sipHeaders,
250+
voipHeaders: options.voipHeaders,
251+
},
252+
sourceCallerIdNumber: PhoneNumberIdentifierModelConverter(options.sourceCallIdNumber),
253+
sourceDisplayName: options.sourceDisplayName,
254+
};
255+
256+
return this.createCallInternal(request, options);
257+
}
258+
232259
/**
233260
* Answer the call.
234261
* @param incomingCallContext - The context associated with the call.
235-
* @param callbackUri - The callback url.
262+
* @param callbackUrl - The callback url.
236263
* @param options - Additional request options contains answerCall api options.
237264
*/
238265
public async answerCall(
239266
incomingCallContext: string,
240-
callbackUri: string,
267+
callbackUrl: string,
241268
options: AnswerCallOptions = {}
242269
): Promise<AnswerCallResult> {
243270
const request: AnswerCallRequest = {
244271
incomingCallContext: incomingCallContext,
245-
callbackUri: callbackUri,
272+
callbackUri: callbackUrl,
246273
mediaStreamingConfiguration: options.mediaStreamingConfiguration,
247274
azureCognitiveServicesEndpointUrl: options.azureCognitiveServicesEndpointUrl,
248275
};
249-
250-
const result = await this.callAutomationApiClient.answerCall(request, options);
276+
const optionsInternal = {
277+
...options,
278+
repeatabilityFirstSent: new Date().toUTCString(),
279+
repeatabilityRequestID: uuidv4(),
280+
};
281+
const result = await this.callAutomationApiClient.answerCall(request, optionsInternal);
251282

252283
if (result?.callConnectionId) {
253284
const callConnectionProperties: CallConnectionProperties = {
@@ -296,8 +327,13 @@ export class CallAutomationClient {
296327
target instanceof CallInvite ? target.voipHeaders : options.voipHeaders ?? undefined,
297328
},
298329
};
330+
const optionsInternal = {
331+
...options,
332+
repeatabilityFirstSent: new Date().toUTCString(),
333+
repeatabilityRequestID: uuidv4(),
334+
};
299335

300-
return this.callAutomationApiClient.redirectCall(request, options);
336+
return this.callAutomationApiClient.redirectCall(request, optionsInternal);
301337
}
302338

303339
/**
@@ -314,7 +350,12 @@ export class CallAutomationClient {
314350
incomingCallContext: incomingCallContext,
315351
callRejectReason: options.callRejectReason,
316352
};
353+
const optionsInternal = {
354+
...options,
355+
repeatabilityFirstSent: new Date().toUTCString(),
356+
repeatabilityRequestID: uuidv4(),
357+
};
317358

318-
return this.callAutomationApiClient.rejectCall(request, options);
359+
return this.callAutomationApiClient.rejectCall(request, optionsInternal);
319360
}
320361
}

sdk/communication/communication-call-automation/src/callAutomationEventParser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const serializer = createSerializer();
3434
* Helper class for parsing Acs callback events.
3535
*/
3636
export class CallAutomationEventParser {
37-
public async parse(encodedEvents: string): Promise<CallAutomationEvent>;
37+
public async parse(encodedEvent: string): Promise<CallAutomationEvent>;
3838

3939
public async parse(encodedEvents: Record<string, unknown>): Promise<CallAutomationEvent>;
4040

sdk/communication/communication-call-automation/src/callConnection.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
phoneNumberIdentifierConverter,
3232
PhoneNumberIdentifierModelConverter,
3333
} from "./utli/converters";
34+
import { v4 as uuidv4 } from "uuid";
3435

3536
/**
3637
* CallConnection class represents call connection based APIs.
@@ -84,7 +85,12 @@ export class CallConnection {
8485
*/
8586
public async hangUp(isForEveryOne: boolean, options: HangUpOptions = {}): Promise<void> {
8687
if (isForEveryOne) {
87-
await this.callConnectionImpl.terminateCall(this.callConnectionId, options);
88+
const optionsInternal = {
89+
...options,
90+
repeatabilityFirstSent: new Date().toUTCString(),
91+
repeatabilityRequestID: uuidv4(),
92+
};
93+
await this.callConnectionImpl.terminateCall(this.callConnectionId, optionsInternal);
8894
} else {
8995
await this.callConnectionImpl.hangupCall(this.callConnectionId, options);
9096
}
@@ -150,11 +156,15 @@ export class CallConnection {
150156
voipHeaders: participant.voipHeaders,
151157
},
152158
};
153-
159+
const optionsInternal = {
160+
...options,
161+
repeatabilityFirstSent: new Date().toUTCString(),
162+
repeatabilityRequestID: uuidv4(),
163+
};
154164
const result = await this.callConnectionImpl.addParticipant(
155165
this.callConnectionId,
156166
addParticipantRequest,
157-
options
167+
optionsInternal
158168
);
159169
const addParticipantsResult: AddParticipantResult = {
160170
...result,
@@ -185,11 +195,15 @@ export class CallConnection {
185195
voipHeaders: target.voipHeaders,
186196
},
187197
};
188-
198+
const optionsInternal = {
199+
...options,
200+
repeatabilityFirstSent: new Date().toUTCString(),
201+
repeatabilityRequestID: uuidv4(),
202+
};
189203
const result = await this.callConnectionImpl.transferToParticipant(
190204
this.callConnectionId,
191205
transferToParticipantRequest,
192-
options
206+
optionsInternal
193207
);
194208
const transferCallResult: TransferCallResult = { ...result };
195209
return transferCallResult;
@@ -208,11 +222,15 @@ export class CallConnection {
208222
participantToRemove: communicationIdentifierModelConverter(participant),
209223
operationContext: options.operationContext,
210224
};
211-
225+
const optionsInternal = {
226+
...options,
227+
repeatabilityFirstSent: new Date().toUTCString(),
228+
repeatabilityRequestID: uuidv4(),
229+
};
212230
const result = await this.callConnectionImpl.removeParticipant(
213231
this.callConnectionId,
214232
removeParticipantRequest,
215-
options
233+
optionsInternal
216234
);
217235
const removeParticipantsResult: RemoveParticipantsResult = {
218236
...result,

sdk/communication/communication-call-automation/src/callRecording.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { communicationIdentifierModelConverter } from "./utli/converters";
1616
import { ContentDownloaderImpl } from "./contentDownloader";
1717
import * as fs from "fs";
18+
import { v4 as uuidv4 } from "uuid";
1819

1920
/**
2021
* CallRecording class represents call recording related APIs.
@@ -64,9 +65,14 @@ export class CallRecording {
6465
startCallRecordingRequest.callLocator.serverCallId = options.callLocator.id;
6566
}
6667

68+
const optionsInternal = {
69+
...options,
70+
repeatabilityFirstSent: new Date().toUTCString(),
71+
repeatabilityRequestID: uuidv4(),
72+
};
6773
const response = await this.callRecordingImpl.startRecording(
6874
startCallRecordingRequest,
69-
options
75+
optionsInternal
7076
);
7177

7278
const result: RecordingStateResult = {

sdk/communication/communication-call-automation/test/callAutomationClient.spec.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Recorder } from "@azure-tools/test-recorder";
55
import Sinon, { SinonStubbedInstance } from "sinon";
66
import { CallConnectionProperties } from "../src/models/models";
77
import { CreateCallResult } from "../src/models/responses";
8-
import { CALL_CALLBACK_URL, CALL_TARGET_ID } from "./utils/connectionUtils";
8+
import { CALL_CALLBACK_URL, CALL_TARGET_ID, CALL_TARGET_ID_2 } from "./utils/connectionUtils";
99
import { CommunicationIdentifier, CommunicationUserIdentifier } from "@azure/communication-common";
1010
import { assert } from "chai";
1111
import { Context } from "mocha";
@@ -24,6 +24,7 @@ import {
2424
loadPersistedEvents,
2525
persistEvents,
2626
} from "./utils/recordedClient";
27+
import { v4 as uuidv4 } from "uuid";
2728

2829
describe("Call Automation Client Unit Tests", () => {
2930
let targets: CommunicationIdentifier[];
@@ -35,33 +36,48 @@ describe("Call Automation Client Unit Tests", () => {
3536
{
3637
communicationUserId: CALL_TARGET_ID,
3738
},
39+
{
40+
communicationUserId: CALL_TARGET_ID_2,
41+
},
3842
];
3943
// stub CallAutomationClient
4044
client = Sinon.createStubInstance(
4145
CallAutomationClient
4246
) as SinonStubbedInstance<CallAutomationClient> & CallAutomationClient;
4347
});
4448

45-
it("CreateCall", async () => {
49+
it("RepeatabilityHeadersGeneration", async () => {
50+
// mocks
51+
const repeatabilityFirstSent: string = new Date().toUTCString();
52+
const repeatabilityRequestID: string = uuidv4();
53+
54+
// asserts
55+
assert.isNotNull(repeatabilityFirstSent);
56+
assert.isNotNull(repeatabilityRequestID);
57+
assert.typeOf(repeatabilityFirstSent, "string");
58+
assert.typeOf(repeatabilityRequestID, "string");
59+
});
60+
61+
it("CreateGroupCall", async () => {
4662
// mocks
47-
const createCallResultMock: CreateCallResult = {
63+
const createGroupCallResultMock: CreateCallResult = {
4864
callConnectionProperties: {} as CallConnectionProperties,
4965
callConnection: {} as CallConnection,
5066
};
51-
client.createCall.returns(
67+
client.createGroupCall.returns(
5268
new Promise((resolve) => {
53-
resolve(createCallResultMock);
69+
resolve(createGroupCallResultMock);
5470
})
5571
);
5672

57-
const promiseResult = client.createCall(targets, CALL_CALLBACK_URL);
73+
const promiseResult = client.createGroupCall(targets, CALL_CALLBACK_URL);
5874

5975
// asserts
6076
promiseResult
6177
.then((result: CreateCallResult) => {
6278
assert.isNotNull(result);
63-
assert.isTrue(client.createCall.calledWith(targets, CALL_CALLBACK_URL));
64-
assert.equal(result, createCallResultMock);
79+
assert.isTrue(client.createGroupCall.calledWith(targets, CALL_CALLBACK_URL));
80+
assert.equal(result, createGroupCallResultMock);
6581
return;
6682
})
6783
.catch((error) => console.error(error));

sdk/communication/communication-call-automation/test/utils/connectionUtils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const CALL_SERVER_CALL_ID = "serverCallId";
1212
export const CALL_CALLER_ID = "callerId";
1313
export const CALL_CALLER_DISPLAY_NAME = "callerDisplayName";
1414
export const CALL_TARGET_ID = "targetId";
15+
export const CALL_TARGET_ID_2 = "targetId2";
1516
export const CALL_CONNECTION_STATE = "connected";
1617
export const CALL_SUBJECT = "subject";
1718
export const CALL_CALLBACK_URL = "https://REDACTED.com/events";

0 commit comments

Comments
 (0)