@livechat/customer-sdk 3.1.0

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.
@@ -0,0 +1,3790 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var createAuth = require('@livechat/customer-auth');
6
+ var mitt = require('@livechat/mitt');
7
+ var dataUtils = require('@livechat/data-utils');
8
+ var redux = require('redux');
9
+ var createSideEffectsMiddleware = require('@livechat/side-effects-middleware');
10
+ var deferred = require('@livechat/deferred');
11
+ var promiseTry = require('@livechat/promise-try');
12
+ var createBackoff = require('@livechat/backoff');
13
+ var storage = require('@livechat/isomorphic-storage');
14
+ var unfetch = require('unfetch');
15
+ var urlUtils = require('@livechat/url-utils');
16
+ var createPlatformClient = require('@livechat/platform-client');
17
+ var rawUploadFile = require('@livechat/file-upload');
18
+
19
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
20
+
21
+ var createAuth__default = /*#__PURE__*/_interopDefaultLegacy(createAuth);
22
+ var mitt__default = /*#__PURE__*/_interopDefaultLegacy(mitt);
23
+ var createSideEffectsMiddleware__default = /*#__PURE__*/_interopDefaultLegacy(createSideEffectsMiddleware);
24
+ var deferred__default = /*#__PURE__*/_interopDefaultLegacy(deferred);
25
+ var promiseTry__default = /*#__PURE__*/_interopDefaultLegacy(promiseTry);
26
+ var createBackoff__default = /*#__PURE__*/_interopDefaultLegacy(createBackoff);
27
+ var storage__default = /*#__PURE__*/_interopDefaultLegacy(storage);
28
+ var unfetch__default = /*#__PURE__*/_interopDefaultLegacy(unfetch);
29
+ var createPlatformClient__default = /*#__PURE__*/_interopDefaultLegacy(createPlatformClient);
30
+ var rawUploadFile__default = /*#__PURE__*/_interopDefaultLegacy(rawUploadFile);
31
+
32
+ function _extends() {
33
+ _extends = Object.assign || function (target) {
34
+ for (var i = 1; i < arguments.length; i++) {
35
+ var source = arguments[i];
36
+
37
+ for (var key in source) {
38
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
39
+ target[key] = source[key];
40
+ }
41
+ }
42
+ }
43
+
44
+ return target;
45
+ };
46
+
47
+ return _extends.apply(this, arguments);
48
+ }
49
+
50
+ function _objectWithoutPropertiesLoose(source, excluded) {
51
+ if (source == null) return {};
52
+ var target = {};
53
+ var sourceKeys = Object.keys(source);
54
+ var key, i;
55
+
56
+ for (i = 0; i < sourceKeys.length; i++) {
57
+ key = sourceKeys[i];
58
+ if (excluded.indexOf(key) >= 0) continue;
59
+ target[key] = source[key];
60
+ }
61
+
62
+ return target;
63
+ }
64
+
65
+ function _toPrimitive(input, hint) {
66
+ if (typeof input !== "object" || input === null) return input;
67
+ var prim = input[Symbol.toPrimitive];
68
+
69
+ if (prim !== undefined) {
70
+ var res = prim.call(input, hint || "default");
71
+ if (typeof res !== "object") return res;
72
+ throw new TypeError("@@toPrimitive must return a primitive value.");
73
+ }
74
+
75
+ return (hint === "string" ? String : Number)(input);
76
+ }
77
+
78
+ function _toPropertyKey(arg) {
79
+ var key = _toPrimitive(arg, "string");
80
+
81
+ return typeof key === "symbol" ? key : String(key);
82
+ }
83
+
84
+ var CHANGE_REGION = 'change_region';
85
+ var CHECK_GOALS = 'check_goals';
86
+ var DESTROY = 'destroy';
87
+ var FAIL_ALL_REQUESTS = 'fail_all_requests';
88
+ var LOGIN_SUCCESS = 'login_success';
89
+ var PAUSE_CONNECTION = 'pause_connection';
90
+ var PREFETCH_TOKEN = 'prefetch_token';
91
+ var PUSH_RECEIVED = 'push_received';
92
+ var PUSH_RESPONSE_RECEIVED = 'push_response_received';
93
+ var RECONNECT = 'reconnect';
94
+ var REQUEST_FAILED = 'request_failed';
95
+ var RESPONSE_RECEIVED = 'response_received';
96
+ var SEND_REQUEST = 'send_request';
97
+ var SET_CHAT_ACTIVE = 'set_chat_active';
98
+ var SET_SELF_ID = 'set_self_id';
99
+ var SOCKET_CONNECTED = 'socket_connected';
100
+ var SOCKET_DISCONNECTED = 'socket_disconnected';
101
+ var SOCKET_RECOVERED = 'socket_recovered';
102
+ var SOCKET_UNSTABLE = 'socket_unstable';
103
+ var START_CONNECTION = 'start_connection';
104
+ var UPDATE_CUSTOMER_PAGE = 'update_customer_page';
105
+
106
+ var CONNECTION_LOST = 'CONNECTION_LOST';
107
+ var IDENTITY_MISMATCH = 'IDENTITY_MISMATCH';
108
+ var MISDIRECTED_CONNECTION = 'MISDIRECTED_CONNECTION';
109
+ var MISSING_CHAT_THREAD = 'MISSING_CHAT_THREAD';
110
+ var NO_CONNECTION = 'NO_CONNECTION';
111
+ var REQUEST_TIMEOUT = 'REQUEST_TIMEOUT';
112
+ var SDK_DESTROYED = 'SDK_DESTROYED';
113
+ var SERVICE_TEMPORARILY_UNAVAILABLE = 'SERVICE_TEMPORARILY_UNAVAILABLE';
114
+ var TOO_BIG_FILE = 'TOO_BIG_FILE';
115
+
116
+ var ACCEPT_GREETING = 'accept_greeting';
117
+ var CANCEL_GREETING = 'cancel_greeting';
118
+ var CHECK_GOALS$1 = 'check_goals';
119
+ var DEACTIVATE_CHAT = 'deactivate_chat';
120
+ var DELETE_CHAT_PROPERTIES = 'delete_chat_properties';
121
+ var DELETE_EVENT_PROPERTIES = 'delete_event_properties';
122
+ var DELETE_THREAD_PROPERTIES = 'delete_thread_properties';
123
+ var GET_CHAT = 'get_chat';
124
+ var GET_CUSTOMER = 'get_customer';
125
+ var GET_FORM = 'get_form';
126
+ var GET_PREDICTED_AGENT = 'get_predicted_agent';
127
+ var GET_URL_INFO = 'get_url_info';
128
+ var LIST_CHATS = 'list_chats';
129
+ var LIST_GROUP_STATUSES = 'list_group_statuses';
130
+ var LIST_THREADS = 'list_threads';
131
+ var LOGIN = 'login';
132
+ var MARK_EVENTS_AS_SEEN = 'mark_events_as_seen';
133
+ var RESUME_CHAT = 'resume_chat';
134
+ var SEND_EVENT = 'send_event';
135
+ var SEND_RICH_MESSAGE_POSTBACK = 'send_rich_message_postback';
136
+ var SEND_SNEAK_PEEK = 'send_sneak_peek';
137
+ var SET_CUSTOMER_SESSION_FIELDS = 'set_customer_session_fields';
138
+ var START_CHAT = 'start_chat';
139
+ var UPDATE_CHAT_PROPERTIES = 'update_chat_properties';
140
+ var UPDATE_CUSTOMER = 'update_customer';
141
+ var UPDATE_CUSTOMER_PAGE$1 = 'update_customer_page';
142
+ var UPDATE_EVENT_PROPERTIES = 'update_event_properties';
143
+ var UPDATE_THREAD_PROPERTIES = 'update_thread_properties';
144
+ var UPLOAD_FILE = 'upload_file';
145
+
146
+ var createReducer = function createReducer(initialState, reducersMap) {
147
+ if (process.env.NODE_ENV !== 'development' && reducersMap[undefined]) {
148
+ // eslint-disable-next-line no-console
149
+ console.warn(["Reducer contains an 'undefined' action type.", 'Have you misspelled a constant?'].join('\n'));
150
+ }
151
+
152
+ return function reducer(state, action) {
153
+ if (state === void 0) {
154
+ state = initialState;
155
+ }
156
+
157
+ if (dataUtils.hasOwn(action.type, reducersMap)) {
158
+ return reducersMap[action.type](state, action.payload);
159
+ }
160
+
161
+ return state;
162
+ };
163
+ }; // TODO: this is the same as built-in redux's combineReducers, should be remobed
164
+
165
+ var CONNECTED = 'connected';
166
+ var DESTROYED = 'destroyed';
167
+ var DISCONNECTED = 'disconnected';
168
+ var PAUSED = 'paused';
169
+ var RECONNECTING = 'reconnecting';
170
+
171
+ var AGENT = 'agent';
172
+ var CUSTOMER = 'customer';
173
+
174
+ var getAllRequests = function getAllRequests(state) {
175
+ return state.requests;
176
+ };
177
+ var getConnectionStatus = function getConnectionStatus(state) {
178
+ return state.connection.status;
179
+ };
180
+ var getRequest = function getRequest(state, id) {
181
+ return state.requests[id];
182
+ };
183
+ var getSelfId = function getSelfId(state) {
184
+ return state.users.self.id;
185
+ };
186
+ var isChatActive = function isChatActive(state, chatId) {
187
+ var chat = state.chats[chatId];
188
+ return !!chat && chat.active;
189
+ };
190
+ var isConnected = function isConnected(state) {
191
+ return getConnectionStatus(state) === CONNECTED;
192
+ };
193
+ var isDestroyed = function isDestroyed(state) {
194
+ return getConnectionStatus(state) === DESTROYED;
195
+ };
196
+
197
+ var getEnvPart = function getEnvPart(_ref) {
198
+ var licenseId = _ref.licenseId,
199
+ env = _ref.env;
200
+
201
+ if (licenseId === 1520) {
202
+ return '.staging';
203
+ }
204
+
205
+ if (env === 'production') {
206
+ return '';
207
+ }
208
+
209
+ return "." + env;
210
+ };
211
+
212
+ var getApiOrigin = function getApiOrigin(state) {
213
+ var region = state.region;
214
+ var regionPart = region ? "-" + region : '';
215
+ return "https://api" + regionPart + getEnvPart(state) + ".livechatinc.com";
216
+ };
217
+ var getServerUrl = function getServerUrl(state) {
218
+ return getApiOrigin(state) + "/v3.3/customer";
219
+ };
220
+ var createInitialState = function createInitialState(initialStateData) {
221
+ var _initialStateData$app = initialStateData.application,
222
+ application = _initialStateData$app === void 0 ? {} : _initialStateData$app,
223
+ licenseId = initialStateData.licenseId,
224
+ _initialStateData$gro = initialStateData.groupId,
225
+ groupId = _initialStateData$gro === void 0 ? null : _initialStateData$gro,
226
+ env = initialStateData.env,
227
+ _initialStateData$pag = initialStateData.page,
228
+ page = _initialStateData$pag === void 0 ? null : _initialStateData$pag,
229
+ _initialStateData$reg = initialStateData.region,
230
+ region = _initialStateData$reg === void 0 ? null : _initialStateData$reg,
231
+ _initialStateData$ref = initialStateData.referrer,
232
+ referrer = _initialStateData$ref === void 0 ? null : _initialStateData$ref,
233
+ _initialStateData$uni = initialStateData.uniqueGroups,
234
+ uniqueGroups = _initialStateData$uni === void 0 ? false : _initialStateData$uni,
235
+ _initialStateData$mob = initialStateData.mobile,
236
+ mobile = _initialStateData$mob === void 0 ? false : _initialStateData$mob;
237
+ return {
238
+ application: _extends({}, application, {
239
+ name: "customer_sdk",
240
+ version: "3.1.0"
241
+ }),
242
+ licenseId: licenseId,
243
+ env: env,
244
+ groupId: groupId,
245
+ chats: {},
246
+ connection: {
247
+ status: DISCONNECTED
248
+ },
249
+ page: page,
250
+ region: region,
251
+ referrer: referrer,
252
+ requests: {},
253
+ users: {
254
+ self: {
255
+ id: null,
256
+ type: CUSTOMER
257
+ },
258
+ others: {}
259
+ },
260
+ uniqueGroups: uniqueGroups,
261
+ mobile: mobile
262
+ };
263
+ };
264
+
265
+ var removeStoredRequest = function removeStoredRequest(state, _ref2) {
266
+ var id = _ref2.id;
267
+
268
+ var _state$requests = state.requests,
269
+ requests = _objectWithoutPropertiesLoose(_state$requests, [id].map(_toPropertyKey));
270
+
271
+ return _extends({}, state, {
272
+ requests: requests
273
+ });
274
+ };
275
+
276
+ var setConnectionStatus = function setConnectionStatus(status, state) {
277
+ return _extends({}, state, {
278
+ connection: _extends({}, state.connection, {
279
+ status: status
280
+ })
281
+ });
282
+ };
283
+
284
+ var createReducer$1 = (function (state) {
285
+ var _createReducer;
286
+
287
+ return createReducer(state, (_createReducer = {}, _createReducer[CHANGE_REGION] = function (state, _ref3) {
288
+ var region = _ref3.region;
289
+ return _extends({}, state, {
290
+ region: region
291
+ });
292
+ }, _createReducer[DESTROY] = function (state) {
293
+ return setConnectionStatus(DESTROYED, state);
294
+ }, _createReducer[LOGIN_SUCCESS] = function (state) {
295
+ return setConnectionStatus(CONNECTED, state);
296
+ }, _createReducer[PAUSE_CONNECTION] = function (state) {
297
+ return setConnectionStatus(PAUSED, state);
298
+ }, _createReducer[REQUEST_FAILED] = removeStoredRequest, _createReducer[RESPONSE_RECEIVED] = removeStoredRequest, _createReducer[PUSH_RESPONSE_RECEIVED] = removeStoredRequest, _createReducer[SEND_REQUEST] = function (state, _ref4) {
299
+ var _extends2;
300
+
301
+ var promise = _ref4.promise,
302
+ resolve = _ref4.resolve,
303
+ reject = _ref4.reject,
304
+ id = _ref4.id,
305
+ request = _ref4.request;
306
+ return _extends({}, state, {
307
+ requests: _extends({}, state.requests, (_extends2 = {}, _extends2[id] = {
308
+ id: id,
309
+ promise: promise,
310
+ resolve: resolve,
311
+ reject: reject,
312
+ request: request
313
+ }, _extends2))
314
+ });
315
+ }, _createReducer[SET_CHAT_ACTIVE] = function (state, _ref5) {
316
+ var _extends3;
317
+
318
+ var id = _ref5.id,
319
+ active = _ref5.active;
320
+ return _extends({}, state, {
321
+ chats: _extends({}, state.chats, (_extends3 = {}, _extends3[id] = _extends({}, state.chats[id], {
322
+ active: active
323
+ }), _extends3))
324
+ });
325
+ }, _createReducer[SET_SELF_ID] = function (state, payload) {
326
+ return _extends({}, state, {
327
+ users: _extends({}, state.users, {
328
+ self: _extends({}, state.users.self, {
329
+ id: payload.id
330
+ })
331
+ })
332
+ });
333
+ }, _createReducer[SOCKET_DISCONNECTED] = function (state) {
334
+ var previousStatus = getConnectionStatus(state);
335
+
336
+ if (process.env.NODE_ENV !== 'production' && (previousStatus === PAUSED || previousStatus === DESTROYED)) {
337
+ throw new Error("Got 'socket_disconnected' action when in " + previousStatus + " state. This should be an impossible state.");
338
+ }
339
+
340
+ var state1 = setConnectionStatus(previousStatus === DISCONNECTED ? DISCONNECTED : RECONNECTING, state);
341
+ return _extends({}, state1, {
342
+ requests: {}
343
+ });
344
+ }, _createReducer[UPDATE_CUSTOMER_PAGE] = function (state, page) {
345
+ return _extends({}, state, {
346
+ page: _extends({}, state.page, page)
347
+ });
348
+ }, _createReducer));
349
+ });
350
+
351
+ function finalCreateStore(initialStateData) {
352
+ var compose = process.env.NODE_ENV === 'development' && typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
353
+ name: '@livechat/customer-sdk'
354
+ }) : dataUtils.identity;
355
+ var sideEffectsMiddleware = createSideEffectsMiddleware__default['default']();
356
+ var store = redux.createStore(createReducer$1(createInitialState(initialStateData)), compose(redux.applyMiddleware(sideEffectsMiddleware)));
357
+ store.addSideEffectsHandler = sideEffectsMiddleware.add;
358
+ return store;
359
+ }
360
+
361
+ function createError(_ref) {
362
+ var message = _ref.message,
363
+ code = _ref.code;
364
+ var error = new Error(message);
365
+ error.code = code;
366
+ return error;
367
+ }
368
+
369
+ var ACCESS_TOKEN_EXPIRED = 'access_token_expired';
370
+ var CUSTOMER_BANNED = 'customer_banned'; // customer tried reconnecting too many times after they received too_many_connections error
371
+
372
+ var CUSTOMER_TEMPORARILY_BLOCKED = 'customer_temporarily_blocked';
373
+ var LICENSE_EXPIRED = 'license_expired';
374
+ var LICENSE_NOT_FOUND = 'license_not_found';
375
+ var MISDIRECTED_CONNECTION$1 = 'misdirected_connection';
376
+ var PRODUCT_VERSION_CHANGED = 'product_version_changed'; // the limit of connections per user host has been exceeded
377
+ // or rate limit for new connections has been hit
378
+ // (in 3.2 only the latter case, the first one is using `too_many_connections` to avoid breaking changes)
379
+
380
+ var SERVICE_TEMPORARILY_UNAVAILABLE$1 = 'service_temporarily_unavailable'; // the limit of those connections is per user
381
+
382
+ var TOO_MANY_CONNECTIONS = 'too_many_connections'; // the limit of unauthorized connections is per IP
383
+
384
+ var TOO_MANY_UNAUTHORIZED_CONNECTIONS = 'too_many_unauthorized_connections';
385
+ var UNSUPPORTED_VERSION = 'unsupported_version';
386
+
387
+ var CHAT_DEACTIVATED = 'chat_deactivated';
388
+ var CHAT_PROPERTIES_DELETED = 'chat_properties_deleted';
389
+ var CHAT_PROPERTIES_UPDATED = 'chat_properties_updated';
390
+ var CHAT_TRANSFERRED = 'chat_transferred';
391
+ var CUSTOMER_DISCONNECTED = 'customer_disconnected';
392
+ var CUSTOMER_PAGE_UPDATED = 'customer_page_updated';
393
+ var CUSTOMER_SIDE_STORAGE_UPDATED = 'customer_side_storage_updated';
394
+ var CUSTOMER_UPDATED = 'customer_updated';
395
+ var EVENT_PROPERTIES_DELETED = 'event_properties_deleted';
396
+ var EVENT_PROPERTIES_UPDATED = 'event_properties_updated';
397
+ var EVENT_UPDATED = 'event_updated';
398
+ var EVENTS_MARKED_AS_SEEN = 'events_marked_as_seen';
399
+ var GREETING_ACCEPTED = 'greeting_accepted';
400
+ var GREETING_CANCELED = 'greeting_canceled';
401
+ var INCOMING_CHAT = 'incoming_chat';
402
+ var INCOMING_EVENT = 'incoming_event';
403
+ var INCOMING_GREETING = 'incoming_greeting';
404
+ var INCOMING_MULTICAST = 'incoming_multicast';
405
+ var INCOMING_RICH_MESSAGE_POSTBACK = 'incoming_rich_message_postback';
406
+ var INCOMING_TYPING_INDICATOR = 'incoming_typing_indicator';
407
+ var QUEUE_POSITION_UPDATED = 'queue_position_updated';
408
+ var THREAD_PROPERTIES_DELETED = 'thread_properties_deleted';
409
+ var THREAD_PROPERTIES_UPDATED = 'thread_properties_updated';
410
+ var USER_ADDED_TO_CHAT = 'user_added_to_chat';
411
+ var USER_REMOVED_FROM_CHAT = 'user_removed_from_chat';
412
+
413
+ var serverPushActions = /*#__PURE__*/Object.freeze({
414
+ __proto__: null,
415
+ CHAT_DEACTIVATED: CHAT_DEACTIVATED,
416
+ CHAT_PROPERTIES_DELETED: CHAT_PROPERTIES_DELETED,
417
+ CHAT_PROPERTIES_UPDATED: CHAT_PROPERTIES_UPDATED,
418
+ CHAT_TRANSFERRED: CHAT_TRANSFERRED,
419
+ CUSTOMER_DISCONNECTED: CUSTOMER_DISCONNECTED,
420
+ CUSTOMER_PAGE_UPDATED: CUSTOMER_PAGE_UPDATED,
421
+ CUSTOMER_SIDE_STORAGE_UPDATED: CUSTOMER_SIDE_STORAGE_UPDATED,
422
+ CUSTOMER_UPDATED: CUSTOMER_UPDATED,
423
+ EVENT_PROPERTIES_DELETED: EVENT_PROPERTIES_DELETED,
424
+ EVENT_PROPERTIES_UPDATED: EVENT_PROPERTIES_UPDATED,
425
+ EVENT_UPDATED: EVENT_UPDATED,
426
+ EVENTS_MARKED_AS_SEEN: EVENTS_MARKED_AS_SEEN,
427
+ GREETING_ACCEPTED: GREETING_ACCEPTED,
428
+ GREETING_CANCELED: GREETING_CANCELED,
429
+ INCOMING_CHAT: INCOMING_CHAT,
430
+ INCOMING_EVENT: INCOMING_EVENT,
431
+ INCOMING_GREETING: INCOMING_GREETING,
432
+ INCOMING_MULTICAST: INCOMING_MULTICAST,
433
+ INCOMING_RICH_MESSAGE_POSTBACK: INCOMING_RICH_MESSAGE_POSTBACK,
434
+ INCOMING_TYPING_INDICATOR: INCOMING_TYPING_INDICATOR,
435
+ QUEUE_POSITION_UPDATED: QUEUE_POSITION_UPDATED,
436
+ THREAD_PROPERTIES_DELETED: THREAD_PROPERTIES_DELETED,
437
+ THREAD_PROPERTIES_UPDATED: THREAD_PROPERTIES_UPDATED,
438
+ USER_ADDED_TO_CHAT: USER_ADDED_TO_CHAT,
439
+ USER_REMOVED_FROM_CHAT: USER_REMOVED_FROM_CHAT
440
+ });
441
+
442
+ var FILE = 'file';
443
+ var FORM = 'form';
444
+ var FILLED_FORM = 'filled_form';
445
+ var MESSAGE = 'message';
446
+ var RICH_MESSAGE = 'rich_message';
447
+ var SYSTEM_MESSAGE = 'system_message';
448
+ var CUSTOM = 'custom';
449
+
450
+ var createEventBase = function createEventBase(event) {
451
+ var base = {};
452
+
453
+ if (typeof event.customId === 'string') {
454
+ base.custom_id = event.customId;
455
+ }
456
+
457
+ if (dataUtils.isObject(event.properties)) {
458
+ base.properties = event.properties;
459
+ }
460
+
461
+ return base;
462
+ }; // TODO: we could validate and throw here
463
+ // but should we? maybe only in DEV mode?
464
+
465
+
466
+ var parseEvent = function parseEvent(event) {
467
+ switch (event.type) {
468
+ case MESSAGE:
469
+ {
470
+ var message = _extends({}, createEventBase(event), {
471
+ type: event.type,
472
+ text: event.text
473
+ });
474
+
475
+ if (event.postback) {
476
+ message.postback = {
477
+ id: event.postback.id,
478
+ thread_id: event.postback.threadId,
479
+ event_id: event.postback.eventId,
480
+ type: event.postback.type,
481
+ value: event.postback.value
482
+ };
483
+ }
484
+
485
+ return message;
486
+ }
487
+
488
+ case FILE:
489
+ {
490
+ var file = _extends({}, createEventBase(event), {
491
+ type: event.type,
492
+ url: event.url,
493
+ alternative_text: event.alternativeText
494
+ });
495
+
496
+ return file;
497
+ }
498
+
499
+ case FILLED_FORM:
500
+ {
501
+ var filledForm = _extends({}, createEventBase(event), {
502
+ type: event.type,
503
+ form_id: event.formId,
504
+ fields: event.fields.map(function (field) {
505
+ switch (field.type) {
506
+ case 'group_chooser':
507
+ {
508
+ if (!field.answer) {
509
+ return field;
510
+ }
511
+
512
+ var _field$answer = field.answer,
513
+ groupId = _field$answer.groupId,
514
+ answer = _objectWithoutPropertiesLoose(_field$answer, ["groupId"]);
515
+
516
+ return _extends({}, field, {
517
+ answer: _extends({}, answer, {
518
+ group_id: groupId
519
+ })
520
+ });
521
+ }
522
+
523
+ default:
524
+ return field;
525
+ }
526
+ })
527
+ });
528
+
529
+ return filledForm;
530
+ }
531
+
532
+ case SYSTEM_MESSAGE:
533
+ {
534
+ var systemMessage = _extends({}, createEventBase(event), {
535
+ type: event.type,
536
+ text: event.text,
537
+ system_message_type: event.systemMessageType
538
+ });
539
+
540
+ if (event.recipients) {
541
+ systemMessage.recipients = event.recipients;
542
+ }
543
+
544
+ return systemMessage;
545
+ }
546
+
547
+ case CUSTOM:
548
+ {
549
+ var customEvent = _extends({}, createEventBase(event), {
550
+ type: event.type
551
+ });
552
+
553
+ if (event.content) {
554
+ customEvent.content = event.content;
555
+ }
556
+
557
+ return customEvent;
558
+ }
559
+ }
560
+ };
561
+
562
+ var parseThreadData = function parseThreadData(thread) {
563
+ var data = {};
564
+ var events = thread.events,
565
+ properties = thread.properties;
566
+
567
+ if (events) {
568
+ data.events = events.map(parseEvent);
569
+ }
570
+
571
+ if (properties) {
572
+ data.properties = properties;
573
+ }
574
+
575
+ return data;
576
+ };
577
+
578
+ var parseStartChatData = function parseStartChatData(_ref) {
579
+ var _ref$active = _ref.active,
580
+ active = _ref$active === void 0 ? true : _ref$active,
581
+ chat = _ref.chat,
582
+ continuous = _ref.continuous;
583
+ var data = {
584
+ active: active,
585
+ chat: {}
586
+ };
587
+
588
+ if (typeof continuous === 'boolean') {
589
+ data.continuous = continuous;
590
+ }
591
+
592
+ if (!chat) {
593
+ return data;
594
+ }
595
+
596
+ var access = chat.access,
597
+ thread = chat.thread,
598
+ properties = chat.properties;
599
+
600
+ if (access && access.groupIds) {
601
+ data.chat.access = {
602
+ group_ids: access.groupIds
603
+ };
604
+ }
605
+
606
+ if (properties) {
607
+ data.chat.properties = properties;
608
+ }
609
+
610
+ if (thread) {
611
+ data.chat.thread = parseThreadData(thread);
612
+ }
613
+
614
+ return data;
615
+ };
616
+ var parseResumeChatData = function parseResumeChatData(requestData) {
617
+ var data = parseStartChatData(requestData);
618
+ return _extends({}, data, {
619
+ chat: _extends({}, data.chat, {
620
+ id: requestData.chat.id
621
+ })
622
+ });
623
+ };
624
+ var parseCustomerSessionFields = function parseCustomerSessionFields(sessionFields) {
625
+ return dataUtils.toPairs(sessionFields).map(function (_ref2) {
626
+ var _ref3;
627
+
628
+ var key = _ref2[0],
629
+ value = _ref2[1];
630
+ return _ref3 = {}, _ref3[key] = value, _ref3;
631
+ });
632
+ };
633
+ var parseCustomerUpdate = function parseCustomerUpdate(update) {
634
+ var result = dataUtils.pickOwn(['avatar', 'name', 'email'], update);
635
+
636
+ if (update.sessionFields) {
637
+ result.session_fields = parseCustomerSessionFields(update.sessionFields);
638
+ }
639
+
640
+ return result;
641
+ };
642
+
643
+ var destroy = function destroy(reason) {
644
+ return {
645
+ type: DESTROY,
646
+ payload: {
647
+ reason: reason
648
+ }
649
+ };
650
+ };
651
+ var loginSuccess = function loginSuccess(payload) {
652
+ return {
653
+ type: LOGIN_SUCCESS,
654
+ payload: payload
655
+ };
656
+ };
657
+ var pauseConnection = function pauseConnection(reason) {
658
+ return {
659
+ type: PAUSE_CONNECTION,
660
+ payload: {
661
+ reason: reason
662
+ }
663
+ };
664
+ };
665
+ var prefetchToken = function prefetchToken(fresh) {
666
+ if (fresh === void 0) {
667
+ fresh = false;
668
+ }
669
+
670
+ return {
671
+ type: PREFETCH_TOKEN,
672
+ payload: {
673
+ fresh: fresh
674
+ }
675
+ };
676
+ };
677
+ var reconnect = function reconnect(delay) {
678
+ return {
679
+ type: RECONNECT,
680
+ payload: {
681
+ delay: delay
682
+ }
683
+ };
684
+ }; // TODO: this one was currently pretty hard to type in full
685
+ // we should explore providing stricter types for this in the future
686
+
687
+ var sendRequest = function sendRequest(action, payload, source) {
688
+ return {
689
+ type: SEND_REQUEST,
690
+ payload: _extends({
691
+ request: {
692
+ action: action,
693
+ payload: payload
694
+ }
695
+ }, source && {
696
+ source: source
697
+ })
698
+ };
699
+ };
700
+ var sendEvent = function sendEvent(_ref) {
701
+ var chatId = _ref.chatId,
702
+ event = _ref.event,
703
+ attachToLastThread = _ref.attachToLastThread;
704
+ var payload = {
705
+ chat_id: chatId,
706
+ event: parseEvent(event)
707
+ };
708
+
709
+ if (attachToLastThread) {
710
+ payload.attach_to_last_thread = true;
711
+ }
712
+
713
+ return sendRequest(SEND_EVENT, payload);
714
+ };
715
+ var setChatActive = function setChatActive(id, active) {
716
+ return {
717
+ type: SET_CHAT_ACTIVE,
718
+ payload: {
719
+ id: id,
720
+ active: active
721
+ }
722
+ };
723
+ };
724
+ var setSelfId = function setSelfId(id) {
725
+ return {
726
+ type: SET_SELF_ID,
727
+ payload: {
728
+ id: id
729
+ }
730
+ };
731
+ };
732
+ var socketDisconnected = function socketDisconnected() {
733
+ return {
734
+ type: SOCKET_DISCONNECTED
735
+ };
736
+ };
737
+
738
+ // TODO: this thing is not really well typed and should be improved
739
+ var sendRequestAction = function sendRequestAction(store, action) {
740
+ action.payload.id = dataUtils.generateUniqueId(store.getState().requests);
741
+
742
+ var _deferred = deferred__default['default'](),
743
+ resolve = _deferred.resolve,
744
+ reject = _deferred.reject,
745
+ promise = _deferred.promise;
746
+
747
+ action.payload.promise = promise;
748
+ action.payload.resolve = resolve;
749
+ action.payload.reject = reject;
750
+ store.dispatch(action);
751
+ return promise;
752
+ };
753
+
754
+ var AUTHENTICATION = 'AUTHENTICATION';
755
+ var CUSTOMER_BANNED$1 = 'CUSTOMER_BANNED';
756
+ var USERS_LIMIT_REACHED = 'USERS_LIMIT_REACHED';
757
+ var WRONG_PRODUCT_VERSION = 'WRONG_PRODUCT_VERSION';
758
+
759
+ var getSideStorageKey = function getSideStorageKey(store) {
760
+ var _store$getState = store.getState(),
761
+ licenseId = _store$getState.licenseId,
762
+ groupId = _store$getState.groupId,
763
+ uniqueGroups = _store$getState.uniqueGroups;
764
+
765
+ return "side_storage_" + licenseId + (uniqueGroups ? ":" + groupId : '');
766
+ };
767
+
768
+ var getSideStorage = function getSideStorage(store) {
769
+ return storage__default['default'].getItem(getSideStorageKey(store))["catch"](dataUtils.noop).then(function (sideStorage) {
770
+ return JSON.parse(sideStorage || '{}');
771
+ }) // shouldnt get triggered, just a defensive measure against malformed storage entries
772
+ ["catch"](function () {
773
+ return {};
774
+ });
775
+ };
776
+ var saveSideStorage = function saveSideStorage(store, sideStorage) {
777
+ return storage__default['default'].setItem(getSideStorageKey(store), JSON.stringify(sideStorage))["catch"](dataUtils.noop);
778
+ };
779
+
780
+ var taskChain = function taskChain(_ref, onSuccess, onError) {
781
+ var steps = _ref.slice(0);
782
+
783
+ var cancelled = false;
784
+
785
+ var next = function next(intermediateResult) {
786
+ var step = steps.shift();
787
+ promiseTry__default['default'](function () {
788
+ return step(intermediateResult);
789
+ }).then(function (result) {
790
+ if (cancelled) {
791
+ return;
792
+ }
793
+
794
+ if (steps.length) {
795
+ next(result);
796
+ return;
797
+ }
798
+
799
+ onSuccess(result);
800
+ }, function (error) {
801
+ if (cancelled) {
802
+ return;
803
+ }
804
+
805
+ onError(error);
806
+ });
807
+ };
808
+
809
+ next();
810
+ return {
811
+ cancel: function cancel() {
812
+ cancelled = true;
813
+ }
814
+ };
815
+ };
816
+
817
+ var sendLoginFlowRequest = function sendLoginFlowRequest(store, type, payload) {
818
+ return sendRequestAction(store, sendRequest(type, payload, 'login'));
819
+ };
820
+
821
+ var delay = function delay(ms) {
822
+ return new Promise(function (resolve) {
823
+ setTimeout(resolve, ms);
824
+ });
825
+ };
826
+
827
+ function createLoginTask(auth, customerDataProvider) {
828
+ var store;
829
+ var sentPage = null;
830
+ var task;
831
+ var backoffConfig = {
832
+ min: 300,
833
+ max: 60000,
834
+ jitter: 0.3
835
+ };
836
+ var defaultBackoffStrategy = createBackoff__default['default'](backoffConfig);
837
+ var slowerBackoffStrategy = createBackoff__default['default'](_extends({}, backoffConfig, {
838
+ min: 1000
839
+ }));
840
+ var currentBackoffStrategy = defaultBackoffStrategy;
841
+
842
+ var destroy$1 = function destroy$1(reason) {
843
+ return store.dispatch(destroy(reason));
844
+ };
845
+
846
+ var reconnect$1 = function reconnect$1() {
847
+ return store.dispatch(reconnect(currentBackoffStrategy.duration()));
848
+ };
849
+
850
+ var getTokenAndSideStorage = function getTokenAndSideStorage() {
851
+ return Promise.all([auth.getToken(), getSideStorage(store)]);
852
+ };
853
+
854
+ var dispatchSelfId = function dispatchSelfId(_ref2) {
855
+ var token = _ref2[0],
856
+ sideStorage = _ref2[1];
857
+ var selfId = getSelfId(store.getState());
858
+
859
+ if (selfId === null) {
860
+ store.dispatch(setSelfId(token.entityId));
861
+ } else if (selfId !== token.entityId) {
862
+ var err = new Error('Identity has changed.');
863
+ err.code = IDENTITY_MISMATCH;
864
+ throw err;
865
+ }
866
+
867
+ return [token, sideStorage];
868
+ };
869
+
870
+ var _sendLogin = function sendLogin(_ref3) {
871
+ var token = _ref3[0],
872
+ sideStorage = _ref3[1];
873
+ var state = store.getState();
874
+ var application = state.application,
875
+ groupId = state.groupId,
876
+ page = state.page,
877
+ referrer = state.referrer,
878
+ mobile = state.mobile;
879
+ var payload = {
880
+ token: token.tokenType + " " + token.accessToken,
881
+ customer: typeof customerDataProvider === 'function' ? parseCustomerUpdate(customerDataProvider()) : {},
882
+ customer_side_storage: sideStorage,
883
+ is_mobile: mobile,
884
+ application: dataUtils.pick(['name', 'version'], application)
885
+ };
886
+
887
+ if (typeof groupId === 'number') {
888
+ payload.group_id = groupId;
889
+ }
890
+
891
+ if (application.channelType) {
892
+ payload.application.channel_type = application.channelType;
893
+ }
894
+
895
+ if (page !== null) {
896
+ sentPage = page;
897
+ payload.customer_page = page;
898
+ }
899
+
900
+ if (referrer !== null) {
901
+ payload.referrer = referrer;
902
+ }
903
+
904
+ return Promise.race([sendLoginFlowRequest(store, LOGIN, payload), delay(15 * 1000).then(function () {
905
+ return Promise.reject(createError({
906
+ message: 'Request timed out.',
907
+ code: REQUEST_TIMEOUT
908
+ }));
909
+ })]);
910
+ };
911
+
912
+ var updateCustomerPageIfNeeded = function updateCustomerPageIfNeeded() {
913
+ var _store$getState = store.getState(),
914
+ page = _store$getState.page;
915
+
916
+ if (sentPage !== page) {
917
+ sendLoginFlowRequest(store, UPDATE_CUSTOMER_PAGE$1, page)["catch"](dataUtils.noop);
918
+ }
919
+
920
+ sentPage = null;
921
+ };
922
+
923
+ return {
924
+ sendLogin: function sendLogin(_store) {
925
+ var _task;
926
+
927
+ // after switching to callbags, we should be able to use smth similar to redux-observable
928
+ // and thus just use store given to epic
929
+ store = _store;
930
+ (_task = task) == null ? void 0 : _task.cancel();
931
+ task = taskChain([getTokenAndSideStorage, dispatchSelfId, _sendLogin], function (loginResponse) {
932
+ task = null;
933
+ defaultBackoffStrategy.reset();
934
+ slowerBackoffStrategy.reset();
935
+ currentBackoffStrategy = defaultBackoffStrategy; // TODO: rethink if this should be handled by SDK consumer
936
+
937
+ updateCustomerPageIfNeeded();
938
+ store.dispatch(loginSuccess(loginResponse));
939
+ }, function (error) {
940
+ task = null;
941
+
942
+ if (process.env.NODE_ENV !== 'production') {
943
+ console.error('[Customer SDK] Login flow has thrown code', error.code, 'with', error);
944
+ }
945
+
946
+ switch (error.code) {
947
+ case AUTHENTICATION:
948
+ auth.getFreshToken();
949
+ reconnect$1();
950
+ return;
951
+
952
+ case CONNECTION_LOST:
953
+ // this is connectivity problem, not a server error
954
+ // and is taken care of in socket module
955
+ // as it has its own backoff implementation
956
+ return;
957
+
958
+ case MISDIRECTED_CONNECTION:
959
+ // socket gets reinitialized on this anyway, so just ignore it here
960
+ return;
961
+
962
+ case SDK_DESTROYED:
963
+ return;
964
+ // those are auth errors, we should maybe export those constants from the auth package
965
+
966
+ case 'SSO_IDENTITY_EXCEPTION':
967
+ case 'SSO_OAUTH_EXCEPTION':
968
+ if (error.message === 'server_error' || error.message === 'temporarily_unavailable') {
969
+ reconnect$1();
970
+ return;
971
+ }
972
+
973
+ destroy$1(error.message);
974
+ return;
975
+
976
+ case USERS_LIMIT_REACHED:
977
+ store.dispatch(pauseConnection(error.code.toLowerCase()));
978
+ return;
979
+
980
+ case IDENTITY_MISMATCH:
981
+ case CUSTOMER_BANNED$1:
982
+ case WRONG_PRODUCT_VERSION:
983
+ destroy$1(error.code.toLowerCase());
984
+ return;
985
+
986
+ case SERVICE_TEMPORARILY_UNAVAILABLE:
987
+ currentBackoffStrategy = slowerBackoffStrategy;
988
+ reconnect$1();
989
+ return;
990
+
991
+ default:
992
+ reconnect$1();
993
+ return;
994
+ }
995
+ });
996
+ },
997
+ cancel: function cancel() {
998
+ var _task2;
999
+
1000
+ (_task2 = task) == null ? void 0 : _task2.cancel();
1001
+ }
1002
+ };
1003
+ }
1004
+
1005
+ var checkGoals = function checkGoals(store, auth, sessionFields) {
1006
+ return auth.getToken().then(function (token) {
1007
+ var state = store.getState();
1008
+
1009
+ if (getSelfId(state) === null) {
1010
+ store.dispatch(setSelfId(token.entityId));
1011
+ }
1012
+
1013
+ var page = state.page;
1014
+
1015
+ if (!page || !page.url) {
1016
+ return;
1017
+ }
1018
+
1019
+ var query = urlUtils.buildQueryString({
1020
+ license_id: state.licenseId
1021
+ });
1022
+ var payload = {
1023
+ session_fields: parseCustomerSessionFields(sessionFields || {}),
1024
+ group_id: state.groupId || 0,
1025
+ page_url: page.url
1026
+ };
1027
+ return unfetch__default['default'](getServerUrl(state) + "/action/" + CHECK_GOALS$1 + "?" + query, {
1028
+ method: 'POST',
1029
+ headers: {
1030
+ 'Content-Type': 'application/json',
1031
+ Authorization: token.tokenType + " " + token.accessToken
1032
+ },
1033
+ body: JSON.stringify(payload)
1034
+ }).then(function () {
1035
+ // TODO: we should actually normalize response here
1036
+ return undefined;
1037
+ });
1038
+ });
1039
+ };
1040
+
1041
+ var failAllRequests = function failAllRequests(_ref, reason) {
1042
+ var getState = _ref.getState,
1043
+ dispatch = _ref.dispatch;
1044
+ var state = getState();
1045
+ var requests = getAllRequests(state);
1046
+ dispatch({
1047
+ type: FAIL_ALL_REQUESTS,
1048
+ payload: {
1049
+ rejects: Object.keys(requests).map(function (requestId) {
1050
+ return requests[requestId].reject;
1051
+ }),
1052
+ reason: reason
1053
+ }
1054
+ });
1055
+ };
1056
+ var failRequest = function failRequest(_ref2, requestAction, error) {
1057
+ var getState = _ref2.getState,
1058
+ dispatch = _ref2.dispatch;
1059
+ var requestId = requestAction.payload.id;
1060
+ dispatch({
1061
+ type: REQUEST_FAILED,
1062
+ payload: {
1063
+ id: requestId,
1064
+ reject: getState().requests[requestId].reject,
1065
+ error: error
1066
+ }
1067
+ });
1068
+ };
1069
+
1070
+ var SUCCESS = Object.freeze({
1071
+ success: true
1072
+ });
1073
+
1074
+ var parseCommonEventProps = function parseCommonEventProps(threadId, event) {
1075
+ var parsed = {
1076
+ id: event.id,
1077
+ authorId: event.author_id,
1078
+ createdAt: event.created_at,
1079
+ threadId: threadId,
1080
+ properties: event.properties || {}
1081
+ };
1082
+
1083
+ if (event.custom_id !== undefined) {
1084
+ parsed.customId = event.custom_id;
1085
+ }
1086
+
1087
+ return parsed;
1088
+ };
1089
+
1090
+ var downsizeWithRatio = function downsizeWithRatio(max, dimensions) {
1091
+ var _ref;
1092
+
1093
+ var biggerProp;
1094
+ var smallerProp;
1095
+ var bigger;
1096
+ var smaller;
1097
+
1098
+ if (dimensions.height > dimensions.width) {
1099
+ biggerProp = 'height';
1100
+ smallerProp = 'width';
1101
+ bigger = dimensions.height;
1102
+ smaller = dimensions.width;
1103
+ } else {
1104
+ biggerProp = 'width';
1105
+ smallerProp = 'height';
1106
+ bigger = dimensions.width;
1107
+ smaller = dimensions.height;
1108
+ }
1109
+
1110
+ var ratio = max / bigger;
1111
+ return _ref = {}, _ref[biggerProp] = Math.ceil(Math.min(bigger, max)), _ref[smallerProp] = Math.ceil(Math.min(ratio * smaller, smaller)), _ref;
1112
+ };
1113
+
1114
+ var parseImage = function parseImage(thread, image) {
1115
+ return _extends({}, parseCommonEventProps(thread, image), {
1116
+ type: FILE,
1117
+ contentType: image.content_type,
1118
+ url: image.url,
1119
+ name: image.name,
1120
+ width: image.width,
1121
+ height: image.height,
1122
+ thumbnails: {
1123
+ "default": _extends({
1124
+ url: image.thumbnail_url
1125
+ }, downsizeWithRatio(300, image)),
1126
+ high: _extends({
1127
+ url: image.thumbnail2x_url
1128
+ }, downsizeWithRatio(600, image))
1129
+ }
1130
+ }, image.alternative_text && {
1131
+ alternativeText: image.alternative_text
1132
+ });
1133
+ };
1134
+
1135
+ var parseFile = function parseFile(thread, file) {
1136
+ if (file.width !== undefined && file.height !== undefined) {
1137
+ return parseImage(thread, file);
1138
+ }
1139
+
1140
+ return _extends({}, parseCommonEventProps(thread, file), {
1141
+ type: FILE,
1142
+ contentType: file.content_type,
1143
+ url: file.url,
1144
+ name: file.name
1145
+ });
1146
+ };
1147
+ var parseForm = function parseForm(thread, form) {
1148
+ return _extends({}, parseCommonEventProps(thread, form), {
1149
+ authorId: 'system',
1150
+ type: FORM,
1151
+ formId: form.form_id,
1152
+ fields: form.fields
1153
+ });
1154
+ };
1155
+ var parseFilledForm = function parseFilledForm(thread, filledForm) {
1156
+ return _extends({}, parseCommonEventProps(thread, filledForm), {
1157
+ type: FILLED_FORM,
1158
+ formId: filledForm.form_id,
1159
+ fields: filledForm.fields.map(function (field) {
1160
+ switch (field.type) {
1161
+ case 'group_chooser':
1162
+ {
1163
+ if (!field.answer) {
1164
+ return field;
1165
+ }
1166
+
1167
+ var _field$answer = field.answer,
1168
+ groupId = _field$answer.group_id,
1169
+ answer = _objectWithoutPropertiesLoose(_field$answer, ["group_id"]);
1170
+
1171
+ return _extends({}, field, {
1172
+ answer: _extends({}, answer, {
1173
+ groupId: groupId
1174
+ })
1175
+ });
1176
+ }
1177
+
1178
+ default:
1179
+ return field;
1180
+ }
1181
+ })
1182
+ });
1183
+ };
1184
+ var parseMessage = function parseMessage(thread, message) {
1185
+ return _extends({}, parseCommonEventProps(thread, message), {
1186
+ type: MESSAGE,
1187
+ text: message.text
1188
+ });
1189
+ };
1190
+ var parseCustomEvent = function parseCustomEvent(thread, event) {
1191
+ return _extends({}, parseCommonEventProps(thread, event), {
1192
+ type: CUSTOM
1193
+ }, event.content && {
1194
+ content: event.content
1195
+ });
1196
+ };
1197
+
1198
+ var parseRichMessageElement = function parseRichMessageElement(element) {
1199
+ var parsed = {};
1200
+
1201
+ if (typeof element.title === 'string') {
1202
+ parsed.title = element.title;
1203
+ }
1204
+
1205
+ if (typeof element.subtitle === 'string') {
1206
+ parsed.subtitle = element.subtitle;
1207
+ }
1208
+
1209
+ if (element.image) {
1210
+ // TODO: we should reuse parseImage here
1211
+ var image = element.image;
1212
+ parsed.image = _extends({
1213
+ url: image.url,
1214
+ name: image.name
1215
+ }, image.alternative_text && {
1216
+ alternativeText: image.alternative_text
1217
+ });
1218
+ }
1219
+
1220
+ if (element.buttons) {
1221
+ parsed.buttons = element.buttons.map(function (serverButton) {
1222
+ switch (serverButton.type) {
1223
+ case 'message':
1224
+ case 'phone':
1225
+ {
1226
+ return {
1227
+ type: serverButton.type,
1228
+ text: serverButton.text,
1229
+ postbackId: serverButton.postback_id,
1230
+ userIds: serverButton.user_ids,
1231
+ value: serverButton.value,
1232
+ role: serverButton.role || 'default'
1233
+ };
1234
+ }
1235
+
1236
+ case 'cancel':
1237
+ {
1238
+ return {
1239
+ type: serverButton.type,
1240
+ text: serverButton.text,
1241
+ postbackId: serverButton.postback_id,
1242
+ userIds: serverButton.user_ids,
1243
+ role: serverButton.role || 'default'
1244
+ };
1245
+ }
1246
+
1247
+ case 'url':
1248
+ {
1249
+ var button = {
1250
+ type: serverButton.type,
1251
+ text: serverButton.text,
1252
+ postbackId: serverButton.postback_id,
1253
+ userIds: serverButton.user_ids,
1254
+ value: serverButton.value,
1255
+ role: serverButton.role || 'default'
1256
+ };
1257
+
1258
+ if (serverButton.target) {
1259
+ button.target = serverButton.target;
1260
+ }
1261
+
1262
+ return button;
1263
+ }
1264
+
1265
+ case 'webview':
1266
+ {
1267
+ var _button = {
1268
+ type: serverButton.type,
1269
+ text: serverButton.text,
1270
+ postbackId: serverButton.postback_id,
1271
+ userIds: serverButton.user_ids,
1272
+ value: serverButton.value,
1273
+ role: serverButton.role || 'default'
1274
+ };
1275
+
1276
+ if (typeof serverButton.webview_height === 'string') {
1277
+ _button.webviewHeight = serverButton.webview_height;
1278
+ }
1279
+
1280
+ return _button;
1281
+ }
1282
+
1283
+ default:
1284
+ {
1285
+ return {
1286
+ text: serverButton.text,
1287
+ postbackId: serverButton.postback_id,
1288
+ userIds: serverButton.user_ids,
1289
+ role: serverButton.role || 'default'
1290
+ };
1291
+ }
1292
+ }
1293
+ });
1294
+ }
1295
+
1296
+ return parsed;
1297
+ };
1298
+
1299
+ var parseRichMessage = function parseRichMessage(thread, richMessage) {
1300
+ switch (richMessage.template_id) {
1301
+ case 'cards':
1302
+ case 'quick_replies':
1303
+ case 'sticker':
1304
+ return _extends({}, parseCommonEventProps(thread, richMessage), {
1305
+ type: RICH_MESSAGE,
1306
+ template: richMessage.template_id,
1307
+ elements: richMessage.elements.map(parseRichMessageElement)
1308
+ });
1309
+
1310
+ default:
1311
+ return null;
1312
+ }
1313
+ };
1314
+ var parseSystemMessage = function parseSystemMessage(thread, systemMessage) {
1315
+ var parsed = _extends({}, parseCommonEventProps(thread, _extends({}, systemMessage, {
1316
+ author_id: 'system'
1317
+ })), {
1318
+ type: SYSTEM_MESSAGE,
1319
+ text: systemMessage.text,
1320
+ systemMessageType: systemMessage.system_message_type
1321
+ });
1322
+
1323
+ if (systemMessage.text_vars) {
1324
+ parsed.textVars = systemMessage.text_vars;
1325
+ }
1326
+
1327
+ return parsed;
1328
+ };
1329
+ var parseEvent$1 = function parseEvent(thread, event) {
1330
+ switch (event.type) {
1331
+ case FILE:
1332
+ return parseFile(thread, event);
1333
+
1334
+ case FORM:
1335
+ return parseForm(thread, event);
1336
+
1337
+ case FILLED_FORM:
1338
+ return parseFilledForm(thread, event);
1339
+
1340
+ case MESSAGE:
1341
+ return parseMessage(thread, event);
1342
+
1343
+ case RICH_MESSAGE:
1344
+ return parseRichMessage(thread, event);
1345
+
1346
+ case SYSTEM_MESSAGE:
1347
+ return parseSystemMessage(thread, event);
1348
+
1349
+ case CUSTOM:
1350
+ return parseCustomEvent(thread, event);
1351
+
1352
+ default:
1353
+ return null;
1354
+ }
1355
+ };
1356
+ var parseGreeting = function parseGreeting(greeting) {
1357
+ return {
1358
+ id: greeting.id,
1359
+ addon: greeting.addon || null,
1360
+ uniqueId: greeting.unique_id,
1361
+ displayedFirstTime: greeting.displayed_first_time,
1362
+ accepted: greeting.accepted || false,
1363
+ subtype: greeting.subtype || 'greeting',
1364
+ // threadId is typed as nonoptional string but for greetings it doesn't exist
1365
+ event: parseEvent$1(null, greeting.event),
1366
+ agent: {
1367
+ id: greeting.agent.id,
1368
+ name: greeting.agent.name,
1369
+ avatar: greeting.agent.avatar,
1370
+ jobTitle: greeting.agent.job_title,
1371
+ isBot: greeting.agent.is_bot || false
1372
+ }
1373
+ };
1374
+ };
1375
+
1376
+ // so it's better to rely on a custom implementation
1377
+
1378
+ var parseCustomerSessionFields$1 = function parseCustomerSessionFields(sessionFields) {
1379
+ return sessionFields.reduce(function (acc, field) {
1380
+ var _Object$keys = Object.keys(field),
1381
+ key = _Object$keys[0];
1382
+
1383
+ acc[key] = field[key];
1384
+ return acc;
1385
+ }, {});
1386
+ };
1387
+
1388
+ var parseAccess = function parseAccess(access) {
1389
+ if (access === void 0) {
1390
+ access = {};
1391
+ }
1392
+
1393
+ return access.group_ids ? {
1394
+ groupIds: access.group_ids
1395
+ } : {};
1396
+ };
1397
+ var getEventsSeenUpToMap = function getEventsSeenUpToMap(users) {
1398
+ return dataUtils.mapValues(function (user) {
1399
+ return user.events_seen_up_to ? user.events_seen_up_to : null;
1400
+ }, dataUtils.keyBy('id', users));
1401
+ };
1402
+ var parseThread = function parseThread(chatId, thread) {
1403
+ var properties = thread.properties || {};
1404
+ return {
1405
+ id: thread.id,
1406
+ chatId: chatId,
1407
+ active: thread.active,
1408
+ access: parseAccess(thread.access),
1409
+ createdAt: thread.created_at,
1410
+ userIds: thread.user_ids,
1411
+ events: thread.events.map(function (event) {
1412
+ return parseEvent$1(thread.id, event);
1413
+ }).filter(Boolean),
1414
+ properties: properties,
1415
+ previousThreadId: thread.previous_thread_id || null,
1416
+ nextThreadId: thread.next_thread_id || null,
1417
+ queue: thread.queue ? parseQueue(thread.queue) : null
1418
+ };
1419
+ };
1420
+ var parseChatCommon = function parseChatCommon(chat) {
1421
+ return {
1422
+ id: chat.id,
1423
+ access: parseAccess(chat.access),
1424
+ users: chat.users.map(parseChatUser),
1425
+ properties: chat.properties || {},
1426
+ eventsSeenUpToMap: getEventsSeenUpToMap(chat.users)
1427
+ };
1428
+ };
1429
+ var parseChatAgent = function parseChatAgent(agent) {
1430
+ return {
1431
+ id: agent.id,
1432
+ // keep literal here, so every non-customer gets treated as agent
1433
+ // currently there are only 2 types of users - customer & agent (bots have type: "agent")
1434
+ // so this is purely defensive measure, trying to stay future-proof
1435
+ type: AGENT,
1436
+ name: agent.name,
1437
+ avatar: agent.avatar,
1438
+ jobTitle: agent.job_title,
1439
+ present: agent.present
1440
+ };
1441
+ };
1442
+ var parseCustomerOptionalProps = function parseCustomerOptionalProps(customerProps) {
1443
+ var optionalProps = dataUtils.pickOwn(['avatar', 'email', 'name'], customerProps);
1444
+
1445
+ if (customerProps.session_fields) {
1446
+ optionalProps.sessionFields = parseCustomerSessionFields$1(customerProps.session_fields);
1447
+ }
1448
+
1449
+ return optionalProps;
1450
+ };
1451
+
1452
+ var parseCustomerCommonProps = function parseCustomerCommonProps(customer) {
1453
+ var optionalProps = parseCustomerOptionalProps(customer);
1454
+ return _extends({
1455
+ id: customer.id,
1456
+ type: CUSTOMER
1457
+ }, optionalProps, {
1458
+ sessionFields: optionalProps.sessionFields || {}
1459
+ });
1460
+ };
1461
+
1462
+ var parseChatCustomer = function parseChatCustomer(customer) {
1463
+ return _extends({}, parseCustomerCommonProps(customer), {
1464
+ present: customer.present
1465
+ });
1466
+ };
1467
+ var parseCustomer = function parseCustomer(customer) {
1468
+ var statistics = customer.statistics;
1469
+ return _extends({}, parseCustomerCommonProps(customer), {
1470
+ statistics: {
1471
+ chatsCount: statistics.chats_count,
1472
+ threadsCount: statistics.threads_count,
1473
+ visitsCount: statistics.visits_count,
1474
+ pageViewsCount: statistics.page_views_count,
1475
+ greetingsShownCount: statistics.greetings_shown_count,
1476
+ greetingsAcceptedCount: statistics.greetings_accepted_count
1477
+ }
1478
+ });
1479
+ };
1480
+ var parsePredictedAgent = function parsePredictedAgent(payload) {
1481
+ var agent = payload.agent,
1482
+ queue = payload.queue;
1483
+ return {
1484
+ agent: {
1485
+ id: agent.id,
1486
+ type: AGENT,
1487
+ name: agent.name,
1488
+ avatar: agent.avatar,
1489
+ jobTitle: agent.job_title,
1490
+ isBot: agent.is_bot
1491
+ },
1492
+ queue: queue
1493
+ };
1494
+ };
1495
+ var parseQueueUpdate = function parseQueueUpdate(queueUpdate) {
1496
+ return {
1497
+ position: queueUpdate.position,
1498
+ waitTime: queueUpdate.wait_time
1499
+ };
1500
+ };
1501
+ var parseQueue = function parseQueue(queue) {
1502
+ return _extends({}, parseQueueUpdate(queue), {
1503
+ queuedAt: queue.queued_at
1504
+ });
1505
+ };
1506
+ var parseChatUser = function parseChatUser(user) {
1507
+ return user.type === CUSTOMER ? parseChatCustomer(user) : parseChatAgent(user);
1508
+ };
1509
+ var parseGroupStatus = function parseGroupStatus(status) {
1510
+ return status === 'offline' ? 'offline' : 'online';
1511
+ };
1512
+
1513
+ var _FAIL_ALL_REQUESTS_ME;
1514
+
1515
+ var SMALL_RECONNECT_DELAY = 100;
1516
+ var FAIL_ALL_REQUESTS_MESSAGES = (_FAIL_ALL_REQUESTS_ME = {}, _FAIL_ALL_REQUESTS_ME[CONNECTION_LOST] = 'Connection lost.', _FAIL_ALL_REQUESTS_ME[MISDIRECTED_CONNECTION] = 'Connected to wrong region.', _FAIL_ALL_REQUESTS_ME);
1517
+
1518
+ var updateStateIfNeeded = function updateStateIfNeeded(store, action) {
1519
+ var state = store.getState();
1520
+
1521
+ switch (action.type) {
1522
+ case PUSH_RESPONSE_RECEIVED:
1523
+ case PUSH_RECEIVED:
1524
+ switch (action.payload.action) {
1525
+ case CHAT_DEACTIVATED:
1526
+ store.dispatch(setChatActive(action.payload.payload.chatId, false));
1527
+ return;
1528
+
1529
+ case INCOMING_CHAT:
1530
+ store.dispatch(setChatActive(action.payload.payload.chat.id, true));
1531
+ return;
1532
+
1533
+ default:
1534
+ return;
1535
+ }
1536
+
1537
+ case RESPONSE_RECEIVED:
1538
+ switch (action.payload.action) {
1539
+ case LIST_CHATS:
1540
+ action.payload.payload.chatsSummary.filter(function (_ref) {
1541
+ var id = _ref.id,
1542
+ active = _ref.active;
1543
+ return isChatActive(state, id) !== active;
1544
+ }).forEach(function (_ref2) {
1545
+ var id = _ref2.id,
1546
+ active = _ref2.active;
1547
+ store.dispatch(setChatActive(id, active));
1548
+ });
1549
+ return;
1550
+
1551
+ default:
1552
+ return;
1553
+ }
1554
+
1555
+ }
1556
+ };
1557
+
1558
+ var sendRequest$1 = function sendRequest(socket, _ref3) {
1559
+ var _ref3$payload = _ref3.payload,
1560
+ id = _ref3$payload.id,
1561
+ request = _ref3$payload.request;
1562
+
1563
+ var frame = _extends({
1564
+ request_id: id
1565
+ }, request);
1566
+
1567
+ switch (frame.action) {
1568
+ case LOGIN:
1569
+ {
1570
+ var upgradedPushes = [];
1571
+ socket.emit(_extends({}, frame, {
1572
+ version: '3.3',
1573
+ payload: _extends({}, frame.payload, {
1574
+ pushes: {
1575
+ // '3.4': upgradedPushes,
1576
+ '3.3': dataUtils.values(serverPushActions).filter(function (pushAction) {
1577
+ return (// `customer_disconnected` can be sent immediately after opening the connection, before it even received login request
1578
+ // therefore it's not possible to subscribe for a particular version of this push - the "connection version" is always used
1579
+ pushAction !== CUSTOMER_DISCONNECTED && !dataUtils.includes(pushAction, upgradedPushes)
1580
+ );
1581
+ })
1582
+ }
1583
+ })
1584
+ }));
1585
+ return;
1586
+ }
1587
+
1588
+ default:
1589
+ socket.emit(frame);
1590
+ return;
1591
+ }
1592
+ };
1593
+
1594
+ var emitUsers = function emitUsers(emit, users) {
1595
+ users.forEach(function (user) {
1596
+ if ('present' in user) {
1597
+ var rest = _objectWithoutPropertiesLoose(user, ["present"]);
1598
+
1599
+ emit('user_data', rest);
1600
+ return;
1601
+ }
1602
+
1603
+ if (user.type === CUSTOMER) {
1604
+ var _rest = _objectWithoutPropertiesLoose(user, ["statistics"]);
1605
+
1606
+ emit('user_data', _rest);
1607
+ return;
1608
+ }
1609
+
1610
+ emit('user_data', user);
1611
+ });
1612
+ };
1613
+
1614
+ var handleMulticast = function handleMulticast(emit, _ref4) {
1615
+ var type = _ref4.type,
1616
+ content = _ref4.content;
1617
+
1618
+ if (type !== 'lc2') {
1619
+ return;
1620
+ }
1621
+
1622
+ if (content.name === 'groups_update' && 'groups' in content && !dataUtils.isEmpty(content.groups)) {
1623
+ var _content$groups = content.groups,
1624
+ group = _content$groups[0];
1625
+ var availability = parseGroupStatus(group.status);
1626
+ emit('availability_updated', {
1627
+ availability: availability
1628
+ });
1629
+ }
1630
+ };
1631
+
1632
+ var handlePush = function handlePush(_ref5, _ref6) {
1633
+ var emit = _ref5.emit,
1634
+ store = _ref5.store;
1635
+ var payload = _ref6.payload;
1636
+
1637
+ switch (payload.action) {
1638
+ case THREAD_PROPERTIES_UPDATED:
1639
+ if (payload.payload.properties.lc2 && 'queue_pos' in payload.payload.properties.lc2) {
1640
+ emit(QUEUE_POSITION_UPDATED, {
1641
+ chatId: payload.payload.chatId,
1642
+ threadId: payload.payload.threadId,
1643
+ queue: {
1644
+ position: payload.payload.properties.lc2.queue_pos,
1645
+ waitTime: payload.payload.properties.lc2.queue_waiting_time
1646
+ }
1647
+ });
1648
+ }
1649
+
1650
+ emit('thread_properties_updated', payload.payload);
1651
+ return;
1652
+
1653
+ case CUSTOMER_SIDE_STORAGE_UPDATED:
1654
+ saveSideStorage(store, payload.payload.customer_side_storage);
1655
+ return;
1656
+
1657
+ case CUSTOMER_DISCONNECTED:
1658
+ // each of those should currently lead to either reconnect or destroy call
1659
+ // after receiving this push server closes the connection with us
1660
+ // which results in SOCKET_DISCONNECTED action being dispatched
1661
+ // we don't want to rely on this (nor we want to risk emitting 'disconnected' twice)
1662
+ // so we should handle all cases ourselves and close the connection preemptively
1663
+ switch (payload.payload.reason) {
1664
+ case ACCESS_TOKEN_EXPIRED:
1665
+ // we passthrough access_token_expired here, so pending requests receive CONNECTION_LOST error
1666
+ // we could fail them with ACCESS_TOKEN_EXPIRED, but it could force people to handle it in special manner
1667
+ // but actually they should handle it exactly like CONNECTION_LOST:
1668
+ // a request could succeed, who knows, it has to be checked after being reconnected
1669
+ store.dispatch(prefetchToken(true));
1670
+ store.dispatch(reconnect(SMALL_RECONNECT_DELAY));
1671
+ emit('disconnected', payload.payload);
1672
+ break;
1673
+
1674
+ case CUSTOMER_BANNED:
1675
+ case CUSTOMER_TEMPORARILY_BLOCKED:
1676
+ case LICENSE_NOT_FOUND:
1677
+ case PRODUCT_VERSION_CHANGED:
1678
+ case TOO_MANY_CONNECTIONS:
1679
+ case UNSUPPORTED_VERSION:
1680
+ // this also emits `disconnected` event - but it's handled in response to this action by destroy handler
1681
+ store.dispatch(destroy(payload.payload.reason));
1682
+ break;
1683
+
1684
+ case MISDIRECTED_CONNECTION$1:
1685
+ failAllRequests(store, MISDIRECTED_CONNECTION);
1686
+ store.dispatch({
1687
+ type: CHANGE_REGION,
1688
+ payload: payload.payload.data
1689
+ });
1690
+ break;
1691
+
1692
+ case SERVICE_TEMPORARILY_UNAVAILABLE$1:
1693
+ case TOO_MANY_UNAUTHORIZED_CONNECTIONS:
1694
+ // this should only really fail a `login` request - as it's the only one sent before authorization
1695
+ // and login should reconnect on its own right now
1696
+ failAllRequests(store, payload.payload.reason.toUpperCase());
1697
+ break;
1698
+
1699
+ default:
1700
+ store.dispatch(reconnect(SMALL_RECONNECT_DELAY));
1701
+ emit('disconnected', payload.payload);
1702
+ break;
1703
+ }
1704
+
1705
+ return;
1706
+
1707
+ case INCOMING_CHAT:
1708
+ emitUsers(emit, payload.payload.chat.users);
1709
+ emit(payload.action, payload.payload);
1710
+ return;
1711
+
1712
+ case INCOMING_EVENT:
1713
+ if (payload.payload.event === null) {
1714
+ return;
1715
+ }
1716
+
1717
+ emit(payload.action, payload.payload);
1718
+ return;
1719
+
1720
+ case INCOMING_TYPING_INDICATOR:
1721
+ emit(payload.action, payload.payload);
1722
+ return;
1723
+
1724
+ case INCOMING_MULTICAST:
1725
+ handleMulticast(emit, payload.payload); // we passthrough this action even if it was already handled above
1726
+
1727
+ emit(payload.action, payload.payload);
1728
+ return;
1729
+
1730
+ case USER_ADDED_TO_CHAT:
1731
+ emitUsers(emit, [payload.payload.user]);
1732
+ emit(payload.action, payload.payload);
1733
+ return;
1734
+
1735
+ default:
1736
+ emit(payload.action, payload.payload);
1737
+ return;
1738
+ }
1739
+ };
1740
+
1741
+ var handleResponse = function handleResponse(_ref7, _ref8) {
1742
+ var emit = _ref7.emit;
1743
+ var payload = _ref8.payload;
1744
+
1745
+ switch (payload.action) {
1746
+ case CHAT_DEACTIVATED:
1747
+ payload.resolve(SUCCESS);
1748
+ return;
1749
+
1750
+ case GET_CHAT:
1751
+ emitUsers(emit, payload.payload.users);
1752
+ payload.resolve(payload.payload);
1753
+ return;
1754
+
1755
+ case INCOMING_CHAT:
1756
+ emitUsers(emit, payload.payload.chat.users);
1757
+ payload.resolve(payload.payload);
1758
+ return;
1759
+
1760
+ case INCOMING_EVENT:
1761
+ payload.resolve(payload.payload.event);
1762
+ return;
1763
+
1764
+ case LIST_CHATS:
1765
+ emitUsers(emit, payload.payload.users);
1766
+ payload.resolve(payload.payload);
1767
+ return;
1768
+
1769
+ default:
1770
+ payload.resolve(payload.payload);
1771
+ return;
1772
+ }
1773
+ };
1774
+
1775
+ var createSideEffectsHandler = (function (_ref9) {
1776
+ var auth = _ref9.auth,
1777
+ customerDataProvider = _ref9.customerDataProvider,
1778
+ emitter = _ref9.emitter,
1779
+ socket = _ref9.socket;
1780
+ var emit = emitter.emit;
1781
+ var loginTask = createLoginTask(auth, customerDataProvider); // TODO: using Store type here is a lie, middleware only provides MiddlewareAPI here
1782
+
1783
+ return function (action, store) {
1784
+ switch (action.type) {
1785
+ case CHANGE_REGION:
1786
+ socket.reinitialize();
1787
+ return;
1788
+
1789
+ case CHECK_GOALS:
1790
+ checkGoals(store, auth, action.payload.sessionFields)["catch"](dataUtils.noop);
1791
+ return;
1792
+
1793
+ case DESTROY:
1794
+ {
1795
+ var payload = action.payload;
1796
+ loginTask.cancel();
1797
+ socket.destroy();
1798
+
1799
+ switch (payload.reason) {
1800
+ case 'manual':
1801
+ failAllRequests(store, SDK_DESTROYED);
1802
+ break;
1803
+
1804
+ case CUSTOMER_BANNED:
1805
+ case LICENSE_EXPIRED:
1806
+ case PRODUCT_VERSION_CHANGED:
1807
+ // normalize those to CONNECTION_LOST as the handling on the consumer's side should be the same
1808
+ failAllRequests(store, CONNECTION_LOST);
1809
+ emit('disconnected', payload);
1810
+ break;
1811
+
1812
+ default:
1813
+ // in general those deestroys should only come either from login errors
1814
+ // or from customer_disconnected pushes that are sent immediately after connection
1815
+ // so this case would only be able to fail login requests but that wouldn't even be caught be a handler there
1816
+ // as we cancel the loginTask beforehand
1817
+ emit('disconnected', payload);
1818
+ break;
1819
+ }
1820
+
1821
+ emitter.off();
1822
+ return;
1823
+ }
1824
+
1825
+ case FAIL_ALL_REQUESTS:
1826
+ {
1827
+ var _action$payload = action.payload,
1828
+ reason = _action$payload.reason,
1829
+ rejects = _action$payload.rejects;
1830
+ var error = {
1831
+ message: FAIL_ALL_REQUESTS_MESSAGES[reason],
1832
+ code: reason
1833
+ };
1834
+ rejects.forEach(function (reject) {
1835
+ reject(createError(error));
1836
+ });
1837
+ return;
1838
+ }
1839
+
1840
+ case LOGIN_SUCCESS:
1841
+ {
1842
+ var _action$payload2 = action.payload,
1843
+ dynamicConfig = _action$payload2.dynamicConfig,
1844
+ customer = _action$payload2.customer,
1845
+ chats = _action$payload2.chats,
1846
+ greeting = _action$payload2.greeting,
1847
+ availability = _action$payload2.availability;
1848
+
1849
+ var eventData = _extends({
1850
+ customer: customer,
1851
+ availability: availability
1852
+ }, greeting && {
1853
+ greeting: greeting
1854
+ });
1855
+
1856
+ Object.defineProperty(eventData, '__unsafeDynamicConfig', {
1857
+ value: dynamicConfig
1858
+ });
1859
+ Object.defineProperty(eventData, '__unsafeChats', {
1860
+ value: chats
1861
+ });
1862
+ emit('connected', eventData);
1863
+ return;
1864
+ }
1865
+
1866
+ case PAUSE_CONNECTION:
1867
+ {
1868
+ var _payload = action.payload;
1869
+ socket.disconnect();
1870
+
1871
+ if (_payload.reason !== 'manual') {
1872
+ emit('disconnected', _payload);
1873
+ }
1874
+
1875
+ return;
1876
+ }
1877
+
1878
+ case PREFETCH_TOKEN:
1879
+ if (action.payload.fresh) {
1880
+ auth.getFreshToken()["catch"](dataUtils.noop);
1881
+ return;
1882
+ }
1883
+
1884
+ auth.hasToken().then(function (hasToken) {
1885
+ if (!hasToken) {
1886
+ return auth.getToken();
1887
+ }
1888
+
1889
+ return auth.getToken().then(function (_ref10) {
1890
+ var creationDate = _ref10.creationDate,
1891
+ expiresIn = _ref10.expiresIn;
1892
+ var ONE_HOUR = 60 * 60 * 1000; // check if the token is worth reusing
1893
+ // we don't want to get disconnected in a moment because of expired token
1894
+
1895
+ if (creationDate + expiresIn - Date.now() > ONE_HOUR) {
1896
+ return;
1897
+ }
1898
+
1899
+ return auth.invalidate().then(auth.getFreshToken);
1900
+ });
1901
+ })["catch"](dataUtils.noop);
1902
+ return;
1903
+
1904
+ case PUSH_RECEIVED:
1905
+ // TODO: this if doesn't seem to make much sense
1906
+ // I'm too afraid to remove it right now though
1907
+ if (action.payload.action === CUSTOMER_DISCONNECTED) {
1908
+ handlePush({
1909
+ emit: emit,
1910
+ store: store
1911
+ }, action);
1912
+ return;
1913
+ }
1914
+
1915
+ updateStateIfNeeded(store, action);
1916
+ handlePush({
1917
+ emit: emit,
1918
+ store: store
1919
+ }, action);
1920
+ return;
1921
+
1922
+ case PUSH_RESPONSE_RECEIVED:
1923
+ updateStateIfNeeded(store, action);
1924
+ handleResponse({
1925
+ emit: emit
1926
+ }, action);
1927
+ return;
1928
+
1929
+ case RECONNECT:
1930
+ failAllRequests(store, CONNECTION_LOST);
1931
+ socket.reconnect(action.payload.delay);
1932
+ return;
1933
+
1934
+ case REQUEST_FAILED:
1935
+ {
1936
+ var _action$payload3 = action.payload,
1937
+ reject = _action$payload3.reject,
1938
+ _error = _action$payload3.error;
1939
+ reject(createError(_error));
1940
+ return;
1941
+ }
1942
+
1943
+ case RESPONSE_RECEIVED:
1944
+ updateStateIfNeeded(store, action);
1945
+ handleResponse({
1946
+ emit: emit
1947
+ }, action);
1948
+ return;
1949
+
1950
+ case SEND_REQUEST:
1951
+ {
1952
+ var state = store.getState();
1953
+
1954
+ if (isDestroyed(state)) {
1955
+ failRequest(store, action, {
1956
+ code: SDK_DESTROYED,
1957
+ message: 'SDK destroyed.'
1958
+ });
1959
+ return;
1960
+ }
1961
+
1962
+ if (!isConnected(state) && action.payload.source !== 'login') {
1963
+ failRequest(store, action, {
1964
+ code: NO_CONNECTION,
1965
+ message: 'No connection.'
1966
+ });
1967
+ return;
1968
+ }
1969
+
1970
+ sendRequest$1(socket, action);
1971
+ }
1972
+ return;
1973
+
1974
+ case SET_SELF_ID:
1975
+ emit('customer_id', action.payload.id);
1976
+ return;
1977
+
1978
+ case SOCKET_DISCONNECTED:
1979
+ emit('disconnected', {
1980
+ reason: 'connection_lost'
1981
+ });
1982
+ return;
1983
+
1984
+ case SOCKET_CONNECTED:
1985
+ loginTask.sendLogin(store);
1986
+ return;
1987
+
1988
+ case SOCKET_RECOVERED:
1989
+ // don't emit if from consumer's perspective we haven't been connected
1990
+ if (!isConnected(store.getState())) {
1991
+ return;
1992
+ }
1993
+
1994
+ emit('connection_recovered');
1995
+ return;
1996
+
1997
+ case SOCKET_UNSTABLE:
1998
+ // don't emit if from consumer's perspective we haven't been connected
1999
+ if (!isConnected(store.getState())) {
2000
+ return;
2001
+ }
2002
+
2003
+ emit('connection_unstable');
2004
+ return;
2005
+
2006
+ case START_CONNECTION:
2007
+ socket.connect();
2008
+ store.dispatch(prefetchToken());
2009
+ return;
2010
+
2011
+ case UPDATE_CUSTOMER_PAGE:
2012
+ if (!isConnected(store.getState())) {
2013
+ return;
2014
+ }
2015
+
2016
+ sendRequestAction(store, sendRequest(UPDATE_CUSTOMER_PAGE$1, action.payload))["catch"](dataUtils.noop);
2017
+ return;
2018
+
2019
+ default:
2020
+ return;
2021
+ }
2022
+ };
2023
+ });
2024
+
2025
+ var HISTORY_EVENT_COUNT_TARGET = 25;
2026
+
2027
+ var createState = function createState() {
2028
+ return {
2029
+ status: 'idle',
2030
+ queuedTasks: [],
2031
+ nextPageId: null
2032
+ };
2033
+ };
2034
+
2035
+ var createChatHistoryIterator = function createChatHistoryIterator(sdk, chatId) {
2036
+ var historyState = createState();
2037
+
2038
+ var next = function next(resolve, reject) {
2039
+ switch (historyState.status) {
2040
+ case 'idle':
2041
+ historyState.status = 'fetching';
2042
+ sdk.listThreads(historyState.nextPageId ? {
2043
+ chatId: chatId,
2044
+ pageId: historyState.nextPageId
2045
+ } : {
2046
+ chatId: chatId,
2047
+ minEventsCount: HISTORY_EVENT_COUNT_TARGET
2048
+ }).then(function (_ref) {
2049
+ var threads = _ref.threads,
2050
+ nextPageId = _ref.nextPageId;
2051
+ historyState.nextPageId = nextPageId;
2052
+
2053
+ if (!historyState.nextPageId) {
2054
+ historyState.status = 'done';
2055
+ resolve({
2056
+ value: {
2057
+ threads: [].concat(threads).reverse()
2058
+ },
2059
+ done: true
2060
+ });
2061
+ } else {
2062
+ historyState.status = 'idle';
2063
+ resolve({
2064
+ value: {
2065
+ threads: [].concat(threads).reverse()
2066
+ },
2067
+ done: false
2068
+ });
2069
+ }
2070
+
2071
+ var queuedTask = historyState.queuedTasks.shift();
2072
+
2073
+ if (!queuedTask) {
2074
+ return;
2075
+ }
2076
+
2077
+ next(queuedTask.resolve, queuedTask.reject);
2078
+ }, function (err) {
2079
+ var queuedTasks = historyState.queuedTasks;
2080
+ historyState.status = 'idle';
2081
+ historyState.queuedTasks = [];
2082
+ reject(err);
2083
+ queuedTasks.forEach(function (queuedTask) {
2084
+ return queuedTask.reject(err);
2085
+ });
2086
+ });
2087
+ return;
2088
+
2089
+ case 'fetching':
2090
+ historyState.queuedTasks.push({
2091
+ resolve: resolve,
2092
+ reject: reject
2093
+ });
2094
+ return;
2095
+
2096
+ case 'done':
2097
+ resolve({
2098
+ value: undefined,
2099
+ done: true
2100
+ });
2101
+ return;
2102
+ }
2103
+ };
2104
+
2105
+ return {
2106
+ next: function (_next) {
2107
+ function next() {
2108
+ return _next.apply(this, arguments);
2109
+ }
2110
+
2111
+ next.toString = function () {
2112
+ return _next.toString();
2113
+ };
2114
+
2115
+ return next;
2116
+ }(function () {
2117
+ return new Promise(next);
2118
+ })
2119
+ };
2120
+ };
2121
+
2122
+ var initialize = function initialize(store, emitter) {
2123
+ var state = store.getState();
2124
+ var url = (getServerUrl(state) + "/rtm/ws").replace(/^https/, 'wss');
2125
+ return createPlatformClient__default['default'](url, {
2126
+ query: {
2127
+ license_id: state.licenseId
2128
+ },
2129
+ emitter: emitter
2130
+ });
2131
+ };
2132
+
2133
+ var createSocketClient = function createSocketClient(store) {
2134
+ var emitter = mitt__default['default']();
2135
+ var client = initialize(store, emitter);
2136
+ return _extends({}, Object.keys(client).reduce(function (proxy, method) {
2137
+ proxy[method] = function () {
2138
+ var _client;
2139
+
2140
+ return (_client = client)[method].apply(_client, arguments);
2141
+ };
2142
+
2143
+ return proxy;
2144
+ }, {}), {
2145
+ reinitialize: function reinitialize() {
2146
+ client.disconnect();
2147
+ client = initialize(store, emitter);
2148
+ client.connect();
2149
+ }
2150
+ });
2151
+ };
2152
+
2153
+ var parseChatPropertiesDeletedPush = function parseChatPropertiesDeletedPush(payload) {
2154
+ return {
2155
+ chatId: payload.chat_id,
2156
+ properties: payload.properties
2157
+ };
2158
+ };
2159
+
2160
+ var parseChatPropertiesUpdatedPush = function parseChatPropertiesUpdatedPush(payload) {
2161
+ return {
2162
+ chatId: payload.chat_id,
2163
+ properties: payload.properties
2164
+ };
2165
+ };
2166
+
2167
+ var parseChatTransferredPush = function parseChatTransferredPush(payload) {
2168
+ var basePayload = {
2169
+ chatId: payload.chat_id,
2170
+ threadId: payload.thread_id,
2171
+ transferredTo: _extends({}, payload.transferred_to.agent_ids && {
2172
+ agentIds: payload.transferred_to.agent_ids
2173
+ }, payload.transferred_to.group_ids && {
2174
+ groupIds: payload.transferred_to.group_ids
2175
+ }),
2176
+ queue: payload.queue ? parseQueue(payload.queue) : null
2177
+ };
2178
+
2179
+ if (payload.reason === 'manual') {
2180
+ return _extends({}, basePayload, {
2181
+ reason: payload.reason,
2182
+ requesterId: payload.requester_id
2183
+ });
2184
+ }
2185
+
2186
+ return _extends({}, basePayload, {
2187
+ reason: payload.reason
2188
+ });
2189
+ };
2190
+
2191
+ var parseCustomerPageUpdatedPush = function parseCustomerPageUpdatedPush(payload) {
2192
+ return {
2193
+ url: payload.url,
2194
+ title: payload.title,
2195
+ openedAt: payload.opened_at
2196
+ };
2197
+ };
2198
+
2199
+ var parseCustomerUpdatedPush = function parseCustomerUpdatedPush(payload) {
2200
+ return _extends({
2201
+ id: payload.id
2202
+ }, parseCustomerOptionalProps(payload));
2203
+ };
2204
+
2205
+ var parseEventPropertiesDeletedPush = function parseEventPropertiesDeletedPush(payload) {
2206
+ return {
2207
+ chatId: payload.chat_id,
2208
+ threadId: payload.thread_id,
2209
+ eventId: payload.event_id,
2210
+ properties: payload.properties
2211
+ };
2212
+ };
2213
+
2214
+ var parseEventPropertiesUpdatedPush = function parseEventPropertiesUpdatedPush(payload) {
2215
+ return {
2216
+ chatId: payload.chat_id,
2217
+ threadId: payload.thread_id,
2218
+ eventId: payload.event_id,
2219
+ properties: payload.properties
2220
+ };
2221
+ };
2222
+
2223
+ var parseEventUpdatedPush = function parseEventUpdatedPush(payload) {
2224
+ var threadId = payload.thread_id;
2225
+ return {
2226
+ chatId: payload.chat_id,
2227
+ threadId: threadId,
2228
+ event: parseEvent$1(threadId, payload.event)
2229
+ };
2230
+ };
2231
+
2232
+ var parseEventsMarkedAsSeenPush = function parseEventsMarkedAsSeenPush(payload) {
2233
+ return {
2234
+ chatId: payload.chat_id,
2235
+ userId: payload.user_id,
2236
+ seenUpTo: payload.seen_up_to
2237
+ };
2238
+ };
2239
+
2240
+ var parseGreetingAcceptedPush = function parseGreetingAcceptedPush(payload) {
2241
+ return {
2242
+ uniqueId: payload.unique_id
2243
+ };
2244
+ };
2245
+
2246
+ var parseGetChatResponse = function parseGetChatResponse(payload) {
2247
+ return _extends({}, parseChatCommon(payload), {
2248
+ thread: payload.thread ? parseThread(payload.id, payload.thread) : null
2249
+ });
2250
+ };
2251
+
2252
+ var parseIncomingChatPush = function parseIncomingChatPush(payload) {
2253
+ var chat = payload.chat;
2254
+ return {
2255
+ chat: _extends({}, parseChatCommon(chat), {
2256
+ thread: parseThread(chat.id, chat.thread)
2257
+ })
2258
+ };
2259
+ };
2260
+
2261
+ var parseIncomingEventPush = function parseIncomingEventPush(payload) {
2262
+ return {
2263
+ chatId: payload.chat_id,
2264
+ event: parseEvent$1(payload.thread_id, payload.event)
2265
+ };
2266
+ };
2267
+
2268
+ var parseIncomingGreetingPush = function parseIncomingGreetingPush(payload) {
2269
+ return parseGreeting(payload);
2270
+ };
2271
+
2272
+ var parseIncomingRichMessagePostbackPush = function parseIncomingRichMessagePostbackPush(payload) {
2273
+ return {
2274
+ userId: payload.user_id,
2275
+ chatId: payload.chat_id,
2276
+ threadId: payload.thread_id,
2277
+ eventId: payload.event_id,
2278
+ postback: payload.postback
2279
+ };
2280
+ };
2281
+
2282
+ var parseIncomingTypingIndicatorPush = function parseIncomingTypingIndicatorPush(payload) {
2283
+ var chatId = payload.chat_id,
2284
+ typingIndicator = payload.typing_indicator;
2285
+ return {
2286
+ chatId: chatId,
2287
+ typingIndicator: {
2288
+ authorId: typingIndicator.author_id,
2289
+ isTyping: typingIndicator.is_typing
2290
+ }
2291
+ };
2292
+ };
2293
+
2294
+ var parseQueuePositionUpdatedPush = function parseQueuePositionUpdatedPush(payload) {
2295
+ return {
2296
+ chatId: payload.chat_id,
2297
+ threadId: payload.thread_id,
2298
+ queue: parseQueueUpdate(payload.queue)
2299
+ };
2300
+ };
2301
+
2302
+ var parseThreadPropertiesDeletedPush = function parseThreadPropertiesDeletedPush(payload) {
2303
+ return {
2304
+ chatId: payload.chat_id,
2305
+ threadId: payload.thread_id,
2306
+ properties: payload.properties
2307
+ };
2308
+ };
2309
+
2310
+ var parseThreadPropertiesUpdatedPush = function parseThreadPropertiesUpdatedPush(payload) {
2311
+ return {
2312
+ chatId: payload.chat_id,
2313
+ threadId: payload.thread_id,
2314
+ properties: payload.properties
2315
+ };
2316
+ };
2317
+
2318
+ var parseUserAddedToChatPush = function parseUserAddedToChatPush(payload) {
2319
+ return {
2320
+ chatId: payload.chat_id,
2321
+ user: parseChatUser(payload.user),
2322
+ present: payload.user.present
2323
+ };
2324
+ };
2325
+
2326
+ var parseUserRemovedFromChatPush = function parseUserRemovedFromChatPush(payload) {
2327
+ return {
2328
+ chatId: payload.chat_id,
2329
+ userId: payload.user_id
2330
+ };
2331
+ };
2332
+
2333
+ var parseFields = function parseFields(fields) {
2334
+ return fields.map(function (field) {
2335
+ switch (field.type) {
2336
+ case 'group_chooser':
2337
+ return _extends({}, field, {
2338
+ options: field.options.map(function (_ref) {
2339
+ var groupId = _ref.group_id,
2340
+ option = _objectWithoutPropertiesLoose(_ref, ["group_id"]);
2341
+
2342
+ return _extends({}, option, {
2343
+ groupId: groupId
2344
+ });
2345
+ })
2346
+ });
2347
+
2348
+ case 'rating':
2349
+ {
2350
+ var commentLabel = field.comment_label,
2351
+ parsed = _objectWithoutPropertiesLoose(field, ["comment_label"]);
2352
+
2353
+ return _extends({}, parsed, {
2354
+ commentLabel: commentLabel
2355
+ });
2356
+ }
2357
+
2358
+ default:
2359
+ return field;
2360
+ }
2361
+ });
2362
+ };
2363
+
2364
+ var parseTicketFormFields = function parseTicketFormFields(fields) {
2365
+ var withFakeIds = fields.map(function (field, index) {
2366
+ return _extends({}, field, {
2367
+ id: String(index)
2368
+ });
2369
+ });
2370
+ return parseFields(withFakeIds);
2371
+ };
2372
+
2373
+ var parseForm$1 = function parseForm(form) {
2374
+ var isTicketForm = !('id' in form.fields[0]);
2375
+ return {
2376
+ id: form.id,
2377
+ fields: isTicketForm ? parseTicketFormFields(form.fields) : parseFields(form.fields)
2378
+ };
2379
+ };
2380
+
2381
+ var parseGetFormResponse = function parseGetFormResponse(payload) {
2382
+ if (!payload.enabled) {
2383
+ return payload;
2384
+ }
2385
+
2386
+ return _extends({}, payload, {
2387
+ form: parseForm$1(payload.form)
2388
+ });
2389
+ };
2390
+
2391
+ var parseGetUrlInfoResponse = function parseGetUrlInfoResponse(payload) {
2392
+ var urlInfo = {
2393
+ url: payload.url
2394
+ };
2395
+
2396
+ if (payload.title) {
2397
+ urlInfo.title = payload.title;
2398
+ }
2399
+
2400
+ if (payload.description) {
2401
+ urlInfo.description = payload.description;
2402
+ }
2403
+
2404
+ if (payload.image_url) {
2405
+ urlInfo.imageUrl = "https://" + payload.image_url;
2406
+
2407
+ if (payload.image_width && payload.image_height) {
2408
+ urlInfo.imageWidth = payload.image_width;
2409
+ urlInfo.imageHeight = payload.image_height;
2410
+ }
2411
+ }
2412
+
2413
+ return urlInfo;
2414
+ };
2415
+
2416
+ var getAvailabilityBasedOnDynamicConfig = function getAvailabilityBasedOnDynamicConfig(_ref2) {
2417
+ var onlineGroups = _ref2.online_groups_ids,
2418
+ customerGroups = _ref2.customer_groups;
2419
+
2420
+ // this might be missing if all groups are offline
2421
+ if (!onlineGroups) {
2422
+ return 'offline';
2423
+ }
2424
+
2425
+ var monitoringGroupId = customerGroups.monitoring.id;
2426
+ return dataUtils.includes(monitoringGroupId, onlineGroups) ? 'online' : 'offline';
2427
+ };
2428
+
2429
+ var parseListChatsResponse = function parseListChatsResponse(payload) {
2430
+ var chatsSummary = payload.chats_summary.map(function (_ref3) {
2431
+ var id = _ref3.id,
2432
+ active = _ref3.active,
2433
+ access = _ref3.access,
2434
+ lastThreadCreatedAt = _ref3.last_thread_created_at,
2435
+ lastThreadId = _ref3.last_thread_id,
2436
+ lastEventsPerType = _ref3.last_event_per_type,
2437
+ _ref3$properties = _ref3.properties,
2438
+ properties = _ref3$properties === void 0 ? {} : _ref3$properties,
2439
+ users = _ref3.users;
2440
+ var chatSummary = {
2441
+ id: id,
2442
+ active: active,
2443
+ access: parseAccess(access),
2444
+ properties: properties,
2445
+ users: users.map(parseChatUser),
2446
+ lastThreadId: lastThreadId || null,
2447
+ lastThreadCreatedAt: lastThreadCreatedAt || null,
2448
+ eventsSeenUpToMap: getEventsSeenUpToMap(users)
2449
+ };
2450
+
2451
+ if (!lastEventsPerType) {
2452
+ return chatSummary;
2453
+ }
2454
+
2455
+ chatSummary.lastEventsPerType = dataUtils.mapValues(function (lastEventPerType) {
2456
+ return parseEvent$1(lastEventPerType.thread_id, lastEventPerType.event);
2457
+ }, lastEventsPerType);
2458
+ var refinedLastEventsPerType = lastEventsPerType;
2459
+ var lastEventSummariesArray = Object.keys(refinedLastEventsPerType).map(function (eventType) {
2460
+ return refinedLastEventsPerType[eventType];
2461
+ });
2462
+ var lastEventSummary = dataUtils.last(lastEventSummariesArray.sort(function (eventSummaryA, eventSummaryB) {
2463
+ return eventSummaryA.thread_id === eventSummaryB.thread_id ? dataUtils.stringCompare(eventSummaryA.event.created_at, eventSummaryB.event.created_at) : dataUtils.stringCompare(eventSummaryA.thread_created_at, eventSummaryB.thread_created_at);
2464
+ }));
2465
+
2466
+ if (lastEventSummary) {
2467
+ chatSummary.lastEvent = chatSummary.lastEventsPerType[lastEventSummary.event.type];
2468
+ }
2469
+
2470
+ return chatSummary;
2471
+ });
2472
+ return {
2473
+ chatsSummary: dataUtils.numericSortBy(function (_ref4) {
2474
+ var lastEvent = _ref4.lastEvent,
2475
+ order = _ref4.order;
2476
+ return -1 * (lastEvent !== undefined ? lastEvent.timestamp : order);
2477
+ }, chatsSummary),
2478
+ totalChats: payload.total_chats,
2479
+ users: dataUtils.uniqBy(function (user) {
2480
+ return user.id;
2481
+ }, dataUtils.flatMap(function (summary) {
2482
+ return summary.users;
2483
+ }, chatsSummary)),
2484
+ previousPageId: payload.previous_page_id || null,
2485
+ nextPageId: payload.next_page_id || null
2486
+ };
2487
+ };
2488
+
2489
+ var parseListGroupStatusesResponse = function parseListGroupStatusesResponse(payload) {
2490
+ return payload.groups_status;
2491
+ };
2492
+
2493
+ var parseListThreadsResponse = function parseListThreadsResponse(request, payload) {
2494
+ return {
2495
+ threads: payload.threads.map(function (thread) {
2496
+ return parseThread(request.payload.chat_id, thread);
2497
+ }),
2498
+ previousPageId: payload.previous_page_id || null,
2499
+ nextPageId: payload.next_page_id || null
2500
+ };
2501
+ };
2502
+
2503
+ var parseLoginResponse = function parseLoginResponse(payload) {
2504
+ var dynamicConfig = payload.__priv_dynamic_config,
2505
+ chats = payload.chats,
2506
+ greeting = payload.greeting;
2507
+ return _extends({
2508
+ dynamicConfig: dynamicConfig,
2509
+ customer: parseCustomer(payload.customer),
2510
+ availability: getAvailabilityBasedOnDynamicConfig(dynamicConfig),
2511
+ chats: chats.map(function (chat) {
2512
+ return {
2513
+ id: chat.chat_id,
2514
+ active: 'has_active_thread' in chat ? chat.has_active_thread : // temporary fallback, waiting for API to move this flag into `chats` array
2515
+ payload.has_active_thread,
2516
+ hasUnreadEvents: chat.has_unread_events
2517
+ };
2518
+ })
2519
+ }, greeting && {
2520
+ greeting: parseGreeting(greeting)
2521
+ });
2522
+ };
2523
+
2524
+ var parsePush = function parsePush(push) {
2525
+ switch (push.action) {
2526
+ case CHAT_DEACTIVATED:
2527
+ return {
2528
+ action: push.action,
2529
+ payload: {
2530
+ chatId: push.payload.chat_id
2531
+ }
2532
+ };
2533
+
2534
+ case CHAT_PROPERTIES_DELETED:
2535
+ return {
2536
+ action: push.action,
2537
+ payload: parseChatPropertiesDeletedPush(push.payload)
2538
+ };
2539
+
2540
+ case CHAT_PROPERTIES_UPDATED:
2541
+ return {
2542
+ action: push.action,
2543
+ payload: parseChatPropertiesUpdatedPush(push.payload)
2544
+ };
2545
+
2546
+ case CHAT_TRANSFERRED:
2547
+ return {
2548
+ action: push.action,
2549
+ payload: parseChatTransferredPush(push.payload)
2550
+ };
2551
+
2552
+ case CUSTOMER_SIDE_STORAGE_UPDATED:
2553
+ return {
2554
+ action: push.action,
2555
+ payload: push.payload
2556
+ };
2557
+
2558
+ case CUSTOMER_DISCONNECTED:
2559
+ return {
2560
+ action: push.action,
2561
+ payload: push.payload
2562
+ };
2563
+
2564
+ case CUSTOMER_PAGE_UPDATED:
2565
+ return {
2566
+ action: push.action,
2567
+ payload: parseCustomerPageUpdatedPush(push.payload)
2568
+ };
2569
+
2570
+ case CUSTOMER_UPDATED:
2571
+ return {
2572
+ action: push.action,
2573
+ payload: parseCustomerUpdatedPush(push.payload)
2574
+ };
2575
+
2576
+ case EVENT_PROPERTIES_DELETED:
2577
+ return {
2578
+ action: push.action,
2579
+ payload: parseEventPropertiesDeletedPush(push.payload)
2580
+ };
2581
+
2582
+ case EVENT_PROPERTIES_UPDATED:
2583
+ return {
2584
+ action: push.action,
2585
+ payload: parseEventPropertiesUpdatedPush(push.payload)
2586
+ };
2587
+
2588
+ case EVENT_UPDATED:
2589
+ return {
2590
+ action: push.action,
2591
+ payload: parseEventUpdatedPush(push.payload)
2592
+ };
2593
+
2594
+ case EVENTS_MARKED_AS_SEEN:
2595
+ return {
2596
+ action: push.action,
2597
+ payload: parseEventsMarkedAsSeenPush(push.payload)
2598
+ };
2599
+
2600
+ case GREETING_ACCEPTED:
2601
+ return {
2602
+ action: push.action,
2603
+ payload: parseGreetingAcceptedPush(push.payload)
2604
+ };
2605
+
2606
+ case GREETING_CANCELED:
2607
+ return {
2608
+ action: push.action,
2609
+ // 'greeting_canceled' has the same payload as `greeting_accepted`
2610
+ payload: parseGreetingAcceptedPush(push.payload)
2611
+ };
2612
+
2613
+ case INCOMING_CHAT:
2614
+ return {
2615
+ action: push.action,
2616
+ payload: parseIncomingChatPush(push.payload)
2617
+ };
2618
+
2619
+ case INCOMING_EVENT:
2620
+ return {
2621
+ action: push.action,
2622
+ payload: parseIncomingEventPush(push.payload)
2623
+ };
2624
+
2625
+ case INCOMING_GREETING:
2626
+ return {
2627
+ action: push.action,
2628
+ payload: parseIncomingGreetingPush(push.payload)
2629
+ };
2630
+
2631
+ case INCOMING_MULTICAST:
2632
+ return {
2633
+ action: push.action,
2634
+ payload: push.payload
2635
+ };
2636
+
2637
+ case INCOMING_RICH_MESSAGE_POSTBACK:
2638
+ return {
2639
+ action: push.action,
2640
+ payload: parseIncomingRichMessagePostbackPush(push.payload)
2641
+ };
2642
+
2643
+ case INCOMING_TYPING_INDICATOR:
2644
+ return {
2645
+ action: push.action,
2646
+ payload: parseIncomingTypingIndicatorPush(push.payload)
2647
+ };
2648
+
2649
+ case QUEUE_POSITION_UPDATED:
2650
+ return {
2651
+ action: push.action,
2652
+ payload: parseQueuePositionUpdatedPush(push.payload)
2653
+ };
2654
+
2655
+ case THREAD_PROPERTIES_DELETED:
2656
+ return {
2657
+ action: push.action,
2658
+ payload: parseThreadPropertiesDeletedPush(push.payload)
2659
+ };
2660
+
2661
+ case THREAD_PROPERTIES_UPDATED:
2662
+ return {
2663
+ action: push.action,
2664
+ payload: parseThreadPropertiesUpdatedPush(push.payload)
2665
+ };
2666
+
2667
+ case USER_ADDED_TO_CHAT:
2668
+ return {
2669
+ action: push.action,
2670
+ payload: parseUserAddedToChatPush(push.payload)
2671
+ };
2672
+
2673
+ case USER_REMOVED_FROM_CHAT:
2674
+ return {
2675
+ action: push.action,
2676
+ payload: parseUserRemovedFromChatPush(push.payload)
2677
+ };
2678
+ }
2679
+ };
2680
+ var parseResponse = function parseResponse(_ref5) {
2681
+ var request = _ref5.request,
2682
+ response = _ref5.response;
2683
+
2684
+ switch (response.action) {
2685
+ case ACCEPT_GREETING:
2686
+ return {
2687
+ action: response.action,
2688
+ payload: SUCCESS
2689
+ };
2690
+
2691
+ case CANCEL_GREETING:
2692
+ return {
2693
+ action: response.action,
2694
+ payload: SUCCESS
2695
+ };
2696
+
2697
+ case DELETE_CHAT_PROPERTIES:
2698
+ return {
2699
+ action: response.action,
2700
+ payload: SUCCESS
2701
+ };
2702
+
2703
+ case DELETE_EVENT_PROPERTIES:
2704
+ return {
2705
+ action: response.action,
2706
+ payload: SUCCESS
2707
+ };
2708
+
2709
+ case DELETE_THREAD_PROPERTIES:
2710
+ return {
2711
+ action: response.action,
2712
+ payload: SUCCESS
2713
+ };
2714
+
2715
+ case GET_CHAT:
2716
+ return {
2717
+ action: response.action,
2718
+ payload: parseGetChatResponse(response.payload)
2719
+ };
2720
+
2721
+ case GET_CUSTOMER:
2722
+ return {
2723
+ action: response.action,
2724
+ payload: parseCustomer(response.payload)
2725
+ };
2726
+
2727
+ case GET_FORM:
2728
+ return {
2729
+ action: response.action,
2730
+ payload: parseGetFormResponse(response.payload)
2731
+ };
2732
+
2733
+ case GET_PREDICTED_AGENT:
2734
+ return {
2735
+ action: response.action,
2736
+ payload: parsePredictedAgent(response.payload)
2737
+ };
2738
+
2739
+ case GET_URL_INFO:
2740
+ return {
2741
+ action: response.action,
2742
+ payload: parseGetUrlInfoResponse(response.payload)
2743
+ };
2744
+
2745
+ case LIST_CHATS:
2746
+ return {
2747
+ action: response.action,
2748
+ payload: parseListChatsResponse(response.payload)
2749
+ };
2750
+
2751
+ case LIST_GROUP_STATUSES:
2752
+ return {
2753
+ action: response.action,
2754
+ payload: parseListGroupStatusesResponse(response.payload)
2755
+ };
2756
+
2757
+ case LIST_THREADS:
2758
+ return {
2759
+ action: response.action,
2760
+ payload: parseListThreadsResponse(request, response.payload)
2761
+ };
2762
+
2763
+ case LOGIN:
2764
+ return {
2765
+ action: response.action,
2766
+ payload: parseLoginResponse(response.payload)
2767
+ };
2768
+
2769
+ case MARK_EVENTS_AS_SEEN:
2770
+ return {
2771
+ action: response.action,
2772
+ payload: SUCCESS
2773
+ };
2774
+
2775
+ case SEND_SNEAK_PEEK:
2776
+ return {
2777
+ action: response.action,
2778
+ payload: SUCCESS
2779
+ };
2780
+
2781
+ case SET_CUSTOMER_SESSION_FIELDS:
2782
+ return {
2783
+ action: response.action,
2784
+ payload: SUCCESS
2785
+ };
2786
+
2787
+ case SEND_RICH_MESSAGE_POSTBACK:
2788
+ return {
2789
+ action: response.action,
2790
+ payload: SUCCESS
2791
+ };
2792
+
2793
+ case UPDATE_CHAT_PROPERTIES:
2794
+ return {
2795
+ action: response.action,
2796
+ payload: SUCCESS
2797
+ };
2798
+
2799
+ case UPDATE_CUSTOMER:
2800
+ return {
2801
+ action: response.action,
2802
+ payload: SUCCESS
2803
+ };
2804
+
2805
+ case UPDATE_CUSTOMER_PAGE$1:
2806
+ return {
2807
+ action: response.action,
2808
+ payload: SUCCESS
2809
+ };
2810
+
2811
+ case UPDATE_EVENT_PROPERTIES:
2812
+ return {
2813
+ action: response.action,
2814
+ payload: SUCCESS
2815
+ };
2816
+
2817
+ case UPDATE_THREAD_PROPERTIES:
2818
+ return {
2819
+ action: response.action,
2820
+ payload: SUCCESS
2821
+ };
2822
+ }
2823
+ };
2824
+ var parseServerError = function parseServerError(error) {
2825
+ return {
2826
+ code: error.type.toUpperCase(),
2827
+ message: error.message
2828
+ };
2829
+ };
2830
+
2831
+ var handleResponseError = function handleResponseError(_ref, response) {
2832
+ var dispatch = _ref.dispatch,
2833
+ getState = _ref.getState;
2834
+ var requestId = response.request_id,
2835
+ payload = response.payload;
2836
+
2837
+ var _getRequest = getRequest(getState(), requestId),
2838
+ reject = _getRequest.reject;
2839
+
2840
+ dispatch({
2841
+ type: REQUEST_FAILED,
2842
+ payload: {
2843
+ id: requestId,
2844
+ reject: reject,
2845
+ error: parseServerError(payload.error)
2846
+ }
2847
+ });
2848
+ };
2849
+
2850
+ var handleResponse$1 = function handleResponse(_ref2, response) {
2851
+ var dispatch = _ref2.dispatch,
2852
+ getState = _ref2.getState;
2853
+ var requestId = response.request_id;
2854
+
2855
+ var _getRequest2 = getRequest(getState(), requestId),
2856
+ promise = _getRequest2.promise,
2857
+ resolve = _getRequest2.resolve,
2858
+ request = _getRequest2.request;
2859
+
2860
+ var parsedResponse = parseResponse({
2861
+ request: request,
2862
+ response: response
2863
+ });
2864
+ dispatch({
2865
+ type: RESPONSE_RECEIVED,
2866
+ payload: _extends({
2867
+ id: requestId,
2868
+ promise: promise,
2869
+ resolve: resolve
2870
+ }, parsedResponse)
2871
+ });
2872
+ };
2873
+
2874
+ var handlePushResponse = function handlePushResponse(_ref3, response) {
2875
+ var dispatch = _ref3.dispatch,
2876
+ getState = _ref3.getState;
2877
+ var requestId = response.request_id;
2878
+
2879
+ var _getRequest3 = getRequest(getState(), requestId),
2880
+ promise = _getRequest3.promise,
2881
+ resolve = _getRequest3.resolve;
2882
+
2883
+ var parsedPush = parsePush(response);
2884
+ dispatch({
2885
+ type: PUSH_RESPONSE_RECEIVED,
2886
+ payload: _extends({
2887
+ id: requestId,
2888
+ promise: promise,
2889
+ resolve: resolve
2890
+ }, parsedPush)
2891
+ });
2892
+ };
2893
+
2894
+ var handlePush$1 = function handlePush(store, push) {
2895
+ var parsedPush = parsePush(push);
2896
+
2897
+ if (!parsedPush) {
2898
+ // defensive measure against receiving unknown push
2899
+ return;
2900
+ }
2901
+
2902
+ store.dispatch({
2903
+ type: PUSH_RECEIVED,
2904
+ payload: parsedPush
2905
+ });
2906
+ };
2907
+
2908
+ var socketListener = (function (store, socket) {
2909
+ var dispatch = store.dispatch;
2910
+ socket.on('connect', function () {
2911
+ dispatch({
2912
+ type: SOCKET_CONNECTED
2913
+ });
2914
+ });
2915
+ socket.on('message', function (message) {
2916
+ if (message.type === 'response') {
2917
+ if (!message.success) {
2918
+ handleResponseError(store, message);
2919
+ return;
2920
+ }
2921
+
2922
+ switch (message.action) {
2923
+ case DEACTIVATE_CHAT:
2924
+ case RESUME_CHAT:
2925
+ case SEND_EVENT:
2926
+ case START_CHAT:
2927
+ // those are requests with indirect responses
2928
+ return;
2929
+
2930
+ default:
2931
+ handleResponse$1(store, message);
2932
+ return;
2933
+ }
2934
+ }
2935
+
2936
+ if ('request_id' in message) {
2937
+ switch (message.action) {
2938
+ case CHAT_DEACTIVATED:
2939
+ case INCOMING_CHAT:
2940
+ case INCOMING_EVENT:
2941
+ // those are acting as indirect responses
2942
+ handlePushResponse(store, message);
2943
+ return;
2944
+ }
2945
+ }
2946
+
2947
+ handlePush$1(store, message);
2948
+ });
2949
+ socket.on('disconnect', function () {
2950
+ failAllRequests(store, CONNECTION_LOST);
2951
+
2952
+ if (getConnectionStatus(store.getState()) === CONNECTED) {
2953
+ store.dispatch(socketDisconnected());
2954
+ }
2955
+ });
2956
+ socket.on('connection_unstable', function () {
2957
+ dispatch({
2958
+ type: SOCKET_UNSTABLE
2959
+ });
2960
+ });
2961
+ socket.on('connection_recovered', function () {
2962
+ dispatch({
2963
+ type: SOCKET_RECOVERED
2964
+ });
2965
+ });
2966
+ return socket.off;
2967
+ });
2968
+
2969
+ var INCORRECT_REQUESTER_STRUCTURE = 'incorrect requester structure';
2970
+
2971
+ var appendString = function appendString(input, str) {
2972
+ return input.length ? input + "\n" + str : str;
2973
+ };
2974
+
2975
+ var createTicketBody = function createTicketBody(state, _ref) {
2976
+ var fields = _ref.fields,
2977
+ customerId = _ref.customerId,
2978
+ _ref$groupId = _ref.groupId,
2979
+ groupId = _ref$groupId === void 0 ? state.groupId : _ref$groupId,
2980
+ timeZone = _ref.timeZone;
2981
+
2982
+ var ticketBody = _extends({
2983
+ licence_id: state.licenseId,
2984
+ ticket_message: '',
2985
+ offline_message: '',
2986
+ visitor_id: customerId,
2987
+ requester: {}
2988
+ }, typeof groupId === 'number' && {
2989
+ group: groupId
2990
+ }, state.page && {
2991
+ source: {
2992
+ url: state.page.url
2993
+ }
2994
+ }, timeZone && {
2995
+ timezone: timeZone
2996
+ });
2997
+
2998
+ return fields.reduce(function (body, field) {
2999
+ switch (field.type) {
3000
+ case 'subject':
3001
+ {
3002
+ var value = field.answer;
3003
+ var text = value ? field.label + " " + value : field.label;
3004
+
3005
+ if (value) {
3006
+ body.subject = value;
3007
+ }
3008
+
3009
+ body.offline_message = appendString(body.offline_message, text);
3010
+ return body;
3011
+ }
3012
+
3013
+ case 'name':
3014
+ {
3015
+ var _value = field.answer;
3016
+
3017
+ var _text = _value ? field.label + " " + _value : field.label;
3018
+
3019
+ if (_value) {
3020
+ body.requester.name = _value;
3021
+ }
3022
+
3023
+ body.offline_message = appendString(body.offline_message, _text);
3024
+ return body;
3025
+ }
3026
+
3027
+ case 'email':
3028
+ {
3029
+ var _value2 = field.answer;
3030
+
3031
+ var _text2 = _value2 ? field.label + " " + _value2 : field.label;
3032
+
3033
+ body.requester.mail = _value2;
3034
+ body.offline_message = appendString(body.offline_message, _text2);
3035
+ return body;
3036
+ }
3037
+
3038
+ case 'question':
3039
+ case 'textarea':
3040
+ {
3041
+ var _value3 = field.answer;
3042
+
3043
+ var _text3 = _value3 ? field.label + " " + _value3 : field.label;
3044
+
3045
+ body.offline_message = appendString(body.offline_message, _text3);
3046
+ body.ticket_message = appendString(body.ticket_message, _text3);
3047
+ return body;
3048
+ }
3049
+
3050
+ case 'radio':
3051
+ case 'select':
3052
+ {
3053
+ var _value4 = field.answer && field.answer.label;
3054
+
3055
+ var _text4 = _value4 ? field.label + " " + _value4 : field.label;
3056
+
3057
+ body.offline_message = appendString(body.offline_message, _text4);
3058
+ body.ticket_message = appendString(body.ticket_message, _text4);
3059
+ return body;
3060
+ }
3061
+
3062
+ case 'checkbox':
3063
+ {
3064
+ var _value5 = field.answers && field.answers.map(function (answer) {
3065
+ return answer.label;
3066
+ }).join(', ');
3067
+
3068
+ var _text5 = _value5 ? field.label + " " + _value5 : field.label;
3069
+
3070
+ body.offline_message = appendString(body.offline_message, _text5);
3071
+ body.ticket_message = appendString(body.ticket_message, _text5);
3072
+ return body;
3073
+ }
3074
+
3075
+ default:
3076
+ return body;
3077
+ }
3078
+ }, ticketBody);
3079
+ };
3080
+
3081
+ var sendTicketForm = function sendTicketForm(store, auth, _ref2) {
3082
+ var filledForm = _ref2.filledForm,
3083
+ groupId = _ref2.groupId,
3084
+ timeZone = _ref2.timeZone;
3085
+ return auth.getToken().then(function (token) {
3086
+ var state = store.getState();
3087
+
3088
+ if (getSelfId(state) === null) {
3089
+ store.dispatch(setSelfId(token.entityId));
3090
+ }
3091
+
3092
+ var url = getApiOrigin(state) + "/v2/tickets/new";
3093
+ var body = createTicketBody(state, {
3094
+ fields: filledForm.fields,
3095
+ customerId: token.entityId,
3096
+ groupId: groupId,
3097
+ timeZone: timeZone
3098
+ });
3099
+ return unfetch__default['default'](url, {
3100
+ method: 'POST',
3101
+ headers: {
3102
+ 'Content-Type': 'application/json'
3103
+ },
3104
+ body: JSON.stringify(body)
3105
+ }).then(function (response) {
3106
+ if (response.ok) {
3107
+ return response.json().then(function (res) {
3108
+ return _extends({}, res, {
3109
+ text: body.ticket_message
3110
+ });
3111
+ });
3112
+ } // we actually should normalize this somehow
3113
+
3114
+
3115
+ if (response.status === 400 || response.status === 422) {
3116
+ var errHandler = function errHandler(error) {
3117
+ if (!error || !error.errors) {
3118
+ // TODO: I honestly don't know if this can even be reached and even if it is - What error should be thrown here
3119
+ throw new Error();
3120
+ } // we receive some hardcore aggregate error here 😱
3121
+
3122
+
3123
+ var firstError = error.errors[0];
3124
+ var type = Object.keys(firstError)[0];
3125
+
3126
+ if (type === INCORRECT_REQUESTER_STRUCTURE) {
3127
+ throw createError({
3128
+ message: firstError[INCORRECT_REQUESTER_STRUCTURE][0],
3129
+ code: 'VALIDATION'
3130
+ });
3131
+ }
3132
+
3133
+ throw new Error();
3134
+ };
3135
+
3136
+ return response.json().then(errHandler, errHandler);
3137
+ }
3138
+
3139
+ throw new Error();
3140
+ });
3141
+ });
3142
+ };
3143
+
3144
+ var KILOBYTE = 1024;
3145
+ var MEGABYTE = 1024 * KILOBYTE;
3146
+ var GIGABYTE = 1024 * MEGABYTE;
3147
+ var SIZE_LIMIT = 10 * MEGABYTE;
3148
+
3149
+ var formatBytes = function formatBytes(bytes, precision) {
3150
+ if (precision === void 0) {
3151
+ precision = 2;
3152
+ }
3153
+
3154
+ if (bytes < KILOBYTE) {
3155
+ return bytes + " b";
3156
+ }
3157
+
3158
+ var kilobytes = bytes / 1024;
3159
+
3160
+ if (bytes < MEGABYTE) {
3161
+ return kilobytes.toFixed(precision) + " kb";
3162
+ }
3163
+
3164
+ var megabytes = kilobytes / 1024;
3165
+
3166
+ if (bytes < GIGABYTE) {
3167
+ return megabytes.toFixed(precision) + " MB";
3168
+ }
3169
+
3170
+ var gigabytes = megabytes / 1024;
3171
+ return gigabytes.toFixed(precision) + " GB";
3172
+ };
3173
+
3174
+ var validateFile = function validateFile(file) {
3175
+ if (file.size > SIZE_LIMIT) {
3176
+ throw createError({
3177
+ message: "The file is too big (max size is " + formatBytes(SIZE_LIMIT) + ").",
3178
+ code: TOO_BIG_FILE
3179
+ });
3180
+ }
3181
+ };
3182
+
3183
+ var uploadFile = function uploadFile(_ref, _ref2) {
3184
+ var auth = _ref.auth,
3185
+ store = _ref.store;
3186
+ var file = _ref2.file,
3187
+ onProgress = _ref2.onProgress;
3188
+ var upload;
3189
+ var cancelled = false;
3190
+ var send = new Promise(function (resolve, reject) {
3191
+ validateFile(file);
3192
+ var state = store.getState();
3193
+ var query = urlUtils.buildQueryString({
3194
+ license_id: state.licenseId
3195
+ });
3196
+ var url = getServerUrl(state) + "/action/" + UPLOAD_FILE + "?" + query;
3197
+ var payload = {
3198
+ file: file
3199
+ };
3200
+ auth.getToken().then(function (token) {
3201
+ if (cancelled) {
3202
+ reject(new Error('Upload cancelled.'));
3203
+ return;
3204
+ }
3205
+
3206
+ upload = rawUploadFile__default['default'](url, payload, {
3207
+ headers: {
3208
+ Authorization: token.tokenType + " " + token.accessToken
3209
+ },
3210
+ onProgress: onProgress
3211
+ });
3212
+ upload.promise.then(resolve, function (uploadError) {
3213
+ // an error might not come from a server
3214
+ if (!uploadError.response) {
3215
+ reject(uploadError);
3216
+ return;
3217
+ }
3218
+
3219
+ var _uploadError$response = uploadError.response.error,
3220
+ type = _uploadError$response.type,
3221
+ message = _uploadError$response.message;
3222
+ reject(createError({
3223
+ message: message,
3224
+ code: type.toUpperCase()
3225
+ }));
3226
+ });
3227
+ });
3228
+ });
3229
+ return {
3230
+ promise: send,
3231
+ cancel: function cancel() {
3232
+ if (cancelled) {
3233
+ return;
3234
+ }
3235
+
3236
+ cancelled = true;
3237
+
3238
+ if (upload) {
3239
+ upload.cancel();
3240
+ }
3241
+ }
3242
+ };
3243
+ };
3244
+
3245
+ var makeGraylogRequest = function makeGraylogRequest(url, body) {
3246
+ return unfetch__default['default'](url, {
3247
+ body: body,
3248
+ method: 'POST',
3249
+ headers: {
3250
+ Accept: '*/*',
3251
+ 'Content-Type': 'application/x-www-form-urlencoded'
3252
+ }
3253
+ })["catch"](dataUtils.noop);
3254
+ };
3255
+
3256
+ /**
3257
+ * Logs event to Graylog with provided config data.
3258
+ * Logging request is fired only when all of those conditions are true:
3259
+ * 1. package is used in lc production environment
3260
+ * 2. package is used standalone because only then "customer_sdk" will be set to customer_sdk
3261
+ */
3262
+ var log = function log(_ref) {
3263
+ var env = _ref.env,
3264
+ licenseId = _ref.licenseId,
3265
+ eventName = _ref.eventName;
3266
+
3267
+ if (env !== 'production' || "customer_sdk" !== 'customer_sdk') {
3268
+ return Promise.resolve();
3269
+ }
3270
+
3271
+ var message = {
3272
+ event_name: eventName,
3273
+ severity: 'Informational',
3274
+ sdkVersion: "3.1.0"
3275
+ };
3276
+ var body = {
3277
+ licence_id: licenseId,
3278
+ event_id: 'chat_widget_customer_sdk',
3279
+ message: JSON.stringify(message)
3280
+ };
3281
+ return makeGraylogRequest('https://queue.livechatinc.com/logs', urlUtils.buildQueryString(body));
3282
+ };
3283
+
3284
+ var LISTENER_IDENTITY = 'LISTENER_IDENTITY';
3285
+ var listenersMap = {};
3286
+
3287
+ var createDebuggedMethods = function createDebuggedMethods(methods, prefix) {
3288
+ if (prefix === void 0) {
3289
+ prefix = '';
3290
+ }
3291
+
3292
+ var methodNames = Object.keys(methods);
3293
+ return methodNames.map(function (methodName) {
3294
+ var method = methods[methodName];
3295
+ return function () {
3296
+ var _console;
3297
+
3298
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3299
+ args[_key] = arguments[_key];
3300
+ }
3301
+
3302
+ (_console = console).info.apply(_console, [prefix + "." + methodName + "() ===>"].concat(args));
3303
+
3304
+ var result = method.apply(void 0, args);
3305
+
3306
+ if (typeof (result == null ? void 0 : result.then) === 'function') {
3307
+ return result.then(function (data) {
3308
+ console.info(prefix + "." + methodName + "() <===", data);
3309
+ return data;
3310
+ }, function (err) {
3311
+ console.error(prefix + "." + methodName + "() <===", err);
3312
+ throw err;
3313
+ });
3314
+ }
3315
+
3316
+ return result;
3317
+ };
3318
+ }).reduce(function (acc, method, index) {
3319
+ acc[methodNames[index]] = method;
3320
+ return acc;
3321
+ }, {});
3322
+ };
3323
+
3324
+ var createEnhancedListener = function createEnhancedListener(label, event, listener) {
3325
+ if (listener[LISTENER_IDENTITY] === undefined) {
3326
+ Object.defineProperty(listener, LISTENER_IDENTITY, {
3327
+ value: {}
3328
+ });
3329
+ }
3330
+
3331
+ if (listener[LISTENER_IDENTITY][event]) {
3332
+ var enhancedListenerId = listener[LISTENER_IDENTITY][event];
3333
+ return listenersMap[enhancedListenerId];
3334
+ }
3335
+
3336
+ var enhancedListener = function enhancedListener(data) {
3337
+ console.info("." + label + "(\"" + event + "\") <===", data);
3338
+ listener(data);
3339
+ };
3340
+
3341
+ var uniqueId = dataUtils.generateUniqueId(listenersMap);
3342
+ listener[LISTENER_IDENTITY][event] = uniqueId;
3343
+ listenersMap[uniqueId] = enhancedListener;
3344
+ return enhancedListener;
3345
+ }; // TODO: this really should just accept & return CustomerSdk type
3346
+
3347
+
3348
+ var debug = (function (_sdk) {
3349
+ var sdk = _sdk;
3350
+
3351
+ if (process.env.NODE_ENV === 'production') {
3352
+ console.warn('You probably do not want to use debug(customerSDK) in your production environment.');
3353
+ }
3354
+
3355
+ var _on = sdk.on,
3356
+ _once = sdk.once,
3357
+ _off = sdk.off,
3358
+ _getChatHistory = sdk.getChatHistory,
3359
+ auth = sdk.auth,
3360
+ rest = _objectWithoutPropertiesLoose(sdk, ["on", "once", "off", "getChatHistory", "auth"]);
3361
+
3362
+ var methods = createDebuggedMethods(rest);
3363
+ return Object.freeze(_extends({
3364
+ auth: Object.freeze(createDebuggedMethods(auth, '.auth'))
3365
+ }, methods, {
3366
+ getChatHistory: function getChatHistory() {
3367
+ var _console2;
3368
+
3369
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
3370
+ args[_key2] = arguments[_key2];
3371
+ }
3372
+
3373
+ (_console2 = console).info.apply(_console2, [".getChatHistory()"].concat(args));
3374
+
3375
+ var history = _getChatHistory.apply(void 0, args);
3376
+
3377
+ var logLabel = 'history.next()';
3378
+ return {
3379
+ next: function next() {
3380
+ var _console3;
3381
+
3382
+ (_console3 = console).info.apply(_console3, [logLabel + " ===>"].concat(args));
3383
+
3384
+ return history.next().then(function (data) {
3385
+ var _console4;
3386
+
3387
+ (_console4 = console).info.apply(_console4, [logLabel + " <==="].concat(args, [data]));
3388
+
3389
+ return data;
3390
+ }, function (err) {
3391
+ var _console5;
3392
+
3393
+ (_console5 = console).error.apply(_console5, [logLabel + " <==="].concat(args, [err]));
3394
+
3395
+ throw err;
3396
+ });
3397
+ }
3398
+ };
3399
+ },
3400
+ off: function off(event, listener) {
3401
+ console.info(".off(\"" + event + "\", " + (listener.name || 'anonymous') + ")");
3402
+ var enhancedListener = listener;
3403
+
3404
+ if (listener[LISTENER_IDENTITY] !== undefined) {
3405
+ var enhancedListenerId = listener[LISTENER_IDENTITY][event];
3406
+ enhancedListener = listenersMap[enhancedListenerId];
3407
+ }
3408
+
3409
+ _off(event, enhancedListener);
3410
+ },
3411
+ on: function on(event, listener) {
3412
+ _on(event, createEnhancedListener('on', event, listener));
3413
+ },
3414
+ once: function once(event, listener) {
3415
+ _once(event, createEnhancedListener('once', event, listener));
3416
+ }
3417
+ }));
3418
+ });
3419
+
3420
+ var CHATS_PAGINATION_MAX_LIMIT = 25;
3421
+ var init = function init(config, env) {
3422
+ if (env === void 0) {
3423
+ env = 'production';
3424
+ }
3425
+
3426
+ createAuth.validateConfig(config);
3427
+
3428
+ var _config$autoConnect = config.autoConnect,
3429
+ autoConnect = _config$autoConnect === void 0 ? true : _config$autoConnect,
3430
+ customerDataProvider = config.customerDataProvider,
3431
+ identityProvider = config.identityProvider,
3432
+ instanceConfig = _objectWithoutPropertiesLoose(config, ["autoConnect", "customerDataProvider", "identityProvider"]);
3433
+
3434
+ var store = finalCreateStore(_extends({}, instanceConfig, {
3435
+ env: env
3436
+ }));
3437
+ var emitter = mitt__default['default']();
3438
+ var socket = createSocketClient(store);
3439
+ var auth = typeof identityProvider === 'function' ? identityProvider() : createAuth__default['default'](instanceConfig, env);
3440
+ store.addSideEffectsHandler(createSideEffectsHandler({
3441
+ emitter: emitter,
3442
+ socket: socket,
3443
+ auth: auth,
3444
+ customerDataProvider: customerDataProvider
3445
+ }));
3446
+ socketListener(store, socket);
3447
+
3448
+ var sendRequestAction$1 = sendRequestAction.bind(null, store);
3449
+
3450
+ var startConnection = function startConnection() {
3451
+ store.dispatch({
3452
+ type: START_CONNECTION
3453
+ });
3454
+ };
3455
+
3456
+ var api = Object.freeze({
3457
+ acceptGreeting: function acceptGreeting(_ref) {
3458
+ var greetingId = _ref.greetingId,
3459
+ uniqueId = _ref.uniqueId;
3460
+ return sendRequestAction$1(sendRequest(ACCEPT_GREETING, {
3461
+ greeting_id: greetingId,
3462
+ unique_id: uniqueId
3463
+ }));
3464
+ },
3465
+ auth: auth,
3466
+ cancelGreeting: function cancelGreeting(_ref2) {
3467
+ var uniqueId = _ref2.uniqueId;
3468
+ return sendRequestAction$1(sendRequest(CANCEL_GREETING, {
3469
+ unique_id: uniqueId
3470
+ }));
3471
+ },
3472
+ cancelRate: function cancelRate(params) {
3473
+ var chatId = params.chatId,
3474
+ _params$properties = params.properties,
3475
+ properties = _params$properties === void 0 ? ['score'] : _params$properties;
3476
+ return api.listThreads({
3477
+ chatId: chatId
3478
+ }).then(function (_ref3) {
3479
+ var threads = _ref3.threads;
3480
+
3481
+ if (!threads.length) {
3482
+ throw createError({
3483
+ message: "There is no thread in \"" + chatId + "\".",
3484
+ code: MISSING_CHAT_THREAD
3485
+ });
3486
+ }
3487
+
3488
+ return api.deleteThreadProperties({
3489
+ chatId: chatId,
3490
+ threadId: threads[0].id,
3491
+ properties: {
3492
+ rating: properties
3493
+ }
3494
+ });
3495
+ });
3496
+ },
3497
+ connect: startConnection,
3498
+ deactivateChat: function deactivateChat(_ref4) {
3499
+ var id = _ref4.id;
3500
+ return sendRequestAction$1(sendRequest(DEACTIVATE_CHAT, {
3501
+ id: id
3502
+ }));
3503
+ },
3504
+ deleteChatProperties: function deleteChatProperties(_ref5) {
3505
+ var id = _ref5.id,
3506
+ properties = _ref5.properties;
3507
+ return sendRequestAction$1(sendRequest(DELETE_CHAT_PROPERTIES, {
3508
+ id: id,
3509
+ properties: properties
3510
+ }));
3511
+ },
3512
+ deleteEventProperties: function deleteEventProperties(_ref6) {
3513
+ var chatId = _ref6.chatId,
3514
+ threadId = _ref6.threadId,
3515
+ eventId = _ref6.eventId,
3516
+ properties = _ref6.properties;
3517
+ return sendRequestAction$1(sendRequest(DELETE_EVENT_PROPERTIES, {
3518
+ chat_id: chatId,
3519
+ thread_id: threadId,
3520
+ event_id: eventId,
3521
+ properties: properties
3522
+ }));
3523
+ },
3524
+ deleteThreadProperties: function deleteThreadProperties(_ref7) {
3525
+ var chatId = _ref7.chatId,
3526
+ threadId = _ref7.threadId,
3527
+ properties = _ref7.properties;
3528
+ return sendRequestAction$1(sendRequest(DELETE_THREAD_PROPERTIES, {
3529
+ chat_id: chatId,
3530
+ thread_id: threadId,
3531
+ properties: properties
3532
+ }));
3533
+ },
3534
+ destroy: function destroy$1() {
3535
+ store.dispatch(destroy('manual'));
3536
+ },
3537
+ disconnect: function disconnect() {
3538
+ store.dispatch(pauseConnection('manual'));
3539
+ },
3540
+ getChat: function getChat(_ref8) {
3541
+ var chatId = _ref8.chatId,
3542
+ threadId = _ref8.threadId;
3543
+ return sendRequestAction$1(sendRequest(GET_CHAT, {
3544
+ chat_id: chatId,
3545
+ thread_id: threadId
3546
+ }));
3547
+ },
3548
+ getChatHistory: function getChatHistory(_ref9) {
3549
+ var chatId = _ref9.chatId;
3550
+ return createChatHistoryIterator(api, chatId);
3551
+ },
3552
+ getCustomer: function getCustomer() {
3553
+ return sendRequestAction$1(sendRequest(GET_CUSTOMER, {}));
3554
+ },
3555
+ getForm: function getForm(_ref10) {
3556
+ var groupId = _ref10.groupId,
3557
+ type = _ref10.type;
3558
+ return sendRequestAction$1(sendRequest(GET_FORM, {
3559
+ group_id: groupId,
3560
+ type: type
3561
+ }));
3562
+ },
3563
+ getPredictedAgent: function getPredictedAgent(params) {
3564
+ if (params === void 0) {
3565
+ params = {};
3566
+ }
3567
+
3568
+ var _params = params,
3569
+ groupId = _params.groupId;
3570
+ return sendRequestAction$1(sendRequest(GET_PREDICTED_AGENT, typeof groupId === 'number' ? {
3571
+ group_id: groupId
3572
+ } : {}));
3573
+ },
3574
+ getUrlInfo: function getUrlInfo(_ref11) {
3575
+ var url = _ref11.url;
3576
+ return sendRequestAction$1(sendRequest(GET_URL_INFO, {
3577
+ url: url
3578
+ }));
3579
+ },
3580
+ listChats: function listChats(params) {
3581
+ if (params === void 0) {
3582
+ params = {};
3583
+ }
3584
+
3585
+ if ('limit' in params && typeof params.limit === 'number' && params.limit > CHATS_PAGINATION_MAX_LIMIT) {
3586
+ return Promise.reject(new Error("Specified limit is too high (max " + CHATS_PAGINATION_MAX_LIMIT + ")."));
3587
+ }
3588
+
3589
+ return sendRequestAction$1(sendRequest(LIST_CHATS, params.pageId === undefined ? {
3590
+ limit: params.limit || 10
3591
+ } : {
3592
+ page_id: params.pageId
3593
+ }));
3594
+ },
3595
+ listGroupStatuses: function listGroupStatuses(_temp) {
3596
+ var _ref12 = _temp === void 0 ? {} : _temp,
3597
+ groupIds = _ref12.groupIds;
3598
+
3599
+ return sendRequestAction$1(sendRequest(LIST_GROUP_STATUSES, groupIds ? {
3600
+ group_ids: groupIds
3601
+ } : {
3602
+ all: true
3603
+ }));
3604
+ },
3605
+ listThreads: function listThreads(params) {
3606
+ return sendRequestAction$1(sendRequest(LIST_THREADS, params.pageId === undefined ? {
3607
+ chat_id: params.chatId,
3608
+ sort_order: params.sortOrder,
3609
+ limit: params.limit,
3610
+ min_events_count: params.minEventsCount
3611
+ } : {
3612
+ chat_id: params.chatId,
3613
+ page_id: params.pageId
3614
+ }));
3615
+ },
3616
+ markEventsAsSeen: function markEventsAsSeen(_ref13) {
3617
+ var chatId = _ref13.chatId,
3618
+ seenUpTo = _ref13.seenUpTo;
3619
+ return sendRequestAction$1(sendRequest(MARK_EVENTS_AS_SEEN, {
3620
+ chat_id: chatId,
3621
+ seen_up_to: seenUpTo
3622
+ }));
3623
+ },
3624
+ on: emitter.on,
3625
+ once: emitter.once,
3626
+ off: emitter.off,
3627
+ rateChat: function rateChat(params) {
3628
+ var chatId = params.chatId,
3629
+ rating = params.rating;
3630
+ return api.listThreads({
3631
+ chatId: chatId
3632
+ }).then(function (_ref14) {
3633
+ var threads = _ref14.threads;
3634
+
3635
+ if (!threads.length) {
3636
+ throw createError({
3637
+ message: "There is no thread in \"" + chatId + "\".",
3638
+ code: MISSING_CHAT_THREAD
3639
+ });
3640
+ }
3641
+
3642
+ return api.updateThreadProperties({
3643
+ chatId: chatId,
3644
+ threadId: threads[0].id,
3645
+ properties: {
3646
+ rating: rating
3647
+ }
3648
+ });
3649
+ });
3650
+ },
3651
+ resumeChat: function resumeChat(data) {
3652
+ log({
3653
+ env: env,
3654
+ licenseId: config.licenseId,
3655
+ eventName: 'chat_started'
3656
+ });
3657
+ return sendRequestAction$1(sendRequest(RESUME_CHAT, parseResumeChatData(data)));
3658
+ },
3659
+ sendEvent: function (_sendEvent) {
3660
+ function sendEvent(_x) {
3661
+ return _sendEvent.apply(this, arguments);
3662
+ }
3663
+
3664
+ sendEvent.toString = function () {
3665
+ return _sendEvent.toString();
3666
+ };
3667
+
3668
+ return sendEvent;
3669
+ }(function (params) {
3670
+ return sendRequestAction$1(sendEvent(params));
3671
+ }),
3672
+ sendTicketForm: function sendTicketForm$1(options) {
3673
+ return sendTicketForm(store, auth, options);
3674
+ },
3675
+ sendRichMessagePostback: function sendRichMessagePostback(_ref15) {
3676
+ var chatId = _ref15.chatId,
3677
+ threadId = _ref15.threadId,
3678
+ eventId = _ref15.eventId,
3679
+ postback = _ref15.postback;
3680
+ return sendRequestAction$1(sendRequest(SEND_RICH_MESSAGE_POSTBACK, {
3681
+ chat_id: chatId,
3682
+ event_id: eventId,
3683
+ thread_id: threadId,
3684
+ postback: postback
3685
+ }));
3686
+ },
3687
+ setCustomerSessionFields: function setCustomerSessionFields(_ref16) {
3688
+ var sessionFields = _ref16.sessionFields;
3689
+ return sendRequestAction$1(sendRequest(SET_CUSTOMER_SESSION_FIELDS, {
3690
+ session_fields: parseCustomerSessionFields(sessionFields)
3691
+ }));
3692
+ },
3693
+ setSneakPeek: function setSneakPeek(_ref17) {
3694
+ var chatId = _ref17.chatId,
3695
+ sneakPeekText = _ref17.sneakPeekText;
3696
+ var state = store.getState();
3697
+
3698
+ if (!isChatActive(state, chatId) || !isConnected(state)) {
3699
+ return;
3700
+ }
3701
+
3702
+ sendRequestAction$1(sendRequest(SEND_SNEAK_PEEK, {
3703
+ chat_id: chatId,
3704
+ sneak_peek_text: sneakPeekText
3705
+ }))["catch"](dataUtils.noop);
3706
+ },
3707
+ startChat: function startChat(data) {
3708
+ if (data === void 0) {
3709
+ data = {};
3710
+ }
3711
+
3712
+ log({
3713
+ env: env,
3714
+ licenseId: config.licenseId,
3715
+ eventName: 'chat_started'
3716
+ });
3717
+ return sendRequestAction$1(sendRequest(START_CHAT, parseStartChatData(data)));
3718
+ },
3719
+ updateChatProperties: function updateChatProperties(_ref18) {
3720
+ var id = _ref18.id,
3721
+ properties = _ref18.properties;
3722
+ return sendRequestAction$1(sendRequest(UPDATE_CHAT_PROPERTIES, {
3723
+ id: id,
3724
+ properties: properties
3725
+ }));
3726
+ },
3727
+ updateCustomer: function updateCustomer(update) {
3728
+ return sendRequestAction$1(sendRequest(UPDATE_CUSTOMER, parseCustomerUpdate(update)));
3729
+ },
3730
+ updateCustomerPage: function updateCustomerPage(page) {
3731
+ store.dispatch({
3732
+ type: UPDATE_CUSTOMER_PAGE,
3733
+ payload: dataUtils.pickOwn(['title', 'url'], page)
3734
+ });
3735
+ },
3736
+ updateEventProperties: function updateEventProperties(_ref19) {
3737
+ var chatId = _ref19.chatId,
3738
+ threadId = _ref19.threadId,
3739
+ eventId = _ref19.eventId,
3740
+ properties = _ref19.properties;
3741
+ return sendRequestAction$1(sendRequest(UPDATE_EVENT_PROPERTIES, {
3742
+ chat_id: chatId,
3743
+ event_id: eventId,
3744
+ thread_id: threadId,
3745
+ properties: properties
3746
+ }));
3747
+ },
3748
+ updateThreadProperties: function updateThreadProperties(_ref20) {
3749
+ var chatId = _ref20.chatId,
3750
+ threadId = _ref20.threadId,
3751
+ properties = _ref20.properties;
3752
+ return sendRequestAction$1(sendRequest(UPDATE_THREAD_PROPERTIES, {
3753
+ chat_id: chatId,
3754
+ thread_id: threadId,
3755
+ properties: properties
3756
+ }));
3757
+ },
3758
+ uploadFile: function uploadFile$1(options) {
3759
+ return uploadFile({
3760
+ auth: auth,
3761
+ store: store
3762
+ }, options);
3763
+ }
3764
+ });
3765
+
3766
+ if (autoConnect) {
3767
+ startConnection();
3768
+ } else {
3769
+ store.dispatch({
3770
+ type: CHECK_GOALS,
3771
+ payload: {
3772
+ sessionFields: typeof customerDataProvider === 'function' ? customerDataProvider().sessionFields : {}
3773
+ }
3774
+ });
3775
+ }
3776
+
3777
+ return api;
3778
+ };
3779
+
3780
+ exports.debug = debug;
3781
+ exports.init = init;
3782
+ exports.parseCustomEvent = parseCustomEvent;
3783
+ exports.parseEvent = parseEvent$1;
3784
+ exports.parseFile = parseFile;
3785
+ exports.parseFilledForm = parseFilledForm;
3786
+ exports.parseForm = parseForm$1;
3787
+ exports.parseGreeting = parseGreeting;
3788
+ exports.parseMessage = parseMessage;
3789
+ exports.parseRichMessage = parseRichMessage;
3790
+ exports.parseSystemMessage = parseSystemMessage;