yelda-webchat 1.1.16 → 1.1.18
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/js/yeldaWebchatInjector.js +2 -2
- package/dist/js/yeldaWebchatInjector.js.gz +0 -0
- package/dist/js/yeldaWebchatInjector.js.map +1 -1
- package/dist/js/yeldaWebchatInjector.min.js +2 -2
- package/dist/js/yeldaWebchatInjector.min.js.gz +0 -0
- package/dist/js/yeldaWebchatInjector.min.js.map +1 -1
- package/package.json +1 -1
- package/src/config/index.js +2 -1
- package/src/js/yeldaWebchatInjector.js +133 -1
package/package.json
CHANGED
package/src/config/index.js
CHANGED
|
@@ -29,7 +29,8 @@ module.exports = {
|
|
|
29
29
|
LISTEN_URL_UPDATE: 'listenUrlUpdate',
|
|
30
30
|
ABSTAIN_URL_UPDATE: 'abstainUrlUpdate',
|
|
31
31
|
ADD_BUBBLE_TEXT: 'addBubbleText',
|
|
32
|
-
ADD_MINIMAL_NOTIFICATION_TEXT: 'addMinimalNotificationText'
|
|
32
|
+
ADD_MINIMAL_NOTIFICATION_TEXT: 'addMinimalNotificationText',
|
|
33
|
+
EXEC_JS_FUNC: 'execJsFunc'
|
|
33
34
|
}
|
|
34
35
|
},
|
|
35
36
|
CHAT_BUBBLE_EXTERNAL_ENDPOINT: 'https://webchat.yelda.ai/webchat',
|
|
@@ -8,7 +8,117 @@ import 'lg-share.js'
|
|
|
8
8
|
|
|
9
9
|
import config from '../config'
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Check whether the string is url encoded
|
|
13
|
+
* @param {String} str
|
|
14
|
+
* @returns {Boolean}
|
|
15
|
+
*/
|
|
16
|
+
const isStrLikelyEncoded = (str) => {
|
|
17
|
+
// Check if the string contains any characters that would typically need encoding
|
|
18
|
+
const needsEncoding = /[?&=<>#%{}|\\\^~\[\]`;"\s]/.test(str)
|
|
19
|
+
|
|
20
|
+
// Check if the string contains any non-ASCII characters
|
|
21
|
+
const hasNonASCII = /[^\x00-\x7F]/.test(str);
|
|
22
|
+
|
|
23
|
+
// Check if the string contains any percent-encoded characters
|
|
24
|
+
const hasPercentEncoding = /%[0-9A-Fa-f]{2}/.test(str)
|
|
25
|
+
|
|
26
|
+
// Return true if any of the conditions are met
|
|
27
|
+
return needsEncoding || hasNonASCII || hasPercentEncoding
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Execute the function by name with the arguments
|
|
32
|
+
* @param {String} functionName
|
|
33
|
+
* @param {Context} context
|
|
34
|
+
* @param {Array} args
|
|
35
|
+
* @return {Any|null}
|
|
36
|
+
*/
|
|
37
|
+
const executeFunctionByName = (functionName, context, args) => {
|
|
38
|
+
try {
|
|
39
|
+
const namespaces = functionName.split(".")
|
|
40
|
+
const func = namespaces.pop()
|
|
41
|
+
for(const element of namespaces) {
|
|
42
|
+
context = context[element]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return context[func].apply(context, args)
|
|
46
|
+
} catch(error) {
|
|
47
|
+
console.error('executeFunctionByName error', error)
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
11
53
|
class YeldaChat {
|
|
54
|
+
/**
|
|
55
|
+
* Parse the function string to get the function name & arguments
|
|
56
|
+
* @param {String} str
|
|
57
|
+
* @returns {Object|null} {functionName, args}
|
|
58
|
+
*/
|
|
59
|
+
parseFunctionString(str) {
|
|
60
|
+
// Regular expression to match function name and its arguments
|
|
61
|
+
const regex = /((?:[a-zA-Z_$][\w$]*\.)*)([a-zA-Z_$][\w$]*)\(([^]*)\)/
|
|
62
|
+
|
|
63
|
+
// Executing the regex to get the match
|
|
64
|
+
const match = regex.exec(str)
|
|
65
|
+
|
|
66
|
+
if (!match) {
|
|
67
|
+
// If the string doesn't match the expected format
|
|
68
|
+
return null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Extracting function name
|
|
72
|
+
const namespaces = match[1] || ''
|
|
73
|
+
const functionName = namespaces + match[2]
|
|
74
|
+
|
|
75
|
+
// Extracting arguments
|
|
76
|
+
const argsStr = match[3].trim()
|
|
77
|
+
|
|
78
|
+
let args = []
|
|
79
|
+
|
|
80
|
+
if (argsStr !== '') {
|
|
81
|
+
let argBuffer = ''
|
|
82
|
+
let parenCount = 0
|
|
83
|
+
for (const element of argsStr) {
|
|
84
|
+
if (element === '(') parenCount++
|
|
85
|
+
else if (element === ')') parenCount--
|
|
86
|
+
|
|
87
|
+
if (element === ',' && parenCount === 0) {
|
|
88
|
+
args.push(argBuffer.trim())
|
|
89
|
+
argBuffer = ''
|
|
90
|
+
} else {
|
|
91
|
+
argBuffer += element
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
args.push(argBuffer.trim())
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Convert string representation of boolean, numbers, arrays, and objects to their actual types
|
|
98
|
+
args = args.map(arg => {
|
|
99
|
+
if (arg === 'true') return true
|
|
100
|
+
else if (arg === 'false') return false
|
|
101
|
+
else if (!isNaN(arg)) return parseFloat(arg)
|
|
102
|
+
else if (arg === 'null') return null
|
|
103
|
+
else if (arg.startsWith('[') && arg.endsWith(']')) {
|
|
104
|
+
try {
|
|
105
|
+
return JSON.parse(arg)
|
|
106
|
+
} catch(err) {
|
|
107
|
+
return ''
|
|
108
|
+
}
|
|
109
|
+
} else if (isStrLikelyEncoded(arg)) {
|
|
110
|
+
try{
|
|
111
|
+
return JSON.parse(decodeURIComponent(arg).replace(/^['"]|['"]$/g, ''))
|
|
112
|
+
} catch(err) {
|
|
113
|
+
return ''
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return arg.replace(/^['"]|['"]$/g, '') // Remove surrounding quotes if any
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
return { functionName, args }
|
|
120
|
+
}
|
|
121
|
+
|
|
12
122
|
/**
|
|
13
123
|
* Updates the url with the given parameter and value
|
|
14
124
|
* @param {String} uri
|
|
@@ -493,10 +603,32 @@ class YeldaChat {
|
|
|
493
603
|
if (!this.configurationData.hasOwnProperty('canBeClosed') || this.configurationData.canBeClosed) {
|
|
494
604
|
this.addAssistantBubbleText(eventData.text, 'y_notification')
|
|
495
605
|
}
|
|
496
|
-
|
|
606
|
+
break
|
|
607
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.EXEC_JS_FUNC:
|
|
608
|
+
this.handleExecFunction(eventData)
|
|
609
|
+
break
|
|
497
610
|
}
|
|
498
611
|
}
|
|
499
612
|
|
|
613
|
+
/**
|
|
614
|
+
* Execute the JS function passed from the webchat window
|
|
615
|
+
* @param {Object} eventData - iframe data sent from webchat window
|
|
616
|
+
*/
|
|
617
|
+
handleExecFunction(eventData) {
|
|
618
|
+
if (!eventData.hasOwnProperty('data')) {
|
|
619
|
+
return
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
const execJsFunc = eventData.data
|
|
623
|
+
const response = this.parseFunctionString(execJsFunc)
|
|
624
|
+
|
|
625
|
+
if (!response) {
|
|
626
|
+
return
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
executeFunctionByName(response.functionName, window, response.args)
|
|
630
|
+
}
|
|
631
|
+
|
|
500
632
|
/**
|
|
501
633
|
* Create DynamicElements & Opens Light Gallery from the received mediaSources
|
|
502
634
|
* @param {Object} data - iframe data sent from webchat window
|