yelda-webchat 1.1.12 → 1.1.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yelda-webchat",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "description": "Website Chat Plugin",
5
5
  "main": "./dist/js/yeldaWebchatInjector.min.js",
6
6
  "license": "MIT",
@@ -30,5 +30,11 @@ module.exports = {
30
30
  ADD_BUBBLE_TEXT: 'addBubbleText',
31
31
  ADD_MINIMAL_NOTIFICATION_TEXT: 'addMinimalNotificationText'
32
32
  }
33
+ },
34
+ CHAT_BUBBLE_EXTERNAL_ENDPOINT: 'https://webchat.yelda.ai/webchat',
35
+ CHAT_BUBBLE_REQUEST_TIMEOUT: 5000,
36
+ APP_ENV_VALUES: {
37
+ STAGING: 'staging',
38
+ PRODUCTION: 'production'
33
39
  }
34
40
  }
@@ -775,38 +775,108 @@ class YeldaChat {
775
775
  return isFound
776
776
  }
777
777
 
778
+ /**
779
+ * Get the app env from the assistant url
780
+ * @param {String} assistantUrl
781
+ * @returns {String} env
782
+ */
783
+ getAppEnv(assistantUrl) {
784
+ if (config.REGEX_HOST.STAGING.test(assistantUrl)) {
785
+ return config.APP_ENV_VALUES.STAGING
786
+ }
787
+
788
+ // By default, use the production env
789
+ return config.APP_ENV_VALUES.PRODUCTION
790
+ }
791
+
792
+ /**
793
+ * Get the chat bubble url base based on isFallback
794
+ * @param {Object} data { assistantUrl, assistantId, settingId }
795
+ * @param {Boolean} isFallback fallback means yelda endpoint
796
+ * @returns {String} url base
797
+ */
798
+ getChatBubbleUrlBase(data, isFallback) {
799
+ if (isFallback) {
800
+ return `${data.assistantUrl}/assistants`
801
+ }
802
+ return config.CHAT_BUBBLE_EXTERNAL_ENDPOINT
803
+ }
804
+
778
805
  /**
779
806
  * return getAssistantSettings endpoint URL from data
780
807
  * @param {Object} data { assistantUrl, assistantId, settingId }
808
+ * @param {Boolean} isFallback
781
809
  * @return {String} url
782
810
  */
783
- getAssistantSettingsUrl(data) {
811
+ getAssistantSettingsUrl(data, isFallback) {
812
+ const urlBase = this.getChatBubbleUrlBase(data, isFallback)
813
+ // The app env is required as query for the external chatbubble endpoint
814
+ // If the env was not explicitly set in data, guess it from the assistant url
815
+ const appEnv = data.env || this.getAppEnv(data.assistantUrl)
816
+ const envQuery = `env=${appEnv}`
784
817
  if(data.settingId) {
785
- return `${data.assistantUrl}/assistants/settings/${data.settingId}/chatBubble`
818
+ return `${urlBase}/settings/${data.settingId}/chatBubble?${envQuery}`
786
819
  }
787
820
 
788
- return `${data.assistantUrl}/assistants/${data.assistantId}/chatBubble/${data.locale}`
821
+ return `${urlBase}/${data.assistantId}/chatBubble/${data.locale}?${envQuery}`
789
822
  }
790
823
 
791
824
  /**
792
825
  * Update assistantImage with assistant settings from backend if any
793
826
  * @param {Object} data { assistantUrl, assistantId, settingId }
827
+ * @param {Object} options
828
+ * @param {Object} options.isFallback
829
+ * @param {Number} options.customTimeout in milliseconds
794
830
  * @return {Promise}
795
831
  */
796
- getAssistantSettings(data) {
832
+ getAssistantSettings(data, { isFallback = false, customTimeout = null } = {}) {
797
833
  return new Promise((resolve, reject) => {
798
834
  try {
799
835
  const xhr = new XMLHttpRequest()
800
- const url = this.getAssistantSettingsUrl(data)
801
836
 
837
+ // Get the url base depending on if we are doing the basic request (external chatbubble endpoint)
838
+ // or the fallback one (chatbubble endpoint in Yelda)
839
+ const url = this.getAssistantSettingsUrl(data, isFallback)
840
+
802
841
  xhr.open('GET', url)
842
+ if (customTimeout) {
843
+ xhr.timeout = customTimeout
844
+ }
803
845
  xhr.send()
804
846
 
805
847
  // Bind and call are necessary to pass the "this" to the callback function
806
- xhr.onreadystatechange = function() {
848
+ xhr.onreadystatechange = () => {
807
849
  if (xhr.readyState === 4) {
808
- const webchatSettings = xhr.responseText ? JSON.parse(xhr.responseText).data : null
809
- resolve(webchatSettings)
850
+ const responseText = xhr.responseText ? JSON.parse(xhr.responseText) : null
851
+ // Yelda endpoint returns { data: ...webchatSettings } (to be compatible with old versions of the chat-plugin)
852
+ // whereas the external endpoint returns { ...webchatSettings }
853
+ // We need to handle both format
854
+ const webchatSettings = responseText && (responseText.data || responseText)
855
+
856
+ if (webchatSettings) {
857
+ return resolve(webchatSettings)
858
+ }
859
+
860
+ // We did not received the expected webchatSettings
861
+ // If we are already in fallback mode, it means there is no webchat settings for the given init information
862
+ if (isFallback) {
863
+ return resolve(null)
864
+ }
865
+
866
+ // If the initial request do not return webchatSettings, it might be because they were not set in Redis yet
867
+ // So let's call the yelda endpoint (fallback) that will find the setting (if it exists) and set it in Redis
868
+ return resolve(this.getAssistantSettings(data, { isFallback: true }))
869
+ }
870
+ }
871
+
872
+ xhr.ontimeout = () => {
873
+ /*
874
+ It the initial request to the external chatbubble endpoint timed out, (maybe the endpoint is down)
875
+ let's fallback on the yelda endpoint
876
+ */
877
+ if (!isFallback) {
878
+ // Set isFallback to true to be sure to not end up in an infinite loop
879
+ return resolve(this.getAssistantSettings(data, { isFallback: true }))
810
880
  }
811
881
  }
812
882
  } catch (e) {
@@ -846,7 +916,7 @@ class YeldaChat {
846
916
 
847
917
  // Get assistant settings from backend
848
918
  try {
849
- this.webchatSettings = await this.getAssistantSettings(data)
919
+ this.webchatSettings = await this.getAssistantSettings(data, { customTimeout: config.CHAT_BUBBLE_REQUEST_TIMEOUT })
850
920
  // Webchat can be loaded thanks to a single settingId or group of data : {assistantId, assistantSlug, locale}
851
921
  // If only settingId is provided, then we will fill {assistantId, assistantSlug, locale} thanks to the assistant settings
852
922
  data = this.updateAssistantData(data, this.webchatSettings)