@ada-support/embed2 1.14.12 → 1.14.14

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.
@@ -19,6 +19,10 @@ export interface EmbedRequestPayloadByEvent {
19
19
  url: string;
20
20
  openInNewTab: boolean;
21
21
  };
22
+ proactiveConfig?: {
23
+ key: string;
24
+ params: Record<string, string>;
25
+ };
22
26
  };
23
27
  DELETE_HISTORY: undefined;
24
28
  DISPATCH: StoreDispatchPayload;
@@ -45,6 +45,7 @@ export interface StoreState extends StartOptionsNoFunction {
45
45
  adaSettings: StartOptions;
46
46
  wasCampaignShownButNowClosed: boolean;
47
47
  proactiveCampaignHadMessages: boolean;
48
+ proactiveEngaged: boolean;
48
49
  deviceToken: string | null;
49
50
  activeModality?: Modality;
50
51
  }
@@ -16125,7 +16125,7 @@ const client = new BrowserClient({
16125
16125
  return event;
16126
16126
  },
16127
16127
  environment: "production",
16128
- release: "1.14.12-ab0ec43",
16128
+ release: "1.14.14-ac7ed67",
16129
16129
  sampleRate: 0.25,
16130
16130
  autoSessionTracking: false,
16131
16131
  // Integrations don't seem to work with Sentry: https://github.com/getsentry/sentry-javascript/issues/2541
@@ -16751,7 +16751,7 @@ function getEmbedURL(_ref) {
16751
16751
  } else {
16752
16752
  host = `http://${handle}.localhost:${ports.localhost.default}`;
16753
16753
  }
16754
- return `${host}/embed/${frameName}/${"ab0ec43"}/index.html`;
16754
+ return `${host}/embed/${frameName}/${"ac7ed67"}/index.html`;
16755
16755
  }
16756
16756
  function constructQueryString(query) {
16757
16757
  return Object.keys(query).map(key => {
@@ -17489,6 +17489,7 @@ const getInitialState = adaSettings => ({
17489
17489
  chatterInLiveChat: false,
17490
17490
  wasCampaignShownButNowClosed: false,
17491
17491
  proactiveCampaignHadMessages: false,
17492
+ proactiveEngaged: false,
17492
17493
  deviceToken: null,
17493
17494
  showFallbackOnTimeout: true
17494
17495
  });
@@ -17538,9 +17539,9 @@ async function log(message, extra, options) {
17538
17539
  service: "embed",
17539
17540
  env: "production",
17540
17541
  embedVersion: 2,
17541
- version: "1.14.12",
17542
+ version: "1.14.14",
17542
17543
  isNpm: true,
17543
- commitHash: "ab0ec43"
17544
+ commitHash: "ac7ed67"
17544
17545
  }))
17545
17546
  });
17546
17547
  }
@@ -18671,6 +18672,11 @@ function proactiveConversation_objectSpread(e) { for (var r = 1; r < arguments.l
18671
18672
 
18672
18673
 
18673
18674
 
18675
+ // Once-per-user suppression persists in localStorage across sessions. It uses a
18676
+ // key distinct from `proactive_conversations_shown` because that key is owned by
18677
+ // the ranking "shown" set (see getRankedShownKeys); sharing it would conflate
18678
+ // user-frequency suppression with ranking's advance-across-visits state.
18679
+ const USER_FREQUENCY_STORAGE_KEY = "proactive_conversations_shown_user";
18674
18680
  function proactiveShownWithinFrequency(proactiveConversationKey, frequency, handle) {
18675
18681
  switch (frequency) {
18676
18682
  case "always":
@@ -18681,6 +18687,12 @@ function proactiveShownWithinFrequency(proactiveConversationKey, frequency, hand
18681
18687
  const perSessionProactives = storageValue ? (storageValue[handle] || "").split(",") : [];
18682
18688
  return perSessionProactives.includes(proactiveConversationKey);
18683
18689
  }
18690
+ case "user":
18691
+ {
18692
+ const storageValue = dist/* adaLocalStorage */.BB.getFnItem(USER_FREQUENCY_STORAGE_KEY);
18693
+ const perUserProactives = storageValue ? (storageValue[handle] || "").split(",") : [];
18694
+ return perUserProactives.includes(proactiveConversationKey);
18695
+ }
18684
18696
  default:
18685
18697
  return false;
18686
18698
  }
@@ -18762,6 +18774,15 @@ function recordProactiveTrigger(proactiveConversationKey, frequency, handle) {
18762
18774
  }));
18763
18775
  break;
18764
18776
  }
18777
+ case "user":
18778
+ {
18779
+ const currentStorageValue = dist/* adaLocalStorage */.BB.getFnItem(USER_FREQUENCY_STORAGE_KEY);
18780
+ const newStorageValue = addProactiveToStorageString(currentStorageValue ? currentStorageValue[handle] || "" : "", proactiveConversationKey);
18781
+ dist/* adaLocalStorage */.BB.setFnItem(USER_FREQUENCY_STORAGE_KEY, proactiveConversation_objectSpread(proactiveConversation_objectSpread({}, currentStorageValue), {}, {
18782
+ [handle]: newStorageValue
18783
+ }));
18784
+ break;
18785
+ }
18765
18786
  default:
18766
18787
  break;
18767
18788
  }
@@ -18799,7 +18820,6 @@ function proactiveTriggerImpl(_ref3) {
18799
18820
  adaSettings,
18800
18821
  messageService,
18801
18822
  language,
18802
- setRecentProactiveConversationConfig,
18803
18823
  clearProactiveConversation
18804
18824
  } = _ref3;
18805
18825
  const {
@@ -18865,10 +18885,6 @@ function proactiveTriggerImpl(_ref3) {
18865
18885
  if (triggerMethod === "url") {
18866
18886
  recordRankedShown(handle, messageKey);
18867
18887
  }
18868
- setRecentProactiveConversationConfig({
18869
- key: messageKey,
18870
- params
18871
- });
18872
18888
  const {
18873
18889
  image,
18874
18890
  cta
@@ -18880,7 +18896,11 @@ function proactiveTriggerImpl(_ref3) {
18880
18896
  duration,
18881
18897
  delay,
18882
18898
  image,
18883
- cta
18899
+ cta,
18900
+ proactiveConfig: {
18901
+ key: messageKey,
18902
+ params
18903
+ }
18884
18904
  });
18885
18905
  log("Proactive message displayed", {
18886
18906
  handle,
@@ -20330,7 +20350,7 @@ class ChatFrame extends d {
20330
20350
  log("Chat frame mount", {
20331
20351
  handle,
20332
20352
  chatUrl: this.url,
20333
- embedVersion: "ab0ec43".slice(0, 7),
20353
+ embedVersion: "ac7ed67".slice(0, 7),
20334
20354
  embedSettings: adaSettings
20335
20355
  });
20336
20356
 
@@ -20418,7 +20438,7 @@ class ChatFrame extends d {
20418
20438
  const hostPageUrlParams = new URL(window.location.href).searchParams;
20419
20439
  const smsToken = hostPageUrlParams.get("adaSMSToken");
20420
20440
  const queryParams = {
20421
- embedVersion: "ab0ec43".slice(0, 7),
20441
+ embedVersion: "ac7ed67".slice(0, 7),
20422
20442
  greeting,
20423
20443
  language,
20424
20444
  skipGreeting,
@@ -21574,6 +21594,7 @@ class Container extends d {
21574
21594
  chatterInLiveChat,
21575
21595
  messageService,
21576
21596
  wasCampaignShownButNowClosed,
21597
+ proactiveEngaged,
21577
21598
  setGlobalState,
21578
21599
  language
21579
21600
  } = this.props;
@@ -21631,9 +21652,6 @@ class Container extends d {
21631
21652
  adaSettings,
21632
21653
  messageService,
21633
21654
  language: language || get_browser_language(),
21634
- setRecentProactiveConversationConfig: config => this.setState({
21635
- recentProactiveConversationConfig: config
21636
- }),
21637
21655
  clearProactiveConversation: () => this.setState({
21638
21656
  proactiveConversation: null
21639
21657
  })
@@ -21658,7 +21676,12 @@ class Container extends d {
21658
21676
  });
21659
21677
  }
21660
21678
  }
21661
- if (isChatWebsocketConnected && isDrawerOpen && recentProactiveConversationConfig) {
21679
+
21680
+ // Only attribute the proactive when the customer engaged it (clicked the
21681
+ // bubble), not on any drawer open. Without the `proactiveEngaged` gate the
21682
+ // meta leaks on: opening during a delay, opening after dismiss, or opening
21683
+ // on a page the proactive no longer matches.
21684
+ if (isChatWebsocketConnected && isDrawerOpen && recentProactiveConversationConfig && proactiveEngaged) {
21662
21685
  const chatChannel = messageService.getChannel(CHAT_IFRAME);
21663
21686
  if (chatChannel) {
21664
21687
  const {
@@ -21676,6 +21699,9 @@ class Container extends d {
21676
21699
  handle: adaSettings.handle,
21677
21700
  embedSettings: adaSettings
21678
21701
  });
21702
+ setGlobalState({
21703
+ proactiveEngaged: false
21704
+ });
21679
21705
  this.setState({
21680
21706
  recentProactiveConversationConfig: null
21681
21707
  });
@@ -22177,11 +22203,17 @@ class Container extends d {
22177
22203
  duration,
22178
22204
  delay,
22179
22205
  image,
22180
- cta
22206
+ cta,
22207
+ proactiveConfig = null
22181
22208
  } = payload;
22182
22209
  const EXTRA_PROACTIVE_DELAY = 1000;
22210
+
22211
+ // A newly shown intro is a fresh engagement opportunity: track only the
22212
+ // proactive it carries (campaigns carry none, clearing any stale config)
22213
+ // and reset engagement so a prior bubble's flag can't attribute this one.
22183
22214
  this.setState({
22184
- hideIntroOverride: true
22215
+ hideIntroOverride: true,
22216
+ recentProactiveConversationConfig: proactiveConfig
22185
22217
  }, async () => {
22186
22218
  const {
22187
22219
  setGlobalState
@@ -22200,7 +22232,8 @@ class Container extends d {
22200
22232
  }));
22201
22233
  await setGlobalState({
22202
22234
  client: newClient,
22203
- isIntroShown: false
22235
+ isIntroShown: false,
22236
+ proactiveEngaged: false
22204
22237
  });
22205
22238
  this.setState({
22206
22239
  hideIntroOverride: false
@@ -22262,8 +22295,21 @@ class Container extends d {
22262
22295
  });
22263
22296
  }
22264
22297
  locationChangeHandler() {
22298
+ const {
22299
+ setGlobalState
22300
+ } = this.props;
22301
+
22302
+ // Drop the proactive recorded on the previous page so navigating to a page
22303
+ // without a matching proactive can't later attribute the stale one; the
22304
+ // re-evaluation below records a fresh config only if the new page matches.
22305
+ // Clear engagement in lockstep so a pre-nav click can't attribute the new
22306
+ // page's proactive.
22307
+ setGlobalState({
22308
+ proactiveEngaged: false
22309
+ });
22265
22310
  this.setState({
22266
- hideIntroOverride: true
22311
+ hideIntroOverride: true,
22312
+ recentProactiveConversationConfig: null
22267
22313
  }, () => {
22268
22314
  /**
22269
22315
  * Re-fetch client (this is especially important for intros)
@@ -22597,7 +22643,8 @@ function Container_mapStateToProps(storeState) {
22597
22643
  chatDimensions,
22598
22644
  isIntroShown,
22599
22645
  language,
22600
- wasCampaignShownButNowClosed
22646
+ wasCampaignShownButNowClosed,
22647
+ proactiveEngaged
22601
22648
  } = storeState;
22602
22649
  return {
22603
22650
  client,
@@ -22614,7 +22661,8 @@ function Container_mapStateToProps(storeState) {
22614
22661
  chatDimensions,
22615
22662
  isIntroShown,
22616
22663
  language,
22617
- wasCampaignShownButNowClosed
22664
+ wasCampaignShownButNowClosed,
22665
+ proactiveEngaged
22618
22666
  };
22619
22667
  }
22620
22668
  function Container_mapDispatchToProps(dispatch) {
@@ -1,15 +1,14 @@
1
1
  import type { StartOptions } from "@ada-support/embed-types";
2
2
  import type { MessageService } from "client/lib/message-service";
3
- import type { ProactiveConversation, ProactiveConversationTriggerMethod, ProactiveConversationUrlTriggerConditions, ProactiveConversations, RecentProactiveConversationConfig } from "./types";
3
+ import type { ProactiveConversation, ProactiveConversationTriggerMethod, ProactiveConversationUrlTriggerConditions, ProactiveConversations } from "./types";
4
4
  export declare function isWithinSchedule(scheduleStart?: string | null, scheduleEnd?: string | null): boolean;
5
5
  export declare function pickHighestPriorityMatch(matches: Array<[string, ProactiveConversation]>): [string, ProactiveConversation] | undefined;
6
- export declare function proactiveTriggerImpl({ proactiveConversation, triggerMethod, adaSettings, messageService, language, setRecentProactiveConversationConfig, clearProactiveConversation, }: {
6
+ export declare function proactiveTriggerImpl({ proactiveConversation, triggerMethod, adaSettings, messageService, language, clearProactiveConversation, }: {
7
7
  proactiveConversation: ProactiveConversation;
8
8
  triggerMethod: ProactiveConversationTriggerMethod | null;
9
9
  adaSettings: StartOptions;
10
10
  messageService: MessageService;
11
11
  language: string;
12
- setRecentProactiveConversationConfig: (config: RecentProactiveConversationConfig) => void;
13
12
  clearProactiveConversation: () => void;
14
13
  }): void;
15
14
  export declare function evaluateUrlTriggerConditions(conditions: ProactiveConversationUrlTriggerConditions, url: string): boolean;
@@ -39,7 +39,7 @@ export interface RecentProactiveConversationConfig {
39
39
  key: string;
40
40
  params: Record<string, string>;
41
41
  }
42
- export type ProactiveConversationFrequency = "always" | "session";
42
+ export type ProactiveConversationFrequency = "always" | "session" | "user";
43
43
  export type ProactiveConversationUrlTriggerConditionType = "equals" | "ends-with" | "regex" | "contains";
44
44
  export interface UrlTriggerCondition {
45
45
  type: ProactiveConversationUrlTriggerConditionType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ada-support/embed2",
3
- "version": "1.14.12",
3
+ "version": "1.14.14",
4
4
  "description": "",
5
5
  "main": "dist/npm-entry",
6
6
  "typings": "dist/npm-entry/index-npm.d.ts",
@@ -91,7 +91,7 @@
91
91
  },
92
92
  "dependencies": {
93
93
  "@ada-support/embed-types": "^1.9.2",
94
- "@ada-support/web-storage": "^1.3.0",
94
+ "@ada-support/web-storage": "^1.4.1",
95
95
  "@babel/runtime-corejs3": "^7.26.10",
96
96
  "@sentry/browser": "^8.33.0",
97
97
  "@sentry/types": "^8.33.1",