@webex/plugin-meetings 3.8.1-next.42 → 3.8.1-next.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/index.js +139 -107
- package/dist/meeting/index.js.map +1 -1
- package/dist/types/meeting/index.d.ts +12 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +1 -1
- package/src/meeting/index.ts +40 -5
- package/test/unit/spec/meeting/index.js +121 -21
@@ -83,6 +83,7 @@ export type CallStateForMetrics = {
|
|
83
83
|
loginType?: string;
|
84
84
|
userNameInput?: string;
|
85
85
|
emailInput?: string;
|
86
|
+
pstnCorrelationId?: string;
|
86
87
|
};
|
87
88
|
export declare const MEDIA_UPDATE_TYPE: {
|
88
89
|
TRANSCODED_MEDIA_CONNECTION: string;
|
@@ -515,6 +516,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
515
516
|
* @param {string} correlationId
|
516
517
|
*/
|
517
518
|
set correlationId(correlationId: string);
|
519
|
+
/**
|
520
|
+
* Getter - Returns callStateForMetrics.pstnCorrelationId
|
521
|
+
* @returns {string | undefined}
|
522
|
+
*/
|
523
|
+
get pstnCorrelationId(): string | undefined;
|
524
|
+
/**
|
525
|
+
* Setter - sets callStateForMetrics.pstnCorrelationId
|
526
|
+
* @param {string | undefined} correlationId
|
527
|
+
*/
|
528
|
+
set pstnCorrelationId(correlationId: string | undefined);
|
518
529
|
/**
|
519
530
|
* Getter - Returns callStateForMetrics.userNameInput
|
520
531
|
* @returns {string}
|
@@ -1341,7 +1352,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1341
1352
|
* @memberof Meeting
|
1342
1353
|
* @returns {Promise}
|
1343
1354
|
*/
|
1344
|
-
disconnectPhoneAudio(): Promise<
|
1355
|
+
disconnectPhoneAudio(): Promise<void>;
|
1345
1356
|
/**
|
1346
1357
|
* Moves the call to the specified resourceId
|
1347
1358
|
* @param {String} resourceId
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
package/src/meeting/index.ts
CHANGED
@@ -251,6 +251,7 @@ export type CallStateForMetrics = {
|
|
251
251
|
loginType?: string;
|
252
252
|
userNameInput?: string;
|
253
253
|
emailInput?: string;
|
254
|
+
pstnCorrelationId?: string;
|
254
255
|
};
|
255
256
|
|
256
257
|
export const MEDIA_UPDATE_TYPE = {
|
@@ -1683,6 +1684,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1683
1684
|
this.callStateForMetrics.correlationId = correlationId;
|
1684
1685
|
}
|
1685
1686
|
|
1687
|
+
/**
|
1688
|
+
* Getter - Returns callStateForMetrics.pstnCorrelationId
|
1689
|
+
* @returns {string | undefined}
|
1690
|
+
*/
|
1691
|
+
get pstnCorrelationId(): string | undefined {
|
1692
|
+
return this.callStateForMetrics.pstnCorrelationId;
|
1693
|
+
}
|
1694
|
+
|
1695
|
+
/**
|
1696
|
+
* Setter - sets callStateForMetrics.pstnCorrelationId
|
1697
|
+
* @param {string | undefined} correlationId
|
1698
|
+
*/
|
1699
|
+
set pstnCorrelationId(correlationId: string | undefined) {
|
1700
|
+
this.callStateForMetrics.pstnCorrelationId = correlationId;
|
1701
|
+
}
|
1702
|
+
|
1686
1703
|
/**
|
1687
1704
|
* Getter - Returns callStateForMetrics.userNameInput
|
1688
1705
|
* @returns {string}
|
@@ -6093,8 +6110,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6093
6110
|
*/
|
6094
6111
|
private dialInPstn() {
|
6095
6112
|
if (this.isPhoneProvisioned(this.dialInDeviceStatus)) return Promise.resolve(); // prevent multiple dial in devices from being provisioned
|
6113
|
+
this.pstnCorrelationId = uuid.v4();
|
6096
6114
|
|
6097
|
-
const {
|
6115
|
+
const {pstnCorrelationId, locusUrl} = this;
|
6098
6116
|
|
6099
6117
|
if (!this.dialInUrl) this.dialInUrl = `dialin:///${uuid.v4()}`;
|
6100
6118
|
|
@@ -6102,7 +6120,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6102
6120
|
this.meetingRequest
|
6103
6121
|
// @ts-ignore
|
6104
6122
|
.dialIn({
|
6105
|
-
correlationId,
|
6123
|
+
correlationId: pstnCorrelationId,
|
6106
6124
|
dialInUrl: this.dialInUrl,
|
6107
6125
|
locusUrl,
|
6108
6126
|
clientUrl: this.deviceUrl,
|
@@ -6111,12 +6129,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6111
6129
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE, {
|
6112
6130
|
correlation_id: this.correlationId,
|
6113
6131
|
dial_in_url: this.dialInUrl,
|
6132
|
+
dial_in_correlation_id: pstnCorrelationId,
|
6114
6133
|
locus_id: locusUrl.split('/').pop(),
|
6115
6134
|
client_url: this.deviceUrl,
|
6116
6135
|
reason: error.error?.message,
|
6117
6136
|
stack: error.stack,
|
6118
6137
|
});
|
6119
6138
|
|
6139
|
+
if (this.pstnCorrelationId === pstnCorrelationId) {
|
6140
|
+
this.pstnCorrelationId = undefined;
|
6141
|
+
}
|
6142
|
+
|
6120
6143
|
return Promise.reject(error);
|
6121
6144
|
})
|
6122
6145
|
);
|
@@ -6131,8 +6154,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6131
6154
|
*/
|
6132
6155
|
private dialOutPstn(phoneNumber: string) {
|
6133
6156
|
if (this.isPhoneProvisioned(this.dialOutDeviceStatus)) return Promise.resolve(); // prevent multiple dial out devices from being provisioned
|
6157
|
+
this.pstnCorrelationId = uuid.v4();
|
6134
6158
|
|
6135
|
-
const {
|
6159
|
+
const {locusUrl, pstnCorrelationId} = this;
|
6136
6160
|
|
6137
6161
|
if (!this.dialOutUrl) this.dialOutUrl = `dialout:///${uuid.v4()}`;
|
6138
6162
|
|
@@ -6140,7 +6164,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6140
6164
|
this.meetingRequest
|
6141
6165
|
// @ts-ignore
|
6142
6166
|
.dialOut({
|
6143
|
-
correlationId,
|
6167
|
+
correlationId: pstnCorrelationId,
|
6144
6168
|
dialOutUrl: this.dialOutUrl,
|
6145
6169
|
phoneNumber,
|
6146
6170
|
locusUrl,
|
@@ -6150,12 +6174,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6150
6174
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE, {
|
6151
6175
|
correlation_id: this.correlationId,
|
6152
6176
|
dial_out_url: this.dialOutUrl,
|
6177
|
+
dial_out_correlation_id: pstnCorrelationId,
|
6153
6178
|
locus_id: locusUrl.split('/').pop(),
|
6154
6179
|
client_url: this.deviceUrl,
|
6155
6180
|
reason: error.error?.message,
|
6156
6181
|
stack: error.stack,
|
6157
6182
|
});
|
6158
6183
|
|
6184
|
+
if (this.pstnCorrelationId === pstnCorrelationId) {
|
6185
|
+
this.pstnCorrelationId = undefined;
|
6186
|
+
}
|
6187
|
+
|
6159
6188
|
return Promise.reject(error);
|
6160
6189
|
})
|
6161
6190
|
);
|
@@ -6169,6 +6198,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6169
6198
|
* @returns {Promise}
|
6170
6199
|
*/
|
6171
6200
|
public disconnectPhoneAudio() {
|
6201
|
+
const correlationToClear = this.pstnCorrelationId;
|
6202
|
+
|
6172
6203
|
return Promise.all([
|
6173
6204
|
this.isPhoneProvisioned(this.dialInDeviceStatus)
|
6174
6205
|
? MeetingUtil.disconnectPhoneAudio(this, this.dialInUrl)
|
@@ -6176,7 +6207,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6176
6207
|
this.isPhoneProvisioned(this.dialOutDeviceStatus)
|
6177
6208
|
? MeetingUtil.disconnectPhoneAudio(this, this.dialOutUrl)
|
6178
6209
|
: Promise.resolve(),
|
6179
|
-
])
|
6210
|
+
]).then(() => {
|
6211
|
+
if (this.pstnCorrelationId === correlationToClear) {
|
6212
|
+
this.pstnCorrelationId = undefined;
|
6213
|
+
}
|
6214
|
+
});
|
6180
6215
|
}
|
6181
6216
|
|
6182
6217
|
/**
|
@@ -485,6 +485,18 @@ describe('plugin-meetings', () => {
|
|
485
485
|
});
|
486
486
|
});
|
487
487
|
|
488
|
+
it('pstnCorrelationId getter/setter should work correctly', () => {
|
489
|
+
const testPstnCorrelationId = uuid.v4();
|
490
|
+
|
491
|
+
meeting.pstnCorrelationId = testPstnCorrelationId;
|
492
|
+
assert.equal(meeting.pstnCorrelationId, testPstnCorrelationId);
|
493
|
+
assert.equal(meeting.callStateForMetrics.pstnCorrelationId, testPstnCorrelationId);
|
494
|
+
|
495
|
+
meeting.pstnCorrelationId = undefined;
|
496
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
497
|
+
assert.equal(meeting.callStateForMetrics.pstnCorrelationId, undefined);
|
498
|
+
});
|
499
|
+
|
488
500
|
describe('creates ReceiveSlot manager instance', () => {
|
489
501
|
let mockReceiveSlotManagerCtor;
|
490
502
|
let providedCreateSlotCallback;
|
@@ -6526,12 +6538,17 @@ describe('plugin-meetings', () => {
|
|
6526
6538
|
const DIAL_IN_URL = meeting.dialInUrl;
|
6527
6539
|
|
6528
6540
|
assert.calledWith(meeting.meetingRequest.dialIn, {
|
6529
|
-
correlationId: meeting.
|
6541
|
+
correlationId: meeting.pstnCorrelationId,
|
6530
6542
|
dialInUrl: DIAL_IN_URL,
|
6531
6543
|
locusUrl: meeting.locusUrl,
|
6532
6544
|
clientUrl: meeting.deviceUrl,
|
6533
6545
|
});
|
6534
6546
|
assert.notCalled(meeting.meetingRequest.dialOut);
|
6547
|
+
|
6548
|
+
// Verify pstnCorrelationId was set
|
6549
|
+
assert.exists(meeting.pstnCorrelationId);
|
6550
|
+
assert.notEqual(meeting.pstnCorrelationId, meeting.correlationId);
|
6551
|
+
const firstPstnCorrelationId = meeting.pstnCorrelationId
|
6535
6552
|
|
6536
6553
|
meeting.meetingRequest.dialIn.resetHistory();
|
6537
6554
|
|
@@ -6539,12 +6556,18 @@ describe('plugin-meetings', () => {
|
|
6539
6556
|
await meeting.usePhoneAudio();
|
6540
6557
|
|
6541
6558
|
assert.calledWith(meeting.meetingRequest.dialIn, {
|
6542
|
-
correlationId: meeting.
|
6559
|
+
correlationId: meeting.pstnCorrelationId,
|
6543
6560
|
dialInUrl: DIAL_IN_URL,
|
6544
6561
|
locusUrl: meeting.locusUrl,
|
6545
6562
|
clientUrl: meeting.deviceUrl,
|
6546
6563
|
});
|
6547
6564
|
assert.notCalled(meeting.meetingRequest.dialOut);
|
6565
|
+
// A new PSTN correlationId should be generated for the second attempt
|
6566
|
+
assert.notEqual(
|
6567
|
+
meeting.pstnCorrelationId,
|
6568
|
+
firstPstnCorrelationId,
|
6569
|
+
'pstnCorrelationId should be regenerated on each dial-in attempt'
|
6570
|
+
);
|
6548
6571
|
});
|
6549
6572
|
|
6550
6573
|
it('given a phone number, triggers dial-out, delegating request to meetingRequest correctly', async () => {
|
@@ -6554,7 +6577,7 @@ describe('plugin-meetings', () => {
|
|
6554
6577
|
const DIAL_OUT_URL = meeting.dialOutUrl;
|
6555
6578
|
|
6556
6579
|
assert.calledWith(meeting.meetingRequest.dialOut, {
|
6557
|
-
correlationId: meeting.
|
6580
|
+
correlationId: meeting.pstnCorrelationId,
|
6558
6581
|
dialOutUrl: DIAL_OUT_URL,
|
6559
6582
|
locusUrl: meeting.locusUrl,
|
6560
6583
|
clientUrl: meeting.deviceUrl,
|
@@ -6562,49 +6585,126 @@ describe('plugin-meetings', () => {
|
|
6562
6585
|
});
|
6563
6586
|
assert.notCalled(meeting.meetingRequest.dialIn);
|
6564
6587
|
|
6588
|
+
// Verify pstnCorrelationId was set
|
6589
|
+
assert.exists(meeting.pstnCorrelationId);
|
6590
|
+
assert.notEqual(meeting.pstnCorrelationId, meeting.correlationId);
|
6591
|
+
const firstPstnCorrelationId = meeting.pstnCorrelationId;
|
6592
|
+
|
6565
6593
|
meeting.meetingRequest.dialOut.resetHistory();
|
6566
6594
|
|
6567
6595
|
// try again. the dial out urls should match
|
6568
6596
|
await meeting.usePhoneAudio(phoneNumber);
|
6569
6597
|
|
6570
6598
|
assert.calledWith(meeting.meetingRequest.dialOut, {
|
6571
|
-
correlationId: meeting.
|
6599
|
+
correlationId: meeting.pstnCorrelationId,
|
6572
6600
|
dialOutUrl: DIAL_OUT_URL,
|
6573
6601
|
locusUrl: meeting.locusUrl,
|
6574
6602
|
clientUrl: meeting.deviceUrl,
|
6575
6603
|
phoneNumber,
|
6576
6604
|
});
|
6577
6605
|
assert.notCalled(meeting.meetingRequest.dialIn);
|
6606
|
+
// A new PSTN correlationId should be generated for the second attempt
|
6607
|
+
assert.notEqual(
|
6608
|
+
meeting.pstnCorrelationId,
|
6609
|
+
firstPstnCorrelationId,
|
6610
|
+
'pstnCorrelationId should be regenerated on each dial-out attempt'
|
6611
|
+
);
|
6578
6612
|
});
|
6579
6613
|
|
6580
|
-
it('rejects if the request failed (dial in)', () => {
|
6581
|
-
const error = '
|
6614
|
+
it('rejects if the request failed (dial in)', async () => {
|
6615
|
+
const error = {error: {message: 'dial in failed'}, stack: 'error stack'};
|
6582
6616
|
|
6583
6617
|
meeting.meetingRequest.dialIn = sinon.stub().returns(Promise.reject(error));
|
6584
6618
|
|
6585
|
-
|
6586
|
-
.usePhoneAudio()
|
6587
|
-
|
6588
|
-
|
6589
|
-
|
6590
|
-
|
6591
|
-
|
6619
|
+
try {
|
6620
|
+
await meeting.usePhoneAudio();
|
6621
|
+
throw new Error('Promise resolved when it should have rejected');
|
6622
|
+
} catch (e) {
|
6623
|
+
assert.equal(e, error);
|
6624
|
+
|
6625
|
+
// Verify behavioral metric was sent with dial_in_correlation_id
|
6626
|
+
assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE, {
|
6627
|
+
correlation_id: meeting.correlationId,
|
6628
|
+
dial_in_url: meeting.dialInUrl,
|
6629
|
+
dial_in_correlation_id: sinon.match.string,
|
6630
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
6631
|
+
client_url: meeting.deviceUrl,
|
6632
|
+
reason: error.error.message,
|
6633
|
+
stack: error.stack,
|
6592
6634
|
});
|
6635
|
+
|
6636
|
+
// Verify pstnCorrelationId was cleared after error
|
6637
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
6638
|
+
}
|
6593
6639
|
});
|
6594
6640
|
|
6595
6641
|
it('rejects if the request failed (dial out)', async () => {
|
6596
|
-
const error = '
|
6642
|
+
const error = {error: {message: 'dial out failed'}, stack: 'error stack'};
|
6597
6643
|
|
6598
6644
|
meeting.meetingRequest.dialOut = sinon.stub().returns(Promise.reject(error));
|
6599
6645
|
|
6600
|
-
|
6601
|
-
.usePhoneAudio('+441234567890')
|
6602
|
-
|
6603
|
-
|
6604
|
-
|
6605
|
-
|
6606
|
-
|
6646
|
+
try {
|
6647
|
+
await meeting.usePhoneAudio('+441234567890');
|
6648
|
+
throw new Error('Promise resolved when it should have rejected');
|
6649
|
+
} catch (e) {
|
6650
|
+
assert.equal(e, error);
|
6651
|
+
|
6652
|
+
// Verify behavioral metric was sent with dial_out_correlation_id
|
6653
|
+
assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE, {
|
6654
|
+
correlation_id: meeting.correlationId,
|
6655
|
+
dial_out_url: meeting.dialOutUrl,
|
6656
|
+
dial_out_correlation_id: sinon.match.string,
|
6657
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
6658
|
+
client_url: meeting.deviceUrl,
|
6659
|
+
reason: error.error.message,
|
6660
|
+
stack: error.stack,
|
6607
6661
|
});
|
6662
|
+
|
6663
|
+
// Verify pstnCorrelationId was cleared after error
|
6664
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
6665
|
+
}
|
6666
|
+
});
|
6667
|
+
});
|
6668
|
+
|
6669
|
+
describe('#disconnectPhoneAudio', () => {
|
6670
|
+
beforeEach(() => {
|
6671
|
+
// Mock the MeetingUtil.disconnectPhoneAudio method
|
6672
|
+
sinon.stub(MeetingUtil, 'disconnectPhoneAudio').resolves();
|
6673
|
+
meeting.dialInUrl = 'dialin:///test-dial-in-url';
|
6674
|
+
meeting.dialOutUrl = 'dialout:///test-dial-out-url';
|
6675
|
+
meeting.dialInDeviceStatus = 'JOINED';
|
6676
|
+
meeting.dialOutDeviceStatus = 'JOINED';
|
6677
|
+
});
|
6678
|
+
|
6679
|
+
afterEach(() => {
|
6680
|
+
MeetingUtil.disconnectPhoneAudio.restore();
|
6681
|
+
});
|
6682
|
+
|
6683
|
+
it('should disconnect phone audio and clear pstnCorrelationId', async () => {
|
6684
|
+
meeting.pstnCorrelationId = 'test-pstn-correlation-id';
|
6685
|
+
|
6686
|
+
await meeting.disconnectPhoneAudio();
|
6687
|
+
|
6688
|
+
// Verify that pstnCorrelationId is cleared
|
6689
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
6690
|
+
|
6691
|
+
// Verify that MeetingUtil.disconnectPhoneAudio was called for both dial-in and dial-out
|
6692
|
+
assert.calledTwice(MeetingUtil.disconnectPhoneAudio);
|
6693
|
+
assert.calledWith(MeetingUtil.disconnectPhoneAudio, meeting, meeting.dialInUrl);
|
6694
|
+
assert.calledWith(MeetingUtil.disconnectPhoneAudio, meeting, meeting.dialOutUrl);
|
6695
|
+
});
|
6696
|
+
|
6697
|
+
it('should handle case when no PSTN connection is active', async () => {
|
6698
|
+
meeting.dialInDeviceStatus = 'IDLE';
|
6699
|
+
meeting.dialOutDeviceStatus = 'IDLE';
|
6700
|
+
meeting.pstnCorrelationId = 'test-pstn-correlation-id';
|
6701
|
+
|
6702
|
+
await meeting.disconnectPhoneAudio();
|
6703
|
+
|
6704
|
+
// Verify that pstnCorrelationId is still cleared even when no phone connection is active
|
6705
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
6706
|
+
// And verify no disconnect was attempted
|
6707
|
+
assert.notCalled(MeetingUtil.disconnectPhoneAudio);
|
6608
6708
|
});
|
6609
6709
|
});
|
6610
6710
|
|