@defra/flood-webchat 0.0.1-beta.47 → 0.0.1-beta.49
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/client.js +1 -2433
- package/dist/server.js +1 -303
- package/package.json +3 -2
- package/src/client/components/screens/feedback.jsx +1 -1
- package/src/client/index.jsx +4 -1
- package/src/client/lib/message-notification.js +4 -10
- package/src/client/store/AppProvider.jsx +2 -6
- package/webpack.config.mjs +0 -2
- package/webpack.prod.mjs +7 -0
- package/dist/client.js.map +0 -1
- package/dist/server.js.map +0 -1
package/dist/server.js
CHANGED
|
@@ -1,303 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/******/ var __webpack_modules__ = ({
|
|
3
|
-
|
|
4
|
-
/***/ "./src/server/index.js":
|
|
5
|
-
/*!*****************************!*\
|
|
6
|
-
!*** ./src/server/index.js ***!
|
|
7
|
-
\*****************************/
|
|
8
|
-
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
9
|
-
|
|
10
|
-
const {
|
|
11
|
-
authenticate,
|
|
12
|
-
getApiBaseUrl,
|
|
13
|
-
getIsOpen,
|
|
14
|
-
getActivity
|
|
15
|
-
} = __webpack_require__(/*! ./lib/client.js */ "./src/server/lib/client.js");
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Returns webchat availability
|
|
19
|
-
* @param options {object}
|
|
20
|
-
* @param options.clientId {string}
|
|
21
|
-
* @param options.clientSecret {string}
|
|
22
|
-
* @param options.accessKey {string}
|
|
23
|
-
* @param options.accessSecret {string}
|
|
24
|
-
* @param options.skillEndpoint {string}
|
|
25
|
-
* @param options.hoursEndpoint {string}
|
|
26
|
-
* @param options.authenticationUri {string}
|
|
27
|
-
* @param options.wellKnownUri {string}
|
|
28
|
-
* @param options.maxQueueCount {string}
|
|
29
|
-
* @returns {Promise<{date: Date, availability: (string)}>}
|
|
30
|
-
*/
|
|
31
|
-
module.exports = async function getAvailability({
|
|
32
|
-
clientId,
|
|
33
|
-
clientSecret,
|
|
34
|
-
accessKey,
|
|
35
|
-
accessSecret,
|
|
36
|
-
maxQueueCount,
|
|
37
|
-
skillEndpoint,
|
|
38
|
-
hoursEndpoint,
|
|
39
|
-
wellKnownUri = 'https://cxone.niceincontact.com/.well-known/cxone-configuration',
|
|
40
|
-
authenticationUri = 'https://cxone.niceincontact.com/auth/token'
|
|
41
|
-
}) {
|
|
42
|
-
const authorisation = 'Basic ' + Buffer.from(`${encodeURIComponent(clientId)}:${encodeURIComponent(clientSecret)}`).toString('base64');
|
|
43
|
-
|
|
44
|
-
// Cache authentication and re-authenticate when needed (lasts 1 hour?)
|
|
45
|
-
const {
|
|
46
|
-
tenantId,
|
|
47
|
-
token,
|
|
48
|
-
tokenType
|
|
49
|
-
} = await authenticate({
|
|
50
|
-
authenticationUri,
|
|
51
|
-
authorisation,
|
|
52
|
-
accessKey,
|
|
53
|
-
accessSecret
|
|
54
|
-
});
|
|
55
|
-
const apiBaseUrl = await getApiBaseUrl({
|
|
56
|
-
wellKnownUri,
|
|
57
|
-
tenantId
|
|
58
|
-
});
|
|
59
|
-
const [{
|
|
60
|
-
hasCapacity,
|
|
61
|
-
hasAgentsAvailable
|
|
62
|
-
}, isOpen] = await Promise.all([getActivity({
|
|
63
|
-
baseUrl: apiBaseUrl,
|
|
64
|
-
tokenType,
|
|
65
|
-
token,
|
|
66
|
-
skillEndpoint,
|
|
67
|
-
maxQueueCount
|
|
68
|
-
}), getIsOpen({
|
|
69
|
-
baseUrl: apiBaseUrl,
|
|
70
|
-
token,
|
|
71
|
-
tokenType,
|
|
72
|
-
hoursEndpoint
|
|
73
|
-
})]);
|
|
74
|
-
const isAvailable = isOpen && hasAgentsAvailable && hasCapacity;
|
|
75
|
-
const isExistingOnly = isOpen && hasAgentsAvailable && !hasCapacity;
|
|
76
|
-
let availability = 'UNAVAILABLE';
|
|
77
|
-
if (isAvailable) {
|
|
78
|
-
availability = 'AVAILABLE';
|
|
79
|
-
} else if (isExistingOnly) {
|
|
80
|
-
availability = 'EXISTING';
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
date: new Date(),
|
|
84
|
-
availability
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
/***/ }),
|
|
89
|
-
|
|
90
|
-
/***/ "./src/server/lib/client.js":
|
|
91
|
-
/*!**********************************!*\
|
|
92
|
-
!*** ./src/server/lib/client.js ***!
|
|
93
|
-
\**********************************/
|
|
94
|
-
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
95
|
-
|
|
96
|
-
const querystring = __webpack_require__(/*! querystring */ "querystring");
|
|
97
|
-
const axios = __webpack_require__(/*! axios */ "axios");
|
|
98
|
-
const jwtdecode = __webpack_require__(/*! jwt-decode */ "jwt-decode");
|
|
99
|
-
const {
|
|
100
|
-
isWithinHours
|
|
101
|
-
} = __webpack_require__(/*! ./utils.js */ "./src/server/lib/utils.js");
|
|
102
|
-
const contentType = 'application/x-www-form-urlencoded';
|
|
103
|
-
const authenticate = async ({
|
|
104
|
-
authenticationUri,
|
|
105
|
-
authorisation,
|
|
106
|
-
accessKey,
|
|
107
|
-
accessSecret
|
|
108
|
-
}) => {
|
|
109
|
-
const url = new URL(authenticationUri);
|
|
110
|
-
const body = querystring.stringify({
|
|
111
|
-
grant_type: 'password',
|
|
112
|
-
username: accessKey,
|
|
113
|
-
password: accessSecret
|
|
114
|
-
});
|
|
115
|
-
const auth = await axios.post(url.href, body, {
|
|
116
|
-
signal: AbortSignal.timeout(3000),
|
|
117
|
-
headers: {
|
|
118
|
-
Host: url.host,
|
|
119
|
-
'Content-Type': contentType,
|
|
120
|
-
Authorization: authorisation
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
return {
|
|
124
|
-
token: auth.data.access_token,
|
|
125
|
-
tokenType: auth.data.token_type,
|
|
126
|
-
tenantId: jwtdecode(auth.data.id_token)?.tenantId
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
const getApiBaseUrl = async ({
|
|
130
|
-
wellKnownUri,
|
|
131
|
-
tenantId
|
|
132
|
-
}) => {
|
|
133
|
-
const url = new URL(wellKnownUri);
|
|
134
|
-
url.searchParams.set('tenantId', tenantId);
|
|
135
|
-
const {
|
|
136
|
-
data
|
|
137
|
-
} = await axios.get(url.href, {
|
|
138
|
-
headers: {
|
|
139
|
-
Host: url.host
|
|
140
|
-
},
|
|
141
|
-
signal: AbortSignal.timeout(3000)
|
|
142
|
-
});
|
|
143
|
-
return data.api_endpoint;
|
|
144
|
-
};
|
|
145
|
-
const getActivity = async ({
|
|
146
|
-
tokenType,
|
|
147
|
-
token,
|
|
148
|
-
baseUrl,
|
|
149
|
-
skillEndpoint,
|
|
150
|
-
maxQueueCount
|
|
151
|
-
}) => {
|
|
152
|
-
const url = new URL(skillEndpoint, baseUrl);
|
|
153
|
-
const skill = await axios.get(url.href, {
|
|
154
|
-
signal: AbortSignal.timeout(3000),
|
|
155
|
-
headers: {
|
|
156
|
-
Host: url.host,
|
|
157
|
-
Authorization: `${tokenType} ${token}`,
|
|
158
|
-
'Content-Type': contentType
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
const activity = skill.data.skillActivity[0];
|
|
162
|
-
return {
|
|
163
|
-
hasCapacity: activity.queueCount < maxQueueCount,
|
|
164
|
-
hasAgentsAvailable: activity.agentsAvailable >= 1
|
|
165
|
-
};
|
|
166
|
-
};
|
|
167
|
-
const getIsOpen = async ({
|
|
168
|
-
baseUrl,
|
|
169
|
-
token,
|
|
170
|
-
tokenType,
|
|
171
|
-
hoursEndpoint
|
|
172
|
-
}) => {
|
|
173
|
-
const url = new URL(hoursEndpoint, baseUrl);
|
|
174
|
-
const hours = await axios.get(url.href, {
|
|
175
|
-
signal: AbortSignal.timeout(3000),
|
|
176
|
-
headers: {
|
|
177
|
-
Host: url.host,
|
|
178
|
-
Authorization: `${tokenType} ${token}`,
|
|
179
|
-
'Content-Type': contentType
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
const days = hours.data.resultSet.hoursOfOperationProfiles[0].days;
|
|
183
|
-
return isWithinHours(days);
|
|
184
|
-
};
|
|
185
|
-
module.exports = {
|
|
186
|
-
authenticate,
|
|
187
|
-
getApiBaseUrl,
|
|
188
|
-
getIsOpen,
|
|
189
|
-
getActivity
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
/***/ }),
|
|
193
|
-
|
|
194
|
-
/***/ "./src/server/lib/utils.js":
|
|
195
|
-
/*!*********************************!*\
|
|
196
|
-
!*** ./src/server/lib/utils.js ***!
|
|
197
|
-
\*********************************/
|
|
198
|
-
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
199
|
-
|
|
200
|
-
const {
|
|
201
|
-
DateTime
|
|
202
|
-
} = __webpack_require__(/*! luxon */ "luxon");
|
|
203
|
-
const getHour = time => Number(time.split(':')[0]);
|
|
204
|
-
const isWithinHours = (days, date) => {
|
|
205
|
-
const now = date ? DateTime.fromISO(date) : DateTime.local();
|
|
206
|
-
now.setZone('Europe/London');
|
|
207
|
-
const newDate = date ? new Date(date) : new Date();
|
|
208
|
-
const today = newDate.toLocaleDateString('en-GB', {
|
|
209
|
-
weekday: 'long'
|
|
210
|
-
});
|
|
211
|
-
const dateParts = newDate.toLocaleDateString('en-GB').split('/');
|
|
212
|
-
const todaysAvailability = days.find(item => item.day === today);
|
|
213
|
-
const todaysDateTimeOpen = DateTime.local(Number(dateParts[2]), Number(dateParts[1]), Number(dateParts[0]), getHour(todaysAvailability.openTime));
|
|
214
|
-
const todaysDateTimeClose = DateTime.local(Number(dateParts[2]), Number(dateParts[1]), Number(dateParts[0]), getHour(todaysAvailability.closeTime));
|
|
215
|
-
return now.diff(todaysDateTimeOpen).milliseconds >= 0 && now.diff(todaysDateTimeClose).milliseconds <= 0;
|
|
216
|
-
};
|
|
217
|
-
module.exports = {
|
|
218
|
-
isWithinHours
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
/***/ }),
|
|
222
|
-
|
|
223
|
-
/***/ "axios":
|
|
224
|
-
/*!************************!*\
|
|
225
|
-
!*** external "axios" ***!
|
|
226
|
-
\************************/
|
|
227
|
-
/***/ ((module) => {
|
|
228
|
-
|
|
229
|
-
"use strict";
|
|
230
|
-
module.exports = require("axios");
|
|
231
|
-
|
|
232
|
-
/***/ }),
|
|
233
|
-
|
|
234
|
-
/***/ "jwt-decode":
|
|
235
|
-
/*!*****************************!*\
|
|
236
|
-
!*** external "jwt-decode" ***!
|
|
237
|
-
\*****************************/
|
|
238
|
-
/***/ ((module) => {
|
|
239
|
-
|
|
240
|
-
"use strict";
|
|
241
|
-
module.exports = require("jwt-decode");
|
|
242
|
-
|
|
243
|
-
/***/ }),
|
|
244
|
-
|
|
245
|
-
/***/ "luxon":
|
|
246
|
-
/*!************************!*\
|
|
247
|
-
!*** external "luxon" ***!
|
|
248
|
-
\************************/
|
|
249
|
-
/***/ ((module) => {
|
|
250
|
-
|
|
251
|
-
"use strict";
|
|
252
|
-
module.exports = require("luxon");
|
|
253
|
-
|
|
254
|
-
/***/ }),
|
|
255
|
-
|
|
256
|
-
/***/ "querystring":
|
|
257
|
-
/*!******************************!*\
|
|
258
|
-
!*** external "querystring" ***!
|
|
259
|
-
\******************************/
|
|
260
|
-
/***/ ((module) => {
|
|
261
|
-
|
|
262
|
-
"use strict";
|
|
263
|
-
module.exports = require("querystring");
|
|
264
|
-
|
|
265
|
-
/***/ })
|
|
266
|
-
|
|
267
|
-
/******/ });
|
|
268
|
-
/************************************************************************/
|
|
269
|
-
/******/ // The module cache
|
|
270
|
-
/******/ var __webpack_module_cache__ = {};
|
|
271
|
-
/******/
|
|
272
|
-
/******/ // The require function
|
|
273
|
-
/******/ function __webpack_require__(moduleId) {
|
|
274
|
-
/******/ // Check if module is in cache
|
|
275
|
-
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
276
|
-
/******/ if (cachedModule !== undefined) {
|
|
277
|
-
/******/ return cachedModule.exports;
|
|
278
|
-
/******/ }
|
|
279
|
-
/******/ // Create a new module (and put it into the cache)
|
|
280
|
-
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
281
|
-
/******/ // no module.id needed
|
|
282
|
-
/******/ // no module.loaded needed
|
|
283
|
-
/******/ exports: {}
|
|
284
|
-
/******/ };
|
|
285
|
-
/******/
|
|
286
|
-
/******/ // Execute the module function
|
|
287
|
-
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
288
|
-
/******/
|
|
289
|
-
/******/ // Return the exports of the module
|
|
290
|
-
/******/ return module.exports;
|
|
291
|
-
/******/ }
|
|
292
|
-
/******/
|
|
293
|
-
/************************************************************************/
|
|
294
|
-
/******/
|
|
295
|
-
/******/ // startup
|
|
296
|
-
/******/ // Load entry module and return exports
|
|
297
|
-
/******/ // This entry module is referenced by other modules so it can't be inlined
|
|
298
|
-
/******/ var __webpack_exports__ = __webpack_require__("./src/server/index.js");
|
|
299
|
-
/******/ module.exports = __webpack_exports__;
|
|
300
|
-
/******/
|
|
301
|
-
/******/ })()
|
|
302
|
-
;
|
|
303
|
-
//# sourceMappingURL=server.js.map
|
|
1
|
+
(()=>{var e={553:(e,t,n)=>{const{authenticate:o,getApiBaseUrl:a,getIsOpen:i,getActivity:s}=n(980);e.exports=async function({clientId:e,clientSecret:t,accessKey:n,accessSecret:r,maxQueueCount:c,skillEndpoint:u,hoursEndpoint:l,wellKnownUri:p="https://cxone.niceincontact.com/.well-known/cxone-configuration",authenticationUri:d="https://cxone.niceincontact.com/auth/token"}){const h="Basic "+Buffer.from(`${encodeURIComponent(e)}:${encodeURIComponent(t)}`).toString("base64"),{tenantId:m,token:y,tokenType:w}=await o({authenticationUri:d,authorisation:h,accessKey:n,accessSecret:r}),g=await a({wellKnownUri:p,tenantId:m}),[{hasCapacity:A,hasAgentsAvailable:k},f]=await Promise.all([s({baseUrl:g,tokenType:w,token:y,skillEndpoint:u,maxQueueCount:c}),i({baseUrl:g,token:y,tokenType:w,hoursEndpoint:l})]);let x="UNAVAILABLE";return f&&k&&A?x="AVAILABLE":f&&k&&!A&&(x="EXISTING"),{date:new Date,availability:x}}},980:(e,t,n)=>{const o=n(819),a=n(167),i=n(567),{isWithinHours:s}=n(393),r="application/x-www-form-urlencoded";e.exports={authenticate:async({authenticationUri:e,authorisation:t,accessKey:n,accessSecret:s})=>{const c=new URL(e),u=o.stringify({grant_type:"password",username:n,password:s}),l=await a.post(c.href,u,{signal:AbortSignal.timeout(3e3),headers:{Host:c.host,"Content-Type":r,Authorization:t}});return{token:l.data.access_token,tokenType:l.data.token_type,tenantId:i(l.data.id_token)?.tenantId}},getApiBaseUrl:async({wellKnownUri:e,tenantId:t})=>{const n=new URL(e);n.searchParams.set("tenantId",t);const{data:o}=await a.get(n.href,{headers:{Host:n.host},signal:AbortSignal.timeout(3e3)});return o.api_endpoint},getIsOpen:async({baseUrl:e,token:t,tokenType:n,hoursEndpoint:o})=>{const i=new URL(o,e),c=(await a.get(i.href,{signal:AbortSignal.timeout(3e3),headers:{Host:i.host,Authorization:`${n} ${t}`,"Content-Type":r}})).data.resultSet.hoursOfOperationProfiles[0].days;return s(c)},getActivity:async({tokenType:e,token:t,baseUrl:n,skillEndpoint:o,maxQueueCount:i})=>{const s=new URL(o,n),c=(await a.get(s.href,{signal:AbortSignal.timeout(3e3),headers:{Host:s.host,Authorization:`${e} ${t}`,"Content-Type":r}})).data.skillActivity[0];return{hasCapacity:c.queueCount<i,hasAgentsAvailable:c.agentsAvailable>=1}}}},393:(e,t,n)=>{const{DateTime:o}=n(748),a=e=>Number(e.split(":")[0]);e.exports={isWithinHours:(e,t)=>{const n=t?o.fromISO(t):o.local();n.setZone("Europe/London");const i=t?new Date(t):new Date,s=i.toLocaleDateString("en-GB",{weekday:"long"}),r=i.toLocaleDateString("en-GB").split("/"),c=e.find((e=>e.day===s)),u=o.local(Number(r[2]),Number(r[1]),Number(r[0]),a(c.openTime)),l=o.local(Number(r[2]),Number(r[1]),Number(r[0]),a(c.closeTime));return n.diff(u).milliseconds>=0&&n.diff(l).milliseconds<=0}}},167:e=>{"use strict";e.exports=require("axios")},567:e=>{"use strict";e.exports=require("jwt-decode")},748:e=>{"use strict";e.exports=require("luxon")},819:e=>{"use strict";e.exports=require("querystring")}},t={},n=function n(o){var a=t[o];if(void 0!==a)return a.exports;var i=t[o]={exports:{}};return e[o](i,i.exports,n),i.exports}(553);module.exports=n})();
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra/flood-webchat",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.49",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"browser": "dist/client.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "npm run lint && npm run unit-test",
|
|
9
9
|
"dev": "(cd demo && webpack server)",
|
|
10
|
-
"build": "webpack",
|
|
10
|
+
"build": "webpack --config webpack.prod.mjs",
|
|
11
11
|
"unit-test": "jest",
|
|
12
12
|
"lint": "npm run lint:js && npm run lint:scss",
|
|
13
13
|
"lint:fix": "npm run lint:js -- --fix && npm run lint:scss -- --fix",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"webpack": "^5.88.2",
|
|
54
54
|
"webpack-cli": "^5.1.4",
|
|
55
55
|
"webpack-dev-server": "^4.15.1",
|
|
56
|
+
"webpack-merge": "^5.10.0",
|
|
56
57
|
"webpack-node-externals": "^3.0.0"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
@@ -30,7 +30,7 @@ export function Feedback ({ onCancel }) {
|
|
|
30
30
|
|
|
31
31
|
<div className='wc-body'>
|
|
32
32
|
<div className='wc-content'>
|
|
33
|
-
<h3 id='wc-subtitle' className='wc-heading'>Give
|
|
33
|
+
<h3 id='wc-subtitle' className='wc-heading'>Give feedback on Floodline webchat</h3>
|
|
34
34
|
<p>We're running webchat as a trial. you can
|
|
35
35
|
<a
|
|
36
36
|
id='feedback-send'
|
package/src/client/index.jsx
CHANGED
|
@@ -5,6 +5,7 @@ import { Availability } from './components/availability/availability.jsx'
|
|
|
5
5
|
import { checkAvailability } from './lib/check-availability'
|
|
6
6
|
import { AppProvider } from './store/AppProvider.jsx'
|
|
7
7
|
import { CUSTOMER_ID_STORAGE_KEY } from './store/constants.js'
|
|
8
|
+
import { messageNotification } from './lib/message-notification.js'
|
|
8
9
|
|
|
9
10
|
export async function init (container, options) {
|
|
10
11
|
const sdk = new ChatSdk({
|
|
@@ -16,14 +17,16 @@ export async function init (container, options) {
|
|
|
16
17
|
|
|
17
18
|
const root = createRoot(container)
|
|
18
19
|
let availability
|
|
20
|
+
let playSound
|
|
19
21
|
try {
|
|
20
22
|
const result = await checkAvailability(options.availabilityEndpoint)
|
|
23
|
+
playSound = await messageNotification(options.audioUrl)
|
|
21
24
|
availability = result.availability
|
|
22
25
|
} catch (e) {
|
|
23
26
|
availability = 'UNAVAILABLE'
|
|
24
27
|
}
|
|
25
28
|
root.render(
|
|
26
|
-
<AppProvider sdk={sdk} availability={availability}
|
|
29
|
+
<AppProvider sdk={sdk} availability={availability} playSound={playSound}>
|
|
27
30
|
<Availability />
|
|
28
31
|
</AppProvider>
|
|
29
32
|
)
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export const messageNotification = audioUrl => {
|
|
2
|
-
let buffer
|
|
3
|
-
|
|
1
|
+
export const messageNotification = async audioUrl => {
|
|
4
2
|
const context = new (window.AudioContext || window.webkitAudioContext)()
|
|
5
3
|
|
|
6
4
|
if (context.state === 'suspended') {
|
|
@@ -19,13 +17,9 @@ export const messageNotification = audioUrl => {
|
|
|
19
17
|
})
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
fetch(audioUrl)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
.then(decodedData => {
|
|
26
|
-
buffer = decodedData
|
|
27
|
-
})
|
|
28
|
-
.catch(console.error)
|
|
20
|
+
const response = await fetch(audioUrl)
|
|
21
|
+
const arrayBuffer = await response.arrayBuffer()
|
|
22
|
+
const buffer = await context.decodeAudioData(arrayBuffer)
|
|
29
23
|
|
|
30
24
|
return () => {
|
|
31
25
|
const source = context.createBufferSource()
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import React, { createContext, useEffect, useReducer, useMemo } from 'react'
|
|
2
2
|
import { ChatEvent } from '@nice-devone/nice-cxone-chat-web-sdk'
|
|
3
3
|
|
|
4
|
-
import { messageNotification } from '../lib/message-notification.js'
|
|
5
|
-
|
|
6
4
|
import { initialState, reducer } from './reducer.js'
|
|
7
5
|
import { CUSTOMER_ID_STORAGE_KEY, THREAD_ID_STORAGE_KEY, SETTINGS_STORAGE_KEY } from './constants.js'
|
|
8
6
|
|
|
9
7
|
export const AppContext = createContext(initialState)
|
|
10
8
|
|
|
11
|
-
export const AppProvider = ({ sdk, availability,
|
|
9
|
+
export const AppProvider = ({ sdk, availability, playSound, children }) => {
|
|
12
10
|
const [state, dispatch] = useReducer(reducer, initialState)
|
|
13
11
|
|
|
14
|
-
const playSound = messageNotification(options.audioUrl)
|
|
15
|
-
|
|
16
12
|
/**
|
|
17
13
|
* SDK event handlers
|
|
18
14
|
*/
|
|
@@ -43,7 +39,7 @@ export const AppProvider = ({ sdk, availability, options, children }) => {
|
|
|
43
39
|
|
|
44
40
|
const isAudioOn = JSON.parse(window.localStorage.getItem(SETTINGS_STORAGE_KEY)).audio
|
|
45
41
|
|
|
46
|
-
if (isAudioOn && e.detail.data.message.direction === 'outbound') {
|
|
42
|
+
if (isAudioOn && e.detail.data.message.direction === 'outbound' && playSound) {
|
|
47
43
|
playSound()
|
|
48
44
|
}
|
|
49
45
|
}
|
package/webpack.config.mjs
CHANGED