Skip to content

Commit

Permalink
adding custom task ringtones, disable task ringtone, and removing loc…
Browse files Browse the repository at this point in the history
…al storage check for login popups
  • Loading branch information
Brett McStotts committed Mar 28, 2024
1 parent f769093 commit c2dcdb0
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 90 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ everything setup correctly and that you will be able to listen for events.
allowFramedVideoCall: true, // optional, default to false
allowEarlyGum: true //optional, default to true
},
task: {
disableRingtone: false, // optional, defaults to false
ringtoneUrl: 'https://customer.com/beep.mp3', // optional, defaults to CCP's default ringtone if a falsy value is set
},
pageOptions: { //optional
enableAudioDeviceSettings: false, //optional, defaults to 'false'
enableVideoDeviceSettings: false, //optional, defaults to 'false'
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "amazon-connect-streams",
"version": "2.14.0",
"version": "2.14.1",
"description": "Amazon Connect Streams Library",
"engines": {
"node": ">=12.0.0"
Expand Down
2 changes: 1 addition & 1 deletion release/connect-streams-dr-min.js

Large diffs are not rendered by default.

37 changes: 16 additions & 21 deletions release/connect-streams-dr.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion release/connect-streams-min.js

Large diffs are not rendered by default.

65 changes: 34 additions & 31 deletions release/connect-streams.js
Original file line number Diff line number Diff line change
Expand Up @@ -26891,7 +26891,7 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-

connect.core = {};
connect.core.initialized = false;
connect.version = "2.14.0";
connect.version = "2.14.1";
connect.outerContextStreamsVersion = null;
connect.DEFAULT_BATCH_SIZE = 500;

Expand Down Expand Up @@ -27454,19 +27454,31 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
params.ringtone.chat.ringtoneUrl = otherParams.chat.ringtoneUrl;
}
}


if (otherParams.task) {
if (otherParams.task.disableRingtone) {
params.ringtone.task.disabled = true;
}

if (otherParams.task.ringtoneUrl) {
params.ringtone.task.ringtoneUrl = otherParams.task.ringtoneUrl;
}
}

// Merge in ringtone settings from downstream.
if (otherParams.ringtone) {
params.ringtone.voice = connect.merge(params.ringtone.voice,
otherParams.ringtone.voice || {});
params.ringtone.queue_callback = connect.merge(params.ringtone.queue_callback,
otherParams.ringtone.voice || {});
params.ringtone.chat = connect.merge(params.ringtone.chat,
otherParams.ringtone.chat || {});
otherParams.ringtone.chat || {});
params.ringtone.task = connect.merge(params.ringtone.task,
otherParams.ringtone.task || {});
}
};
// Merge params from params.softphone and params.chat into params.ringtone

// Merge params from params.softphone and params.chat and params.task into params.ringtone
// for embedded and non-embedded use cases so that defaults are picked up.
mergeParams(params, params);

Expand Down Expand Up @@ -28229,12 +28241,13 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
connect.core.masterClient = new connect.UpstreamConduitMasterClient(conduit);
connect.core.portStreamId = data.id;

if (params.softphone || params.chat || params.pageOptions || params.shouldAddNamespaceToLogs || params.disasterRecoveryOn) {
if (params.softphone || params.chat || params.task || params.pageOptions || params.shouldAddNamespaceToLogs || params.disasterRecoveryOn) {
// Send configuration up to the CCP.
//set it to false if secondary
conduit.sendUpstream(connect.EventType.CONFIGURE, {
softphone: params.softphone,
chat: params.chat,
task: params.task,
pageOptions: params.pageOptions,
shouldAddNamespaceToLogs: params.shouldAddNamespaceToLogs,
disasterRecoveryOn: params.disasterRecoveryOn,
Expand Down Expand Up @@ -28316,10 +28329,6 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
try {
var loginUrl = getLoginUrl(params);
connect.getLog().warn("ACK_TIMEOUT occurred, attempting to pop the login page if not already open.").sendInternalLogToServer();
// clear out last opened timestamp for SAML authentication when there is ACK_TIMEOUT
if (params.loginUrl) {
connect.core.getPopupManager().clear(connect.MasterTopics.LOGIN_POPUP);
}
connect.core.loginWindow = connect.core.getPopupManager().open(loginUrl, connect.MasterTopics.LOGIN_POPUP, params.loginOptions);
} catch (e) {
connect.getLog().error("ACK_TIMEOUT occurred but we are unable to open the login popup.").withException(e).sendInternalLogToServer();
Expand All @@ -28332,7 +28341,6 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
this.unsubscribe();
global.clearTimeout(connect.core.iframeRefreshTimeout);
connect.core.iframeRefreshTimeout = null;
connect.core.getPopupManager().clear(connect.MasterTopics.LOGIN_POPUP);
if ((params.loginPopupAutoClose || (params.loginOptions && params.loginOptions.autoClose)) && connect.core.loginWindow) {
connect.core.loginWindow.close();
connect.core.loginWindow = null;
Expand Down Expand Up @@ -33986,28 +33994,23 @@ AWS.apiLoader.services['connect']['2017-02-15'] = require('../apis/connect-2017-
connect.PopupManager = function () { };

connect.PopupManager.prototype.open = function (url, name, options) {
var then = this._getLastOpenedTimestamp(name);
var now = new Date().getTime();
var win = null;
if (now - then > ONE_DAY_MILLIS) {
if (options) {
// default values are chosen to provide a minimum height without scrolling
// and a uniform margin based on the css of the ccp login page
var height = options.height || DEFAULT_POPUP_HEIGHT;
var width = options.width || DEFAULT_POPUP_WIDTH;
var top = options.top || 0;
var left = options.left || 0;
win = window.open('', name, "width="+width+", height="+height+", top="+top+", left="+left);
if (win.location !== url) {
win = window.open(url, name, "width="+width+", height="+height+", top="+top+", left="+left);
}
} else {
win = window.open('', name);
if (win.location !== url) {
win = window.open(url, name);
}
if (options) {
// default values are chosen to provide a minimum height without scrolling
// and a uniform margin based on the css of the ccp login page
var height = options.height || DEFAULT_POPUP_HEIGHT;
var width = options.width || DEFAULT_POPUP_WIDTH;
var top = options.top || 0;
var left = options.left || 0;
win = window.open('', name, "width="+width+", height="+height+", top="+top+", left="+left);
if (win.location !== url) {
win = window.open(url, name, "width="+width+", height="+height+", top="+top+", left="+left);
}
} else {
win = window.open('', name);
if (win.location !== url) {
win = window.open(url, name);
}
this._setLastOpenedTimestamp(name, now);
}
return win;
};
Expand Down
28 changes: 18 additions & 10 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -574,19 +574,31 @@
params.ringtone.chat.ringtoneUrl = otherParams.chat.ringtoneUrl;
}
}


if (otherParams.task) {
if (otherParams.task.disableRingtone) {
params.ringtone.task.disabled = true;
}

if (otherParams.task.ringtoneUrl) {
params.ringtone.task.ringtoneUrl = otherParams.task.ringtoneUrl;
}
}

// Merge in ringtone settings from downstream.
if (otherParams.ringtone) {
params.ringtone.voice = connect.merge(params.ringtone.voice,
otherParams.ringtone.voice || {});
params.ringtone.queue_callback = connect.merge(params.ringtone.queue_callback,
otherParams.ringtone.voice || {});
params.ringtone.chat = connect.merge(params.ringtone.chat,
otherParams.ringtone.chat || {});
otherParams.ringtone.chat || {});
params.ringtone.task = connect.merge(params.ringtone.task,
otherParams.ringtone.task || {});
}
};
// Merge params from params.softphone and params.chat into params.ringtone

// Merge params from params.softphone and params.chat and params.task into params.ringtone
// for embedded and non-embedded use cases so that defaults are picked up.
mergeParams(params, params);

Expand Down Expand Up @@ -1349,12 +1361,13 @@
connect.core.masterClient = new connect.UpstreamConduitMasterClient(conduit);
connect.core.portStreamId = data.id;

if (params.softphone || params.chat || params.pageOptions || params.shouldAddNamespaceToLogs || params.disasterRecoveryOn) {
if (params.softphone || params.chat || params.task || params.pageOptions || params.shouldAddNamespaceToLogs || params.disasterRecoveryOn) {
// Send configuration up to the CCP.
//set it to false if secondary
conduit.sendUpstream(connect.EventType.CONFIGURE, {
softphone: params.softphone,
chat: params.chat,
task: params.task,
pageOptions: params.pageOptions,
shouldAddNamespaceToLogs: params.shouldAddNamespaceToLogs,
disasterRecoveryOn: params.disasterRecoveryOn,
Expand Down Expand Up @@ -1436,10 +1449,6 @@
try {
var loginUrl = getLoginUrl(params);
connect.getLog().warn("ACK_TIMEOUT occurred, attempting to pop the login page if not already open.").sendInternalLogToServer();
// clear out last opened timestamp for SAML authentication when there is ACK_TIMEOUT
if (params.loginUrl) {
connect.core.getPopupManager().clear(connect.MasterTopics.LOGIN_POPUP);
}
connect.core.loginWindow = connect.core.getPopupManager().open(loginUrl, connect.MasterTopics.LOGIN_POPUP, params.loginOptions);
} catch (e) {
connect.getLog().error("ACK_TIMEOUT occurred but we are unable to open the login popup.").withException(e).sendInternalLogToServer();
Expand All @@ -1452,7 +1461,6 @@
this.unsubscribe();
global.clearTimeout(connect.core.iframeRefreshTimeout);
connect.core.iframeRefreshTimeout = null;
connect.core.getPopupManager().clear(connect.MasterTopics.LOGIN_POPUP);
if ((params.loginPopupAutoClose || (params.loginOptions && params.loginOptions.autoClose)) && connect.core.loginWindow) {
connect.core.loginWindow.close();
connect.core.loginWindow = null;
Expand Down
11 changes: 11 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,14 @@ declare namespace connect {
readonly ringtoneUrl?: string;
}

interface TaskOptions {
/** This option allows you to completely disable the built-in ringtone audio that is played when a task is incoming. */
readonly disableRingtone?: boolean;

/** If the ringtone is not disabled, this allows for overriding the ringtone with any browser-supported audio file accessible by the user. */
readonly ringtoneUrl?: string;
}

interface LoginOptions {
/*
* Whether to auto close the login prompt.
Expand Down Expand Up @@ -526,6 +534,9 @@ declare namespace connect {
/** Allows you to specify ringtone settings for Chat. */
readonly chat?: ChatOptions;

/** Allows you to specify ringtone settings for Task. */
readonly task?: TaskOptions;

/**
* Allows you to customize the title attribute of the CCP iframe.
* @example "Contact Control Panel"
Expand Down
35 changes: 15 additions & 20 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -560,28 +560,23 @@
connect.PopupManager = function () { };

connect.PopupManager.prototype.open = function (url, name, options) {
var then = this._getLastOpenedTimestamp(name);
var now = new Date().getTime();
var win = null;
if (now - then > ONE_DAY_MILLIS) {
if (options) {
// default values are chosen to provide a minimum height without scrolling
// and a uniform margin based on the css of the ccp login page
var height = options.height || DEFAULT_POPUP_HEIGHT;
var width = options.width || DEFAULT_POPUP_WIDTH;
var top = options.top || 0;
var left = options.left || 0;
win = window.open('', name, "width="+width+", height="+height+", top="+top+", left="+left);
if (win.location !== url) {
win = window.open(url, name, "width="+width+", height="+height+", top="+top+", left="+left);
}
} else {
win = window.open('', name);
if (win.location !== url) {
win = window.open(url, name);
}
if (options) {
// default values are chosen to provide a minimum height without scrolling
// and a uniform margin based on the css of the ccp login page
var height = options.height || DEFAULT_POPUP_HEIGHT;
var width = options.width || DEFAULT_POPUP_WIDTH;
var top = options.top || 0;
var left = options.left || 0;
win = window.open('', name, "width="+width+", height="+height+", top="+top+", left="+left);
if (win.location !== url) {
win = window.open(url, name, "width="+width+", height="+height+", top="+top+", left="+left);
}
} else {
win = window.open('', name);
if (win.location !== url) {
win = window.open(url, name);
}
this._setLastOpenedTimestamp(name, now);
}
return win;
};
Expand Down
34 changes: 31 additions & 3 deletions test/unit/core.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,32 @@ describe('Core', function () {
assert.isTrue(connect.TaskRingtoneEngine.calledOnceWith(usedRingtoneParams.ringtone.task));
assert.isTrue(connect.QueueCallbackRingtoneEngine.calledOnceWith(usedRingtoneParams.ringtone.queue_callback));
});

it('initializes ringtone engines WITHOUT using stored ringtone params when CONFIGURE message IS delivered, for disabled ringtone', () => {
const otherRingtoneUrl = 'some_other_ringtone_url';
const usedRingtoneParams = {
ringtone: {
voice: { disabled: true, ringtoneUrl: otherRingtoneUrl },
queue_callback: { disabled: true, ringtoneUrl: otherRingtoneUrl },
chat: { disabled: true, ringtoneUrl: otherRingtoneUrl },
task: { disabled: true, ringtoneUrl: otherRingtoneUrl },
}
}
connect.core.initRingtoneEngines(usedRingtoneParams);
connect.core.getEventBus().trigger(connect.EventType.ACKNOWLEDGE, { id: 'portId' });
clock.tick(99); // set to below 100 to NOT execute the setimeout handler
// trigger configure
connect.core.getEventBus().trigger(connect.EventType.CONFIGURE, {});
connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent());
connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent());
connect.ifMaster.callArg(1);

sandbox.assert.calledWithExactly(global.localStorage.getItem, ringtoneParamsKey);
assert.isFalse(connect.VoiceRingtoneEngine.calledOnceWith(usedRingtoneParams.ringtone.voice));
assert.isFalse(connect.ChatRingtoneEngine.calledOnceWith(usedRingtoneParams.ringtone.chat));
assert.isFalse(connect.TaskRingtoneEngine.calledOnceWith(usedRingtoneParams.ringtone.task));
assert.isFalse(connect.QueueCallbackRingtoneEngine.calledOnceWith(usedRingtoneParams.ringtone.queue_callback));
});
});

it('Ringtone parameters should get cleaned up on every initCCP call', () => {
Expand Down Expand Up @@ -1262,6 +1288,7 @@ describe('Core', function () {
let clearStub, openStub, closeStub;
const softphoneParams = { ringtoneUrl: "customVoiceRingtone.amazon.com" };
const chatParams = { ringtoneUrl: "customChatRingtone.amazon.com" };
const taskParams = { ringtoneUrl: "customTaskRingtone.amazon.com" };
const pageOptionsParams = {
enableAudioDeviceSettings: false,
enableVideoDeviceSettings: false,
Expand All @@ -1278,6 +1305,7 @@ describe('Core', function () {
loginUrl: "loginUrl.com",
softphone: softphoneParams,
chat: chatParams,
task: taskParams,
loginOptions: { autoClose: true },
pageOptions: pageOptionsParams,
shouldAddNamespaceToLogs: shouldAddNamespaceToLogs
Expand Down Expand Up @@ -1435,6 +1463,7 @@ describe('Core', function () {
sinon.assert.calledWith(connect.core.getUpstream().sendUpstream, connect.EventType.CONFIGURE, {
softphone: softphoneParams,
chat: chatParams,
task: taskParams,
pageOptions: pageOptionsParams,
shouldAddNamespaceToLogs: shouldAddNamespaceToLogs,
disasterRecoveryOn: disasterRecoveryOn
Expand All @@ -1451,16 +1480,13 @@ describe('Core', function () {
});
it("calls _refreshIframeOnTimeout when ack timeout occurs", function () {
expect(connect.core._refreshIframeOnTimeout.calledOnce).to.be.true;
expect(clearStub.calledOnce).to.be.true;
expect(clearStub.calledWith(connect.MasterTopics.LOGIN_POPUP)).to.be.true;
expect(openStub.calledOnce).to.be.true;
expect(openStub.calledWith(params.loginUrl, connect.MasterTopics.LOGIN_POPUP, params.loginOptions));
});
describe("on ACK", function () {
it("resets the iframe refresh timeout, calls popupManager.clear, calls loginWindow.close", () => {
connect.core.getUpstream().upstreamBus.trigger(connect.EventType.ACKNOWLEDGE, { id: 'portId' });
expect(connect.core.iframeRefreshTimeout === null).to.be.true;
expect(clearStub.calledTwice).to.be.true;
expect(closeStub.calledOnce).to.be.true;
expect(connect.core.loginWindow === null).to.be.true;
});
Expand All @@ -1475,6 +1501,7 @@ describe('Core', function () {
let clearStub, openStub, closeStub;
const softphoneParams = { ringtoneUrl: "customVoiceRingtone.amazon.com" };
const chatParams = { ringtoneUrl: "customChatRingtone.amazon.com" };
const taskParams = { ringtoneUrl: "customTaskRingtone.amazon.com" };
const pageOptionsParams = {
enableAudioDeviceSettings: false,
enableVideoDeviceSettings: false,
Expand All @@ -1486,6 +1513,7 @@ describe('Core', function () {
loginUrl: "loginUrl.com",
softphone: softphoneParams,
chat: chatParams,
task: taskParams,
loginOptions: { autoClose: true },
pageOptions: pageOptionsParams,
shouldAddNamespaceToLogs: shouldAddNamespaceToLogs,
Expand Down

0 comments on commit c2dcdb0

Please sign in to comment.