Skip to content

Commit e2e11be

Browse files
authored
CallInvite has CustomContext class (Azure#26624)
### Packages impacted by this PR azure/communication-call-automation ### Issues associated with this PR #customers' feedback: SIP UUI format: The format used by ACS (userToUser) is not aligned to RFC format. Developers being more familiar with the latter, I recommend we align to RFC format (User-to-User) in SDK as well as EG payload, just we like we do for custom headers. In line with No.1, it might be a better experience to manage the strict header key format at SDK layer, so that every developer doesnt have to remember to set the correct format in the request. eg. Instead of callInvite.SipHeaders.Add("userToUser", "616d617a6f6e5f6368696;encoding=hex"); we do callInvite.SipHeaders.AddUserToUser("616d617a6f6e5f6368696;encoding=hex"); eg. Instead of callInvite.SipHeaders.Add("X-MS-Custom-", "434erdr454tf"), we do callInvite.SipHeaders.AddCustomHeader("", "434erdr454tf"); #Design: 1.1.1 PSTN target ``` CallInvite callInvite = new CallInvite(new PhoneNumberIdentifier(targetParticipant), callerIdNumber); callInvite.CustomContext.Add(new SIPUUIHeader(“jason”)); callInvite.CustomContext.Add(new SIPCustomHeader("Frank", "Rizzo")); // SDK will add prefix "X-MS-Custom-" ``` Then SDK will send this payload to PMA: ``` customContext: { "sipHeaders": { "User-to-User": "jason", "X-MS-Custom-Frank": "Rizzo" } } ``` 1.1.2 VoiP Target ``` CallInvite callInvite = new CallInvite(new CommunicationUserIdentifier(targetParticipant)) callInvite.CustomContext.Add(new VoipHeader("Foo-1", "Bar")); //no prefix ``` Then SDK will send below payload to PMA: ``` customContext: { "voipHeaders": { "Foo-1": "Bar" } } ``` ### 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 01f528f commit e2e11be

File tree

5 files changed

+142
-40
lines changed

5 files changed

+142
-40
lines changed

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

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,11 @@ export interface CallDisconnected extends Omit<RestCallDisconnected, "callConnec
133133

134134
// @public
135135
export interface CallInvite {
136-
readonly sipHeaders?: {
137-
[propertyName: string]: string;
138-
};
136+
customContext?: CustomContext;
139137
readonly sourceCallIdNumber?: PhoneNumberIdentifier;
140138
// (undocumented)
141139
sourceDisplayName?: string;
142140
readonly targetParticipant: PhoneNumberIdentifier | CommunicationUserIdentifier;
143-
readonly voipHeaders?: {
144-
[propertyName: string]: string;
145-
};
146141
}
147142

148143
// @public
@@ -314,21 +309,33 @@ export interface ContinuousDtmfRecognitionToneReceived extends Omit<RestContinuo
314309
// @public
315310
export interface CreateCallOptions extends OperationOptions {
316311
azureCognitiveServicesEndpointUrl?: string;
312+
customContext?: CustomContext;
317313
mediaStreamingConfiguration?: MediaStreamingConfiguration;
318314
operationContext?: string;
319-
sipHeaders?: {
320-
[propertyName: string]: string;
321-
};
322315
sourceCallIdNumber?: PhoneNumberIdentifier;
323316
sourceDisplayName?: string;
324-
voipHeaders?: {
325-
[propertyName: string]: string;
326-
};
327317
}
328318

329319
// @public
330320
export type CreateCallResult = CallResult;
331321

322+
// @public
323+
export class CustomContext {
324+
constructor(sipHeaders: {
325+
[key: string]: string;
326+
}, voipHeaders: {
327+
[key: string]: string;
328+
});
329+
// Warning: (ae-forgotten-export) The symbol "CustomContextHeader" needs to be exported by the entry point index.d.ts
330+
add(header: CustomContextHeader): void;
331+
sipHeaders: {
332+
[key: string]: string;
333+
};
334+
voipHeaders: {
335+
[key: string]: string;
336+
};
337+
}
338+
332339
// @public
333340
export type DeleteRecordingOptions = OperationOptions;
334341

@@ -862,6 +869,24 @@ export interface SendDtmfOptions extends OperationOptions {
862869
operationContext?: string;
863870
}
864871

872+
// @public
873+
export interface SIPCustomHeader extends CustomContextHeader {
874+
}
875+
876+
// @public
877+
export class SIPCustomHeader implements CustomContextHeader {
878+
constructor(key: string, value: string);
879+
}
880+
881+
// @public
882+
export interface SIPUserToUserHeader extends CustomContextHeader {
883+
}
884+
885+
// @public
886+
export class SIPUserToUserHeader implements CustomContextHeader {
887+
constructor(value: string);
888+
}
889+
865890
// @public
866891
export interface SsmlSource extends PlaySource {
867892
// (undocumented)
@@ -916,14 +941,18 @@ export interface TransferCallResult {
916941
// @public
917942
export interface TransferCallToParticipantOptions extends OperationOptions {
918943
callbackUrlOverride?: string;
944+
customContext?: CustomContext;
919945
operationContext?: string;
920-
sipHeaders?: {
921-
[propertyName: string]: string;
922-
};
923946
transferee?: CommunicationIdentifier;
924-
voipHeaders?: {
925-
[propertyName: string]: string;
926-
};
947+
}
948+
949+
// @public
950+
export interface VoipHeader extends CustomContextHeader {
951+
}
952+
953+
// @public
954+
export class VoipHeader implements CustomContextHeader {
955+
constructor(key: string, value: string);
927956
}
928957

929958
// (No @packageDocumentation comment for this package)

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ export class CallAutomationClient {
231231
azureCognitiveServicesEndpointUrl: options.azureCognitiveServicesEndpointUrl,
232232
mediaStreamingConfiguration: options.mediaStreamingConfiguration,
233233
customContext: {
234-
sipHeaders: targetParticipant.sipHeaders,
235-
voipHeaders: targetParticipant.voipHeaders,
234+
sipHeaders: targetParticipant.customContext?.sipHeaders,
235+
voipHeaders: targetParticipant.customContext?.voipHeaders,
236236
},
237237
sourceCallerIdNumber: PhoneNumberIdentifierModelConverter(
238238
targetParticipant.sourceCallIdNumber
@@ -262,8 +262,8 @@ export class CallAutomationClient {
262262
azureCognitiveServicesEndpointUrl: options.azureCognitiveServicesEndpointUrl,
263263
mediaStreamingConfiguration: options.mediaStreamingConfiguration,
264264
customContext: {
265-
sipHeaders: options.sipHeaders,
266-
voipHeaders: options.voipHeaders,
265+
sipHeaders: options.customContext?.sipHeaders,
266+
voipHeaders: options.customContext?.voipHeaders,
267267
},
268268
sourceCallerIdNumber: PhoneNumberIdentifierModelConverter(options.sourceCallIdNumber),
269269
sourceDisplayName: options.sourceDisplayName,
@@ -355,8 +355,9 @@ export class CallAutomationClient {
355355
incomingCallContext: incomingCallContext,
356356
target: communicationIdentifierModelConverter(targetParticipant.targetParticipant),
357357
customContext: {
358-
sipHeaders: targetParticipant.sipHeaders ?? options.sipHeaders ?? undefined,
359-
voipHeaders: targetParticipant.voipHeaders ?? options.voipHeaders ?? undefined,
358+
sipHeaders: targetParticipant.customContext?.sipHeaders ?? options.sipHeaders ?? undefined,
359+
voipHeaders:
360+
targetParticipant.customContext?.voipHeaders ?? options.voipHeaders ?? undefined,
360361
},
361362
};
362363
const optionsInternal = {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ export class CallConnection {
183183
invitationTimeoutInSeconds: options.invitationTimeoutInSeconds,
184184
operationContext: options.operationContext,
185185
customContext: {
186-
sipHeaders: targetParticipant.sipHeaders,
187-
voipHeaders: targetParticipant.voipHeaders,
186+
sipHeaders: targetParticipant.customContext?.sipHeaders,
187+
voipHeaders: targetParticipant.customContext?.voipHeaders,
188188
},
189189
callbackUriOverride: options.callbackUrlOverride,
190190
};
@@ -223,8 +223,8 @@ export class CallConnection {
223223
targetParticipant: communicationIdentifierModelConverter(targetParticipant),
224224
operationContext: options.operationContext,
225225
customContext: {
226-
sipHeaders: options.sipHeaders,
227-
voipHeaders: options.voipHeaders,
226+
sipHeaders: options.customContext?.sipHeaders,
227+
voipHeaders: options.customContext?.voipHeaders,
228228
},
229229
callbackUriOverride: options.callbackUrlOverride,
230230
transferee: options.transferee && communicationIdentifierModelConverter(options.transferee),

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

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,92 @@ export enum RecognizeInputType {
153153
Choices = "choices",
154154
}
155155

156+
interface CustomContextHeader {
157+
key: string;
158+
value: string;
159+
}
160+
161+
/** SIPCustomHeader */
162+
export interface SIPCustomHeader extends CustomContextHeader {}
163+
164+
/** SIPUserToUserHeader */
165+
export interface SIPUserToUserHeader extends CustomContextHeader {}
166+
167+
/** VoipHeader */
168+
export interface VoipHeader extends CustomContextHeader {}
169+
170+
/** Custom Context SIP header */
171+
export class SIPCustomHeader implements CustomContextHeader {
172+
// Create a new SIP custom header.
173+
constructor(key: string, value: string) {
174+
this.key = "X-MS-Custom-" + key;
175+
this.value = value;
176+
}
177+
}
178+
179+
/** Custom Context SIP User-to-User header */
180+
export class SIPUserToUserHeader implements CustomContextHeader {
181+
// Create a new SIP UUI header.
182+
constructor(value: string) {
183+
this.key = "User-to-User";
184+
this.value = value;
185+
}
186+
}
187+
188+
/** Custom Context VOIP header */
189+
export class VoipHeader implements CustomContextHeader {
190+
constructor(key: string, value: string) {
191+
this.key = key;
192+
this.value = value;
193+
}
194+
}
195+
196+
/** Custom Context */
197+
export class CustomContext {
198+
/** Dictionary of VOIP headers. */
199+
public voipHeaders: { [key: string]: string };
200+
201+
/** Dictionary of SIP headers. */
202+
public sipHeaders: { [key: string]: string };
203+
204+
// Creates a new CustomContext.
205+
constructor(sipHeaders: { [key: string]: string }, voipHeaders: { [key: string]: string }) {
206+
this.sipHeaders = sipHeaders;
207+
this.voipHeaders = voipHeaders;
208+
}
209+
210+
/** Add a custom context sip or voip header. */
211+
public add(header: CustomContextHeader): void {
212+
if (header instanceof SIPUserToUserHeader) {
213+
if (this.sipHeaders == null) {
214+
throw new Error("Cannot add sip header, SipHeaders is null.");
215+
}
216+
this.sipHeaders[header.key] = header.value;
217+
} else if (header instanceof SIPCustomHeader) {
218+
if (this.sipHeaders == null) {
219+
throw new Error("Cannot add sip header, SipHeaders is null.");
220+
}
221+
this.sipHeaders[header.key] = header.value;
222+
} else if (header instanceof VoipHeader) {
223+
if (this.voipHeaders == null) {
224+
throw new Error("Cannot add voip header, VoipHeaders is null");
225+
}
226+
this.voipHeaders[header.key] = header.value;
227+
} else {
228+
throw new Error("Unknown custom context header type.");
229+
}
230+
}
231+
}
232+
156233
/** Call invitee details. */
157234
export interface CallInvite {
158235
/** The Target's PhoneNumberIdentifier or CommunicationUserIdentifier. */
159236
readonly targetParticipant: PhoneNumberIdentifier | CommunicationUserIdentifier;
160237
/** Caller's phone number identifier. */
161238
readonly sourceCallIdNumber?: PhoneNumberIdentifier;
162239
sourceDisplayName?: string;
163-
/** Custom context for PSTN. */
164-
readonly sipHeaders?: { [propertyName: string]: string };
165-
/** Custom context for voipr. */
166-
readonly voipHeaders?: { [propertyName: string]: string };
240+
/** The Custom Context. */
241+
customContext?: CustomContext;
167242
}
168243

169244
/** The locator type of a call. */

sdk/communication/communication-call-automation/src/models/options.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
RecordingFormat,
1717
CallLocator,
1818
ChannelAffinity,
19+
CustomContext,
1920
} from "./models";
2021

2122
/** Options to configure the recognize operation. */
@@ -80,10 +81,8 @@ export interface CreateCallOptions extends OperationOptions {
8081
azureCognitiveServicesEndpointUrl?: string;
8182
/** Configuration of Media streaming. */
8283
mediaStreamingConfiguration?: MediaStreamingConfiguration;
83-
/** Headers for SIP calls */
84-
sipHeaders?: { [propertyName: string]: string };
85-
/** Headers for VOIP calls */
86-
voipHeaders?: { [propertyName: string]: string };
84+
/** The Custom Context. */
85+
customContext?: CustomContext;
8786
}
8887

8988
/**
@@ -122,10 +121,8 @@ export interface RejectCallOptions extends OperationOptions {
122121
export interface TransferCallToParticipantOptions extends OperationOptions {
123122
/** Used by customers when calling mid-call actions to correlate the request to the response event. */
124123
operationContext?: string;
125-
/** Custom context for PSTN. */
126-
sipHeaders?: { [propertyName: string]: string };
127-
/** Custom context for voip. */
128-
voipHeaders?: { [propertyName: string]: string };
124+
/** The Custom Context. */
125+
customContext?: CustomContext;
129126
/** Call back URI override for this request */
130127
callbackUrlOverride?: string;
131128
/** Participant that is being transferred away */

0 commit comments

Comments
 (0)