Skip to content

Commit 1ee5d13

Browse files
andywang219Andy Wang
andauthored
Adding Citrix support, RSA customization, and updating docs (#821)
* Adding Citrix support, new request-storage-access customization parameters, and updating documentation --------- Co-authored-by: Andy Wang <wangdy@amazon.com>
1 parent 3d4a271 commit 1ee5d13

16 files changed

+356
-237
lines changed

Documentation-DR.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,11 @@ globalConnect.core.initCCP(containerDiv, {
234234

235235
Since the full `window.connect` binding will not be available until the Global Resiliency setup is initialized on the page, code that relies on modifying the Connect Streams object, such as ChatJS, TaskJS, and other custom code you may have written to work with the standard (non-Global Resiliency) Streams distribution should be loaded in your code that handles the promise returned by your function passed as the getPrimaryRegion parameter of `globalConnect.core.initCCP()`, instead of being loaded immediately at page load time along with Streams itself, as with the non-Global Resiliency version of Streams.
236236

237-
Any scripts loaded this way should also be loaded as part of a `globalConnect.core.onFailoverCompleted()` hook, to ensure that the code will apply to the newly-active CCP in the event of an active region change; otherwise the code would be applied only to the CCP for the region that was originally active.
237+
Any scripts loaded this way should also be loaded as part of a `globalConnect.core.onFailoverComplete()` hook, to ensure that the code will apply to the newly-active CCP in the event of an active region change; otherwise the code would be applied only to the CCP for the region that was originally active.
238238

239239

240240
```
241-
globalConnect.core.onFailoverCompleted(() => {
241+
globalConnect.core.onFailoverComplete(() => {
242242
const script = document.createElement('script');
243243
script.src = "https://example.com/amazon-connect-chat.js";
244244
document.body.appendChild(script);
@@ -331,7 +331,7 @@ This function provides a convenient place to set up init-time logic using the St
331331

332332
Returns a function that can be called if you wish to deregister the trigger.
333333

334-
### globalConnect.core.onFailoverCompleted(f)
334+
### globalConnect.core.onFailoverComplete(f)
335335

336336
Register a function to be triggered when the UI changes to display a different region, and agents are able to begin taking contacts in the new CCP region. This function will also be triggered when CCP is initialized and ready for use, if the region whose CCP was provided in the `ccpUrl` parameter (i.e. not the `standByRegion`) is not the currently active region for the agent. If you wish, you can set up hooks using this function before calling `globalConnect.core.initCCP()`.
337337

@@ -340,7 +340,6 @@ The function will be called with an Object parameter with three properties:
340340

341341
1. `activeRegion`: the string name of the AWS region for the newly-active CCP instance
342342
2. `activeCcpUrl`: the value of the ccpUrl parameter for the newly-active instance, as originally provided in the initCCP() parameters
343-
3. `connect`: the Streams API object for the newly-active region’s CCP.
344343

345344
Returns a function that can be called if you wish to deregister the trigger.
346345

Documentation.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,13 @@ everything set up correctly and that you are able to listen for events.
214214
ringtoneUrl: '[your-ringtone-filepath].mp3', // optional, defaults to CCP’s default ringtone if a falsy value is set
215215
disableEchoCancellation: false, // optional, defaults to false
216216
allowFramedVideoCall: true, // optional, default to false
217+
VDIPlatform: null // optional, provide with 'CITRIX' if using Citrix VDI, or use enum VDIPlatformType
217218
allowEarlyGum: true //optional, default to true
218219
},
219220
storageAccess: {
220221
canRequest: true, // By default this is set to true. You can set it to false to opt out from checking storage access.
221222
mode: "custom", // To use the default banner, set this to "default"
222-
/** More customization options can be found here: https://docs.aws.amazon.com/connect/latest/adminguide/admin-3pcookies.html#config-grant-access */
223+
/** More customization options can be found here: https://github.com/amazon-connect/amazon-connect-streams/blob/master/src/index.d.ts under StorageAccessParameters */
223224
},
224225
pageOptions: { //optional
225226
enableAudioDeviceSettings: false, //optional, defaults to 'false'
@@ -269,6 +270,9 @@ and made available to your JS client code.
269270
the softphone session must not be closed during the course of a softphone
270271
call or the call will be disconnected. If `allowFramedSoftphone` is `true`,
271272
the softphone components will be allowed to be hosted in this window or tab.
273+
If `allowFramedSoftphone` is `false`, please make sure you are importing the
274+
[lily-rtc.js](https://github.com/aws/connect-rtc-js) package and adding `connect.core.initSoftphoneManager()`
275+
to your code after `connect.core.initCCP()`.
272276
* `disableRingtone`: This option allows you to completely disable the built-in
273277
ringtone audio that is played when a call is incoming.
274278
* `ringtoneUrl`: If the ringtone is not disabled, this allows for overriding
@@ -279,6 +283,7 @@ and made available to your JS client code.
279283
- `allowFramedVideoCall`: Currently video call can only be in one single window or tab.. If `true`, CCP will handle
280284
video calling experience in this window or tab and agents would be able to see and turn
281285
on their video if they have video permission set in the security profile. If `false` or not provided, CCP will only provide voice calling.
286+
- `VDIPlatform`: This option is only applicable for virtual desktop interface integrations. If set, it will configure CCP to optimize softphone audio configuration for the VDI. Options can be provided by using enum `VDIPlatformType`. If `allowFramedSoftphone` is `false` and `VDIPlatform` is going to be set, please make sure you are passing this parameter into `connect.core.initSoftphoneManager()`. For example, `connect.core.initSoftphoneManager({ VDIPlatform: "CITRIX" })`
282287
- `allowEarlyGum`: If `true` or not provided, CCP will capture the agent’s browser microphone media stream before the contact arrives to reduce the call setup latency. If `false`, CCP will only capture agent media stream after the contact arrives.
283288
- `pageOptions`: This object is optional and allows you to configure which configuration sections are displayed in the settings tab.
284289
- `enableAudioDeviceSettings`: If `true`, the settings tab will display a section for configuring audio input and output devices for the agent's local

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "amazon-connect-streams",
3-
"version": "2.11.0",
3+
"version": "2.12.0",
44
"description": "Amazon Connect Streams Library",
55
"engines": {
66
"node": ">=12.0.0"

release/connect-streams-dr-min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

release/connect-streams-dr.js

Lines changed: 2 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

release/connect-streams-min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

release/connect-streams.js

Lines changed: 79 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,8 @@
400400
'user_busy_error',
401401
'webrtc_error',
402402
'realtime_communication_error',
403+
'vdi_strategy_not_supported',
404+
'vdi_redir_not_supported',
403405
'other'
404406
]);
405407

@@ -26723,7 +26725,7 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
2672326725

2672426726
connect.core = {};
2672526727
connect.core.initialized = false;
26726-
connect.version = "2.11.0";
26728+
connect.version = "2.12.0";
2672726729
connect.outerContextStreamsVersion = null;
2672826730
connect.DEFAULT_BATCH_SIZE = 500;
2672926731

@@ -28216,7 +28218,7 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
2821628218
connect.assertNotNull(containerDiv, 'containerDiv');
2821728219
var iframe = document.createElement('iframe');
2821828220
iframe.src = initCCPParams.ccpUrl;
28219-
iframe.allow = "microphone; camera; autoplay; clipboard-write";
28221+
iframe.allow = "microphone; camera; autoplay; clipboard-write; identity-credentials-get";
2822028222
iframe.style = initCCPParams.style || "width: 100%; height: 100%";
2822128223
iframe.title = initCCPParams.iframeTitle || CCP_IFRAME_NAME;
2822228224
iframe.name = CCP_IFRAME_NAME;
@@ -31525,6 +31527,10 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
3152531527
global.lily = connect;
3152631528
global.ccpVersion = "V2";
3152731529

31530+
const VDIPlatformType = {
31531+
CITRIX: "CITRIX",
31532+
}
31533+
3152831534
var RTPJobIntervalMs = 1000;
3152931535
var statsReportingJobIntervalMs = 30000;
3153031536
var streamBufferSize = 500;
@@ -31594,16 +31600,56 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
3159431600
var self = this;
3159531601
logger = new SoftphoneLogger(connect.getLog());
3159631602
logger.info("[Softphone Manager] softphone manager initialization has begun").sendInternalLogToServer();
31603+
logger.info(`[SoftphoneManager] Client Provided Strategy: ${softphoneParams.VDIPlatform}`).sendInternalLogToServer();
31604+
31605+
let rtcJsStrategy;
31606+
if (softphoneParams.VDIPlatform) {
31607+
try {
31608+
if (softphoneParams.VDIPlatform === VDIPlatformType.CITRIX) {
31609+
rtcJsStrategy = new connect.CitrixVDIStrategy();
31610+
logger.info(`[SoftphoneManager] Strategy constructor retrieved: ${rtcJsStrategy}`).sendInternalLogToServer();
31611+
} else {
31612+
throw new Error("VDI Strategy not supported");
31613+
}
31614+
} catch (error) {
31615+
if (error.message === "VDI Strategy not supported") {
31616+
publishError(SoftphoneErrorTypes.VDI_STRATEGY_NOT_SUPPORTED, error.message, "");
31617+
throw error;
31618+
}
31619+
else if (error.message === "Citrix WebRTC redirection feature is NOT supported!") {
31620+
publishError(SoftphoneErrorTypes.VDI_REDIR_NOT_SUPPORTED, error.message, "");
31621+
throw error;
31622+
}
31623+
else {
31624+
publishError(SoftphoneErrorTypes.OTHER, error.message, "");
31625+
throw error;
31626+
}
31627+
}
31628+
}
31629+
3159731630
var rtcPeerConnectionFactory;
3159831631
if (connect.RtcPeerConnectionFactory) {
31599-
rtcPeerConnectionFactory = new connect.RtcPeerConnectionFactory(logger,
31600-
connect.core.getWebSocketManager(),
31601-
softphoneClientId,
31602-
connect.hitch(self, requestIceAccess, {
31603-
transportType: "softphone",
31604-
softphoneClientId: softphoneClientId
31605-
}),
31606-
connect.hitch(self, publishError));
31632+
if (rtcJsStrategy) {
31633+
rtcPeerConnectionFactory = new connect.RtcPeerConnectionFactory(logger,
31634+
connect.core.getWebSocketManager(),
31635+
softphoneClientId,
31636+
connect.hitch(self, requestIceAccess, {
31637+
transportType: "softphone",
31638+
softphoneClientId: softphoneClientId
31639+
}),
31640+
connect.hitch(self, publishError),
31641+
rtcJsStrategy
31642+
);
31643+
} else {
31644+
rtcPeerConnectionFactory = new connect.RtcPeerConnectionFactory(logger,
31645+
connect.core.getWebSocketManager(),
31646+
softphoneClientId,
31647+
connect.hitch(self, requestIceAccess, {
31648+
transportType: "softphone",
31649+
softphoneClientId: softphoneClientId
31650+
}),
31651+
connect.hitch(self, publishError));
31652+
}
3160731653
}
3160831654
if (!SoftphoneManager.isBrowserSoftPhoneSupported()) {
3160931655
publishError(SoftphoneErrorTypes.UNSUPPORTED_BROWSER,
@@ -31733,14 +31779,27 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
3173331779
if (callConfig.useWebSocketProvider) {
3173431780
webSocketProvider = connect.core.getWebSocketManager();
3173531781
}
31736-
var session = new connect.RTCSession(
31737-
callConfig.signalingEndpoint,
31738-
callConfig.iceServers,
31739-
softphoneInfo.callContextToken,
31740-
logger,
31741-
contact.getContactId(),
31742-
agentConnectionId,
31743-
webSocketProvider);
31782+
var session;
31783+
if (rtcJsStrategy) {
31784+
session = new connect.RTCSession(
31785+
callConfig.signalingEndpoint,
31786+
callConfig.iceServers,
31787+
softphoneInfo.callContextToken,
31788+
logger,
31789+
contact.getContactId(),
31790+
agentConnectionId,
31791+
webSocketProvider,
31792+
rtcJsStrategy);
31793+
} else {
31794+
session = new connect.RTCSession(
31795+
callConfig.signalingEndpoint,
31796+
callConfig.iceServers,
31797+
softphoneInfo.callContextToken,
31798+
logger,
31799+
contact.getContactId(),
31800+
agentConnectionId,
31801+
webSocketProvider);
31802+
}
3174431803

3174531804
session.echoCancellation = !softphoneParams.disableEchoCancellation;
3174631805

@@ -31796,7 +31855,7 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
3179631855
});
3179731856
};
3179831857

31799-
session.remoteAudioElement = document.getElementById('remote-audio');
31858+
session.remoteAudioElement = document.getElementById('remote-audio') || window.parent.parent.document.getElementById('remote-audio');
3180031859
if (rtcPeerConnectionFactory) {
3180131860
session.connect(rtcPeerConnectionFactory.get(callConfig.iceServers));
3180231861
} else {
@@ -31993,7 +32052,7 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
3199332052
return;
3199432053
}
3199532054

31996-
var remoteAudioElement = document.getElementById('remote-audio');
32055+
var remoteAudioElement = document.getElementById('remote-audio') || window.parent.parent.document.getElementById('remote-audio');
3199732056
if (remoteAudioElement && typeof remoteAudioElement.setSinkId === 'function') {
3199832057
remoteAudioElement.setSinkId(deviceId).then(() => {
3199932058
connect.getLog().info(`[Audio Device Settings] Speaker device ${deviceId} successfully set to speaker audio element`).sendInternalLogToServer();
@@ -32478,7 +32537,6 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
3247832537
connect.SoftphoneManager = SoftphoneManager;
3247932538
})();
3248032539

32481-
3248232540
/***/ }),
3248332541

3248432542
/***/ 944:

src/api.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@
206206
'user_busy_error',
207207
'webrtc_error',
208208
'realtime_communication_error',
209+
'vdi_strategy_not_supported',
210+
'vdi_redir_not_supported',
209211
'other'
210212
]);
211213

src/core.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@
15041504
connect.assertNotNull(containerDiv, 'containerDiv');
15051505
var iframe = document.createElement('iframe');
15061506
iframe.src = initCCPParams.ccpUrl;
1507-
iframe.allow = "microphone; camera; autoplay; clipboard-write";
1507+
iframe.allow = "microphone; camera; autoplay; clipboard-write; identity-credentials-get";
15081508
iframe.style = initCCPParams.style || "width: 100%; height: 100%";
15091509
iframe.title = initCCPParams.iframeTitle || CCP_IFRAME_NAME;
15101510
iframe.name = CCP_IFRAME_NAME;

0 commit comments

Comments
 (0)