@opencx/widget 3.0.42 → 3.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/designs.cjs +51 -51
- package/dist/designs.cjs.map +1 -1
- package/dist/designs.js +3116 -3090
- package/dist/designs.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.js +2 -2
- package/dist/src/designs/translation/translation.types.d.ts +1 -1
- package/dist/src/headless/core/context/contact.ctx.d.ts +2 -1
- package/dist/src/headless/core/context/message.ctx.d.ts +8 -3
- package/dist/src/headless/core/index.d.ts +1 -1
- package/dist/src/headless/core/types/helpers.d.ts +0 -2
- package/dist/src/headless/core/types/widget-config.d.ts +67 -15
- package/dist/src/headless/react/hooks/useContact.d.ts +2 -1
- package/dist/src/headless/react/hooks/useMessages.d.ts +4 -1
- package/dist/{useUploadFiles-BmEispgd.js → useUploadFiles-BPZLXbFK.js} +3 -3
- package/dist/{useUploadFiles-BmEispgd.js.map → useUploadFiles-BPZLXbFK.js.map} +1 -1
- package/dist/{useUploadFiles-eYRjtkaZ.cjs → useUploadFiles-Bt32Tf5N.cjs} +2 -2
- package/dist/{useUploadFiles-eYRjtkaZ.cjs.map → useUploadFiles-Bt32Tf5N.cjs.map} +1 -1
- package/dist/{widget.ctx-DIcAO9ZA.js → widget.ctx-Db_LSB7d.js} +81 -64
- package/dist/widget.ctx-Db_LSB7d.js.map +1 -0
- package/dist/widget.ctx-Z3nrC8tP.cjs +5 -0
- package/dist/widget.ctx-Z3nrC8tP.cjs.map +1 -0
- package/dist-embed/script.js +43 -40
- package/dist-embed/script.js.map +1 -1
- package/package.json +1 -1
- package/dist/widget.ctx-DB_VxiMQ.cjs +0 -2
- package/dist/widget.ctx-DB_VxiMQ.cjs.map +0 -1
- package/dist/widget.ctx-DIcAO9ZA.js.map +0 -1
|
@@ -17,7 +17,7 @@ const O = (o) => {
|
|
|
17
17
|
};
|
|
18
18
|
return t.use(e), t;
|
|
19
19
|
};
|
|
20
|
-
class
|
|
20
|
+
class P {
|
|
21
21
|
constructor({
|
|
22
22
|
config: t
|
|
23
23
|
}) {
|
|
@@ -114,7 +114,7 @@ class b {
|
|
|
114
114
|
this.client = this.createOpenAPIClient({ baseUrl: e, headers: i }), this.uploadFileClient = this.createAxiosUploadClient({ baseUrl: e, headers: i });
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
class
|
|
117
|
+
class f {
|
|
118
118
|
constructor(t) {
|
|
119
119
|
s(this, "subscribers", /* @__PURE__ */ new Set());
|
|
120
120
|
s(this, "state");
|
|
@@ -148,7 +148,7 @@ class C {
|
|
|
148
148
|
}
|
|
149
149
|
class k {
|
|
150
150
|
constructor() {
|
|
151
|
-
s(this, "state", new
|
|
151
|
+
s(this, "state", new f({
|
|
152
152
|
isPolling: !1,
|
|
153
153
|
isError: !1
|
|
154
154
|
}));
|
|
@@ -179,7 +179,7 @@ class k {
|
|
|
179
179
|
});
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
-
class
|
|
182
|
+
class D {
|
|
183
183
|
constructor({
|
|
184
184
|
api: t,
|
|
185
185
|
config: e,
|
|
@@ -267,7 +267,7 @@ class L {
|
|
|
267
267
|
this.api = t, this.config = e, this.sessionCtx = i, this.messageCtx = a, this.sessionPollingIntervalSeconds = n, this.registerPolling();
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
-
class
|
|
270
|
+
class L {
|
|
271
271
|
constructor({
|
|
272
272
|
config: t,
|
|
273
273
|
api: e,
|
|
@@ -282,34 +282,37 @@ class B {
|
|
|
282
282
|
return !!(!((t = this.state.get().contact) != null && t.token) && this.config.collectUserData);
|
|
283
283
|
});
|
|
284
284
|
s(this, "autoCreateUnverifiedUserIfNotExists", async () => {
|
|
285
|
-
var t, e, i, a, n, r, l, d, u, p, S;
|
|
285
|
+
var t, e, i, a, n, r, l, d, u, p, m, S;
|
|
286
286
|
if (!((t = this.config.user) != null && t.token)) {
|
|
287
287
|
if (this.config.collectUserData && !((i = (e = this.config.user) == null ? void 0 : e.data) != null && i.email)) {
|
|
288
|
-
|
|
288
|
+
if ((a = this.config.extraDataCollectionFields) != null && a.length)
|
|
289
|
+
return;
|
|
290
|
+
const g = await ((n = this.storageCtx) == null ? void 0 : n.getContactToken());
|
|
289
291
|
g && await this.setUnverifiedContact(g);
|
|
290
292
|
return;
|
|
291
293
|
}
|
|
292
|
-
if (!((
|
|
293
|
-
const g = await ((
|
|
294
|
+
if (!((l = (r = this.config.user) == null ? void 0 : r.data) != null && l.email)) {
|
|
295
|
+
const g = await ((d = this.storageCtx) == null ? void 0 : d.getContactToken());
|
|
294
296
|
if (g) {
|
|
295
297
|
await this.setUnverifiedContact(g);
|
|
296
298
|
return;
|
|
297
299
|
}
|
|
298
300
|
}
|
|
299
301
|
await this.createUnverifiedContact({
|
|
300
|
-
name: ((
|
|
301
|
-
email: (S = (
|
|
302
|
+
name: ((p = (u = this.config.user) == null ? void 0 : u.data) == null ? void 0 : p.name) || "Anonymous",
|
|
303
|
+
email: (S = (m = this.config.user) == null ? void 0 : m.data) == null ? void 0 : S.email
|
|
302
304
|
});
|
|
303
305
|
}
|
|
304
306
|
});
|
|
305
|
-
s(this, "createUnverifiedContact", async (t) => {
|
|
307
|
+
s(this, "createUnverifiedContact", async (t, e) => {
|
|
308
|
+
this.state.setPartial({ extraCollectedData: e });
|
|
306
309
|
try {
|
|
307
310
|
this.state.setPartial({
|
|
308
311
|
isCreatingUnverifiedContact: !0,
|
|
309
312
|
isErrorCreatingUnverifiedContact: !1
|
|
310
313
|
});
|
|
311
|
-
const { data:
|
|
312
|
-
|
|
314
|
+
const { data: i } = await this.api.createUnverifiedContact(t);
|
|
315
|
+
i != null && i.token ? await this.setUnverifiedContact(i.token) : this.state.setPartial({ isErrorCreatingUnverifiedContact: !0 });
|
|
313
316
|
} finally {
|
|
314
317
|
this.state.setPartial({ isCreatingUnverifiedContact: !1 });
|
|
315
318
|
}
|
|
@@ -320,21 +323,22 @@ class B {
|
|
|
320
323
|
this.api.setAuthToken(t), await ((r = this.storageCtx) == null ? void 0 : r.setContactToken(t)), await ((l = this.storageCtx) == null ? void 0 : l.setExternalContactId(i)), this.state.setPartial({ contact: { token: t, externalId: i } });
|
|
321
324
|
});
|
|
322
325
|
var a;
|
|
323
|
-
this.config = t, this.storageCtx = i, this.api = e, this.state = new
|
|
326
|
+
this.config = t, this.storageCtx = i, this.api = e, this.state = new f({
|
|
324
327
|
contact: (a = t.user) != null && a.token ? {
|
|
325
328
|
token: t.user.token,
|
|
326
329
|
// Set optional externalId from config... not local storage
|
|
327
330
|
externalId: t.user.externalId
|
|
328
331
|
} : null,
|
|
332
|
+
extraCollectedData: void 0,
|
|
329
333
|
isCreatingUnverifiedContact: !1,
|
|
330
334
|
isErrorCreatingUnverifiedContact: !1
|
|
331
335
|
}), this.autoCreateUnverifiedUserIfNotExists();
|
|
332
336
|
}
|
|
333
337
|
}
|
|
334
|
-
function
|
|
338
|
+
function w() {
|
|
335
339
|
return y();
|
|
336
340
|
}
|
|
337
|
-
class
|
|
341
|
+
class B {
|
|
338
342
|
constructor({
|
|
339
343
|
api: t,
|
|
340
344
|
contactCtx: e,
|
|
@@ -344,11 +348,11 @@ class D {
|
|
|
344
348
|
s(this, "contactCtx");
|
|
345
349
|
s(this, "sessionsPollingIntervalSeconds");
|
|
346
350
|
s(this, "sessionsRefresher", new k());
|
|
347
|
-
s(this, "sessionState", new
|
|
351
|
+
s(this, "sessionState", new f({
|
|
348
352
|
session: null,
|
|
349
353
|
isCreatingSession: !1
|
|
350
354
|
}));
|
|
351
|
-
s(this, "sessionsState", new
|
|
355
|
+
s(this, "sessionsState", new f({
|
|
352
356
|
data: [],
|
|
353
357
|
cursor: void 0,
|
|
354
358
|
isLastPage: !1,
|
|
@@ -426,12 +430,14 @@ class q {
|
|
|
426
430
|
constructor({
|
|
427
431
|
config: t,
|
|
428
432
|
api: e,
|
|
429
|
-
sessionCtx: i
|
|
433
|
+
sessionCtx: i,
|
|
434
|
+
contactCtx: a
|
|
430
435
|
}) {
|
|
431
436
|
s(this, "config");
|
|
432
437
|
s(this, "api");
|
|
438
|
+
s(this, "contactCtx");
|
|
433
439
|
s(this, "sessionCtx");
|
|
434
|
-
s(this, "state", new
|
|
440
|
+
s(this, "state", new f({
|
|
435
441
|
messages: [],
|
|
436
442
|
isSendingMessage: !1,
|
|
437
443
|
lastAIResMightSolveUserIssue: !1,
|
|
@@ -442,7 +448,7 @@ class q {
|
|
|
442
448
|
this.sendMessageAbortController.abort("Resetting chat"), this.state.reset();
|
|
443
449
|
});
|
|
444
450
|
s(this, "sendMessage", async (t) => {
|
|
445
|
-
var n, r, l, d, u, p, S, g
|
|
451
|
+
var n, r, l, d, u, p, m, S, g;
|
|
446
452
|
if (!t.content.trim() && (!t.attachments || t.attachments.length === 0)) {
|
|
447
453
|
console.warn("Cannot send an empty message of no content or attachments");
|
|
448
454
|
return;
|
|
@@ -456,12 +462,12 @@ class q {
|
|
|
456
462
|
this.sendMessageAbortController = new AbortController(), this.state.setPartial({ lastAIResMightSolveUserIssue: !1 });
|
|
457
463
|
try {
|
|
458
464
|
this.state.setPartial({ isSendingMessage: !0 });
|
|
459
|
-
const
|
|
465
|
+
const x = this.toUserMessage(
|
|
460
466
|
t.content.trim(),
|
|
461
467
|
t.attachments || void 0
|
|
462
468
|
), A = this.state.get().messages;
|
|
463
469
|
if (this.state.setPartial({
|
|
464
|
-
messages: [...A,
|
|
470
|
+
messages: [...A, x]
|
|
465
471
|
}), !((r = this.sessionCtx.sessionState.get().session) != null && r.id)) {
|
|
466
472
|
if (!await this.sessionCtx.createSession()) {
|
|
467
473
|
console.error("Failed to create session");
|
|
@@ -469,26 +475,27 @@ class q {
|
|
|
469
475
|
}
|
|
470
476
|
this.sessionCtx.refreshSessions();
|
|
471
477
|
}
|
|
472
|
-
const
|
|
473
|
-
if (!
|
|
478
|
+
const b = (l = this.sessionCtx.sessionState.get().session) == null ? void 0 : l.id;
|
|
479
|
+
if (!b) return;
|
|
474
480
|
const { data: c } = await this.api.sendMessage(
|
|
475
481
|
{
|
|
476
|
-
uuid:
|
|
482
|
+
uuid: x.id,
|
|
477
483
|
bot_token: this.config.token,
|
|
478
484
|
headers: this.config.headers,
|
|
479
485
|
query_params: this.config.queryParams,
|
|
480
|
-
session_id:
|
|
486
|
+
session_id: b,
|
|
481
487
|
user: (d = this.config.user) == null ? void 0 : d.data,
|
|
482
|
-
|
|
488
|
+
content: x.content,
|
|
489
|
+
attachments: t.attachments
|
|
483
490
|
},
|
|
484
491
|
this.sendMessageAbortController.signal
|
|
485
492
|
);
|
|
486
493
|
if (c != null && c.success) {
|
|
487
|
-
const
|
|
488
|
-
if (
|
|
489
|
-
const
|
|
490
|
-
if (!!
|
|
491
|
-
(U) => U.id ===
|
|
494
|
+
const C = this.toBotMessage(c);
|
|
495
|
+
if (C) {
|
|
496
|
+
const v = this.state.get().messages;
|
|
497
|
+
if (!!v.some(
|
|
498
|
+
(U) => U.id === C.id
|
|
492
499
|
)) {
|
|
493
500
|
this.state.setPartial({
|
|
494
501
|
lastAIResMightSolveUserIssue: ((u = c.autopilotResponse) == null ? void 0 : u.mightSolveUserIssue) || ((p = c.uiResponse) == null ? void 0 : p.mightSolveUserIssue)
|
|
@@ -496,37 +503,46 @@ class q {
|
|
|
496
503
|
return;
|
|
497
504
|
}
|
|
498
505
|
this.state.setPartial({
|
|
499
|
-
messages: [...
|
|
500
|
-
lastAIResMightSolveUserIssue: ((
|
|
506
|
+
messages: [...v, C],
|
|
507
|
+
lastAIResMightSolveUserIssue: ((m = c.autopilotResponse) == null ? void 0 : m.mightSolveUserIssue) || ((S = c.uiResponse) == null ? void 0 : S.mightSolveUserIssue)
|
|
501
508
|
});
|
|
502
509
|
}
|
|
503
510
|
} else {
|
|
504
|
-
const
|
|
505
|
-
((
|
|
506
|
-
),
|
|
511
|
+
const C = this.toBotErrorMessage(
|
|
512
|
+
((g = c == null ? void 0 : c.error) == null ? void 0 : g.message) || "Unknown error occurred"
|
|
513
|
+
), v = this.state.get().messages;
|
|
507
514
|
this.state.setPartial({
|
|
508
|
-
messages: [...
|
|
515
|
+
messages: [...v, C]
|
|
509
516
|
});
|
|
510
517
|
}
|
|
511
|
-
} catch (
|
|
512
|
-
this.sendMessageAbortController.signal.aborted || console.error("Failed to send message:",
|
|
518
|
+
} catch (x) {
|
|
519
|
+
this.sendMessageAbortController.signal.aborted || console.error("Failed to send message:", x);
|
|
513
520
|
} finally {
|
|
514
521
|
this.state.setPartial({ isSendingMessage: !1 });
|
|
515
522
|
}
|
|
516
523
|
});
|
|
517
|
-
s(this, "toUserMessage", (t, e) =>
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
524
|
+
s(this, "toUserMessage", (t, e) => {
|
|
525
|
+
const i = (() => {
|
|
526
|
+
const a = this.contactCtx.state.get().extraCollectedData;
|
|
527
|
+
return this.state.get().messages.length === 0 && a && Object.keys(a).length > 0 ? `${Object.entries(a).filter(([r, l]) => !!l).map(([r, l]) => `${r}: ${l}`).join(`
|
|
528
|
+
`)}
|
|
529
|
+
|
|
530
|
+
${t}` : t;
|
|
531
|
+
})();
|
|
532
|
+
return {
|
|
533
|
+
id: w(),
|
|
534
|
+
type: "FROM_USER",
|
|
535
|
+
content: i,
|
|
536
|
+
deliveredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
537
|
+
attachments: e,
|
|
538
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
539
|
+
};
|
|
540
|
+
});
|
|
525
541
|
s(this, "toBotMessage", (t) => {
|
|
526
542
|
var e;
|
|
527
543
|
return t.success && t.autopilotResponse ? {
|
|
528
544
|
type: "FROM_BOT",
|
|
529
|
-
id: t.autopilotResponse.id ||
|
|
545
|
+
id: t.autopilotResponse.id || w(),
|
|
530
546
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
531
547
|
component: "bot_message",
|
|
532
548
|
agent: this.config.bot ? {
|
|
@@ -546,7 +562,7 @@ class q {
|
|
|
546
562
|
});
|
|
547
563
|
s(this, "toBotErrorMessage", (t) => ({
|
|
548
564
|
type: "FROM_BOT",
|
|
549
|
-
id:
|
|
565
|
+
id: w(),
|
|
550
566
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
551
567
|
component: "TEXT",
|
|
552
568
|
data: {
|
|
@@ -555,10 +571,10 @@ class q {
|
|
|
555
571
|
action: void 0
|
|
556
572
|
}
|
|
557
573
|
}));
|
|
558
|
-
this.config = t, this.api = e, this.sessionCtx = i;
|
|
574
|
+
this.config = t, this.api = e, this.sessionCtx = i, this.contactCtx = a;
|
|
559
575
|
}
|
|
560
576
|
}
|
|
561
|
-
class
|
|
577
|
+
class $ {
|
|
562
578
|
constructor({
|
|
563
579
|
contactCtx: t,
|
|
564
580
|
sessionCtx: e,
|
|
@@ -587,12 +603,12 @@ class G {
|
|
|
587
603
|
}
|
|
588
604
|
this.state.setPartial({ screen: "chat" });
|
|
589
605
|
});
|
|
590
|
-
this.state = new
|
|
606
|
+
this.state = new f({
|
|
591
607
|
screen: t.shouldCollectData() ? "welcome" : "sessions"
|
|
592
608
|
}), this.contactCtx = t, this.sessionCtx = e, this.resetChat = i, this.registerRoutingListener();
|
|
593
609
|
}
|
|
594
610
|
}
|
|
595
|
-
class
|
|
611
|
+
class j {
|
|
596
612
|
constructor({ storage: t }) {
|
|
597
613
|
s(this, "storage");
|
|
598
614
|
s(this, "KEYS", {
|
|
@@ -630,25 +646,26 @@ const h = class h {
|
|
|
630
646
|
throw Error(
|
|
631
647
|
"Widget polling values are not defined, did you call WidgetCtx.initialize()"
|
|
632
648
|
);
|
|
633
|
-
this.config = t, this.api = new
|
|
649
|
+
this.config = t, this.api = new P({ config: t }), this.storageCtx = e ? new j({ storage: e }) : void 0, this.contactCtx = new L({
|
|
634
650
|
api: this.api,
|
|
635
651
|
config: this.config,
|
|
636
652
|
storageCtx: this.storageCtx
|
|
637
|
-
}), this.sessionCtx = new
|
|
653
|
+
}), this.sessionCtx = new B({
|
|
638
654
|
api: this.api,
|
|
639
655
|
contactCtx: this.contactCtx,
|
|
640
656
|
sessionsPollingIntervalSeconds: h.pollingIntervalsSeconds.sessions
|
|
641
657
|
}), this.messageCtx = new q({
|
|
642
658
|
config: this.config,
|
|
643
659
|
api: this.api,
|
|
644
|
-
sessionCtx: this.sessionCtx
|
|
645
|
-
|
|
660
|
+
sessionCtx: this.sessionCtx,
|
|
661
|
+
contactCtx: this.contactCtx
|
|
662
|
+
}), this.activeSessionPollingCtx = new D({
|
|
646
663
|
api: this.api,
|
|
647
664
|
config: this.config,
|
|
648
665
|
sessionCtx: this.sessionCtx,
|
|
649
666
|
messageCtx: this.messageCtx,
|
|
650
667
|
sessionPollingIntervalSeconds: h.pollingIntervalsSeconds.session
|
|
651
|
-
}), this.routerCtx = new
|
|
668
|
+
}), this.routerCtx = new $({
|
|
652
669
|
contactCtx: this.contactCtx,
|
|
653
670
|
sessionCtx: this.sessionCtx,
|
|
654
671
|
resetChat: this.resetChat
|
|
@@ -660,7 +677,7 @@ s(h, "pollingIntervalsSeconds", null), s(h, "initialize", async ({
|
|
|
660
677
|
storage: e
|
|
661
678
|
}) => {
|
|
662
679
|
var a, n;
|
|
663
|
-
const i = await new
|
|
680
|
+
const i = await new P({
|
|
664
681
|
config: t
|
|
665
682
|
}).getExternalWidgetConfig();
|
|
666
683
|
return h.pollingIntervalsSeconds = {
|
|
@@ -673,7 +690,7 @@ s(h, "pollingIntervalsSeconds", null), s(h, "initialize", async ({
|
|
|
673
690
|
});
|
|
674
691
|
let I = h;
|
|
675
692
|
export {
|
|
676
|
-
|
|
693
|
+
f as P,
|
|
677
694
|
I as W
|
|
678
695
|
};
|
|
679
|
-
//# sourceMappingURL=widget.ctx-
|
|
696
|
+
//# sourceMappingURL=widget.ctx-Db_LSB7d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget.ctx-Db_LSB7d.js","sources":["../src/headless/core/api/client.ts","../src/headless/core/api/api-caller.ts","../src/headless/core/utils/PrimitiveState.ts","../src/headless/core/utils/Poller.ts","../src/headless/core/context/active-session-polling.ctx.ts","../src/headless/core/context/contact.ctx.ts","../src/headless/core/utils/uuid.ts","../src/headless/core/context/session.ctx.ts","../src/headless/core/context/message.ctx.ts","../src/headless/core/context/router.ctx.ts","../src/headless/core/context/storage.ctx.ts","../src/headless/core/context/widget.ctx.ts"],"sourcesContent":["import createClient, { type Middleware } from \"openapi-fetch\";\nimport type { paths } from \"./schema\";\nimport type { components } from \"./schema\";\n\ntype Options = {\n baseUrl: string;\n onRequest?: Middleware[\"onRequest\"];\n onResponse?: Middleware[\"onResponse\"];\n onError?: Middleware[\"onError\"];\n};\n\nconst defaultOnError: Middleware[\"onError\"] = (onErrorOptions) => {\n console.log(onErrorOptions.error);\n};\n\nexport const basicClient = (options: Options) => {\n const client = createClient<paths>({\n baseUrl: options.baseUrl,\n });\n\n const middlewares: Middleware = {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n onError: options.onError || defaultOnError,\n };\n\n client.use(middlewares);\n return client;\n};\n\nexport type Endpoint = keyof paths;\nexport type Dto = components[\"schemas\"];\n","import axios, { type AxiosInstance, type AxiosRequestConfig } from \"axios\";\nimport { type Dto, type Endpoint, basicClient } from \"./client\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport type { SendMessageDto, VoteInputDto } from \"../types/schemas\";\n\nexport class ApiCaller {\n private client: ReturnType<typeof basicClient>;\n private uploadFileClient: AxiosInstance;\n private config: WidgetConfig;\n\n constructor({\n config,\n }: {\n config: WidgetConfig;\n }) {\n this.config = config;\n const { baseUrl, headers } = this.constructClientOptions(\n config.user?.token,\n );\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n this.uploadFileClient = this.createAxiosUploadClient({ baseUrl, headers });\n }\n\n private constructClientOptions = (token: string | null | undefined) => {\n const baseUrl =\n import.meta.env.MODE === \"test\"\n ? \"http://localhost:8080\"\n : this.config.apiUrl || \"https://api.open.cx\";\n const headers = {\n \"X-Bot-Token\": this.config.token,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: token ? `Bearer ${token}` : undefined,\n };\n\n return { baseUrl, headers };\n };\n\n private createOpenAPIClient = ({\n baseUrl,\n headers,\n }: ReturnType<typeof this.constructClientOptions>) => {\n return basicClient({\n baseUrl,\n onRequest: ({ request }) => {\n Object.entries(headers).forEach(([key, value]) => {\n if (value) {\n request.headers.set(key, value);\n }\n });\n },\n });\n };\n private createAxiosUploadClient = ({\n baseUrl,\n headers,\n }: ReturnType<typeof this.constructClientOptions>) => {\n const uploadPath = \"/backend/widget/v2/upload\" satisfies Endpoint;\n return axios.create({\n baseURL: `${baseUrl}${uploadPath}`,\n headers,\n });\n };\n\n setAuthToken = (token: string) => {\n const { baseUrl, headers } = this.constructClientOptions(token);\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n this.uploadFileClient = this.createAxiosUploadClient({ baseUrl, headers });\n };\n\n getExternalWidgetConfig = async () => {\n return await this.client.GET(\"/backend/widget/v2/config\", {\n params: { header: { \"X-Bot-Token\": this.config.token } },\n });\n };\n\n widgetPrelude = async () => {\n return await this.client.GET(\"/backend/widget/v2/prelude\", {\n params: { header: { \"X-Bot-Token\": this.config.token } },\n });\n };\n\n sendMessage = async (body: SendMessageDto, abortSignal?: AbortSignal) => {\n return await this.client.POST(\"/backend/widget/v2/chat/send\", {\n body,\n signal: abortSignal,\n });\n };\n\n createUnverifiedContact = async (body: Dto[\"CreateUnverifiedContactDto\"]) => {\n return await this.client.POST(\n \"/backend/widget/v2/contact/create-unverified\",\n {\n params: { header: { \"x-bot-token\": this.config.token } },\n body,\n },\n );\n };\n\n createSession = async (body: Dto[\"CreateWidgetSessionDto\"]) => {\n return await this.client.POST(\"/backend/widget/v2/create-session\", {\n body,\n });\n };\n\n pollSessionAndHistory = async ({\n sessionId,\n lastMessageTimestamp,\n abortSignal,\n }: {\n sessionId: string;\n lastMessageTimestamp?: string;\n abortSignal: AbortSignal;\n }) => {\n const query = lastMessageTimestamp ? { lastMessageTimestamp } : undefined;\n return await this.client.GET(\"/backend/widget/v2/poll/{sessionId}\", {\n params: { path: { sessionId }, query },\n signal: abortSignal,\n });\n };\n\n getSessions = async ({\n cursor,\n filters,\n abortSignal,\n }: {\n cursor: string | undefined;\n filters: Record<string, string>;\n abortSignal?: AbortSignal;\n }) => {\n return await this.client.GET(\"/backend/widget/v2/sessions\", {\n params: { query: { cursor, filters: JSON.stringify(filters) } },\n signal: abortSignal,\n });\n };\n\n uploadFile = async (\n file: {\n id: string;\n file: File;\n },\n config: Partial<AxiosRequestConfig> = {},\n ) => {\n const formData = new FormData();\n formData.append(\"file\", file.file);\n\n // Couldn't get this to work with the openapi client... dunno why...\n const { data } = await this.uploadFileClient.post<\n Dto[\"UploadWidgetFileResponseDto\"]\n >(\"\", formData, {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n ...config,\n });\n return data;\n };\n\n vote = async (body: VoteInputDto) => {\n return await this.client.POST(\"/backend/widget/v2/chat/vote\", { body });\n };\n}\n","import isEqual from \"lodash.isequal\";\n\nexport type Subscriber<T> = (data: T) => void;\n\nexport class PrimitiveState<S> {\n private subscribers = new Set<Subscriber<S>>();\n private state: S;\n private initialState: S;\n\n constructor(state: S) {\n this.state = state;\n this.initialState = state;\n }\n\n get = (): S => this.state;\n\n set = (newState: S): void => {\n if (!isEqual(this.state, newState)) {\n this.state = newState;\n this.notifySubscribers(newState);\n }\n };\n\n setPartial = (_s: Partial<S>): void => {\n if (_s === undefined || _s === null) return;\n const newState = { ...this.state, ..._s };\n this.set(newState);\n };\n\n reset = (): void => {\n this.set(this.initialState);\n };\n\n private notifySubscribers = (state: S) => {\n const subscribersArray = Array.from(this.subscribers);\n subscribersArray.forEach((callback) => {\n try {\n callback(state);\n } catch (error) {\n if (import.meta.env.MODE !== \"test\") {\n console.error(error);\n }\n }\n });\n };\n\n subscribe = (callback: Subscriber<S>): (() => void) => {\n this.subscribers.add(callback);\n\n return () => {\n this.subscribers.delete(callback);\n };\n };\n}\n","import { PrimitiveState } from \"./PrimitiveState\";\n\nexport type PollingState = {\n isPolling: boolean;\n isError: boolean;\n};\n\nexport class Poller {\n state = new PrimitiveState<PollingState>({\n isPolling: false,\n isError: false,\n });\n private abortController = new AbortController();\n\n reset = () => {\n this.abortController.abort(\"Resetting poller\");\n this.stopPolling?.();\n this.stopPolling = null;\n };\n\n private stopPolling: (() => void) | null = null;\n\n startPolling = (\n cb: (abortSignal: AbortSignal) => Promise<void>,\n intervalMs: number,\n ) => {\n if (this.stopPolling) return;\n\n const timeouts: NodeJS.Timeout[] = [];\n\n const poll = async () => {\n this.abortController = new AbortController();\n this.state.setPartial({ isPolling: true });\n\n try {\n await cb(this.abortController.signal);\n } catch (error) {\n if (this.abortController.signal.aborted) {\n // If aborted, just return and do not schedule the nest poll\n return;\n }\n console.error(\"Failed to poll:\", error);\n this.state.setPartial({ isError: true });\n } finally {\n this.state.setPartial({ isPolling: false });\n }\n\n // Another check to stop scheduling polls in case someone removes the early return in the catch above\n if (this.abortController.signal.aborted) {\n console.log(\"Poller aborted, not scheduling anymore\");\n } else {\n timeouts.push(setTimeout(poll, intervalMs));\n }\n };\n\n poll();\n\n this.stopPolling = () => {\n timeouts.forEach(clearTimeout);\n this.state.reset();\n };\n };\n}\n","import type { ApiCaller } from \"../api/api-caller\";\nimport type { MessageType } from \"../types/messages\";\nimport type { MessageDto } from \"../types/schemas\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport { Poller } from \"../utils/Poller\";\nimport type { MessageCtx } from \"./message.ctx\";\nimport type { SessionCtx } from \"./session.ctx\";\n\nexport class ActiveSessionPollingCtx {\n private api: ApiCaller;\n private config: WidgetConfig;\n private sessionCtx: SessionCtx;\n private messageCtx: MessageCtx;\n private sessionPollingIntervalSeconds: number;\n\n private poller = new Poller();\n\n constructor({\n api,\n config,\n sessionCtx,\n messageCtx,\n sessionPollingIntervalSeconds,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n sessionCtx: SessionCtx;\n messageCtx: MessageCtx;\n sessionPollingIntervalSeconds: number;\n }) {\n this.api = api;\n this.config = config;\n this.sessionCtx = sessionCtx;\n this.messageCtx = messageCtx;\n this.sessionPollingIntervalSeconds = sessionPollingIntervalSeconds;\n\n this.registerPolling();\n }\n\n private registerPolling = () => {\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (session?.id) {\n this.poller.startPolling(async (abortSignal) => {\n this.hackAndSlash(session.id, abortSignal);\n }, this.sessionPollingIntervalSeconds * 1000);\n } else {\n this.poller.reset();\n }\n });\n };\n\n private hackAndSlash = async (\n sessionId: string,\n abortSignal: AbortSignal,\n ): Promise<void> => {\n /**\n * This is a bit of an implicit contract... there are two cases here\n * 1. If there are no messages in state, it means the user selected a previous session from the sessions screen and got routed to the chat,\n * in this case, we want to show a loading indicator until the initial fetch is done\n * 2. There is a single message in state, which is the optimistically rendered user message,\n * in this case, we don't want to show a loading indicator\n */\n if (this.messageCtx.state.get().messages.length === 0) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: true });\n }\n\n const lastMessageTimestamp = this.messageCtx.state\n .get()\n .messages.at(-1)?.timestamp;\n\n const { data } = await this.api.pollSessionAndHistory({\n sessionId,\n abortSignal,\n lastMessageTimestamp,\n });\n\n if (data?.session) {\n this.sessionCtx.sessionState.setPartial({ session: data.session });\n }\n\n if (data?.history && data.history.length > 0) {\n // Get a fresh reference to current messages after the poll is done\n const prevMessages = this.messageCtx.state.get().messages;\n const newMessages = data.history\n .map(this.mapHistoryToMessage)\n .filter(\n (newMsg) =>\n !prevMessages.some((existingMsg) => existingMsg.id === newMsg.id),\n );\n this.messageCtx.state.setPartial({\n messages: [...prevMessages, ...newMessages],\n });\n }\n\n if (this.messageCtx.state.get().isInitialFetchLoading) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: false });\n }\n };\n\n mapHistoryToMessage = (history: MessageDto): MessageType => {\n const commonFields = {\n id: history.publicId,\n timestamp: history.sentAt || \"\",\n attachments: history.attachments || undefined,\n };\n\n if (history.sender.kind === \"user\") {\n return {\n ...commonFields,\n type: \"FROM_USER\",\n content: history.content.text || \"\",\n deliveredAt: history.sentAt || \"\",\n };\n }\n\n if (history.sender.kind === \"agent\") {\n return {\n ...commonFields,\n type: \"FROM_AGENT\",\n component: \"agent_message\",\n data: {\n message: history.content.text || \"\",\n },\n agent: {\n name: history.sender.name || \"\",\n avatar: history.sender.avatar || \"\",\n id: null,\n isAi: false,\n },\n };\n }\n\n const action = history.actionCalls?.at(-1);\n return {\n ...commonFields,\n type: \"FROM_BOT\",\n component: \"bot_message\",\n agent: {\n id: null,\n name: this.config.bot?.name || \"\",\n isAi: true,\n avatar: this.config.bot?.avatar || \"\",\n },\n data: {\n message: history.content.text || \"\",\n action: action\n ? { name: action.actionName, data: action.result }\n : undefined,\n },\n };\n };\n}\n","import { PrimitiveState } from \"../utils/PrimitiveState\";\nimport { ApiCaller } from \"../api/api-caller\";\nimport { type WidgetConfig } from \"../types/widget-config\";\nimport { type Dto } from \"../api/client\";\nimport type { StorageCtx } from \"./storage.ctx\";\nimport { v4 } from \"uuid\";\n\ntype ContactState = {\n contact: {\n token: string;\n externalId: string | undefined;\n } | null;\n extraCollectedData: Record<string, string> | undefined;\n isCreatingUnverifiedContact: boolean;\n isErrorCreatingUnverifiedContact: boolean;\n};\n\nexport class ContactCtx {\n private config: WidgetConfig;\n private storageCtx?: StorageCtx;\n private api: ApiCaller;\n state: PrimitiveState<ContactState>;\n\n constructor({\n config,\n api,\n storageCtx,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n storageCtx?: StorageCtx;\n }) {\n this.config = config;\n this.storageCtx = storageCtx;\n this.api = api;\n\n this.state = new PrimitiveState<ContactState>({\n contact: config.user?.token\n ? {\n token: config.user.token,\n // Set optional externalId from config... not local storage\n externalId: config.user.externalId,\n }\n : null,\n extraCollectedData: undefined,\n isCreatingUnverifiedContact: false,\n isErrorCreatingUnverifiedContact: false,\n });\n\n this.autoCreateUnverifiedUserIfNotExists();\n }\n\n shouldCollectData = (): boolean => {\n if (!this.state.get().contact?.token && this.config.collectUserData) {\n return true;\n }\n return false;\n };\n\n private autoCreateUnverifiedUserIfNotExists = async () => {\n /**\n * If token is passed in config... we consider it as a verified user and do nothing (we don't force generate an externalId)\n * If a non-verified user take their token and place it in the config... the backend will refuse their requests saying that a non-verified token must have an externalId to create and get sessions\n */\n if (this.config.user?.token) return;\n\n /**\n * If collectUserData is true... we check if the user entered their credentials before, otherwise, show them the welcome screen so they can enter their credentials\n */\n if (this.config.collectUserData && !this.config.user?.data?.email) {\n /**\n * If extra data collection fields are passed,\n * we do not check for a persisted token.\n * This will force the contact to enter the extra data fields every time they visit the page.\n */\n if (this.config.extraDataCollectionFields?.length) {\n return;\n }\n\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n }\n // return early whether there is a persisted token or not\n return;\n }\n\n /**\n * If there is no email, then it is an anonymous contact, we check if the contact is persisted or we create a new one\n */\n if (!this.config.user?.data?.email) {\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n // return early only if there is a persisted token\n return;\n }\n }\n\n /**\n * If we reach here... then it is one of two\n * 1. There is an email passed in the config, let's just upsert the unverified contact without checking for persistence; maybe the email in the config did change.\n * 2. It is an anonymous contact (without an email) using this device for the first time.\n *\n * This is still safe even if the email in the config is tampered with by the contact, because there is a client-side externalId that will be generated for the current device...\n * So, only sessions created on this device will be accessible.\n */\n await this.createUnverifiedContact({\n name: this.config.user?.data?.name || \"Anonymous\",\n email: this.config.user?.data?.email,\n });\n };\n\n createUnverifiedContact = async (\n payload: Dto[\"CreateUnverifiedContactDto\"],\n extraCollectedData?: Record<string, string>,\n ): Promise<void> => {\n this.state.setPartial({ extraCollectedData });\n\n try {\n this.state.setPartial({\n isCreatingUnverifiedContact: true,\n isErrorCreatingUnverifiedContact: false,\n });\n\n const { data } = await this.api.createUnverifiedContact(payload);\n if (data?.token) {\n await this.setUnverifiedContact(data.token);\n } else {\n this.state.setPartial({ isErrorCreatingUnverifiedContact: true });\n }\n } finally {\n this.state.setPartial({ isCreatingUnverifiedContact: false });\n }\n };\n\n setUnverifiedContact = async (token: string) => {\n const persistedExternalId = await this.storageCtx?.getExternalContactId();\n /** Give priority to `externalId` from the config */\n const externalId: string =\n this.config.user?.externalId || persistedExternalId || v4();\n this.api.setAuthToken(token);\n // Set token in state after setting the token in the api handler\n await this.storageCtx?.setContactToken(token);\n await this.storageCtx?.setExternalContactId(externalId);\n this.state.setPartial({ contact: { token, externalId } });\n };\n}\n","import { v4 as uuidv4 } from \"uuid\";\n\nexport function genUuid() {\n return uuidv4();\n}\n","import type { ApiCaller } from \"../api/api-caller\";\nimport type { SessionDto } from \"../types/schemas\";\nimport { Poller } from \"../utils/Poller\";\nimport { PrimitiveState } from \"../utils/PrimitiveState\";\nimport type { ContactCtx } from \"./contact.ctx\";\n\ntype SessionState = {\n /**\n * The currently selected session.\n * Can be null if no session is selected, or if in chat screen and the session is not created yet.\n */\n session: SessionDto | null;\n isCreatingSession: boolean;\n};\ntype SessionsState = {\n /** List of all user sessions */\n data: SessionDto[];\n /** A cursor to get the next page of sessions */\n cursor: string | undefined;\n /** Indicates if no more pages are left */\n isLastPage: boolean;\n /** Did fetch for the first time */\n didStartInitialFetch: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class SessionCtx {\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private sessionsPollingIntervalSeconds: number;\n private sessionsRefresher = new Poller();\n\n public sessionState = new PrimitiveState<SessionState>({\n session: null,\n isCreatingSession: false,\n });\n public sessionsState = new PrimitiveState<SessionsState>({\n data: [],\n cursor: undefined,\n isLastPage: false,\n didStartInitialFetch: false,\n /**\n * Initialize this as `true` so it always starts loading until the first fetch is done\n */\n isInitialFetchLoading: true,\n });\n\n constructor({\n api,\n contactCtx,\n sessionsPollingIntervalSeconds,\n }: {\n api: ApiCaller;\n contactCtx: ContactCtx;\n sessionsPollingIntervalSeconds: number;\n }) {\n this.api = api;\n this.contactCtx = contactCtx;\n this.sessionsPollingIntervalSeconds = sessionsPollingIntervalSeconds;\n\n this.registerSessionsRefresherWrapper();\n }\n\n /** Clears the session and stops polling */\n reset = async () => {\n // Reset the session only, leave sessions as-is\n this.sessionState.reset();\n };\n\n private registerSessionsRefresherWrapper = () => {\n if (\n // If the widget config was initially provided with a contact token, no state change would be triggered, so we just fetch\n this.contactCtx.state.get().contact?.token &&\n !this.sessionsState.get().didStartInitialFetch\n ) {\n this.registerSessionsRefresher();\n } else {\n // In other cases where auto authenticate is fired, the token would be eventually set in state, so we wait for it\n this.contactCtx.state.subscribe(({ contact }) => {\n if (contact?.token && !this.sessionsState.get().didStartInitialFetch) {\n this.registerSessionsRefresher();\n }\n });\n }\n };\n\n private registerSessionsRefresher = () => {\n this.sessionsRefresher.startPolling(async () => {\n if (this.sessionsState.get().didStartInitialFetch === false) {\n this.sessionsState.setPartial({ didStartInitialFetch: true });\n }\n\n await this.refreshSessions();\n\n if (this.sessionsState.get().isInitialFetchLoading === true) {\n this.sessionsState.setPartial({ isInitialFetchLoading: false });\n }\n }, this.sessionsPollingIntervalSeconds * 1000);\n };\n\n createSession = async () => {\n this.sessionState.setPartial({ session: null, isCreatingSession: true });\n\n const externalId = this.contactCtx.state.get().contact?.externalId;\n const { data: session, error } = await this.api.createSession({\n customData: externalId\n ? {\n external_id: externalId,\n }\n : undefined,\n });\n if (session) {\n this.sessionState.setPartial({ session, isCreatingSession: false });\n return session;\n }\n\n console.error(\"Failed to create session:\", error);\n return null;\n };\n\n loadMoreSessions = async () => {\n if (this.sessionsState.get().isLastPage) return;\n\n const { data } = await this.getSessions({\n cursor: this.sessionsState.get().cursor,\n });\n\n if (data) {\n const allSessions = [...this.sessionsState.get().data, ...data.items];\n // TODO sort by updated at\n const deduped = allSessions.filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n\n this.sessionsState.setPartial({\n data: deduped,\n cursor: data.next || undefined,\n isLastPage: data.next === null,\n });\n }\n };\n\n private getSessions = async ({ cursor }: { cursor: string | undefined }) => {\n if (!this.contactCtx.state.get().contact?.token) return { data: null };\n\n const externalId = this.contactCtx.state.get().contact?.externalId;\n return await this.api.getSessions({\n cursor,\n filters: externalId\n ? {\n external_id: externalId,\n }\n : {},\n });\n };\n\n refreshSessions = async () => {\n // Get the first page only (pass no `cursor`)\n const { data } = await this.getSessions({ cursor: undefined });\n if (!data) return;\n const sessions = [...data.items, ...this.sessionsState.get().data].filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n this.sessionsState.setPartial({ data: sessions });\n };\n}\n","import { ApiCaller } from \"../api/api-caller\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport type {\n BotMessageType,\n MessageType,\n UserMessageType,\n} from \"../types/messages\";\nimport type {\n MessageAttachmentType,\n SendMessageDto,\n SendMessageOutputDto,\n} from \"../types/schemas\";\nimport { PrimitiveState } from \"../utils/PrimitiveState\";\nimport { genUuid } from \"../utils/uuid\";\nimport { SessionCtx } from \"./session.ctx\";\nimport type { ContactCtx } from \"./contact.ctx\";\n\ntype MessageCtxState = {\n messages: MessageType[];\n isSendingMessage: boolean;\n lastAIResMightSolveUserIssue: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class MessageCtx {\n private config: WidgetConfig;\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n\n public state = new PrimitiveState<MessageCtxState>({\n messages: [],\n isSendingMessage: false,\n lastAIResMightSolveUserIssue: false,\n isInitialFetchLoading: false,\n });\n\n private sendMessageAbortController = new AbortController();\n\n constructor({\n config,\n api,\n sessionCtx,\n contactCtx,\n }: {\n config: WidgetConfig;\n api: ApiCaller;\n sessionCtx: SessionCtx;\n contactCtx: ContactCtx;\n }) {\n this.config = config;\n this.api = api;\n this.sessionCtx = sessionCtx;\n this.contactCtx = contactCtx;\n }\n\n reset = () => {\n this.sendMessageAbortController.abort(\"Resetting chat\");\n this.state.reset();\n };\n\n sendMessage = async (\n input: {\n content: SendMessageDto['content']\n attachments?: SendMessageDto['attachments']\n },\n ): Promise<void> => {\n /* ------------------------------------------------------ */\n /* Prevent sending if there is no content */\n /* ------------------------------------------------------ */\n if (\n !input.content.trim() &&\n (!input.attachments || input.attachments.length === 0)\n ) {\n console.warn(\"Cannot send an empty message of no content or attachments\");\n return;\n }\n /* ------------------------------------------------------ */\n /* Prevent sending while waiting for AI res */\n /* ------------------------------------------------------ */\n const isSending = this.state.get().isSendingMessage;\n const isAssignedToAI =\n this.sessionCtx.sessionState.get().session?.assignee.kind === \"ai\";\n const lastMessage = this.state.get().messages.at(-1);\n if (\n (isAssignedToAI && isSending) ||\n // If last message is from user, then bot response did not arrive yet\n (isAssignedToAI && lastMessage?.type === \"FROM_USER\")\n ) {\n console.warn(\"Cannot send messages while awaiting AI response\");\n return;\n }\n\n this.sendMessageAbortController = new AbortController();\n\n /* ------------------------------------------------------ */\n /* Clear last AI response might solve user issue */\n /* ------------------------------------------------------ */\n this.state.setPartial({ lastAIResMightSolveUserIssue: false });\n\n try {\n this.state.setPartial({ isSendingMessage: true });\n /* ------------------------------------------------------ */\n /* Optimistically add message to rendered messages */\n /* ------------------------------------------------------ */\n const userMessage = this.toUserMessage(\n input.content.trim(),\n input.attachments || undefined,\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, userMessage],\n });\n\n /* ------------------------------------------------------ */\n /* Create session if not exists */\n /* ------------------------------------------------------ */\n if (!this.sessionCtx.sessionState.get().session?.id) {\n const createdSession = await this.sessionCtx.createSession();\n\n // TODO: apply some retry logic here\n if (!createdSession) {\n console.error(\"Failed to create session\");\n return;\n }\n\n // Refresh sessions list instantly to get the newly created session in the sessions list\n void this.sessionCtx.refreshSessions();\n }\n const sessionId = this.sessionCtx.sessionState.get().session?.id;\n if (!sessionId) return;\n /* ------------------------------------------------------ */\n /* Send and wait for bot response */\n /* ------------------------------------------------------ */\n const { data } = await this.api.sendMessage(\n {\n uuid: userMessage.id,\n bot_token: this.config.token,\n headers: this.config.headers,\n query_params: this.config.queryParams,\n session_id: sessionId,\n user: this.config.user?.data,\n content: userMessage.content,\n attachments: input.attachments,\n },\n this.sendMessageAbortController.signal,\n );\n\n if (data?.success) {\n /* ------------------------------------------------------ */\n /* Append bot reply if not fetched from polling */\n /* ------------------------------------------------------ */\n const botMessage = this.toBotMessage(data);\n if (botMessage) {\n const prevMessages = this.state.get().messages;\n const shouldAppend = !prevMessages.some(\n (m) => m.id === botMessage.id,\n );\n if (!shouldAppend) {\n this.state.setPartial({\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n return;\n }\n this.state.setPartial({\n messages: [...prevMessages, botMessage],\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n }\n } else {\n const errorMessage = this.toBotErrorMessage(\n data?.error?.message || \"Unknown error occurred\",\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, errorMessage],\n });\n }\n } catch (error) {\n if (!this.sendMessageAbortController.signal.aborted) {\n console.error(\"Failed to send message:\", error);\n }\n } finally {\n this.state.setPartial({ isSendingMessage: false });\n }\n };\n\n private toUserMessage = (\n content: string,\n attachments?: MessageAttachmentType[],\n ): UserMessageType => {\n const messageContent = (() => {\n const extraCollectedData = this.contactCtx.state.get().extraCollectedData;\n // Prepend extra collected data if this is the first message in the session\n if (\n this.state.get().messages.length === 0 &&\n extraCollectedData &&\n Object.keys(extraCollectedData).length > 0\n ) {\n const data = Object.entries(extraCollectedData)\n .filter(([_, value]) => !!value)\n .map(([key, value]) => `${key}: ${value}`)\n .join(\" \\n\");\n return `${data} \\n\\n${content}`;\n }\n\n return content;\n })();\n\n return {\n id: genUuid(),\n type: \"FROM_USER\",\n content: messageContent,\n deliveredAt: new Date().toISOString(),\n attachments,\n timestamp: new Date().toISOString(),\n };\n };\n\n private toBotMessage = (\n response: SendMessageOutputDto,\n ): BotMessageType | null => {\n if (response.success && response.autopilotResponse) {\n return {\n type: \"FROM_BOT\",\n id: response.autopilotResponse.id || genUuid(),\n timestamp: new Date().toISOString(),\n component: \"bot_message\",\n agent: this.config.bot\n ? {\n name: this.config.bot.name || \"\",\n isAi: true,\n avatar: this.config.bot.avatar || \"\",\n id: null,\n }\n : undefined,\n data: {\n message: response.autopilotResponse.value.content,\n action: response.uiResponse?.value.name\n ? {\n name: response.uiResponse.value.name,\n data: response.uiResponse.value.request_response,\n }\n : undefined,\n },\n };\n }\n\n return null;\n };\n\n private toBotErrorMessage = (message: string): BotMessageType => {\n return {\n type: \"FROM_BOT\",\n id: genUuid(),\n timestamp: new Date().toISOString(),\n component: \"TEXT\",\n data: {\n message,\n variant: \"error\",\n action: undefined,\n },\n };\n };\n}\n","import { PrimitiveState } from \"../utils/PrimitiveState\";\nimport type { ContactCtx } from \"./contact.ctx\";\nimport type { SessionCtx } from \"./session.ctx\";\nimport type { WidgetCtx } from \"./widget.ctx\";\n\ntype RouterState = {\n screen:\n | /** A welcome screen to collect user data. Useful in public non-logged-in environments */\n \"welcome\"\n /** Show a list of the user's previous sessions */\n | \"sessions\"\n /** Self-explanatory */\n | \"chat\";\n};\n\nexport class RouterCtx {\n state: PrimitiveState<RouterState>;\n\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n private resetChat: WidgetCtx[\"resetChat\"];\n\n constructor({\n contactCtx,\n sessionCtx,\n resetChat,\n }: {\n contactCtx: ContactCtx;\n sessionCtx: SessionCtx;\n resetChat: WidgetCtx[\"resetChat\"];\n }) {\n this.state = new PrimitiveState<RouterState>({\n screen: contactCtx.shouldCollectData() ? \"welcome\" : \"sessions\",\n });\n this.contactCtx = contactCtx;\n this.sessionCtx = sessionCtx;\n this.resetChat = resetChat;\n\n this.registerRoutingListener();\n }\n\n private registerRoutingListener = () => {\n this.contactCtx.state.subscribe(({ contact }) => {\n // Auto navigate to sessions screen after collecting user data\n if (contact?.token && this.state.get().screen === \"welcome\") {\n this.state.setPartial({ screen: \"sessions\" });\n }\n });\n };\n\n toSessionsScreen = () => {\n this.resetChat();\n this.state.setPartial({ screen: \"sessions\" });\n };\n\n /**\n * @param sessionId The ID of the session to open, or `undefined` if it is a new chat session\n */\n toChatScreen = (sessionId?: string) => {\n this.resetChat();\n\n if (sessionId) {\n const session = this.sessionCtx.sessionsState\n .get()\n .data.find((s) => s.id === sessionId);\n // Do not navigate if session is not found (this shouldn't happen, unless a wrong ID is passed)\n if (!session) return;\n this.sessionCtx.sessionState.setPartial({ session });\n }\n\n this.state.setPartial({ screen: \"chat\" });\n };\n}\n","import type { ExternalStorage } from \"../types/external-storage\";\n\nexport class StorageCtx {\n private storage: ExternalStorage;\n private KEYS = {\n contactToken: \"opencx__widget__contactToken\",\n externalContactId: \"opencx__widget__externalContactId\",\n };\n\n constructor({ storage }: { storage: ExternalStorage }) {\n this.storage = storage;\n }\n\n setContactToken = async (token: string) => {\n await this.storage.set(this.KEYS.contactToken, token);\n };\n getContactToken = async () => {\n return this.storage.get(this.KEYS.contactToken);\n };\n\n setExternalContactId = async (id: string) => {\n await this.storage.set(this.KEYS.externalContactId, id);\n };\n getExternalContactId = async () => {\n return this.storage.get(this.KEYS.externalContactId);\n };\n}\n","import { ApiCaller } from \"../api/api-caller\";\nimport type { ExternalStorage } from \"../types/external-storage\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport { ActiveSessionPollingCtx } from \"./active-session-polling.ctx\";\nimport { ContactCtx } from \"./contact.ctx\";\nimport { MessageCtx } from \"./message.ctx\";\nimport { RouterCtx } from \"./router.ctx\";\nimport { SessionCtx } from \"./session.ctx\";\nimport { StorageCtx } from \"./storage.ctx\";\n\nexport class WidgetCtx {\n public config: WidgetConfig;\n public api: ApiCaller;\n\n public contactCtx: ContactCtx;\n public sessionCtx: SessionCtx;\n public messageCtx: MessageCtx;\n public routerCtx: RouterCtx;\n public storageCtx?: StorageCtx;\n\n private static pollingIntervalsSeconds: {\n session: number;\n sessions: number;\n } | null = null;\n private activeSessionPollingCtx: ActiveSessionPollingCtx;\n\n private constructor({\n config,\n storage,\n }: { config: WidgetConfig; storage?: ExternalStorage }) {\n if (!WidgetCtx.pollingIntervalsSeconds) {\n throw Error(\n \"Widget polling values are not defined, did you call WidgetCtx.initialize()\",\n );\n }\n\n this.config = config;\n this.api = new ApiCaller({ config });\n this.storageCtx = storage ? new StorageCtx({ storage }) : undefined;\n\n this.contactCtx = new ContactCtx({\n api: this.api,\n config: this.config,\n storageCtx: this.storageCtx,\n });\n\n this.sessionCtx = new SessionCtx({\n api: this.api,\n contactCtx: this.contactCtx,\n sessionsPollingIntervalSeconds:\n WidgetCtx.pollingIntervalsSeconds.sessions,\n });\n\n this.messageCtx = new MessageCtx({\n config: this.config,\n api: this.api,\n sessionCtx: this.sessionCtx,\n contactCtx: this.contactCtx,\n });\n\n this.activeSessionPollingCtx = new ActiveSessionPollingCtx({\n api: this.api,\n config: this.config,\n sessionCtx: this.sessionCtx,\n messageCtx: this.messageCtx,\n sessionPollingIntervalSeconds: WidgetCtx.pollingIntervalsSeconds.session,\n });\n\n this.routerCtx = new RouterCtx({\n contactCtx: this.contactCtx,\n sessionCtx: this.sessionCtx,\n resetChat: this.resetChat,\n });\n }\n\n static initialize = async ({\n config,\n storage,\n }: { config: WidgetConfig; storage?: ExternalStorage }) => {\n const externalConfig = await new ApiCaller({\n config,\n }).getExternalWidgetConfig();\n\n this.pollingIntervalsSeconds = {\n session: externalConfig.data?.sessionPollingIntervalSeconds || 10,\n sessions: externalConfig.data?.sessionsPollingIntervalSeconds || 60,\n };\n\n return new WidgetCtx({\n config,\n storage,\n });\n };\n\n resetChat = () => {\n this.sessionCtx.reset();\n this.messageCtx.reset();\n };\n}\n"],"names":["defaultOnError","onErrorOptions","basicClient","options","client","createClient","middlewares","ApiCaller","config","__publicField","token","baseUrl","headers","request","key","value","axios","body","abortSignal","sessionId","lastMessageTimestamp","query","cursor","filters","file","formData","data","_a","PrimitiveState","state","newState","isEqual","_s","callback","error","Poller","cb","intervalMs","timeouts","poll","ActiveSessionPollingCtx","api","sessionCtx","messageCtx","sessionPollingIntervalSeconds","session","prevMessages","newMessages","newMsg","existingMsg","history","commonFields","action","_b","_c","ContactCtx","storageCtx","_d","persistedToken","_e","_g","_f","_h","_j","_i","_l","_k","payload","extraCollectedData","persistedExternalId","externalId","v4","genUuid","uuidv4","SessionCtx","contactCtx","sessionsPollingIntervalSeconds","contact","deduped","s","i","self","sessions","MessageCtx","input","isSending","isAssignedToAI","lastMessage","userMessage","currentMessages","botMessage","m","errorMessage","content","attachments","messageContent","_","response","message","RouterCtx","resetChat","StorageCtx","storage","id","_WidgetCtx","externalConfig","WidgetCtx"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";var R=Object.defineProperty;var M=(o,t,e)=>t in o?R(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e;var s=(o,t,e)=>M(o,typeof t!="symbol"?t+"":t,e);const E=require("axios"),T=require("openapi-fetch"),F=require("lodash.isequal"),y=require("uuid"),O=o=>{console.log(o.error)},_=o=>{const t=T({baseUrl:o.baseUrl}),e={onRequest:o.onRequest,onResponse:o.onResponse,onError:o.onError||O};return t.use(e),t};class I{constructor({config:t}){s(this,"client");s(this,"uploadFileClient");s(this,"config");s(this,"constructClientOptions",t=>{const e=this.config.apiUrl||"https://api.open.cx",i={"X-Bot-Token":this.config.token,"Content-Type":"application/json",Accept:"application/json",Authorization:t?`Bearer ${t}`:void 0};return{baseUrl:e,headers:i}});s(this,"createOpenAPIClient",({baseUrl:t,headers:e})=>_({baseUrl:t,onRequest:({request:i})=>{Object.entries(e).forEach(([a,n])=>{n&&i.headers.set(a,n)})}}));s(this,"createAxiosUploadClient",({baseUrl:t,headers:e})=>E.create({baseURL:`${t}/backend/widget/v2/upload`,headers:e}));s(this,"setAuthToken",t=>{const{baseUrl:e,headers:i}=this.constructClientOptions(t);this.client=this.createOpenAPIClient({baseUrl:e,headers:i}),this.uploadFileClient=this.createAxiosUploadClient({baseUrl:e,headers:i})});s(this,"getExternalWidgetConfig",async()=>await this.client.GET("/backend/widget/v2/config",{params:{header:{"X-Bot-Token":this.config.token}}}));s(this,"widgetPrelude",async()=>await this.client.GET("/backend/widget/v2/prelude",{params:{header:{"X-Bot-Token":this.config.token}}}));s(this,"sendMessage",async(t,e)=>await this.client.POST("/backend/widget/v2/chat/send",{body:t,signal:e}));s(this,"createUnverifiedContact",async t=>await this.client.POST("/backend/widget/v2/contact/create-unverified",{params:{header:{"x-bot-token":this.config.token}},body:t}));s(this,"createSession",async t=>await this.client.POST("/backend/widget/v2/create-session",{body:t}));s(this,"pollSessionAndHistory",async({sessionId:t,lastMessageTimestamp:e,abortSignal:i})=>{const a=e?{lastMessageTimestamp:e}:void 0;return await this.client.GET("/backend/widget/v2/poll/{sessionId}",{params:{path:{sessionId:t},query:a},signal:i})});s(this,"getSessions",async({cursor:t,filters:e,abortSignal:i})=>await this.client.GET("/backend/widget/v2/sessions",{params:{query:{cursor:t,filters:JSON.stringify(e)}},signal:i}));s(this,"uploadFile",async(t,e={})=>{const i=new FormData;i.append("file",t.file);const{data:a}=await this.uploadFileClient.post("",i,{headers:{"Content-Type":"multipart/form-data"},...e});return a});s(this,"vote",async t=>await this.client.POST("/backend/widget/v2/chat/vote",{body:t}));var a;this.config=t;const{baseUrl:e,headers:i}=this.constructClientOptions((a=t.user)==null?void 0:a.token);this.client=this.createOpenAPIClient({baseUrl:e,headers:i}),this.uploadFileClient=this.createAxiosUploadClient({baseUrl:e,headers:i})}}class C{constructor(t){s(this,"subscribers",new Set);s(this,"state");s(this,"initialState");s(this,"get",()=>this.state);s(this,"set",t=>{F(this.state,t)||(this.state=t,this.notifySubscribers(t))});s(this,"setPartial",t=>{if(t==null)return;const e={...this.state,...t};this.set(e)});s(this,"reset",()=>{this.set(this.initialState)});s(this,"notifySubscribers",t=>{Array.from(this.subscribers).forEach(i=>{try{i(t)}catch(a){console.error(a)}})});s(this,"subscribe",t=>(this.subscribers.add(t),()=>{this.subscribers.delete(t)}));this.state=t,this.initialState=t}}class k{constructor(){s(this,"state",new C({isPolling:!1,isError:!1}));s(this,"abortController",new AbortController);s(this,"reset",()=>{var t;this.abortController.abort("Resetting poller"),(t=this.stopPolling)==null||t.call(this),this.stopPolling=null});s(this,"stopPolling",null);s(this,"startPolling",(t,e)=>{if(this.stopPolling)return;const i=[],a=async()=>{this.abortController=new AbortController,this.state.setPartial({isPolling:!0});try{await t(this.abortController.signal)}catch(n){if(this.abortController.signal.aborted)return;console.error("Failed to poll:",n),this.state.setPartial({isError:!0})}finally{this.state.setPartial({isPolling:!1})}this.abortController.signal.aborted?console.log("Poller aborted, not scheduling anymore"):i.push(setTimeout(a,e))};a(),this.stopPolling=()=>{i.forEach(clearTimeout),this.state.reset()}})}}class D{constructor({api:t,config:e,sessionCtx:i,messageCtx:a,sessionPollingIntervalSeconds:n}){s(this,"api");s(this,"config");s(this,"sessionCtx");s(this,"messageCtx");s(this,"sessionPollingIntervalSeconds");s(this,"poller",new k);s(this,"registerPolling",()=>{this.sessionCtx.sessionState.subscribe(({session:t})=>{t!=null&&t.id?this.poller.startPolling(async e=>{this.hackAndSlash(t.id,e)},this.sessionPollingIntervalSeconds*1e3):this.poller.reset()})});s(this,"hackAndSlash",async(t,e)=>{var n;this.messageCtx.state.get().messages.length===0&&this.messageCtx.state.setPartial({isInitialFetchLoading:!0});const i=(n=this.messageCtx.state.get().messages.at(-1))==null?void 0:n.timestamp,{data:a}=await this.api.pollSessionAndHistory({sessionId:t,abortSignal:e,lastMessageTimestamp:i});if(a!=null&&a.session&&this.sessionCtx.sessionState.setPartial({session:a.session}),a!=null&&a.history&&a.history.length>0){const r=this.messageCtx.state.get().messages,l=a.history.map(this.mapHistoryToMessage).filter(d=>!r.some(u=>u.id===d.id));this.messageCtx.state.setPartial({messages:[...r,...l]})}this.messageCtx.state.get().isInitialFetchLoading&&this.messageCtx.state.setPartial({isInitialFetchLoading:!1})});s(this,"mapHistoryToMessage",t=>{var a,n,r;const e={id:t.publicId,timestamp:t.sentAt||"",attachments:t.attachments||void 0};if(t.sender.kind==="user")return{...e,type:"FROM_USER",content:t.content.text||"",deliveredAt:t.sentAt||""};if(t.sender.kind==="agent")return{...e,type:"FROM_AGENT",component:"agent_message",data:{message:t.content.text||""},agent:{name:t.sender.name||"",avatar:t.sender.avatar||"",id:null,isAi:!1}};const i=(a=t.actionCalls)==null?void 0:a.at(-1);return{...e,type:"FROM_BOT",component:"bot_message",agent:{id:null,name:((n=this.config.bot)==null?void 0:n.name)||"",isAi:!0,avatar:((r=this.config.bot)==null?void 0:r.avatar)||""},data:{message:t.content.text||"",action:i?{name:i.actionName,data:i.result}:void 0}}});this.api=t,this.config=e,this.sessionCtx=i,this.messageCtx=a,this.sessionPollingIntervalSeconds=n,this.registerPolling()}}class q{constructor({config:t,api:e,storageCtx:i}){s(this,"config");s(this,"storageCtx");s(this,"api");s(this,"state");s(this,"shouldCollectData",()=>{var t;return!!(!((t=this.state.get().contact)!=null&&t.token)&&this.config.collectUserData)});s(this,"autoCreateUnverifiedUserIfNotExists",async()=>{var t,e,i,a,n,r,l,d,u,p,S,x;if(!((t=this.config.user)!=null&&t.token)){if(this.config.collectUserData&&!((i=(e=this.config.user)==null?void 0:e.data)!=null&&i.email)){if((a=this.config.extraDataCollectionFields)!=null&&a.length)return;const g=await((n=this.storageCtx)==null?void 0:n.getContactToken());g&&await this.setUnverifiedContact(g);return}if(!((l=(r=this.config.user)==null?void 0:r.data)!=null&&l.email)){const g=await((d=this.storageCtx)==null?void 0:d.getContactToken());if(g){await this.setUnverifiedContact(g);return}}await this.createUnverifiedContact({name:((p=(u=this.config.user)==null?void 0:u.data)==null?void 0:p.name)||"Anonymous",email:(x=(S=this.config.user)==null?void 0:S.data)==null?void 0:x.email})}});s(this,"createUnverifiedContact",async(t,e)=>{this.state.setPartial({extraCollectedData:e});try{this.state.setPartial({isCreatingUnverifiedContact:!0,isErrorCreatingUnverifiedContact:!1});const{data:i}=await this.api.createUnverifiedContact(t);i!=null&&i.token?await this.setUnverifiedContact(i.token):this.state.setPartial({isErrorCreatingUnverifiedContact:!0})}finally{this.state.setPartial({isCreatingUnverifiedContact:!1})}});s(this,"setUnverifiedContact",async t=>{var a,n,r,l;const e=await((a=this.storageCtx)==null?void 0:a.getExternalContactId()),i=((n=this.config.user)==null?void 0:n.externalId)||e||y.v4();this.api.setAuthToken(t),await((r=this.storageCtx)==null?void 0:r.setContactToken(t)),await((l=this.storageCtx)==null?void 0:l.setExternalContactId(i)),this.state.setPartial({contact:{token:t,externalId:i}})});var a;this.config=t,this.storageCtx=i,this.api=e,this.state=new C({contact:(a=t.user)!=null&&a.token?{token:t.user.token,externalId:t.user.externalId}:null,extraCollectedData:void 0,isCreatingUnverifiedContact:!1,isErrorCreatingUnverifiedContact:!1}),this.autoCreateUnverifiedUserIfNotExists()}}function w(){return y.v4()}class L{constructor({api:t,contactCtx:e,sessionsPollingIntervalSeconds:i}){s(this,"api");s(this,"contactCtx");s(this,"sessionsPollingIntervalSeconds");s(this,"sessionsRefresher",new k);s(this,"sessionState",new C({session:null,isCreatingSession:!1}));s(this,"sessionsState",new C({data:[],cursor:void 0,isLastPage:!1,didStartInitialFetch:!1,isInitialFetchLoading:!0}));s(this,"reset",async()=>{this.sessionState.reset()});s(this,"registerSessionsRefresherWrapper",()=>{var t;(t=this.contactCtx.state.get().contact)!=null&&t.token&&!this.sessionsState.get().didStartInitialFetch?this.registerSessionsRefresher():this.contactCtx.state.subscribe(({contact:e})=>{e!=null&&e.token&&!this.sessionsState.get().didStartInitialFetch&&this.registerSessionsRefresher()})});s(this,"registerSessionsRefresher",()=>{this.sessionsRefresher.startPolling(async()=>{this.sessionsState.get().didStartInitialFetch===!1&&this.sessionsState.setPartial({didStartInitialFetch:!0}),await this.refreshSessions(),this.sessionsState.get().isInitialFetchLoading===!0&&this.sessionsState.setPartial({isInitialFetchLoading:!1})},this.sessionsPollingIntervalSeconds*1e3)});s(this,"createSession",async()=>{var a;this.sessionState.setPartial({session:null,isCreatingSession:!0});const t=(a=this.contactCtx.state.get().contact)==null?void 0:a.externalId,{data:e,error:i}=await this.api.createSession({customData:t?{external_id:t}:void 0});return e?(this.sessionState.setPartial({session:e,isCreatingSession:!1}),e):(console.error("Failed to create session:",i),null)});s(this,"loadMoreSessions",async()=>{if(this.sessionsState.get().isLastPage)return;const{data:t}=await this.getSessions({cursor:this.sessionsState.get().cursor});if(t){const i=[...this.sessionsState.get().data,...t.items].filter((a,n,r)=>n===r.findIndex(l=>a.id===l.id));this.sessionsState.setPartial({data:i,cursor:t.next||void 0,isLastPage:t.next===null})}});s(this,"getSessions",async({cursor:t})=>{var i,a;if(!((i=this.contactCtx.state.get().contact)!=null&&i.token))return{data:null};const e=(a=this.contactCtx.state.get().contact)==null?void 0:a.externalId;return await this.api.getSessions({cursor:t,filters:e?{external_id:e}:{}})});s(this,"refreshSessions",async()=>{const{data:t}=await this.getSessions({cursor:void 0});if(!t)return;const e=[...t.items,...this.sessionsState.get().data].filter((i,a,n)=>a===n.findIndex(r=>i.id===r.id));this.sessionsState.setPartial({data:e})});this.api=t,this.contactCtx=e,this.sessionsPollingIntervalSeconds=i,this.registerSessionsRefresherWrapper()}}class B{constructor({config:t,api:e,sessionCtx:i,contactCtx:a}){s(this,"config");s(this,"api");s(this,"contactCtx");s(this,"sessionCtx");s(this,"state",new C({messages:[],isSendingMessage:!1,lastAIResMightSolveUserIssue:!1,isInitialFetchLoading:!1}));s(this,"sendMessageAbortController",new AbortController);s(this,"reset",()=>{this.sendMessageAbortController.abort("Resetting chat"),this.state.reset()});s(this,"sendMessage",async t=>{var n,r,l,d,u,p,S,x,g;if(!t.content.trim()&&(!t.attachments||t.attachments.length===0)){console.warn("Cannot send an empty message of no content or attachments");return}const e=this.state.get().isSendingMessage,i=((n=this.sessionCtx.sessionState.get().session)==null?void 0:n.assignee.kind)==="ai",a=this.state.get().messages.at(-1);if(i&&e||i&&(a==null?void 0:a.type)==="FROM_USER"){console.warn("Cannot send messages while awaiting AI response");return}this.sendMessageAbortController=new AbortController,this.state.setPartial({lastAIResMightSolveUserIssue:!1});try{this.state.setPartial({isSendingMessage:!0});const m=this.toUserMessage(t.content.trim(),t.attachments||void 0),A=this.state.get().messages;if(this.state.setPartial({messages:[...A,m]}),!((r=this.sessionCtx.sessionState.get().session)!=null&&r.id)){if(!await this.sessionCtx.createSession()){console.error("Failed to create session");return}this.sessionCtx.refreshSessions()}const P=(l=this.sessionCtx.sessionState.get().session)==null?void 0:l.id;if(!P)return;const{data:c}=await this.api.sendMessage({uuid:m.id,bot_token:this.config.token,headers:this.config.headers,query_params:this.config.queryParams,session_id:P,user:(d=this.config.user)==null?void 0:d.data,content:m.content,attachments:t.attachments},this.sendMessageAbortController.signal);if(c!=null&&c.success){const f=this.toBotMessage(c);if(f){const v=this.state.get().messages;if(!!v.some(U=>U.id===f.id)){this.state.setPartial({lastAIResMightSolveUserIssue:((u=c.autopilotResponse)==null?void 0:u.mightSolveUserIssue)||((p=c.uiResponse)==null?void 0:p.mightSolveUserIssue)});return}this.state.setPartial({messages:[...v,f],lastAIResMightSolveUserIssue:((S=c.autopilotResponse)==null?void 0:S.mightSolveUserIssue)||((x=c.uiResponse)==null?void 0:x.mightSolveUserIssue)})}}else{const f=this.toBotErrorMessage(((g=c==null?void 0:c.error)==null?void 0:g.message)||"Unknown error occurred"),v=this.state.get().messages;this.state.setPartial({messages:[...v,f]})}}catch(m){this.sendMessageAbortController.signal.aborted||console.error("Failed to send message:",m)}finally{this.state.setPartial({isSendingMessage:!1})}});s(this,"toUserMessage",(t,e)=>{const i=(()=>{const a=this.contactCtx.state.get().extraCollectedData;return this.state.get().messages.length===0&&a&&Object.keys(a).length>0?`${Object.entries(a).filter(([r,l])=>!!l).map(([r,l])=>`${r}: ${l}`).join(`
|
|
2
|
+
`)}
|
|
3
|
+
|
|
4
|
+
${t}`:t})();return{id:w(),type:"FROM_USER",content:i,deliveredAt:new Date().toISOString(),attachments:e,timestamp:new Date().toISOString()}});s(this,"toBotMessage",t=>{var e;return t.success&&t.autopilotResponse?{type:"FROM_BOT",id:t.autopilotResponse.id||w(),timestamp:new Date().toISOString(),component:"bot_message",agent:this.config.bot?{name:this.config.bot.name||"",isAi:!0,avatar:this.config.bot.avatar||"",id:null}:void 0,data:{message:t.autopilotResponse.value.content,action:(e=t.uiResponse)!=null&&e.value.name?{name:t.uiResponse.value.name,data:t.uiResponse.value.request_response}:void 0}}:null});s(this,"toBotErrorMessage",t=>({type:"FROM_BOT",id:w(),timestamp:new Date().toISOString(),component:"TEXT",data:{message:t,variant:"error",action:void 0}}));this.config=t,this.api=e,this.sessionCtx=i,this.contactCtx=a}}class ${constructor({contactCtx:t,sessionCtx:e,resetChat:i}){s(this,"state");s(this,"contactCtx");s(this,"sessionCtx");s(this,"resetChat");s(this,"registerRoutingListener",()=>{this.contactCtx.state.subscribe(({contact:t})=>{t!=null&&t.token&&this.state.get().screen==="welcome"&&this.state.setPartial({screen:"sessions"})})});s(this,"toSessionsScreen",()=>{this.resetChat(),this.state.setPartial({screen:"sessions"})});s(this,"toChatScreen",t=>{if(this.resetChat(),t){const e=this.sessionCtx.sessionsState.get().data.find(i=>i.id===t);if(!e)return;this.sessionCtx.sessionState.setPartial({session:e})}this.state.setPartial({screen:"chat"})});this.state=new C({screen:t.shouldCollectData()?"welcome":"sessions"}),this.contactCtx=t,this.sessionCtx=e,this.resetChat=i,this.registerRoutingListener()}}class j{constructor({storage:t}){s(this,"storage");s(this,"KEYS",{contactToken:"opencx__widget__contactToken",externalContactId:"opencx__widget__externalContactId"});s(this,"setContactToken",async t=>{await this.storage.set(this.KEYS.contactToken,t)});s(this,"getContactToken",async()=>this.storage.get(this.KEYS.contactToken));s(this,"setExternalContactId",async t=>{await this.storage.set(this.KEYS.externalContactId,t)});s(this,"getExternalContactId",async()=>this.storage.get(this.KEYS.externalContactId));this.storage=t}}const h=class h{constructor({config:t,storage:e}){s(this,"config");s(this,"api");s(this,"contactCtx");s(this,"sessionCtx");s(this,"messageCtx");s(this,"routerCtx");s(this,"storageCtx");s(this,"activeSessionPollingCtx");s(this,"resetChat",()=>{this.sessionCtx.reset(),this.messageCtx.reset()});if(!h.pollingIntervalsSeconds)throw Error("Widget polling values are not defined, did you call WidgetCtx.initialize()");this.config=t,this.api=new I({config:t}),this.storageCtx=e?new j({storage:e}):void 0,this.contactCtx=new q({api:this.api,config:this.config,storageCtx:this.storageCtx}),this.sessionCtx=new L({api:this.api,contactCtx:this.contactCtx,sessionsPollingIntervalSeconds:h.pollingIntervalsSeconds.sessions}),this.messageCtx=new B({config:this.config,api:this.api,sessionCtx:this.sessionCtx,contactCtx:this.contactCtx}),this.activeSessionPollingCtx=new D({api:this.api,config:this.config,sessionCtx:this.sessionCtx,messageCtx:this.messageCtx,sessionPollingIntervalSeconds:h.pollingIntervalsSeconds.session}),this.routerCtx=new $({contactCtx:this.contactCtx,sessionCtx:this.sessionCtx,resetChat:this.resetChat})}};s(h,"pollingIntervalsSeconds",null),s(h,"initialize",async({config:t,storage:e})=>{var a,n;const i=await new I({config:t}).getExternalWidgetConfig();return h.pollingIntervalsSeconds={session:((a=i.data)==null?void 0:a.sessionPollingIntervalSeconds)||10,sessions:((n=i.data)==null?void 0:n.sessionsPollingIntervalSeconds)||60},new h({config:t,storage:e})});let b=h;exports.PrimitiveState=C;exports.WidgetCtx=b;
|
|
5
|
+
//# sourceMappingURL=widget.ctx-Z3nrC8tP.cjs.map
|