@customerhero/js 2.3.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -105,7 +105,10 @@ var en = {
105
105
  drop_files_here: "Drop files here",
106
106
  incident_dismiss: "Dismiss",
107
107
  incident_default_link_label: "Learn more",
108
- attachment_unsupported_type: "Unsupported file type"
108
+ attachment_unsupported_type: "Unsupported file type",
109
+ attachment_open: "Open attachment",
110
+ attachment_image_alt: "Image attachment",
111
+ attachment_location: "Shared location"
109
112
  };
110
113
 
111
114
  // src/i18n/locales/es.ts
@@ -136,7 +139,10 @@ var es = {
136
139
  drop_files_here: "Suelta los archivos aqu\xED",
137
140
  incident_dismiss: "Descartar",
138
141
  incident_default_link_label: "M\xE1s informaci\xF3n",
139
- attachment_unsupported_type: "Tipo de archivo no admitido"
142
+ attachment_unsupported_type: "Tipo de archivo no admitido",
143
+ attachment_open: "Abrir adjunto",
144
+ attachment_image_alt: "Imagen adjunta",
145
+ attachment_location: "Ubicaci\xF3n compartida"
140
146
  };
141
147
 
142
148
  // src/i18n/locales/pt-BR.ts
@@ -167,7 +173,10 @@ var ptBR = {
167
173
  drop_files_here: "Solte os arquivos aqui",
168
174
  incident_dismiss: "Dispensar",
169
175
  incident_default_link_label: "Saiba mais",
170
- attachment_unsupported_type: "Tipo de arquivo n\xE3o suportado"
176
+ attachment_unsupported_type: "Tipo de arquivo n\xE3o suportado",
177
+ attachment_open: "Abrir anexo",
178
+ attachment_image_alt: "Imagem anexada",
179
+ attachment_location: "Localiza\xE7\xE3o compartilhada"
171
180
  };
172
181
 
173
182
  // src/i18n/locales/pt-PT.ts
@@ -198,7 +207,10 @@ var ptPT = {
198
207
  drop_files_here: "Largue os ficheiros aqui",
199
208
  incident_dismiss: "Dispensar",
200
209
  incident_default_link_label: "Saiba mais",
201
- attachment_unsupported_type: "Tipo de ficheiro n\xE3o suportado"
210
+ attachment_unsupported_type: "Tipo de ficheiro n\xE3o suportado",
211
+ attachment_open: "Abrir anexo",
212
+ attachment_image_alt: "Imagem anexa",
213
+ attachment_location: "Localiza\xE7\xE3o partilhada"
202
214
  };
203
215
 
204
216
  // src/i18n/locales/fr.ts
@@ -229,7 +241,10 @@ var fr = {
229
241
  drop_files_here: "D\xE9posez les fichiers ici",
230
242
  incident_dismiss: "Ignorer",
231
243
  incident_default_link_label: "En savoir plus",
232
- attachment_unsupported_type: "Type de fichier non pris en charge"
244
+ attachment_unsupported_type: "Type de fichier non pris en charge",
245
+ attachment_open: "Ouvrir la pi\xE8ce jointe",
246
+ attachment_image_alt: "Pi\xE8ce jointe (image)",
247
+ attachment_location: "Position partag\xE9e"
233
248
  };
234
249
 
235
250
  // src/i18n/locales/de.ts
@@ -260,7 +275,10 @@ var de = {
260
275
  drop_files_here: "Dateien hier ablegen",
261
276
  incident_dismiss: "Schlie\xDFen",
262
277
  incident_default_link_label: "Mehr erfahren",
263
- attachment_unsupported_type: "Dateityp nicht unterst\xFCtzt"
278
+ attachment_unsupported_type: "Dateityp nicht unterst\xFCtzt",
279
+ attachment_open: "Anhang \xF6ffnen",
280
+ attachment_image_alt: "Bildanhang",
281
+ attachment_location: "Geteilter Standort"
264
282
  };
265
283
 
266
284
  // src/i18n/locales/it.ts
@@ -291,7 +309,10 @@ var it = {
291
309
  drop_files_here: "Trascina qui i file",
292
310
  incident_dismiss: "Chiudi",
293
311
  incident_default_link_label: "Scopri di pi\xF9",
294
- attachment_unsupported_type: "Tipo di file non supportato"
312
+ attachment_unsupported_type: "Tipo di file non supportato",
313
+ attachment_open: "Apri allegato",
314
+ attachment_image_alt: "Allegato immagine",
315
+ attachment_location: "Posizione condivisa"
295
316
  };
296
317
 
297
318
  // src/i18n/locales/nl.ts
@@ -322,7 +343,10 @@ var nl = {
322
343
  drop_files_here: "Sleep bestanden hier",
323
344
  incident_dismiss: "Sluiten",
324
345
  incident_default_link_label: "Meer informatie",
325
- attachment_unsupported_type: "Bestandstype niet ondersteund"
346
+ attachment_unsupported_type: "Bestandstype niet ondersteund",
347
+ attachment_open: "Bijlage openen",
348
+ attachment_image_alt: "Afbeeldingsbijlage",
349
+ attachment_location: "Gedeelde locatie"
326
350
  };
327
351
 
328
352
  // src/i18n/locales/pl.ts
@@ -353,7 +377,10 @@ var pl = {
353
377
  drop_files_here: "Upu\u015B\u0107 pliki tutaj",
354
378
  incident_dismiss: "Zamknij",
355
379
  incident_default_link_label: "Dowiedz si\u0119 wi\u0119cej",
356
- attachment_unsupported_type: "Nieobs\u0142ugiwany typ pliku"
380
+ attachment_unsupported_type: "Nieobs\u0142ugiwany typ pliku",
381
+ attachment_open: "Otw\xF3rz za\u0142\u0105cznik",
382
+ attachment_image_alt: "Za\u0142\u0105cznik obrazu",
383
+ attachment_location: "Udost\u0119pniona lokalizacja"
357
384
  };
358
385
 
359
386
  // src/i18n/locales/tr.ts
@@ -384,7 +411,10 @@ var tr = {
384
411
  drop_files_here: "Dosyalar\u0131 buraya b\u0131rak",
385
412
  incident_dismiss: "Kapat",
386
413
  incident_default_link_label: "Daha fazla bilgi",
387
- attachment_unsupported_type: "Desteklenmeyen dosya t\xFCr\xFC"
414
+ attachment_unsupported_type: "Desteklenmeyen dosya t\xFCr\xFC",
415
+ attachment_open: "Eki a\xE7",
416
+ attachment_image_alt: "Resim eki",
417
+ attachment_location: "Payla\u015F\u0131lan konum"
388
418
  };
389
419
 
390
420
  // src/i18n/locales/ar.ts
@@ -415,7 +445,10 @@ var ar = {
415
445
  drop_files_here: "\u0623\u0641\u0644\u062A \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0647\u0646\u0627",
416
446
  incident_dismiss: "\u0625\u063A\u0644\u0627\u0642",
417
447
  incident_default_link_label: "\u0627\u0639\u0631\u0641 \u0627\u0644\u0645\u0632\u064A\u062F",
418
- attachment_unsupported_type: "\u0646\u0648\u0639 \u0627\u0644\u0645\u0644\u0641 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645"
448
+ attachment_unsupported_type: "\u0646\u0648\u0639 \u0627\u0644\u0645\u0644\u0641 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645",
449
+ attachment_open: "\u0641\u062A\u062D \u0627\u0644\u0645\u0631\u0641\u0642",
450
+ attachment_image_alt: "\u0635\u0648\u0631\u0629 \u0645\u0631\u0641\u0642\u0629",
451
+ attachment_location: "\u0645\u0648\u0642\u0639 \u0645\u0634\u062A\u0631\u0643"
419
452
  };
420
453
 
421
454
  // src/i18n/locales/ja.ts
@@ -446,7 +479,10 @@ var ja = {
446
479
  drop_files_here: "\u30D5\u30A1\u30A4\u30EB\u3092\u3053\u3053\u306B\u30C9\u30ED\u30C3\u30D7",
447
480
  incident_dismiss: "\u9589\u3058\u308B",
448
481
  incident_default_link_label: "\u8A73\u7D30\u3092\u898B\u308B",
449
- attachment_unsupported_type: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F"
482
+ attachment_unsupported_type: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F",
483
+ attachment_open: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u958B\u304F",
484
+ attachment_image_alt: "\u753B\u50CF\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB",
485
+ attachment_location: "\u5171\u6709\u3055\u308C\u305F\u4F4D\u7F6E\u60C5\u5831"
450
486
  };
451
487
 
452
488
  // src/i18n/locales/ko.ts
@@ -477,7 +513,10 @@ var ko = {
477
513
  drop_files_here: "\uD30C\uC77C\uC744 \uC5EC\uAE30\uC5D0 \uB193\uAE30",
478
514
  incident_dismiss: "\uB2EB\uAE30",
479
515
  incident_default_link_label: "\uC790\uC138\uD788 \uC54C\uC544\uBCF4\uAE30",
480
- attachment_unsupported_type: "\uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 \uD30C\uC77C \uD615\uC2DD"
516
+ attachment_unsupported_type: "\uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 \uD30C\uC77C \uD615\uC2DD",
517
+ attachment_open: "\uCCA8\uBD80 \uD30C\uC77C \uC5F4\uAE30",
518
+ attachment_image_alt: "\uC774\uBBF8\uC9C0 \uCCA8\uBD80 \uD30C\uC77C",
519
+ attachment_location: "\uACF5\uC720\uB41C \uC704\uCE58"
481
520
  };
482
521
 
483
522
  // src/i18n/locales/zh-CN.ts
@@ -508,7 +547,10 @@ var zhCN = {
508
547
  drop_files_here: "\u5C06\u6587\u4EF6\u62D6\u653E\u5230\u6B64\u5904",
509
548
  incident_dismiss: "\u5173\u95ED",
510
549
  incident_default_link_label: "\u4E86\u89E3\u66F4\u591A",
511
- attachment_unsupported_type: "\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B"
550
+ attachment_unsupported_type: "\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B",
551
+ attachment_open: "\u6253\u5F00\u9644\u4EF6",
552
+ attachment_image_alt: "\u56FE\u7247\u9644\u4EF6",
553
+ attachment_location: "\u5171\u4EAB\u7684\u4F4D\u7F6E"
512
554
  };
513
555
 
514
556
  // src/i18n/locales/zh-TW.ts
@@ -539,7 +581,10 @@ var zhTW = {
539
581
  drop_files_here: "\u5C07\u6A94\u6848\u62D6\u653E\u5230\u6B64\u8655",
540
582
  incident_dismiss: "\u95DC\u9589",
541
583
  incident_default_link_label: "\u77AD\u89E3\u66F4\u591A",
542
- attachment_unsupported_type: "\u4E0D\u652F\u63F4\u7684\u6A94\u6848\u985E\u578B"
584
+ attachment_unsupported_type: "\u4E0D\u652F\u63F4\u7684\u6A94\u6848\u985E\u578B",
585
+ attachment_open: "\u958B\u555F\u9644\u4EF6",
586
+ attachment_image_alt: "\u5716\u7247\u9644\u4EF6",
587
+ attachment_location: "\u5171\u4EAB\u7684\u4F4D\u7F6E"
543
588
  };
544
589
 
545
590
  // src/i18n/index.ts
@@ -1319,12 +1364,15 @@ var CustomerHeroChat = class {
1319
1364
  const { chatbotId, apiBase } = this.state.config;
1320
1365
  const { conversationId } = this.state;
1321
1366
  if (!conversationId) return;
1367
+ const readToken = this.storage?.getItem(`ch_conv_token_${chatbotId}`);
1368
+ const messagesUrl = `${apiBase}/api/chat/${chatbotId}/messages/${conversationId}`;
1322
1369
  try {
1323
1370
  const response = await fetch(
1324
- `${apiBase}/api/chat/${chatbotId}/messages/${conversationId}`
1371
+ readToken ? `${messagesUrl}?t=${encodeURIComponent(readToken)}` : messagesUrl
1325
1372
  );
1326
1373
  if (!response.ok) {
1327
1374
  this.storage?.removeItem(`ch_conv_${chatbotId}`);
1375
+ this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
1328
1376
  this.setState({ conversationId: null });
1329
1377
  return;
1330
1378
  }
@@ -1336,7 +1384,8 @@ var CustomerHeroChat = class {
1336
1384
  content: m.content,
1337
1385
  ...m.sources ? { sources: m.sources } : {},
1338
1386
  ...m.blocks ? { blocks: m.blocks } : {},
1339
- ...m.suggestions ? { suggestions: m.suggestions } : {}
1387
+ ...m.suggestions ? { suggestions: m.suggestions } : {},
1388
+ ...m.attachments?.length ? { attachments: m.attachments } : {}
1340
1389
  }));
1341
1390
  const lastBotIndex = findLastIndex(
1342
1391
  messages,
@@ -1389,12 +1438,14 @@ var CustomerHeroChat = class {
1389
1438
  });
1390
1439
  const { chatbotId, apiBase } = this.state.config;
1391
1440
  let botMessageCreated = false;
1441
+ const continuationReadToken = this.state.conversationId ? this.storage?.getItem(`ch_conv_token_${chatbotId}`) : null;
1392
1442
  try {
1393
1443
  const response = await fetch(`${apiBase}/api/chat/${chatbotId}`, {
1394
1444
  method: "POST",
1395
1445
  headers: {
1396
1446
  "Content-Type": "application/json",
1397
- Accept: "text/event-stream"
1447
+ Accept: "text/event-stream",
1448
+ ...continuationReadToken ? { "X-CH-Read-Token": continuationReadToken } : {}
1398
1449
  },
1399
1450
  body: JSON.stringify({
1400
1451
  message: trimmed,
@@ -1440,6 +1491,16 @@ var CustomerHeroChat = class {
1440
1491
  }
1441
1492
  break;
1442
1493
  }
1494
+ case "read-token": {
1495
+ const tok = safeParse(evt.data);
1496
+ if (tok?.readToken) {
1497
+ this.storage?.setItem(
1498
+ `ch_conv_token_${chatbotId}`,
1499
+ tok.readToken
1500
+ );
1501
+ }
1502
+ break;
1503
+ }
1443
1504
  case "token": {
1444
1505
  const tok = safeParse(evt.data);
1445
1506
  const text = tok?.text ?? "";
@@ -1552,6 +1613,9 @@ var CustomerHeroChat = class {
1552
1613
  await this.loadHistory();
1553
1614
  return;
1554
1615
  }
1616
+ const decisionBlock = this.state.messages[targetIndex].blocks?.find(
1617
+ (b) => b.type === "action_confirmation" && b.pendingToolCallId === pendingId
1618
+ );
1555
1619
  const messages = this.state.messages.slice();
1556
1620
  const original = messages[targetIndex];
1557
1621
  messages[targetIndex] = {
@@ -1560,7 +1624,10 @@ var CustomerHeroChat = class {
1560
1624
  };
1561
1625
  this.setState({ messages, error: null });
1562
1626
  const { chatbotId, apiBase } = this.state.config;
1563
- const url = `${apiBase}/api/chat/${chatbotId}/tool-calls/${pendingId}/decision`;
1627
+ const href = decision === "approve" ? decisionBlock?.approveHref : decisionBlock?.cancelHref;
1628
+ const baseUrl = href ? `${apiBase}${href}` : `${apiBase}/api/chat/${chatbotId}/tool-calls/${pendingId}/decision`;
1629
+ const readToken = this.storage?.getItem(`ch_conv_token_${chatbotId}`);
1630
+ const url = readToken ? `${baseUrl}${baseUrl.includes("?") ? "&" : "?"}t=${encodeURIComponent(readToken)}` : baseUrl;
1564
1631
  try {
1565
1632
  const response = await fetch(url, {
1566
1633
  method: "POST",
@@ -1592,6 +1659,16 @@ var CustomerHeroChat = class {
1592
1659
  }
1593
1660
  break;
1594
1661
  }
1662
+ case "read-token": {
1663
+ const tok = safeParse(evt.data);
1664
+ if (tok?.readToken) {
1665
+ this.storage?.setItem(
1666
+ `ch_conv_token_${chatbotId}`,
1667
+ tok.readToken
1668
+ );
1669
+ }
1670
+ break;
1671
+ }
1595
1672
  case "token": {
1596
1673
  const tok = safeParse(evt.data);
1597
1674
  const text = tok?.text ?? "";
@@ -1668,8 +1745,10 @@ var CustomerHeroChat = class {
1668
1745
  const { chatbotId, apiBase } = this.state.config;
1669
1746
  const { conversationId } = this.state;
1670
1747
  if (!conversationId) return;
1748
+ const readToken = this.storage?.getItem(`ch_conv_token_${chatbotId}`);
1749
+ const url = readToken ? `${apiBase}/api/chat/${chatbotId}/feedback?t=${encodeURIComponent(readToken)}` : `${apiBase}/api/chat/${chatbotId}/feedback`;
1671
1750
  try {
1672
- await fetch(`${apiBase}/api/chat/${chatbotId}/rate`, {
1751
+ await fetch(url, {
1673
1752
  method: "POST",
1674
1753
  headers: { "Content-Type": "application/json" },
1675
1754
  body: JSON.stringify({ conversationId, messageId, rating })
@@ -1698,6 +1777,7 @@ var CustomerHeroChat = class {
1698
1777
  reset() {
1699
1778
  const { chatbotId, welcomeMessage } = this.state.config;
1700
1779
  this.storage?.removeItem(`ch_conv_${chatbotId}`);
1780
+ this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
1701
1781
  this.setState({
1702
1782
  messages: welcomeMessage ? [{ role: "bot", content: welcomeMessage }] : [],
1703
1783
  conversationId: null,
@@ -1865,6 +1945,7 @@ var CustomerHeroChat = class {
1865
1945
  };
1866
1946
  const { chatbotId, welcomeMessage } = this.state.config;
1867
1947
  this.storage?.removeItem(`ch_conv_${chatbotId}`);
1948
+ this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
1868
1949
  this.setState({
1869
1950
  messages: welcomeMessage ? [{ role: "bot", content: welcomeMessage }] : [],
1870
1951
  conversationId: null,
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- type TranslationKey = "online" | "typing" | "unable_to_load" | "powered_by" | "new_conversation" | "open_chat" | "close_chat" | "send_message" | "helpful" | "not_helpful" | "menu" | "action_approve" | "action_cancel" | "action_what_will_happen" | "action_already_resolved" | "action_failed" | "status_sending" | "status_sent" | "status_failed" | "screenshot_capture" | "attachment_remove" | "attach_menu_open" | "attach_photo" | "drop_files_here" | "attachment_unsupported_type" | "incident_dismiss" | "incident_default_link_label";
1
+ type TranslationKey = "online" | "typing" | "unable_to_load" | "powered_by" | "new_conversation" | "open_chat" | "close_chat" | "send_message" | "helpful" | "not_helpful" | "menu" | "action_approve" | "action_cancel" | "action_what_will_happen" | "action_already_resolved" | "action_failed" | "status_sending" | "status_sent" | "status_failed" | "screenshot_capture" | "attachment_remove" | "attach_menu_open" | "attach_photo" | "drop_files_here" | "attachment_unsupported_type" | "attachment_open" | "attachment_image_alt" | "attachment_location" | "incident_dismiss" | "incident_default_link_label";
2
2
  type Translations = Record<TranslationKey, string>;
3
3
 
4
4
  declare const SUPPORTED_LOCALES: readonly ["en", "es", "pt-BR", "pt-PT", "fr", "de", "it", "nl", "pl", "tr", "ar", "ja", "ko", "zh-CN", "zh-TW"];
@@ -137,6 +137,27 @@ type ActionConfirmationBlock = {
137
137
  };
138
138
  type MessageBlock = QuickRepliesBlock | ActionConfirmationBlock;
139
139
  type MessageStatus = "sending" | "sent" | "failed";
140
+ /**
141
+ * Attachment hung off a historical message. The widget only ever uploads
142
+ * `image` and `document` kinds, but inbox agents can attach `audio` /
143
+ * `video` / `location` from the dashboard, and the history endpoint returns
144
+ * everything the conversation has accumulated.
145
+ */
146
+ interface MessageAttachment {
147
+ id: string;
148
+ kind: "image" | "document" | "audio" | "video" | "location";
149
+ mimeType: string | null;
150
+ filename: string | null;
151
+ sizeBytes: number | null;
152
+ /** Public R2 URL. Null for `location` attachments (use `location` instead). */
153
+ url: string | null;
154
+ /** Geo payload for `location` attachments. */
155
+ location: {
156
+ label?: string | null;
157
+ latitude: number;
158
+ longitude: number;
159
+ } | null;
160
+ }
140
161
  interface ChatMessage {
141
162
  /** Message ID from the API (only present for bot messages) */
142
163
  id?: string;
@@ -151,6 +172,11 @@ interface ChatMessage {
151
172
  * tappable chips under the most recent bot message only.
152
173
  */
153
174
  suggestions?: string[];
175
+ /**
176
+ * Files / screenshots / locations attached to this message. Populated from
177
+ * the history endpoint on conversation reload.
178
+ */
179
+ attachments?: MessageAttachment[];
154
180
  /** True while this message is still receiving streaming tokens. */
155
181
  streaming?: boolean;
156
182
  /**
@@ -617,4 +643,4 @@ interface StartTriggersRuntimeOptions {
617
643
  }
618
644
  declare function startTriggersRuntime(options: StartTriggersRuntimeOptions): TriggersRuntimeHandle;
619
645
 
620
- export { type ActionConfirmationBlock, CORNER_RADIUS, type ChatMessage, type ChatState, type ConsentSettings, CustomerHeroChat, type CustomerHeroChatConfig, DEFAULTS, type EffectiveScheme, type IdentifyPayload, type IdentityData, type IncidentBanner, type MessageBlock, type MessageRating, type MessageSource, type MessageStatus, type PreChatField, type PreChatFieldKind, type PreChatFormConfig, type PreChatSubmission, type QuickRepliesBlock, type ResolvedConfig, SIZE_PRESETS, SUPPORTED_LOCALES, ScreenshotCancelled, ScreenshotUnavailable, type StringOverrides, type SupportedLocale, type TranslateFn, type TranslationKey, type Translations, type TriggerAction, type TriggerConditionLeaf, type TriggerConditionNode, type TriggerDefinition, type TriggerFrequency, type TriggersRuntimeHandle, type VisitorContext, canCaptureScreenshot, captureScreenshot, createTranslator, detectLocale, effectiveColors, evaluate, isRtlLocale, panelRadius, pickFire, resolveLocale, resolveScheme, sizePreset, startTriggersRuntime };
646
+ export { type ActionConfirmationBlock, CORNER_RADIUS, type ChatMessage, type ChatState, type ConsentSettings, CustomerHeroChat, type CustomerHeroChatConfig, DEFAULTS, type EffectiveScheme, type IdentifyPayload, type IdentityData, type IncidentBanner, type MessageAttachment, type MessageBlock, type MessageRating, type MessageSource, type MessageStatus, type PreChatField, type PreChatFieldKind, type PreChatFormConfig, type PreChatSubmission, type QuickRepliesBlock, type ResolvedConfig, SIZE_PRESETS, SUPPORTED_LOCALES, ScreenshotCancelled, ScreenshotUnavailable, type StringOverrides, type SupportedLocale, type TranslateFn, type TranslationKey, type Translations, type TriggerAction, type TriggerConditionLeaf, type TriggerConditionNode, type TriggerDefinition, type TriggerFrequency, type TriggersRuntimeHandle, type VisitorContext, canCaptureScreenshot, captureScreenshot, createTranslator, detectLocale, effectiveColors, evaluate, isRtlLocale, panelRadius, pickFire, resolveLocale, resolveScheme, sizePreset, startTriggersRuntime };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- type TranslationKey = "online" | "typing" | "unable_to_load" | "powered_by" | "new_conversation" | "open_chat" | "close_chat" | "send_message" | "helpful" | "not_helpful" | "menu" | "action_approve" | "action_cancel" | "action_what_will_happen" | "action_already_resolved" | "action_failed" | "status_sending" | "status_sent" | "status_failed" | "screenshot_capture" | "attachment_remove" | "attach_menu_open" | "attach_photo" | "drop_files_here" | "attachment_unsupported_type" | "incident_dismiss" | "incident_default_link_label";
1
+ type TranslationKey = "online" | "typing" | "unable_to_load" | "powered_by" | "new_conversation" | "open_chat" | "close_chat" | "send_message" | "helpful" | "not_helpful" | "menu" | "action_approve" | "action_cancel" | "action_what_will_happen" | "action_already_resolved" | "action_failed" | "status_sending" | "status_sent" | "status_failed" | "screenshot_capture" | "attachment_remove" | "attach_menu_open" | "attach_photo" | "drop_files_here" | "attachment_unsupported_type" | "attachment_open" | "attachment_image_alt" | "attachment_location" | "incident_dismiss" | "incident_default_link_label";
2
2
  type Translations = Record<TranslationKey, string>;
3
3
 
4
4
  declare const SUPPORTED_LOCALES: readonly ["en", "es", "pt-BR", "pt-PT", "fr", "de", "it", "nl", "pl", "tr", "ar", "ja", "ko", "zh-CN", "zh-TW"];
@@ -137,6 +137,27 @@ type ActionConfirmationBlock = {
137
137
  };
138
138
  type MessageBlock = QuickRepliesBlock | ActionConfirmationBlock;
139
139
  type MessageStatus = "sending" | "sent" | "failed";
140
+ /**
141
+ * Attachment hung off a historical message. The widget only ever uploads
142
+ * `image` and `document` kinds, but inbox agents can attach `audio` /
143
+ * `video` / `location` from the dashboard, and the history endpoint returns
144
+ * everything the conversation has accumulated.
145
+ */
146
+ interface MessageAttachment {
147
+ id: string;
148
+ kind: "image" | "document" | "audio" | "video" | "location";
149
+ mimeType: string | null;
150
+ filename: string | null;
151
+ sizeBytes: number | null;
152
+ /** Public R2 URL. Null for `location` attachments (use `location` instead). */
153
+ url: string | null;
154
+ /** Geo payload for `location` attachments. */
155
+ location: {
156
+ label?: string | null;
157
+ latitude: number;
158
+ longitude: number;
159
+ } | null;
160
+ }
140
161
  interface ChatMessage {
141
162
  /** Message ID from the API (only present for bot messages) */
142
163
  id?: string;
@@ -151,6 +172,11 @@ interface ChatMessage {
151
172
  * tappable chips under the most recent bot message only.
152
173
  */
153
174
  suggestions?: string[];
175
+ /**
176
+ * Files / screenshots / locations attached to this message. Populated from
177
+ * the history endpoint on conversation reload.
178
+ */
179
+ attachments?: MessageAttachment[];
154
180
  /** True while this message is still receiving streaming tokens. */
155
181
  streaming?: boolean;
156
182
  /**
@@ -617,4 +643,4 @@ interface StartTriggersRuntimeOptions {
617
643
  }
618
644
  declare function startTriggersRuntime(options: StartTriggersRuntimeOptions): TriggersRuntimeHandle;
619
645
 
620
- export { type ActionConfirmationBlock, CORNER_RADIUS, type ChatMessage, type ChatState, type ConsentSettings, CustomerHeroChat, type CustomerHeroChatConfig, DEFAULTS, type EffectiveScheme, type IdentifyPayload, type IdentityData, type IncidentBanner, type MessageBlock, type MessageRating, type MessageSource, type MessageStatus, type PreChatField, type PreChatFieldKind, type PreChatFormConfig, type PreChatSubmission, type QuickRepliesBlock, type ResolvedConfig, SIZE_PRESETS, SUPPORTED_LOCALES, ScreenshotCancelled, ScreenshotUnavailable, type StringOverrides, type SupportedLocale, type TranslateFn, type TranslationKey, type Translations, type TriggerAction, type TriggerConditionLeaf, type TriggerConditionNode, type TriggerDefinition, type TriggerFrequency, type TriggersRuntimeHandle, type VisitorContext, canCaptureScreenshot, captureScreenshot, createTranslator, detectLocale, effectiveColors, evaluate, isRtlLocale, panelRadius, pickFire, resolveLocale, resolveScheme, sizePreset, startTriggersRuntime };
646
+ export { type ActionConfirmationBlock, CORNER_RADIUS, type ChatMessage, type ChatState, type ConsentSettings, CustomerHeroChat, type CustomerHeroChatConfig, DEFAULTS, type EffectiveScheme, type IdentifyPayload, type IdentityData, type IncidentBanner, type MessageAttachment, type MessageBlock, type MessageRating, type MessageSource, type MessageStatus, type PreChatField, type PreChatFieldKind, type PreChatFormConfig, type PreChatSubmission, type QuickRepliesBlock, type ResolvedConfig, SIZE_PRESETS, SUPPORTED_LOCALES, ScreenshotCancelled, ScreenshotUnavailable, type StringOverrides, type SupportedLocale, type TranslateFn, type TranslationKey, type Translations, type TriggerAction, type TriggerConditionLeaf, type TriggerConditionNode, type TriggerDefinition, type TriggerFrequency, type TriggersRuntimeHandle, type VisitorContext, canCaptureScreenshot, captureScreenshot, createTranslator, detectLocale, effectiveColors, evaluate, isRtlLocale, panelRadius, pickFire, resolveLocale, resolveScheme, sizePreset, startTriggersRuntime };
package/dist/index.js CHANGED
@@ -60,7 +60,10 @@ var en = {
60
60
  drop_files_here: "Drop files here",
61
61
  incident_dismiss: "Dismiss",
62
62
  incident_default_link_label: "Learn more",
63
- attachment_unsupported_type: "Unsupported file type"
63
+ attachment_unsupported_type: "Unsupported file type",
64
+ attachment_open: "Open attachment",
65
+ attachment_image_alt: "Image attachment",
66
+ attachment_location: "Shared location"
64
67
  };
65
68
 
66
69
  // src/i18n/locales/es.ts
@@ -91,7 +94,10 @@ var es = {
91
94
  drop_files_here: "Suelta los archivos aqu\xED",
92
95
  incident_dismiss: "Descartar",
93
96
  incident_default_link_label: "M\xE1s informaci\xF3n",
94
- attachment_unsupported_type: "Tipo de archivo no admitido"
97
+ attachment_unsupported_type: "Tipo de archivo no admitido",
98
+ attachment_open: "Abrir adjunto",
99
+ attachment_image_alt: "Imagen adjunta",
100
+ attachment_location: "Ubicaci\xF3n compartida"
95
101
  };
96
102
 
97
103
  // src/i18n/locales/pt-BR.ts
@@ -122,7 +128,10 @@ var ptBR = {
122
128
  drop_files_here: "Solte os arquivos aqui",
123
129
  incident_dismiss: "Dispensar",
124
130
  incident_default_link_label: "Saiba mais",
125
- attachment_unsupported_type: "Tipo de arquivo n\xE3o suportado"
131
+ attachment_unsupported_type: "Tipo de arquivo n\xE3o suportado",
132
+ attachment_open: "Abrir anexo",
133
+ attachment_image_alt: "Imagem anexada",
134
+ attachment_location: "Localiza\xE7\xE3o compartilhada"
126
135
  };
127
136
 
128
137
  // src/i18n/locales/pt-PT.ts
@@ -153,7 +162,10 @@ var ptPT = {
153
162
  drop_files_here: "Largue os ficheiros aqui",
154
163
  incident_dismiss: "Dispensar",
155
164
  incident_default_link_label: "Saiba mais",
156
- attachment_unsupported_type: "Tipo de ficheiro n\xE3o suportado"
165
+ attachment_unsupported_type: "Tipo de ficheiro n\xE3o suportado",
166
+ attachment_open: "Abrir anexo",
167
+ attachment_image_alt: "Imagem anexa",
168
+ attachment_location: "Localiza\xE7\xE3o partilhada"
157
169
  };
158
170
 
159
171
  // src/i18n/locales/fr.ts
@@ -184,7 +196,10 @@ var fr = {
184
196
  drop_files_here: "D\xE9posez les fichiers ici",
185
197
  incident_dismiss: "Ignorer",
186
198
  incident_default_link_label: "En savoir plus",
187
- attachment_unsupported_type: "Type de fichier non pris en charge"
199
+ attachment_unsupported_type: "Type de fichier non pris en charge",
200
+ attachment_open: "Ouvrir la pi\xE8ce jointe",
201
+ attachment_image_alt: "Pi\xE8ce jointe (image)",
202
+ attachment_location: "Position partag\xE9e"
188
203
  };
189
204
 
190
205
  // src/i18n/locales/de.ts
@@ -215,7 +230,10 @@ var de = {
215
230
  drop_files_here: "Dateien hier ablegen",
216
231
  incident_dismiss: "Schlie\xDFen",
217
232
  incident_default_link_label: "Mehr erfahren",
218
- attachment_unsupported_type: "Dateityp nicht unterst\xFCtzt"
233
+ attachment_unsupported_type: "Dateityp nicht unterst\xFCtzt",
234
+ attachment_open: "Anhang \xF6ffnen",
235
+ attachment_image_alt: "Bildanhang",
236
+ attachment_location: "Geteilter Standort"
219
237
  };
220
238
 
221
239
  // src/i18n/locales/it.ts
@@ -246,7 +264,10 @@ var it = {
246
264
  drop_files_here: "Trascina qui i file",
247
265
  incident_dismiss: "Chiudi",
248
266
  incident_default_link_label: "Scopri di pi\xF9",
249
- attachment_unsupported_type: "Tipo di file non supportato"
267
+ attachment_unsupported_type: "Tipo di file non supportato",
268
+ attachment_open: "Apri allegato",
269
+ attachment_image_alt: "Allegato immagine",
270
+ attachment_location: "Posizione condivisa"
250
271
  };
251
272
 
252
273
  // src/i18n/locales/nl.ts
@@ -277,7 +298,10 @@ var nl = {
277
298
  drop_files_here: "Sleep bestanden hier",
278
299
  incident_dismiss: "Sluiten",
279
300
  incident_default_link_label: "Meer informatie",
280
- attachment_unsupported_type: "Bestandstype niet ondersteund"
301
+ attachment_unsupported_type: "Bestandstype niet ondersteund",
302
+ attachment_open: "Bijlage openen",
303
+ attachment_image_alt: "Afbeeldingsbijlage",
304
+ attachment_location: "Gedeelde locatie"
281
305
  };
282
306
 
283
307
  // src/i18n/locales/pl.ts
@@ -308,7 +332,10 @@ var pl = {
308
332
  drop_files_here: "Upu\u015B\u0107 pliki tutaj",
309
333
  incident_dismiss: "Zamknij",
310
334
  incident_default_link_label: "Dowiedz si\u0119 wi\u0119cej",
311
- attachment_unsupported_type: "Nieobs\u0142ugiwany typ pliku"
335
+ attachment_unsupported_type: "Nieobs\u0142ugiwany typ pliku",
336
+ attachment_open: "Otw\xF3rz za\u0142\u0105cznik",
337
+ attachment_image_alt: "Za\u0142\u0105cznik obrazu",
338
+ attachment_location: "Udost\u0119pniona lokalizacja"
312
339
  };
313
340
 
314
341
  // src/i18n/locales/tr.ts
@@ -339,7 +366,10 @@ var tr = {
339
366
  drop_files_here: "Dosyalar\u0131 buraya b\u0131rak",
340
367
  incident_dismiss: "Kapat",
341
368
  incident_default_link_label: "Daha fazla bilgi",
342
- attachment_unsupported_type: "Desteklenmeyen dosya t\xFCr\xFC"
369
+ attachment_unsupported_type: "Desteklenmeyen dosya t\xFCr\xFC",
370
+ attachment_open: "Eki a\xE7",
371
+ attachment_image_alt: "Resim eki",
372
+ attachment_location: "Payla\u015F\u0131lan konum"
343
373
  };
344
374
 
345
375
  // src/i18n/locales/ar.ts
@@ -370,7 +400,10 @@ var ar = {
370
400
  drop_files_here: "\u0623\u0641\u0644\u062A \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0647\u0646\u0627",
371
401
  incident_dismiss: "\u0625\u063A\u0644\u0627\u0642",
372
402
  incident_default_link_label: "\u0627\u0639\u0631\u0641 \u0627\u0644\u0645\u0632\u064A\u062F",
373
- attachment_unsupported_type: "\u0646\u0648\u0639 \u0627\u0644\u0645\u0644\u0641 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645"
403
+ attachment_unsupported_type: "\u0646\u0648\u0639 \u0627\u0644\u0645\u0644\u0641 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645",
404
+ attachment_open: "\u0641\u062A\u062D \u0627\u0644\u0645\u0631\u0641\u0642",
405
+ attachment_image_alt: "\u0635\u0648\u0631\u0629 \u0645\u0631\u0641\u0642\u0629",
406
+ attachment_location: "\u0645\u0648\u0642\u0639 \u0645\u0634\u062A\u0631\u0643"
374
407
  };
375
408
 
376
409
  // src/i18n/locales/ja.ts
@@ -401,7 +434,10 @@ var ja = {
401
434
  drop_files_here: "\u30D5\u30A1\u30A4\u30EB\u3092\u3053\u3053\u306B\u30C9\u30ED\u30C3\u30D7",
402
435
  incident_dismiss: "\u9589\u3058\u308B",
403
436
  incident_default_link_label: "\u8A73\u7D30\u3092\u898B\u308B",
404
- attachment_unsupported_type: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F"
437
+ attachment_unsupported_type: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F",
438
+ attachment_open: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u958B\u304F",
439
+ attachment_image_alt: "\u753B\u50CF\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB",
440
+ attachment_location: "\u5171\u6709\u3055\u308C\u305F\u4F4D\u7F6E\u60C5\u5831"
405
441
  };
406
442
 
407
443
  // src/i18n/locales/ko.ts
@@ -432,7 +468,10 @@ var ko = {
432
468
  drop_files_here: "\uD30C\uC77C\uC744 \uC5EC\uAE30\uC5D0 \uB193\uAE30",
433
469
  incident_dismiss: "\uB2EB\uAE30",
434
470
  incident_default_link_label: "\uC790\uC138\uD788 \uC54C\uC544\uBCF4\uAE30",
435
- attachment_unsupported_type: "\uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 \uD30C\uC77C \uD615\uC2DD"
471
+ attachment_unsupported_type: "\uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 \uD30C\uC77C \uD615\uC2DD",
472
+ attachment_open: "\uCCA8\uBD80 \uD30C\uC77C \uC5F4\uAE30",
473
+ attachment_image_alt: "\uC774\uBBF8\uC9C0 \uCCA8\uBD80 \uD30C\uC77C",
474
+ attachment_location: "\uACF5\uC720\uB41C \uC704\uCE58"
436
475
  };
437
476
 
438
477
  // src/i18n/locales/zh-CN.ts
@@ -463,7 +502,10 @@ var zhCN = {
463
502
  drop_files_here: "\u5C06\u6587\u4EF6\u62D6\u653E\u5230\u6B64\u5904",
464
503
  incident_dismiss: "\u5173\u95ED",
465
504
  incident_default_link_label: "\u4E86\u89E3\u66F4\u591A",
466
- attachment_unsupported_type: "\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B"
505
+ attachment_unsupported_type: "\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B",
506
+ attachment_open: "\u6253\u5F00\u9644\u4EF6",
507
+ attachment_image_alt: "\u56FE\u7247\u9644\u4EF6",
508
+ attachment_location: "\u5171\u4EAB\u7684\u4F4D\u7F6E"
467
509
  };
468
510
 
469
511
  // src/i18n/locales/zh-TW.ts
@@ -494,7 +536,10 @@ var zhTW = {
494
536
  drop_files_here: "\u5C07\u6A94\u6848\u62D6\u653E\u5230\u6B64\u8655",
495
537
  incident_dismiss: "\u95DC\u9589",
496
538
  incident_default_link_label: "\u77AD\u89E3\u66F4\u591A",
497
- attachment_unsupported_type: "\u4E0D\u652F\u63F4\u7684\u6A94\u6848\u985E\u578B"
539
+ attachment_unsupported_type: "\u4E0D\u652F\u63F4\u7684\u6A94\u6848\u985E\u578B",
540
+ attachment_open: "\u958B\u555F\u9644\u4EF6",
541
+ attachment_image_alt: "\u5716\u7247\u9644\u4EF6",
542
+ attachment_location: "\u5171\u4EAB\u7684\u4F4D\u7F6E"
498
543
  };
499
544
 
500
545
  // src/i18n/index.ts
@@ -1274,12 +1319,15 @@ var CustomerHeroChat = class {
1274
1319
  const { chatbotId, apiBase } = this.state.config;
1275
1320
  const { conversationId } = this.state;
1276
1321
  if (!conversationId) return;
1322
+ const readToken = this.storage?.getItem(`ch_conv_token_${chatbotId}`);
1323
+ const messagesUrl = `${apiBase}/api/chat/${chatbotId}/messages/${conversationId}`;
1277
1324
  try {
1278
1325
  const response = await fetch(
1279
- `${apiBase}/api/chat/${chatbotId}/messages/${conversationId}`
1326
+ readToken ? `${messagesUrl}?t=${encodeURIComponent(readToken)}` : messagesUrl
1280
1327
  );
1281
1328
  if (!response.ok) {
1282
1329
  this.storage?.removeItem(`ch_conv_${chatbotId}`);
1330
+ this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
1283
1331
  this.setState({ conversationId: null });
1284
1332
  return;
1285
1333
  }
@@ -1291,7 +1339,8 @@ var CustomerHeroChat = class {
1291
1339
  content: m.content,
1292
1340
  ...m.sources ? { sources: m.sources } : {},
1293
1341
  ...m.blocks ? { blocks: m.blocks } : {},
1294
- ...m.suggestions ? { suggestions: m.suggestions } : {}
1342
+ ...m.suggestions ? { suggestions: m.suggestions } : {},
1343
+ ...m.attachments?.length ? { attachments: m.attachments } : {}
1295
1344
  }));
1296
1345
  const lastBotIndex = findLastIndex(
1297
1346
  messages,
@@ -1344,12 +1393,14 @@ var CustomerHeroChat = class {
1344
1393
  });
1345
1394
  const { chatbotId, apiBase } = this.state.config;
1346
1395
  let botMessageCreated = false;
1396
+ const continuationReadToken = this.state.conversationId ? this.storage?.getItem(`ch_conv_token_${chatbotId}`) : null;
1347
1397
  try {
1348
1398
  const response = await fetch(`${apiBase}/api/chat/${chatbotId}`, {
1349
1399
  method: "POST",
1350
1400
  headers: {
1351
1401
  "Content-Type": "application/json",
1352
- Accept: "text/event-stream"
1402
+ Accept: "text/event-stream",
1403
+ ...continuationReadToken ? { "X-CH-Read-Token": continuationReadToken } : {}
1353
1404
  },
1354
1405
  body: JSON.stringify({
1355
1406
  message: trimmed,
@@ -1395,6 +1446,16 @@ var CustomerHeroChat = class {
1395
1446
  }
1396
1447
  break;
1397
1448
  }
1449
+ case "read-token": {
1450
+ const tok = safeParse(evt.data);
1451
+ if (tok?.readToken) {
1452
+ this.storage?.setItem(
1453
+ `ch_conv_token_${chatbotId}`,
1454
+ tok.readToken
1455
+ );
1456
+ }
1457
+ break;
1458
+ }
1398
1459
  case "token": {
1399
1460
  const tok = safeParse(evt.data);
1400
1461
  const text = tok?.text ?? "";
@@ -1507,6 +1568,9 @@ var CustomerHeroChat = class {
1507
1568
  await this.loadHistory();
1508
1569
  return;
1509
1570
  }
1571
+ const decisionBlock = this.state.messages[targetIndex].blocks?.find(
1572
+ (b) => b.type === "action_confirmation" && b.pendingToolCallId === pendingId
1573
+ );
1510
1574
  const messages = this.state.messages.slice();
1511
1575
  const original = messages[targetIndex];
1512
1576
  messages[targetIndex] = {
@@ -1515,7 +1579,10 @@ var CustomerHeroChat = class {
1515
1579
  };
1516
1580
  this.setState({ messages, error: null });
1517
1581
  const { chatbotId, apiBase } = this.state.config;
1518
- const url = `${apiBase}/api/chat/${chatbotId}/tool-calls/${pendingId}/decision`;
1582
+ const href = decision === "approve" ? decisionBlock?.approveHref : decisionBlock?.cancelHref;
1583
+ const baseUrl = href ? `${apiBase}${href}` : `${apiBase}/api/chat/${chatbotId}/tool-calls/${pendingId}/decision`;
1584
+ const readToken = this.storage?.getItem(`ch_conv_token_${chatbotId}`);
1585
+ const url = readToken ? `${baseUrl}${baseUrl.includes("?") ? "&" : "?"}t=${encodeURIComponent(readToken)}` : baseUrl;
1519
1586
  try {
1520
1587
  const response = await fetch(url, {
1521
1588
  method: "POST",
@@ -1547,6 +1614,16 @@ var CustomerHeroChat = class {
1547
1614
  }
1548
1615
  break;
1549
1616
  }
1617
+ case "read-token": {
1618
+ const tok = safeParse(evt.data);
1619
+ if (tok?.readToken) {
1620
+ this.storage?.setItem(
1621
+ `ch_conv_token_${chatbotId}`,
1622
+ tok.readToken
1623
+ );
1624
+ }
1625
+ break;
1626
+ }
1550
1627
  case "token": {
1551
1628
  const tok = safeParse(evt.data);
1552
1629
  const text = tok?.text ?? "";
@@ -1623,8 +1700,10 @@ var CustomerHeroChat = class {
1623
1700
  const { chatbotId, apiBase } = this.state.config;
1624
1701
  const { conversationId } = this.state;
1625
1702
  if (!conversationId) return;
1703
+ const readToken = this.storage?.getItem(`ch_conv_token_${chatbotId}`);
1704
+ const url = readToken ? `${apiBase}/api/chat/${chatbotId}/feedback?t=${encodeURIComponent(readToken)}` : `${apiBase}/api/chat/${chatbotId}/feedback`;
1626
1705
  try {
1627
- await fetch(`${apiBase}/api/chat/${chatbotId}/rate`, {
1706
+ await fetch(url, {
1628
1707
  method: "POST",
1629
1708
  headers: { "Content-Type": "application/json" },
1630
1709
  body: JSON.stringify({ conversationId, messageId, rating })
@@ -1653,6 +1732,7 @@ var CustomerHeroChat = class {
1653
1732
  reset() {
1654
1733
  const { chatbotId, welcomeMessage } = this.state.config;
1655
1734
  this.storage?.removeItem(`ch_conv_${chatbotId}`);
1735
+ this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
1656
1736
  this.setState({
1657
1737
  messages: welcomeMessage ? [{ role: "bot", content: welcomeMessage }] : [],
1658
1738
  conversationId: null,
@@ -1820,6 +1900,7 @@ var CustomerHeroChat = class {
1820
1900
  };
1821
1901
  const { chatbotId, welcomeMessage } = this.state.config;
1822
1902
  this.storage?.removeItem(`ch_conv_${chatbotId}`);
1903
+ this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
1823
1904
  this.setState({
1824
1905
  messages: welcomeMessage ? [{ role: "bot", content: welcomeMessage }] : [],
1825
1906
  conversationId: null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@customerhero/js",
3
- "version": "2.3.0",
3
+ "version": "2.4.1",
4
4
  "private": false,
5
5
  "description": "Framework-agnostic JavaScript client for the CustomerHero chat widget.",
6
6
  "keywords": [