@flowengage/react-chatbot 5.0.16 → 5.0.18

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.
@@ -466,6 +466,16 @@ var v = Object.defineProperty, y = Object.getOwnPropertyDescriptor, b = Object.g
466
466
  ...n ? { siteId: String(n) } : {}
467
467
  }, o = new Blob([JSON.stringify(a)], { type: "application/json" });
468
468
  return navigator.sendBeacon(`${e}/api/ai/voice/sync`, o);
469
+ },
470
+ beaconWidgetClosed(r) {
471
+ if (typeof navigator > "u" || !navigator.sendBeacon) return !1;
472
+ let i = {
473
+ chatId: r,
474
+ type: "widget_closed",
475
+ ...t ? { userId: String(t) } : {},
476
+ ...n ? { siteId: String(n) } : {}
477
+ }, a = new Blob([JSON.stringify(i)], { type: "application/json" });
478
+ return navigator.sendBeacon(`${e}/api/chat/status`, a);
469
479
  }
470
480
  };
471
481
  }, qe = Object.create(null);
@@ -2786,7 +2796,7 @@ function Tr() {
2786
2796
  }
2787
2797
  //#endregion
2788
2798
  //#region src/provider/FlowEngageProvider.jsx
2789
- var Er = (e) => !e || typeof e != "string" ? e : e.replace(/<human_assistance_request>[\s\S]*?<\/human_assistance_request>/gi, "").replace(/<human_assistance_request>/gi, "").replace(/<\/human_assistance_request>/gi, "").replace(/<navigate[^>]*\/>/gi, "").replace(/<navigate[^>]*>[\s\S]*?<\/navigate>/gi, "").replace(/<[a-z]+(?:_[a-z]+)+[^>]*>[\s\S]*?<\/[a-z]+(?:_[a-z]+)+>/gi, "").replace(/<[a-z]+(?:_[a-z]+)+[^>]*\/>/gi, "").trim(), Dr = (e = []) => e.filter((e) => e.type !== "call_recording").map((e) => ({
2799
+ var Er = (e) => !e || typeof e != "string" ? e : e.replace(/<human_assistance_request[^>]*>/gi, "").replace(/<\/human_assistance_request>/gi, "").replace(/<navigate[^>]*\/>/gi, "").replace(/<navigate[^>]*>[\s\S]*?<\/navigate>/gi, "").replace(/<[a-z]+(?:_[a-z]+)+[^>]*>[\s\S]*?<\/[a-z]+(?:_[a-z]+)+>/gi, "").replace(/<[a-z]+(?:_[a-z]+)+[^>]*\/>/gi, "").trim(), Dr = (e = []) => e.filter((e) => e.type !== "call_recording" && !(typeof e.message == "string" && e.message.includes("AI chat recording"))).map((e) => ({
2790
2800
  ...e,
2791
2801
  message: Er(e.message),
2792
2802
  isPending: !1,
@@ -2903,7 +2913,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
2903
2913
  }, bt.current = a, Ct.current = Date.now(), a.start(1e3), setTimeout(() => {
2904
2914
  try {
2905
2915
  if (!window.speechSynthesis) return;
2906
- let e = new SpeechSynthesisUtterance("This call is being recorded.");
2916
+ let e = new SpeechSynthesisUtterance("This call is being recorded for quality and training purposes.");
2907
2917
  if (e.rate = .95, e.pitch = 1, e.volume = 1, window.MediaStreamTrackGenerator || window.AudioContext) try {
2908
2918
  let t = n.createMediaStreamDestination();
2909
2919
  e.onstart = () => {
@@ -3046,7 +3056,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3046
3056
  ...t,
3047
3057
  message: Er(t.message)
3048
3058
  };
3049
- we(!1), Se(!1), S((e) => [...e.filter((e) => !e.isPending), {
3059
+ we(!1), Se(!1), !(n.type === "call_recording" || typeof n.message == "string" && n.message.includes("AI chat recording")) && S((e) => [...e.filter((e) => !e.isPending), {
3050
3060
  ...n,
3051
3061
  isPending: !1,
3052
3062
  id: n.messageId || `${n.sender}-${Date.now()}-${Math.random()}`
@@ -3064,7 +3074,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3064
3074
  ...t,
3065
3075
  message: Er(t.message)
3066
3076
  };
3067
- we(!1), (n.sender === "agent" || n.agent_name || n.sender === "ai" || n.sender === "bot") && Se(!1), S((e) => n.sender === "bot" || n.sender === "ai" ? [...e, {
3077
+ we(!1), !(n.type === "call_recording" || typeof n.message == "string" && n.message.includes("AI chat recording")) && ((n.sender === "agent" || n.agent_name || n.sender === "ai" || n.sender === "bot") && Se(!1), S((e) => n.sender === "bot" || n.sender === "ai" ? [...e, {
3068
3078
  ...n,
3069
3079
  isPending: !1,
3070
3080
  id: n.messageId || `${n.sender}-${Date.now()}-${Math.random()}`
@@ -3080,7 +3090,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3080
3090
  n.agent_name,
3081
3091
  n.agentName,
3082
3092
  n.metadata?.agentName
3083
- ], d)), n.sender_headshot && de(n.sender_headshot), w(!0), Re((e) => e + 1));
3093
+ ], d)), n.sender_headshot && de(n.sender_headshot), w(!0), Re((e) => e + 1)));
3084
3094
  });
3085
3095
  let p = (e = {}) => {
3086
3096
  let t = jr([
@@ -3240,7 +3250,21 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3240
3250
  let e = A.current, t = Tt.current, n = k.current;
3241
3251
  n && e && t.length > 0 && (console.log("[FlowEngageProvider] safety-net: syncing voice transcript on unmount"), n.beaconSyncVoice(e, t) || n.syncVoice(e, t).catch(() => {}), Et.current = !0);
3242
3252
  }
3243
- }, [Fe, _]), c(() => {
3253
+ }, [Fe, _]);
3254
+ let Bt = p(null);
3255
+ c(() => {
3256
+ if (Bt.current === !0 && !C) {
3257
+ let e = A.current, t = k.current;
3258
+ t && e && t.updateChatStatus(e, "widget_closed").catch(() => {});
3259
+ }
3260
+ Bt.current = C;
3261
+ }, [C]), c(() => {
3262
+ let e = () => {
3263
+ let e = A.current, t = k.current;
3264
+ !e || !t || typeof navigator > "u" || t.beaconWidgetClosed?.(e) || t.updateChatStatus(e, "widget_closed").catch(() => {});
3265
+ };
3266
+ return window.addEventListener("pagehide", e), () => window.removeEventListener("pagehide", e);
3267
+ }, []), c(() => {
3244
3268
  if (!k.current || !y || l !== "ready") return;
3245
3269
  let e = window.setInterval(async () => {
3246
3270
  try {
@@ -3254,7 +3278,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3254
3278
  l,
3255
3279
  At
3256
3280
  ]);
3257
- let Bt = async () => {
3281
+ let Vt = async () => {
3258
3282
  if (!(!O?.callId || !k.current || !ot.current || !y)) {
3259
3283
  Mt(), gt.current = O.callId, Nt();
3260
3284
  try {
@@ -3344,7 +3368,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3344
3368
  rt("We couldn't connect the call right now. Please try again.");
3345
3369
  }
3346
3370
  }
3347
- }, Vt = async () => {
3371
+ }, Ht = async () => {
3348
3372
  if (!O?.callId || !k.current || !y) {
3349
3373
  Ft("reject_call_without_server_context");
3350
3374
  return;
@@ -3357,15 +3381,15 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3357
3381
  } finally {
3358
3382
  Ft("reject_call_finally");
3359
3383
  }
3360
- }, Ht = p(Vt);
3361
- Ht.current = Vt, c(() => {
3384
+ }, Ut = p(Ht);
3385
+ Ut.current = Ht, c(() => {
3362
3386
  if (!O?.callId || Je) {
3363
3387
  Nt();
3364
3388
  return;
3365
3389
  }
3366
3390
  let e = O.callId;
3367
3391
  return Nt(), j.current = window.setTimeout(() => {
3368
- lt.current?.callId === e && gt.current !== e && ht.current !== e && Ht.current();
3392
+ lt.current?.callId === e && gt.current !== e && ht.current !== e && Ut.current();
3369
3393
  }, oe), () => {
3370
3394
  j.current &&= (window.clearTimeout(j.current), null);
3371
3395
  };
@@ -3374,7 +3398,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3374
3398
  Nt,
3375
3399
  O?.callId
3376
3400
  ]);
3377
- let Ut = async () => {
3401
+ let Wt = async () => {
3378
3402
  if (!Je || !k.current || !y) {
3379
3403
  Ft("end_call_without_server_context");
3380
3404
  return;
@@ -3387,14 +3411,14 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3387
3411
  } finally {
3388
3412
  Ft("end_call_finally");
3389
3413
  }
3390
- }, Wt = () => {
3414
+ }, Gt = () => {
3391
3415
  let e = dt.current?.getAudioTracks?.() || [], t = ut.current?.getSenders?.().map((e) => e.track).filter((e) => e?.kind === "audio") || [], n = [...e, ...t].filter(Boolean);
3392
3416
  if (n.length === 0) return;
3393
3417
  let r = !et;
3394
3418
  n.forEach((e) => {
3395
3419
  e.enabled = !r;
3396
3420
  }), tt(r);
3397
- }, Gt = async (e = {}) => {
3421
+ }, Kt = async (e = {}) => {
3398
3422
  let t = e.notifyChatInitiated === !0;
3399
3423
  if (w(!0), !(!t || !k.current || !y || typeof window > "u")) {
3400
3424
  try {
@@ -3407,7 +3431,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3407
3431
  await k.current.updateChatStatus(y, "open");
3408
3432
  } catch {}
3409
3433
  }
3410
- }, Kt = async (e) => {
3434
+ }, qt = async (e) => {
3411
3435
  let t = Pt(e);
3412
3436
  if (!t || !k.current || !A.current) return t;
3413
3437
  try {
@@ -3420,26 +3444,26 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3420
3444
  console.error("[FlowEngageProvider] failed to persist visitor email", e);
3421
3445
  }
3422
3446
  return t;
3423
- }, qt = () => {
3447
+ }, Jt = () => {
3424
3448
  !y || !ot.current?.connected || vt.current || (vt.current = !0, ot.current.emit("typing:start", {
3425
3449
  chatId: y,
3426
3450
  sender: "user"
3427
3451
  }));
3428
- }, Jt = () => {
3452
+ }, Yt = () => {
3429
3453
  !y || !ot.current?.connected || !vt.current || (vt.current = !1, ot.current.emit("typing:stop", {
3430
3454
  chatId: y,
3431
3455
  sender: "user"
3432
3456
  }));
3433
- }, Yt = (e = "") => {
3457
+ }, Xt = (e = "") => {
3434
3458
  let t = typeof e == "string" ? e : "";
3435
3459
  !y || !ot.current?.connected || t !== "" && yt.current === t || (yt.current = t, ot.current.emit("typing:update", {
3436
3460
  chatId: y,
3437
3461
  sender: "user",
3438
3462
  text: t
3439
3463
  }));
3440
- }, Xt = async (e, t = "", n = null, a = {}) => {
3464
+ }, Zt = async (e, t = "", n = null, a = {}) => {
3441
3465
  if (!(typeof e == "string" && e.trim()) || !k.current || !y || l !== "ready" || He) return;
3442
- Jt();
3466
+ Yt();
3443
3467
  let o = `pending-user-${Date.now()}`, s = {
3444
3468
  id: o,
3445
3469
  sender: "user",
@@ -3498,10 +3522,10 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3498
3522
  je(!1), Ne("");
3499
3523
  }, ie)) : h(e);
3500
3524
  }
3501
- }, Zt = async (e) => {
3525
+ }, Qt = async (e) => {
3502
3526
  if (!k.current || !e) throw Error("Upload is unavailable right now.");
3503
3527
  return k.current.uploadChatFile(e);
3504
- }, Qt = async (e) => {
3528
+ }, $t = async (e) => {
3505
3529
  if (!(!k.current || !y)) {
3506
3530
  try {
3507
3531
  let t = e ? "voice" : "text";
@@ -3509,7 +3533,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3509
3533
  } catch {}
3510
3534
  Ie(e), e && (Et.current = !1);
3511
3535
  }
3512
- }, $t = async (e) => {
3536
+ }, en = async (e) => {
3513
3537
  if (Et.current) return;
3514
3538
  if (Et.current = !0, !k.current || !y || !e?.length) {
3515
3539
  Ie(!1);
@@ -3538,9 +3562,9 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3538
3562
  } finally {
3539
3563
  Ie(!1);
3540
3564
  }
3541
- }, en = async () => {
3565
+ }, tn = async () => {
3542
3566
  if (!(!k.current || !y)) {
3543
- Fe && !Et.current && Tt.current.length > 0 && await $t(Tt.current);
3567
+ Fe && !Et.current && Tt.current.length > 0 && await en(Tt.current);
3544
3568
  try {
3545
3569
  await k.current.endConversation(y);
3546
3570
  } catch {
@@ -3560,7 +3584,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3560
3584
  c(() => {
3561
3585
  if (Xe !== "connected" || !Je || !y || !Qe || !jt) return;
3562
3586
  let e = new Date(Qe).getTime(), t = Number.isFinite(e) ? Date.now() - e : 0, n = Math.max(0, jt * 1e3 - t), r = window.setTimeout(() => {
3563
- rt("The call ended because it reached the time limit."), Ut();
3587
+ rt("The call ended because it reached the time limit."), Wt();
3564
3588
  }, n);
3565
3589
  return () => window.clearTimeout(r);
3566
3590
  }, [
@@ -3568,7 +3592,7 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3568
3592
  Qe,
3569
3593
  Xe,
3570
3594
  y,
3571
- Ut,
3595
+ Wt,
3572
3596
  jt
3573
3597
  ]), c(() => {
3574
3598
  let e = () => {
@@ -3589,12 +3613,12 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3589
3613
  window.removeEventListener("pagehide", e), window.removeEventListener("beforeunload", e);
3590
3614
  };
3591
3615
  }, []);
3592
- let tn = o(() => {
3616
+ let nn = o(() => {
3593
3617
  let e = i?.siteId;
3594
3618
  ge(e), st.current = !0, ct.current = null, ot.current?.disconnect(), S([]), b(""), A.current = "", Ue(!1), re(!1), D(null), de(null), at(!0), s((e) => e + 1);
3595
- }, [i?.siteId]), nn = o((e) => {
3619
+ }, [i?.siteId]), rn = o((e) => {
3596
3620
  i?.siteId, st.current = !1, ct.current = e, ot.current?.disconnect(), S([]), b(""), A.current = "", Ue(!1), re(!1), D(null), de(null), at(!0), s((e) => e + 1);
3597
- }, [i?.siteId]), rn = f(() => ({
3621
+ }, [i?.siteId]), an = f(() => ({
3598
3622
  status: l,
3599
3623
  error: d,
3600
3624
  runtimeConfig: _,
@@ -3628,33 +3652,33 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3628
3652
  historyRef: Tt,
3629
3653
  hasSyncedRef: Et,
3630
3654
  dismissCallError: Mt,
3631
- captureVisitorEmail: Kt,
3632
- startTyping: qt,
3633
- stopTyping: Jt,
3634
- updateTypingDraft: Yt,
3655
+ captureVisitorEmail: qt,
3656
+ startTyping: Jt,
3657
+ stopTyping: Yt,
3658
+ updateTypingDraft: Xt,
3635
3659
  notifyRouteChange: () => kt.current?.notifyRouteChange?.(),
3636
- openWidget: Gt,
3660
+ openWidget: Kt,
3637
3661
  closeWidget: () => w(!1),
3638
3662
  toggleWidget: () => {
3639
3663
  if (C) {
3640
3664
  w(!1);
3641
3665
  return;
3642
3666
  }
3643
- Gt({ notifyChatInitiated: !0 });
3667
+ Kt({ notifyChatInitiated: !0 });
3644
3668
  },
3645
- sendMessage: Xt,
3646
- uploadChatFile: Zt,
3647
- setVoiceMode: Qt,
3648
- onMessageSync: $t,
3649
- endConversation: en,
3650
- startNewChat: tn,
3651
- resumeChat: nn,
3669
+ sendMessage: Zt,
3670
+ uploadChatFile: Qt,
3671
+ setVoiceMode: $t,
3672
+ onMessageSync: en,
3673
+ endConversation: tn,
3674
+ startNewChat: nn,
3675
+ resumeChat: rn,
3652
3676
  getVisitorChatHistory: () => k.current?.getVisitorChatHistory?.(),
3653
3677
  getVisitorChatThread: (e) => k.current?.getVisitorChatThread?.(e),
3654
- acceptCall: Bt,
3655
- rejectCall: Vt,
3656
- endWebRTCCall: Ut,
3657
- toggleCallMute: Wt
3678
+ acceptCall: Vt,
3679
+ rejectCall: Ht,
3680
+ endWebRTCCall: Wt,
3681
+ toggleCallMute: Gt
3658
3682
  }), [
3659
3683
  l,
3660
3684
  d,
@@ -3686,25 +3710,25 @@ function Nr({ siteId: e, config: t, children: n, language: r = "en" }) {
3686
3710
  et,
3687
3711
  nt,
3688
3712
  r,
3689
- Kt,
3690
3713
  qt,
3691
3714
  Jt,
3692
3715
  Yt,
3693
- Bt,
3716
+ Xt,
3694
3717
  Vt,
3695
- Ut,
3718
+ Ht,
3696
3719
  Wt,
3697
3720
  Gt,
3698
- Xt,
3721
+ Kt,
3699
3722
  Zt,
3700
3723
  Qt,
3701
3724
  $t,
3702
3725
  en,
3703
3726
  tn,
3727
+ nn,
3704
3728
  Mt
3705
3729
  ]);
3706
3730
  return /* @__PURE__ */ g(In.Provider, {
3707
- value: rn,
3731
+ value: an,
3708
3732
  children: n
3709
3733
  });
3710
3734
  }
@@ -26609,7 +26633,7 @@ function UD({ chatHistory: e, isAiTyping: t, isLoading: n, isAgentTyping: r, set
26609
26633
  },
26610
26634
  children: [
26611
26635
  e.map((e) => {
26612
- if (e.type === "call_recording") return null;
26636
+ if (e.type === "call_recording" || typeof e.message == "string" && e.message.includes("AI chat recording")) return null;
26613
26637
  let t = e.sender === "system", n = e.sender === "user", r = e.sender === "ai" || e.sender === "bot", c = e.sender === "agent", u = e.isPending, d = e.type === "file" && e.metadata?.fileUrl, p = e.agent_name || e.agentName || e.metadata?.agentName || s, m = typeof e.sender_headshot == "string" && e.sender_headshot.trim() || typeof o == "string" && o.trim() || null, b = ED(e.replyToContent || e.replyContext?.message || ""), x = e.replyToSender === "user" ? "You" : e.replyToSender === "agent" ? "Agent" : e.replyToSender === "ai" || e.replyToSender === "bot" ? "AI Assistant" : "Message";
26614
26638
  return t ? /* @__PURE__ */ g("div", {
26615
26639
  style: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowengage/react-chatbot",
3
- "version": "5.0.16",
3
+ "version": "5.0.18",
4
4
  "description": "Embeddable AI chat widget for React — powered by FlowEngage. Drop it in with a single siteId.",
5
5
  "keywords": [
6
6
  "chatbot",