@product7/feedback-sdk 1.6.5 → 1.6.7

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 CHANGED
@@ -439,6 +439,10 @@ messenger.mount();
439
439
  | `welcomeMessage` | string | 'How can we help?' | Welcome message on home view |
440
440
  | `enableHelp` | boolean | true | Show help articles section |
441
441
  | `enableChangelog` | boolean | true | Show changelog section |
442
+ | `enableNews` | boolean | - | Alias for `enableChangelog` |
443
+ | `autoLoadData` | boolean | true | Auto-fetch conversations/help/changelog |
444
+ | `initialView` | string | 'home' | Initial view on mount |
445
+ | `previewData` | object | null | Seed deterministic local data |
442
446
  | `logoUrl` | string | - | Custom logo URL |
443
447
  | `primaryColor` | string | '#155EEF' | Primary accent color |
444
448
  | `onSendMessage` | function | null | Callback when message is sent |
package/dist/README.md CHANGED
@@ -439,6 +439,10 @@ messenger.mount();
439
439
  | `welcomeMessage` | string | 'How can we help?' | Welcome message on home view |
440
440
  | `enableHelp` | boolean | true | Show help articles section |
441
441
  | `enableChangelog` | boolean | true | Show changelog section |
442
+ | `enableNews` | boolean | - | Alias for `enableChangelog` |
443
+ | `autoLoadData` | boolean | true | Auto-fetch conversations/help/changelog |
444
+ | `initialView` | string | 'home' | Initial view on mount |
445
+ | `previewData` | object | null | Seed deterministic local data |
442
446
  | `logoUrl` | string | - | Custom logo URL |
443
447
  | `primaryColor` | string | '#155EEF' | Primary accent color |
444
448
  | `onSendMessage` | function | null | Callback when message is sent |
@@ -921,15 +921,19 @@
921
921
  body: JSON.stringify(payload),
922
922
  headers: { 'Content-Type': 'application/json' },
923
923
  });
924
+ const initData = this._extractInitResponseData(response);
924
925
 
925
- this.sessionToken = response.session_token;
926
- this.sessionExpiry = new Date(Date.now() + response.expires_in * 1000);
926
+ this.sessionToken = initData.sessionToken;
927
+ this.sessionExpiry = new Date(Date.now() + initData.expiresIn * 1000);
927
928
  this._storeSession();
928
929
 
929
930
  return {
930
931
  sessionToken: this.sessionToken,
931
- config: response.config || {},
932
- expiresIn: response.expires_in,
932
+ config: initData.config,
933
+ expiresIn: initData.expiresIn,
934
+ status: initData.status,
935
+ message: initData.message,
936
+ configVersion: initData.configVersion,
933
937
  };
934
938
  } catch (error) {
935
939
  throw new APIError$1(
@@ -940,6 +944,34 @@
940
944
  }
941
945
  }
942
946
 
947
+ _extractInitResponseData(response) {
948
+ const payload =
949
+ response && typeof response.data === 'object' ? response.data : response || {};
950
+
951
+ const sessionToken = payload.session_token || payload.sessionToken;
952
+ const expiresIn = Number(payload.expires_in ?? payload.expiresIn);
953
+
954
+ if (!sessionToken) {
955
+ throw new APIError$1(500, 'Invalid init response: missing session_token');
956
+ }
957
+
958
+ if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
959
+ throw new APIError$1(500, 'Invalid init response: missing expires_in');
960
+ }
961
+
962
+ return {
963
+ sessionToken,
964
+ expiresIn,
965
+ config:
966
+ payload.config && typeof payload.config === 'object'
967
+ ? payload.config
968
+ : {},
969
+ configVersion: payload.config_version ?? payload.configVersion ?? null,
970
+ status: response?.status ?? payload?.status ?? true,
971
+ message: response?.message ?? payload?.message ?? null,
972
+ };
973
+ }
974
+
943
975
  async _ensureSession() {
944
976
  if (!this.isSessionValid()) {
945
977
  await this.init();
@@ -1725,6 +1757,15 @@
1725
1757
  mount(container) {
1726
1758
  if (this.mounted || this.destroyed) return this;
1727
1759
 
1760
+ if (this.options.enabled === false) {
1761
+ this.sdk.eventBus.emit('widget:suppressed', {
1762
+ widget: this,
1763
+ type: this.type,
1764
+ reason: 'disabled',
1765
+ });
1766
+ return this;
1767
+ }
1768
+
1728
1769
  if (this.options.suppressAfterSubmission && this._hasRecentlySubmitted()) {
1729
1770
  this.sdk.eventBus.emit('widget:suppressed', {
1730
1771
  widget: this,
@@ -5902,6 +5943,11 @@
5902
5943
  constructor(options) {
5903
5944
  super({ ...options, type: 'messenger' });
5904
5945
 
5946
+ const resolvedEnableChangelog =
5947
+ typeof options.enableChangelog === 'boolean'
5948
+ ? options.enableChangelog
5949
+ : options.enableNews !== false;
5950
+
5905
5951
  this.messengerOptions = {
5906
5952
  position: options.position || 'bottom-right',
5907
5953
  theme: options.theme || 'light',
@@ -5914,7 +5960,10 @@
5914
5960
  greetingMessage: options.greetingMessage || 'Hi there 👋',
5915
5961
  welcomeMessage: options.welcomeMessage || 'How can we help?',
5916
5962
  enableHelp: options.enableHelp !== false,
5917
- enableChangelog: options.enableChangelog !== false,
5963
+ enableChangelog: resolvedEnableChangelog,
5964
+ autoLoadData: options.autoLoadData !== false,
5965
+ initialView: options.initialView || 'home',
5966
+ previewData: options.previewData || null,
5918
5967
  featuredContent: options.featuredContent || null,
5919
5968
  feedbackUrl: options.feedbackUrl || null,
5920
5969
  changelogUrl: options.changelogUrl || null,
@@ -6382,6 +6431,51 @@
6382
6431
  };
6383
6432
  }
6384
6433
 
6434
+ _applyPreviewData() {
6435
+ const data = this.messengerOptions.previewData;
6436
+ if (!data || typeof data !== 'object') {
6437
+ return;
6438
+ }
6439
+
6440
+ if (Array.isArray(data.conversations)) {
6441
+ this.messengerState.setConversations(data.conversations);
6442
+ }
6443
+
6444
+ if (Array.isArray(data.helpArticles)) {
6445
+ this.messengerState.setHelpArticles(data.helpArticles);
6446
+ }
6447
+
6448
+ if (Array.isArray(data.homeChangelogItems)) {
6449
+ this.messengerState.setHomeChangelogItems(data.homeChangelogItems);
6450
+ }
6451
+
6452
+ if (Array.isArray(data.changelogItems)) {
6453
+ this.messengerState.setChangelogItems(data.changelogItems);
6454
+ }
6455
+
6456
+ if (typeof data.unreadCount === 'number') {
6457
+ this.setUnreadCount(data.unreadCount);
6458
+ }
6459
+
6460
+ if (data.availability && typeof data.availability === 'object') {
6461
+ const availability = data.availability;
6462
+ this.messengerState.agentsOnline = Boolean(
6463
+ availability.agentsOnline ?? availability.agents_online
6464
+ );
6465
+ this.messengerState.onlineCount =
6466
+ availability.onlineCount ?? availability.online_count ?? 0;
6467
+ this.messengerState.responseTime =
6468
+ availability.responseTime ??
6469
+ availability.response_time ??
6470
+ this.messengerState.responseTime;
6471
+ this.messengerState._notify('availabilityUpdate', availability);
6472
+ }
6473
+
6474
+ if (typeof data.currentView === 'string') {
6475
+ this.messengerState.setView(data.currentView);
6476
+ }
6477
+ }
6478
+
6385
6479
  async loadInitialData() {
6386
6480
  try {
6387
6481
  const conversations = await this._fetchConversations();
@@ -6708,17 +6802,28 @@
6708
6802
  }
6709
6803
 
6710
6804
  async onMount() {
6711
- this.loadInitialData();
6805
+ this._applyPreviewData();
6712
6806
 
6713
- if (this.apiService?.sessionToken) {
6714
- this._initWebSocket();
6715
- }
6807
+ if (this.messengerOptions.autoLoadData) {
6808
+ this.loadInitialData();
6716
6809
 
6717
- this.checkAgentAvailability();
6810
+ if (this.apiService?.sessionToken) {
6811
+ this._initWebSocket();
6812
+ }
6718
6813
 
6719
- this._availabilityInterval = setInterval(() => {
6720
6814
  this.checkAgentAvailability();
6721
- }, 60000);
6815
+
6816
+ this._availabilityInterval = setInterval(() => {
6817
+ this.checkAgentAvailability();
6818
+ }, 60000);
6819
+ }
6820
+
6821
+ if (
6822
+ this.messengerOptions.initialView &&
6823
+ this.messengerOptions.initialView !== this.messengerState.currentView
6824
+ ) {
6825
+ this.messengerState.setView(this.messengerOptions.initialView);
6826
+ }
6722
6827
  }
6723
6828
 
6724
6829
  onDestroy() {
@@ -6760,6 +6865,8 @@
6760
6865
  surveyId: options.surveyId || null,
6761
6866
  surveyType: options.surveyType || 'nps',
6762
6867
  position: options.position || 'bottom-right',
6868
+ enabled:
6869
+ typeof options.enabled === 'boolean' ? options.enabled : undefined,
6763
6870
  title: options.title || null,
6764
6871
  description: options.description || null,
6765
6872
  lowLabel: options.lowLabel || null,
@@ -6813,6 +6920,15 @@
6813
6920
  }
6814
6921
 
6815
6922
  show() {
6923
+ if (this.options.enabled === false || this.surveyOptions.enabled === false) {
6924
+ this.sdk.eventBus.emit('survey:suppressed', {
6925
+ widget: this,
6926
+ surveyId: this.surveyOptions.surveyId,
6927
+ reason: 'disabled',
6928
+ });
6929
+ return this;
6930
+ }
6931
+
6816
6932
  this._renderSurvey();
6817
6933
  this.surveyState.isVisible = true;
6818
6934
  this.sdk.eventBus.emit('survey:shown', {
@@ -8096,6 +8212,10 @@
8096
8212
  const widgetId = generateId('widget');
8097
8213
  const widgetConfig = this._getWidgetTypeConfig(type);
8098
8214
  const explicitOptions = this._omitUndefined(options);
8215
+ const widgetEnabled = this._isWidgetEnabled(type, {
8216
+ ...widgetConfig,
8217
+ ...explicitOptions,
8218
+ });
8099
8219
  const widgetOptions = {
8100
8220
  id: widgetId,
8101
8221
  sdk: this,
@@ -8103,6 +8223,7 @@
8103
8223
  ...this.config,
8104
8224
  ...widgetConfig,
8105
8225
  ...explicitOptions,
8226
+ enabled: widgetEnabled,
8106
8227
  };
8107
8228
 
8108
8229
  try {
@@ -8193,6 +8314,7 @@
8193
8314
  surveyConfig.showDescription ?? surveyConfig.show_description,
8194
8315
  customQuestions: surveyConfig.customQuestions || surveyConfig.questions,
8195
8316
  pages: surveyConfig.pages,
8317
+ enabled: surveyConfig.enabled,
8196
8318
  ...displayOptions,
8197
8319
  });
8198
8320
  }
@@ -8215,6 +8337,17 @@
8215
8337
 
8216
8338
  const normalizedOptions = this._normalizeSurveyConfig(options);
8217
8339
  const surveyConfigDefaults = this._getWidgetTypeConfig('survey');
8340
+ const surveyEnabled = this._isWidgetEnabled('survey', normalizedOptions);
8341
+
8342
+ if (!surveyEnabled) {
8343
+ this.eventBus.emit('survey:suppressed', {
8344
+ surveyId:
8345
+ normalizedOptions.surveyId || normalizedOptions.id || options.id || null,
8346
+ reason: 'disabled',
8347
+ survey: normalizedOptions,
8348
+ });
8349
+ return null;
8350
+ }
8218
8351
 
8219
8352
  const surveyWidget = this.createWidget('survey', {
8220
8353
  surveyId: normalizedOptions.surveyId,
@@ -8246,6 +8379,7 @@
8246
8379
  email: normalizedOptions.email,
8247
8380
  onSubmit: normalizedOptions.onSubmit,
8248
8381
  onDismiss: normalizedOptions.onDismiss,
8382
+ enabled: surveyEnabled,
8249
8383
  });
8250
8384
 
8251
8385
  surveyWidget.mount();
@@ -8339,13 +8473,19 @@
8339
8473
  : {};
8340
8474
 
8341
8475
  const inferredType =
8342
- survey.type || this._inferSurveyTypeFromPage(firstPage) || 'nps';
8476
+ survey.surveyType ||
8477
+ survey.survey_type ||
8478
+ survey.type ||
8479
+ this._inferSurveyTypeFromPage(firstPage) ||
8480
+ 'nps';
8343
8481
 
8344
8482
  return {
8345
8483
  ...survey,
8346
- surveyId: survey.surveyId || survey.id || null,
8347
- surveyType: survey.surveyType || inferredType,
8348
- type: survey.type || inferredType,
8484
+ surveyId: survey.surveyId || survey.survey_id || survey.id || null,
8485
+ surveyType: survey.surveyType || survey.survey_type || inferredType,
8486
+ type: survey.type || survey.survey_type || inferredType,
8487
+ enabled:
8488
+ typeof survey.enabled === 'boolean' ? survey.enabled : undefined,
8349
8489
  should_show:
8350
8490
  survey.should_show ??
8351
8491
  (survey.eligibility ? survey.eligibility.should_show : undefined),
@@ -8374,7 +8514,11 @@
8374
8514
  showTitle: survey.showTitle ?? survey.show_title ?? null,
8375
8515
  showDescription:
8376
8516
  survey.showDescription ?? survey.show_description ?? null,
8377
- customQuestions: survey.customQuestions || survey.questions || [],
8517
+ customQuestions:
8518
+ survey.customQuestions ||
8519
+ survey.custom_questions ||
8520
+ survey.questions ||
8521
+ [],
8378
8522
  pages: this._normalizeSurveyPages(survey.pages || []),
8379
8523
  };
8380
8524
  }
@@ -8449,6 +8593,23 @@
8449
8593
  return this._toCamelCaseObject(mergedTypeConfig);
8450
8594
  }
8451
8595
 
8596
+ _isWidgetEnabled(type, options = {}) {
8597
+ const typeConfig = this._getWidgetTypeConfig(type);
8598
+ if (typeConfig.enabled === false) {
8599
+ return false;
8600
+ }
8601
+
8602
+ if (typeof options.enabled === 'boolean') {
8603
+ return options.enabled;
8604
+ }
8605
+
8606
+ if (typeof typeConfig.enabled === 'boolean') {
8607
+ return typeConfig.enabled;
8608
+ }
8609
+
8610
+ return true;
8611
+ }
8612
+
8452
8613
  _isPlainObject(value) {
8453
8614
  return Object.prototype.toString.call(value) === '[object Object]';
8454
8615
  }
@@ -8502,11 +8663,21 @@
8502
8663
 
8503
8664
  const configDefaults = this._getWidgetTypeConfig('changelog');
8504
8665
  const explicitOptions = this._omitUndefined(options);
8666
+ const changelogEnabled = this._isWidgetEnabled('changelog', explicitOptions);
8667
+
8668
+ if (!changelogEnabled) {
8669
+ this.eventBus.emit('widget:suppressed', {
8670
+ type: 'changelog',
8671
+ reason: 'disabled',
8672
+ });
8673
+ return null;
8674
+ }
8505
8675
 
8506
8676
  const changelogWidget = this.createWidget('changelog', {
8507
8677
  ...defaults,
8508
8678
  ...configDefaults,
8509
8679
  ...explicitOptions,
8680
+ enabled: changelogEnabled,
8510
8681
  });
8511
8682
 
8512
8683
  changelogWidget.mount();