@hellotext/hellotext 2.4.53 → 2.5.0

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/lib/hellotext.cjs CHANGED
@@ -36,12 +36,17 @@ let Hellotext = /*#__PURE__*/function () {
36
36
  this.query = new _models.Query();
37
37
  const businessData = await this.business.hydrate();
38
38
  const webchatConfig = config.webchat === false ? false : this.mergeWebchatConfig(businessData && businessData.webchat || {}, config.webchat || {});
39
+ const whatsappConfig = config.whatsappWidget === false ? false : this.mergeWhatsAppConfig(businessData && businessData.whatsapp || {}, config.whatsappWidget || {});
39
40
  const hasExplicitBehaviourOverride = config.webchat && config.webchat !== false && Object.prototype.hasOwnProperty.call(config.webchat, 'behaviour');
40
41
  _core.Configuration.webchat.behaviourOverride = hasExplicitBehaviourOverride;
41
42
  if (webchatConfig && webchatConfig.id) {
42
43
  _core.Configuration.webchat.assign(webchatConfig);
43
44
  this.webchat = await _models.Webchat.load(webchatConfig.id);
44
45
  }
46
+ if (whatsappConfig && whatsappConfig.id) {
47
+ _core.Configuration.whatsapp.assign(whatsappConfig);
48
+ this.whatsapp = await _models.WhatsAppWidget.load(whatsappConfig.id);
49
+ }
45
50
  if (typeof MutationObserver !== 'undefined') {
46
51
  this.forms.collectExistingFormsOnPage();
47
52
  }
@@ -51,6 +56,11 @@ let Hellotext = /*#__PURE__*/function () {
51
56
  value: function mergeWebchatConfig(dashboardConfig, localConfig) {
52
57
  return this.deepMergePlainObjects(dashboardConfig, localConfig);
53
58
  }
59
+ }, {
60
+ key: "mergeWhatsAppConfig",
61
+ value: function mergeWhatsAppConfig(dashboardConfig, localConfig) {
62
+ return this.deepMergePlainObjects(dashboardConfig, localConfig);
63
+ }
54
64
  }, {
55
65
  key: "deepMergePlainObjects",
56
66
  value: function deepMergePlainObjects(base, override) {
@@ -226,5 +236,6 @@ Hellotext.eventEmitter = new _core.Event();
226
236
  Hellotext.forms = void 0;
227
237
  Hellotext.business = void 0;
228
238
  Hellotext.webchat = void 0;
239
+ Hellotext.whatsapp = void 0;
229
240
  var _default = Hellotext;
230
241
  exports.default = _default;
package/lib/hellotext.js CHANGED
@@ -10,7 +10,7 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typ
10
10
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
11
11
  import { Configuration, Event } from './core';
12
12
  import API, { Response, keepaliveFor } from './api';
13
- import { Business, Fingerprint, FormCollection, Page, Query, Session, User, Webchat } from './models';
13
+ import { Business, Fingerprint, FormCollection, Page, Query, Session, User, Webchat, WhatsAppWidget } from './models';
14
14
  import { NotInitializedError } from './errors';
15
15
  var Hellotext = /*#__PURE__*/function () {
16
16
  function Hellotext() {
@@ -35,12 +35,17 @@ var Hellotext = /*#__PURE__*/function () {
35
35
  this.query = new Query();
36
36
  var businessData = yield this.business.hydrate();
37
37
  var webchatConfig = config.webchat === false ? false : this.mergeWebchatConfig(businessData && businessData.webchat || {}, config.webchat || {});
38
+ var whatsappConfig = config.whatsappWidget === false ? false : this.mergeWhatsAppConfig(businessData && businessData.whatsapp || {}, config.whatsappWidget || {});
38
39
  var hasExplicitBehaviourOverride = config.webchat && config.webchat !== false && Object.prototype.hasOwnProperty.call(config.webchat, 'behaviour');
39
40
  Configuration.webchat.behaviourOverride = hasExplicitBehaviourOverride;
40
41
  if (webchatConfig && webchatConfig.id) {
41
42
  Configuration.webchat.assign(webchatConfig);
42
43
  this.webchat = yield Webchat.load(webchatConfig.id);
43
44
  }
45
+ if (whatsappConfig && whatsappConfig.id) {
46
+ Configuration.whatsapp.assign(whatsappConfig);
47
+ this.whatsapp = yield WhatsAppWidget.load(whatsappConfig.id);
48
+ }
44
49
  if (typeof MutationObserver !== 'undefined') {
45
50
  this.forms.collectExistingFormsOnPage();
46
51
  }
@@ -55,6 +60,11 @@ var Hellotext = /*#__PURE__*/function () {
55
60
  value: function mergeWebchatConfig(dashboardConfig, localConfig) {
56
61
  return this.deepMergePlainObjects(dashboardConfig, localConfig);
57
62
  }
63
+ }, {
64
+ key: "mergeWhatsAppConfig",
65
+ value: function mergeWhatsAppConfig(dashboardConfig, localConfig) {
66
+ return this.deepMergePlainObjects(dashboardConfig, localConfig);
67
+ }
58
68
  }, {
59
69
  key: "deepMergePlainObjects",
60
70
  value: function deepMergePlainObjects(base, override) {
@@ -240,4 +250,5 @@ Hellotext.eventEmitter = new Event();
240
250
  Hellotext.forms = void 0;
241
251
  Hellotext.business = void 0;
242
252
  Hellotext.webchat = void 0;
253
+ Hellotext.whatsapp = void 0;
243
254
  export default Hellotext;
@@ -69,6 +69,12 @@ Object.defineProperty(exports, "Webchat", {
69
69
  return _webchat.Webchat;
70
70
  }
71
71
  });
72
+ Object.defineProperty(exports, "WhatsAppWidget", {
73
+ enumerable: true,
74
+ get: function () {
75
+ return _whatsapp_widget.WhatsAppWidget;
76
+ }
77
+ });
72
78
  var _business = require("./business");
73
79
  var _cookies = require("./cookies");
74
80
  var _fingerprint = require("./fingerprint");
@@ -79,4 +85,5 @@ var _query = require("./query");
79
85
  var _session = require("./session");
80
86
  var _user = require("./user");
81
87
  var _utm = require("./utm");
82
- var _webchat = require("./webchat");
88
+ var _webchat = require("./webchat");
89
+ var _whatsapp_widget = require("./whatsapp_widget");
@@ -8,4 +8,5 @@ export { Query } from './query';
8
8
  export { Session } from './session';
9
9
  export { User } from './user';
10
10
  export { UTM } from './utm';
11
- export { Webchat } from './webchat';
11
+ export { Webchat } from './webchat';
12
+ export { WhatsAppWidget } from './whatsapp_widget';
@@ -29,6 +29,7 @@ let Webchat = /*#__PURE__*/function () {
29
29
  return false;
30
30
  }
31
31
  this.containerToAppendTo.appendChild(this.data.html);
32
+ this.markCoexistingWidgets();
32
33
  this.mounted = true;
33
34
  return true;
34
35
  }
@@ -66,6 +67,15 @@ let Webchat = /*#__PURE__*/function () {
66
67
  get: function () {
67
68
  return _business.Business.waitForStylesheet(_business.Business.latestStylesheet);
68
69
  }
70
+ }, {
71
+ key: "markCoexistingWidgets",
72
+ value: function markCoexistingWidgets() {
73
+ const webchat = this.data.html;
74
+ const whatsapp = document.querySelector('.hellotext--whatsapp-widget');
75
+ if (!webchat || !whatsapp) return;
76
+ webchat.classList.add('hellotext--with-whatsapp-widget');
77
+ whatsapp.classList.add('hellotext--with-webchat');
78
+ }
69
79
  }], [{
70
80
  key: "load",
71
81
  value: async function load(id) {
@@ -25,6 +25,7 @@ var Webchat = /*#__PURE__*/function () {
25
25
  return false;
26
26
  }
27
27
  this.containerToAppendTo.appendChild(this.data.html);
28
+ this.markCoexistingWidgets();
28
29
  this.mounted = true;
29
30
  return true;
30
31
  });
@@ -67,6 +68,15 @@ var Webchat = /*#__PURE__*/function () {
67
68
  get: function get() {
68
69
  return Business.waitForStylesheet(Business.latestStylesheet);
69
70
  }
71
+ }, {
72
+ key: "markCoexistingWidgets",
73
+ value: function markCoexistingWidgets() {
74
+ var webchat = this.data.html;
75
+ var whatsapp = document.querySelector('.hellotext--whatsapp-widget');
76
+ if (!webchat || !whatsapp) return;
77
+ webchat.classList.add('hellotext--with-whatsapp-widget');
78
+ whatsapp.classList.add('hellotext--with-webchat');
79
+ }
70
80
  }], [{
71
81
  key: "load",
72
82
  value: function () {
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.WhatsAppWidget = void 0;
7
+ var _core = require("../core");
8
+ var _api = _interopRequireDefault(require("../api"));
9
+ var _business = require("./business");
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
13
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
14
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
15
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
16
+ let WhatsAppWidget = /*#__PURE__*/function () {
17
+ function WhatsAppWidget(data) {
18
+ _classCallCheck(this, WhatsAppWidget);
19
+ this.data = data;
20
+ this.mounted = false;
21
+ this.rendered = Promise.resolve(false);
22
+ }
23
+ _createClass(WhatsAppWidget, [{
24
+ key: "render",
25
+ value: async function render() {
26
+ if (!this.data.html) return false;
27
+ const container = this.containerToAppendTo;
28
+ if (!container) {
29
+ console.warn(`Hellotext WhatsApp widget was not mounted because the container ${_core.Configuration.whatsapp.container} was not found.`);
30
+ return false;
31
+ }
32
+ if (!(await this.stylesheetLoaded)) {
33
+ console.warn('Hellotext WhatsApp widget was not mounted because its stylesheet failed to load.');
34
+ return false;
35
+ }
36
+ container.appendChild(this.data.html);
37
+ this.markCoexistingWidgets();
38
+ this.mounted = true;
39
+ return true;
40
+ }
41
+ }, {
42
+ key: "containerToAppendTo",
43
+ get: function () {
44
+ try {
45
+ return document.querySelector(_core.Configuration.whatsapp.container);
46
+ } catch (_) {
47
+ return null;
48
+ }
49
+ }
50
+ }, {
51
+ key: "stylesheetLoaded",
52
+ get: function () {
53
+ return _business.Business.waitForStylesheet(_business.Business.latestStylesheet);
54
+ }
55
+ }, {
56
+ key: "markCoexistingWidgets",
57
+ value: function markCoexistingWidgets() {
58
+ const webchat = document.querySelector('.hellotext--webchat:not(.hellotext--whatsapp-widget)');
59
+ const whatsapp = this.data.html;
60
+ if (!webchat || !whatsapp) return;
61
+ webchat.classList.add('hellotext--with-whatsapp-widget');
62
+ whatsapp.classList.add('hellotext--with-webchat');
63
+ }
64
+ }], [{
65
+ key: "load",
66
+ value: async function load(id) {
67
+ const widget = new WhatsAppWidget({
68
+ id,
69
+ html: await _api.default.whatsappWidgets.get(id)
70
+ });
71
+ widget.rendered = widget.render();
72
+ return widget;
73
+ }
74
+ }]);
75
+ return WhatsAppWidget;
76
+ }();
77
+ exports.WhatsAppWidget = WhatsAppWidget;
@@ -0,0 +1,84 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
2
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
3
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
5
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
6
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
7
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
8
+ import { Configuration } from '../core';
9
+ import API from '../api';
10
+ import { Business } from './business';
11
+ var WhatsAppWidget = /*#__PURE__*/function () {
12
+ function WhatsAppWidget(data) {
13
+ _classCallCheck(this, WhatsAppWidget);
14
+ this.data = data;
15
+ this.mounted = false;
16
+ this.rendered = Promise.resolve(false);
17
+ }
18
+ _createClass(WhatsAppWidget, [{
19
+ key: "render",
20
+ value: function () {
21
+ var _render = _asyncToGenerator(function* () {
22
+ if (!this.data.html) return false;
23
+ var container = this.containerToAppendTo;
24
+ if (!container) {
25
+ console.warn("Hellotext WhatsApp widget was not mounted because the container ".concat(Configuration.whatsapp.container, " was not found."));
26
+ return false;
27
+ }
28
+ if (!(yield this.stylesheetLoaded)) {
29
+ console.warn('Hellotext WhatsApp widget was not mounted because its stylesheet failed to load.');
30
+ return false;
31
+ }
32
+ container.appendChild(this.data.html);
33
+ this.markCoexistingWidgets();
34
+ this.mounted = true;
35
+ return true;
36
+ });
37
+ function render() {
38
+ return _render.apply(this, arguments);
39
+ }
40
+ return render;
41
+ }()
42
+ }, {
43
+ key: "containerToAppendTo",
44
+ get: function get() {
45
+ try {
46
+ return document.querySelector(Configuration.whatsapp.container);
47
+ } catch (_) {
48
+ return null;
49
+ }
50
+ }
51
+ }, {
52
+ key: "stylesheetLoaded",
53
+ get: function get() {
54
+ return Business.waitForStylesheet(Business.latestStylesheet);
55
+ }
56
+ }, {
57
+ key: "markCoexistingWidgets",
58
+ value: function markCoexistingWidgets() {
59
+ var webchat = document.querySelector('.hellotext--webchat:not(.hellotext--whatsapp-widget)');
60
+ var whatsapp = this.data.html;
61
+ if (!webchat || !whatsapp) return;
62
+ webchat.classList.add('hellotext--with-whatsapp-widget');
63
+ whatsapp.classList.add('hellotext--with-webchat');
64
+ }
65
+ }], [{
66
+ key: "load",
67
+ value: function () {
68
+ var _load = _asyncToGenerator(function* (id) {
69
+ var widget = new WhatsAppWidget({
70
+ id,
71
+ html: yield API.whatsappWidgets.get(id)
72
+ });
73
+ widget.rendered = widget.render();
74
+ return widget;
75
+ });
76
+ function load(_x) {
77
+ return _load.apply(this, arguments);
78
+ }
79
+ return load;
80
+ }()
81
+ }]);
82
+ return WhatsAppWidget;
83
+ }();
84
+ export { WhatsAppWidget };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellotext/hellotext",
3
- "version": "2.4.53",
3
+ "version": "2.5.0",
4
4
  "description": "Hellotext JavaScript Client",
5
5
  "source": "src/index.js",
6
6
  "main": "lib/index.cjs",
package/src/api/index.js CHANGED
@@ -3,6 +3,7 @@ import EventsAPI from './events'
3
3
  import FormsAPI from './forms'
4
4
  import IdentificationsAPI from './identifications'
5
5
  import WebchatsAPI from './webchats'
6
+ import WhatsAppWidgetsAPI from './whatsapp_widgets'
6
7
  import AcksAPI from './acks'
7
8
 
8
9
  // Browsers keep `fetch(..., { keepalive: true })` requests alive during page
@@ -45,6 +46,10 @@ export default class API {
45
46
  return WebchatsAPI
46
47
  }
47
48
 
49
+ static get whatsappWidgets() {
50
+ return WhatsAppWidgetsAPI
51
+ }
52
+
48
53
  static get identifications() {
49
54
  return IdentificationsAPI
50
55
  }
@@ -0,0 +1,71 @@
1
+ import { Configuration, Locale } from '../core'
2
+ import Hellotext from '../hellotext'
3
+
4
+ class WhatsAppWidgetsAPI {
5
+ static get endpoint() {
6
+ return Configuration.endpoint('public/widgets/whatsapp')
7
+ }
8
+
9
+ static async get(id) {
10
+ const url = new URL(`${this.endpoint}/${id}`)
11
+
12
+ url.searchParams.append('locale', Locale.toString())
13
+ url.searchParams.append('placement', Configuration.whatsapp.placement)
14
+ this.appendWhatsAppOverrides(url)
15
+
16
+ const response = await this.fetchWidget(url)
17
+
18
+ if (!response.ok) return null
19
+
20
+ const data = await this.parseWidgetResponse(response)
21
+
22
+ if (!data) return null
23
+
24
+ if (!Hellotext.business.data) {
25
+ Hellotext.business.setData(data.business)
26
+ Hellotext.business.setLocale(data.locale)
27
+ }
28
+
29
+ return new DOMParser().parseFromString(data.html, 'text/html').querySelector('article')
30
+ }
31
+
32
+ static appendWhatsAppOverrides(url) {
33
+ const { appearance, body, number } = Configuration.whatsapp
34
+
35
+ this.appendIfSupplied(
36
+ url,
37
+ 'whatsapp[appearance][launcher][icon_url]',
38
+ appearance.launcher?.iconUrl,
39
+ )
40
+
41
+ this.appendIfSupplied(url, 'whatsapp[number]', number)
42
+ this.appendIfSupplied(url, 'whatsapp[body]', body)
43
+ }
44
+
45
+ static appendIfSupplied(url, key, value) {
46
+ if (value === undefined || value === null) return
47
+
48
+ url.searchParams.append(key, String(value))
49
+ }
50
+
51
+ static async fetchWidget(url) {
52
+ try {
53
+ return await fetch(url, {
54
+ method: 'GET',
55
+ headers: Hellotext.headers,
56
+ })
57
+ } catch (_) {
58
+ return { ok: false }
59
+ }
60
+ }
61
+
62
+ static async parseWidgetResponse(response) {
63
+ try {
64
+ return await response.json()
65
+ } catch (_) {
66
+ return null
67
+ }
68
+ }
69
+ }
70
+
71
+ export default WhatsAppWidgetsAPI
@@ -0,0 +1,143 @@
1
+ /**
2
+ * @typedef {'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'} Placement
3
+ * @description Valid placements for the WhatsApp widget.
4
+ */
5
+
6
+ /**
7
+ * @enum {Placement}
8
+ */
9
+ const placements = {
10
+ TOP_LEFT: 'top-left',
11
+ TOP_RIGHT: 'top-right',
12
+ BOTTOM_LEFT: 'bottom-left',
13
+ BOTTOM_RIGHT: 'bottom-right'
14
+ }
15
+
16
+ /**
17
+ * @typedef {Object} WhatsAppWidgetAppearance
18
+ * @property {Object} [launcher] - Launcher appearance overrides.
19
+ * @property {string} [launcher.iconUrl] - Image URL used for the launcher icon.
20
+ */
21
+
22
+ /**
23
+ * @class WhatsApp
24
+ * @classdesc Configuration for the standalone WhatsApp widget.
25
+ * @property {String} id - The id of the WhatsApp widget.
26
+ * @property {String} container - The container to append the widget to, defaults to 'body'.
27
+ * @property {Placement} placement - The placement of the widget, defaults to 'bottom-right'.
28
+ * @property {String} number - WhatsApp number used by the widget link.
29
+ * @property {String} body - Prefilled WhatsApp compose text.
30
+ * @property {WhatsAppWidgetAppearance} appearance - Appearance overrides.
31
+ */
32
+ class WhatsApp {
33
+ static _id
34
+ static _container = 'body'
35
+ static _placement = 'bottom-right'
36
+ static _appearance = {}
37
+ static _number = null
38
+ static _body = null
39
+
40
+ static set id(value) {
41
+ this._id = value
42
+ }
43
+
44
+ static get id() {
45
+ return this._id
46
+ }
47
+
48
+ static set container(value) {
49
+ this._container = value
50
+ }
51
+
52
+ static get container() {
53
+ return this._container
54
+ }
55
+
56
+ static set placement(value) {
57
+ if (!Object.values(placements).includes(value)) {
58
+ throw new Error(`Invalid placement value: ${value}`)
59
+ }
60
+
61
+ this._placement = value
62
+ }
63
+
64
+ static get placement() {
65
+ return this._placement
66
+ }
67
+
68
+ static get appearance() {
69
+ return this._appearance
70
+ }
71
+
72
+ static set appearance(value) {
73
+ if (!this.isPlainObject(value)) {
74
+ throw new Error('Appearance must be an object')
75
+ }
76
+
77
+ Object.entries(value).forEach(([key, nestedValue]) => {
78
+ if (key !== 'launcher') {
79
+ throw new Error(`Invalid appearance property: ${key}`)
80
+ }
81
+
82
+ if (!this.isPlainObject(nestedValue)) {
83
+ throw new Error(`Appearance ${key} must be an object`)
84
+ }
85
+
86
+ Object.entries(nestedValue).forEach(([nestedKey, propertyValue]) => {
87
+ if (nestedKey !== 'iconUrl') {
88
+ throw new Error(`Invalid appearance launcher property: ${nestedKey}`)
89
+ }
90
+
91
+ if (propertyValue == null) {
92
+ return
93
+ }
94
+
95
+ if (typeof propertyValue !== 'string') {
96
+ throw new Error(`Invalid appearance ${key}.${nestedKey} value: ${propertyValue}`)
97
+ }
98
+ })
99
+ })
100
+
101
+ this._appearance = value
102
+ }
103
+
104
+ static get number() {
105
+ return this._number
106
+ }
107
+
108
+ static set number(value) {
109
+ if (value != null && typeof value !== 'string') {
110
+ throw new Error(`Invalid number value: ${value}`)
111
+ }
112
+
113
+ this._number = value
114
+ }
115
+
116
+ static get body() {
117
+ return this._body
118
+ }
119
+
120
+ static set body(value) {
121
+ if (value != null && typeof value !== 'string') {
122
+ throw new Error(`Invalid body value: ${value}`)
123
+ }
124
+
125
+ this._body = value
126
+ }
127
+
128
+ static assign(props) {
129
+ if (props) {
130
+ Object.entries(props).forEach(([key, value]) => {
131
+ this[key] = value
132
+ })
133
+ }
134
+
135
+ return this
136
+ }
137
+
138
+ static isPlainObject(value) {
139
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
140
+ }
141
+ }
142
+
143
+ export { WhatsApp }
@@ -1,6 +1,7 @@
1
1
  import { Forms } from './configuration/forms'
2
2
  import { Locale } from './configuration/locale'
3
3
  import { Webchat } from './configuration/webchat'
4
+ import { WhatsApp } from './configuration/whatsapp'
4
5
 
5
6
  /**
6
7
  * @class Configuration
@@ -10,6 +11,7 @@ import { Webchat } from './configuration/webchat'
10
11
  * @property {String} [session] - session id
11
12
  * @property {Forms} [forms] - form configuration
12
13
  * @property {Webchat} [webchat] - webchat configuration
14
+ * @property {WhatsApp} [whatsappWidget] - WhatsApp widget configuration
13
15
  * @property {Locale} [locale] - locale configuration
14
16
  */
15
17
  class Configuration {
@@ -21,6 +23,7 @@ class Configuration {
21
23
 
22
24
  static forms = Forms
23
25
  static webchat = Webchat
26
+ static whatsapp = WhatsApp
24
27
 
25
28
  /**
26
29
  *
@@ -42,6 +45,8 @@ class Configuration {
42
45
  this.forms = Forms.assign(value)
43
46
  } else if (key === 'webchat') {
44
47
  this.webchat = Webchat.assign(value)
48
+ } else if (key === 'whatsappWidget') {
49
+ this.whatsapp = WhatsApp.assign(value)
45
50
  } else {
46
51
  this[key] = value
47
52
  }
package/src/core/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Configuration } from './configuration'
2
2
  export { Locale } from './configuration/locale'
3
3
  export { Webchat } from './configuration/webchat'
4
+ export { WhatsApp } from './configuration/whatsapp'
4
5
  export { default as Event } from './event'
package/src/hellotext.js CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  Session,
11
11
  User,
12
12
  Webchat,
13
+ WhatsAppWidget,
13
14
  } from './models'
14
15
 
15
16
  import { NotInitializedError } from './errors'
@@ -19,6 +20,7 @@ class Hellotext {
19
20
  static forms
20
21
  static business
21
22
  static webchat
23
+ static whatsapp
22
24
 
23
25
  /**
24
26
  * initialize the module.
@@ -44,6 +46,13 @@ class Hellotext {
44
46
  (businessData && businessData.webchat) || {},
45
47
  config.webchat || {},
46
48
  )
49
+ const whatsappConfig =
50
+ config.whatsappWidget === false
51
+ ? false
52
+ : this.mergeWhatsAppConfig(
53
+ (businessData && businessData.whatsapp) || {},
54
+ config.whatsappWidget || {},
55
+ )
47
56
 
48
57
  const hasExplicitBehaviourOverride =
49
58
  config.webchat &&
@@ -56,6 +65,11 @@ class Hellotext {
56
65
  this.webchat = await Webchat.load(webchatConfig.id)
57
66
  }
58
67
 
68
+ if (whatsappConfig && whatsappConfig.id) {
69
+ Configuration.whatsapp.assign(whatsappConfig)
70
+ this.whatsapp = await WhatsAppWidget.load(whatsappConfig.id)
71
+ }
72
+
59
73
  if (typeof MutationObserver !== 'undefined') {
60
74
  this.forms.collectExistingFormsOnPage()
61
75
  }
@@ -65,6 +79,10 @@ class Hellotext {
65
79
  return this.deepMergePlainObjects(dashboardConfig, localConfig)
66
80
  }
67
81
 
82
+ static mergeWhatsAppConfig(dashboardConfig, localConfig) {
83
+ return this.deepMergePlainObjects(dashboardConfig, localConfig)
84
+ }
85
+
68
86
  static deepMergePlainObjects(base, override) {
69
87
  const result = { ...base }
70
88
 
@@ -9,3 +9,4 @@ export { Session } from './session'
9
9
  export { User } from './user'
10
10
  export { UTM } from './utm'
11
11
  export { Webchat } from './webchat'
12
+ export { WhatsAppWidget } from './whatsapp_widget'