aumera-on-screen-widget 0.0.13 → 0.0.15
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/df-btn.js +206 -58
- package/package.json +1 -1
package/df-btn.js
CHANGED
|
@@ -1,30 +1,192 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
1
|
+
(async function() {
|
|
2
|
+
const wrapper = document.querySelector("#df-btn");
|
|
3
|
+
|
|
4
|
+
// Helper function to get GraphQL endpoint based on environment
|
|
5
|
+
function getGraphQLUrl(env) {
|
|
6
|
+
return env === "dev"
|
|
7
|
+
? "https://admin.dev.aumera.ai/g/"
|
|
8
|
+
: "https://admin.aumera.ai/g/";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Helper function to get language from page
|
|
12
|
+
function getLanguage() {
|
|
13
|
+
// Check HTML lang attribute first
|
|
14
|
+
let lang = document.documentElement.lang || "";
|
|
15
|
+
|
|
16
|
+
// Fallback to browser language
|
|
17
|
+
if (!lang) {
|
|
18
|
+
lang = navigator.language || navigator.languages?.[0] || "en";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Extract language code (e.g., "en" from "en-US")
|
|
22
|
+
lang = lang.split("-")[0].toLowerCase();
|
|
23
|
+
|
|
24
|
+
// Validate against supported languages
|
|
25
|
+
const supportedLangs = ["en", "de", "it", "fr", "es"];
|
|
26
|
+
return supportedLangs.includes(lang) ? lang : "de";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Async function to fetch chatbot settings from GraphQL
|
|
30
|
+
async function fetchChatbotSettings(orgId, env, language) {
|
|
31
|
+
try {
|
|
32
|
+
const graphqlUrl = getGraphQLUrl(env);
|
|
33
|
+
console.log("[OSW Widget] Fetching settings from:", graphqlUrl);
|
|
34
|
+
console.log("[OSW Widget] Request params - orgId:", orgId, "env:", env, "language:", language);
|
|
35
|
+
|
|
36
|
+
const query = `
|
|
37
|
+
query osw {
|
|
38
|
+
oswChatbotSettingsPublic(organizationId: ${orgId}) {
|
|
39
|
+
message
|
|
40
|
+
success
|
|
41
|
+
settings {
|
|
42
|
+
animation
|
|
43
|
+
chatbotMask
|
|
44
|
+
oswColourBackgroundDark
|
|
45
|
+
oswColourBackgroundLight
|
|
46
|
+
oswColourFontDark
|
|
47
|
+
oswColourFontLight
|
|
48
|
+
oswHintMessage
|
|
49
|
+
oswLabel
|
|
50
|
+
position
|
|
51
|
+
showNotification
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
const response = await fetch(graphqlUrl, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: {
|
|
60
|
+
"Content-Type": "application/json",
|
|
61
|
+
"Accept-Language": language
|
|
62
|
+
},
|
|
63
|
+
body: JSON.stringify({ query })
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
console.log("[OSW Widget] Response status:", response.status, response.statusText);
|
|
67
|
+
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
console.error("[OSW Widget] Failed to fetch - Status:", response.status, response.statusText);
|
|
70
|
+
const errorText = await response.text().catch(() => "Unable to read error response");
|
|
71
|
+
console.error("[OSW Widget] Error response:", errorText);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const result = await response.json();
|
|
76
|
+
console.log("[OSW Widget] GraphQL response:", result);
|
|
77
|
+
|
|
78
|
+
if (result.data?.oswChatbotSettingsPublic?.success) {
|
|
79
|
+
console.log("[OSW Widget] Settings retrieved successfully:", result.data.oswChatbotSettingsPublic.settings);
|
|
80
|
+
return result.data.oswChatbotSettingsPublic.settings;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
console.warn("[OSW Widget] GraphQL query succeeded but success=false or missing data");
|
|
84
|
+
return null;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error("[OSW Widget] Exception while fetching settings:", error);
|
|
87
|
+
console.error("[OSW Widget] Error details:", error.message, error.stack);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Default configuration with fallback values
|
|
93
|
+
const defaultConfig = {
|
|
94
|
+
env: "prod",
|
|
95
|
+
width: "414px",
|
|
96
|
+
height: "75vh",
|
|
97
|
+
openText: "Chat",
|
|
98
|
+
closeText: "Close",
|
|
99
|
+
background: "#FEFFFF",
|
|
100
|
+
backgroundDark: "#171717",
|
|
101
|
+
fontColor: "#3c4043",
|
|
102
|
+
fontColorDark: "#FFFFFF",
|
|
103
|
+
position: "right",
|
|
104
|
+
animation: "message",
|
|
105
|
+
shakeDuration: 3000,
|
|
106
|
+
shakeInterval: 1000,
|
|
107
|
+
shakeAmplitude: 10,
|
|
108
|
+
shakeFrequency: 1,
|
|
109
|
+
showNotification: false,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Initial config from HTML attributes with fallback to defaults
|
|
113
|
+
const config = {
|
|
114
|
+
src: wrapper.getAttribute("src"),
|
|
115
|
+
orgId: wrapper.getAttribute("orgId"),
|
|
116
|
+
env: wrapper.getAttribute("env") || defaultConfig.env,
|
|
117
|
+
width: wrapper.getAttribute("width") || defaultConfig.width,
|
|
118
|
+
height: wrapper.getAttribute("height") || defaultConfig.height,
|
|
119
|
+
openText: wrapper.getAttribute("openText") || defaultConfig.openText,
|
|
120
|
+
closeText: wrapper.getAttribute("closeText") || defaultConfig.closeText,
|
|
121
|
+
background: wrapper.getAttribute("background") || defaultConfig.background,
|
|
122
|
+
backgroundDark: wrapper.getAttribute("backgroundDark") || defaultConfig.backgroundDark,
|
|
123
|
+
fontColor: wrapper.getAttribute("fontColor") || defaultConfig.fontColor,
|
|
124
|
+
fontColorDark: wrapper.getAttribute("fontColorDark") || defaultConfig.fontColorDark,
|
|
125
|
+
logo: wrapper.getAttribute("logo"),
|
|
126
|
+
logoDark: wrapper.getAttribute("logoDark"),
|
|
127
|
+
position: wrapper.getAttribute("position") || defaultConfig.position,
|
|
128
|
+
animation: wrapper.getAttribute("animation") || defaultConfig.animation,
|
|
129
|
+
shakeDuration: parseInt(wrapper.getAttribute("shakeDuration")) || defaultConfig.shakeDuration,
|
|
130
|
+
shakeInterval: parseInt(wrapper.getAttribute("shakeInterval")) || defaultConfig.shakeInterval,
|
|
131
|
+
shakeAmplitude: parseInt(wrapper.getAttribute("shakeAmplitude")) || defaultConfig.shakeAmplitude,
|
|
132
|
+
shakeFrequency: parseInt(wrapper.getAttribute("shakeFrequency")) || defaultConfig.shakeFrequency,
|
|
133
|
+
showNotification: wrapper.getAttribute("showNotification") === "true" || defaultConfig.showNotification,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const origin = config.src.substring(0, config.src.lastIndexOf("/"));
|
|
137
|
+
|
|
138
|
+
// Get detected language
|
|
139
|
+
const detectedLang = getLanguage();
|
|
140
|
+
console.log("[OSW Widget] Detected language:", detectedLang);
|
|
141
|
+
console.log("[OSW Widget] Initial config from HTML:", config);
|
|
142
|
+
|
|
143
|
+
// Fetch settings from GraphQL and merge with config
|
|
144
|
+
if (!config.orgId) {
|
|
145
|
+
console.error("[OSW Widget] No organization ID provided! Widget will not be displayed.");
|
|
146
|
+
console.error("[OSW Widget] Add orgId attribute to the script tag: <script id='df-btn' orgId='YOUR_ORG_ID' ...>");
|
|
147
|
+
return; // Exit if no orgId
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const settings = await fetchChatbotSettings(config.orgId, config.env, detectedLang);
|
|
151
|
+
|
|
152
|
+
if (!settings) {
|
|
153
|
+
console.warn("[OSW Widget] Failed to fetch chatbot settings. Using fallback configuration.");
|
|
154
|
+
console.warn("[OSW Widget] Check:");
|
|
155
|
+
console.warn("[OSW Widget] 1. Network tab for CORS errors");
|
|
156
|
+
console.warn("[OSW Widget] 2. Organization ID is correct");
|
|
157
|
+
console.warn("[OSW Widget] 3. API endpoint is accessible");
|
|
158
|
+
// Continue with default config instead of exiting
|
|
159
|
+
config.hintMessage = "Click to check messages";
|
|
160
|
+
} else {
|
|
161
|
+
console.log("[OSW Widget] Merging GraphQL settings with config...");
|
|
162
|
+
|
|
163
|
+
// Merge GraphQL settings with config (GraphQL takes precedence, but null values fall back to HTML attributes)
|
|
164
|
+
config.animation = settings.animation || config.animation;
|
|
165
|
+
config.openText = settings.oswLabel || config.openText;
|
|
166
|
+
config.position = settings.position || config.position;
|
|
167
|
+
config.background = settings.oswColourBackgroundLight || config.background;
|
|
168
|
+
config.backgroundDark = settings.oswColourBackgroundDark || config.backgroundDark;
|
|
169
|
+
config.fontColor = settings.oswColourFontLight || config.fontColor;
|
|
170
|
+
config.fontColorDark = settings.oswColourFontDark || config.fontColorDark;
|
|
171
|
+
config.showNotification = settings.showNotification ?? config.showNotification;
|
|
172
|
+
config.hintMessage = settings.oswHintMessage || "Click to check messages";
|
|
173
|
+
|
|
174
|
+
// Use chatbotMask as logo if available
|
|
175
|
+
if (settings.chatbotMask) {
|
|
176
|
+
config.logo = settings.chatbotMask;
|
|
177
|
+
config.logoDark = settings.chatbotMask;
|
|
178
|
+
console.log("[OSW Widget] Using chatbotMask as logo:", settings.chatbotMask);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log("[OSW Widget] Final merged config:", config);
|
|
183
|
+
console.log("[OSW Widget] Widget will render with:", {
|
|
184
|
+
animation: config.animation,
|
|
185
|
+
openText: config.openText,
|
|
186
|
+
position: config.position,
|
|
187
|
+
showNotification: config.showNotification,
|
|
188
|
+
logo: config.logo ? "Custom logo" : "Default logo"
|
|
189
|
+
});
|
|
28
190
|
const style = document.createElement("style");
|
|
29
191
|
style.innerHTML = `
|
|
30
192
|
.df-btn {
|
|
@@ -32,6 +194,7 @@ if (!config.orgId) {
|
|
|
32
194
|
border: none;
|
|
33
195
|
box-shadow: 0 1px 2px 0 rgba(60,64,67,0.302),0 1px 3px 1px rgba(60,64,67,0.149);
|
|
34
196
|
font-family: 'Google Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
197
|
+
font-size: 16px;
|
|
35
198
|
background-color: ${config.background || "#FEFFFF"};
|
|
36
199
|
border-radius: 24px;
|
|
37
200
|
cursor: pointer;
|
|
@@ -84,12 +247,12 @@ if (!config.orgId) {
|
|
|
84
247
|
|
|
85
248
|
.df-btn-text {
|
|
86
249
|
min-width: 56px;
|
|
87
|
-
color: #3c4043;
|
|
250
|
+
color: ${config.fontColor || "#3c4043"};
|
|
88
251
|
display: inline-flex;
|
|
89
252
|
align-items: center;
|
|
90
253
|
font-weight: 500;
|
|
91
254
|
padding: 0 24px 0 0;
|
|
92
|
-
font-size:
|
|
255
|
+
font-size: 14px;
|
|
93
256
|
height: 48px
|
|
94
257
|
}
|
|
95
258
|
|
|
@@ -105,7 +268,7 @@ if (!config.orgId) {
|
|
|
105
268
|
background-position: center;
|
|
106
269
|
background-repeat: no-repeat;
|
|
107
270
|
background-size: cover;
|
|
108
|
-
background-image: url('${origin + "/assets/chat-agent.jpg"}');
|
|
271
|
+
background-image: url('${config.logo || origin + "/assets/chat-agent.jpg"}');
|
|
109
272
|
border-radius: 50%;
|
|
110
273
|
width: 32px;
|
|
111
274
|
height: 32px;
|
|
@@ -238,7 +401,7 @@ if (!config.orgId) {
|
|
|
238
401
|
.df-btn-text {
|
|
239
402
|
padding: 0 16px 0 0;
|
|
240
403
|
height: 56px;
|
|
241
|
-
font-size:
|
|
404
|
+
font-size: 16px;
|
|
242
405
|
}
|
|
243
406
|
}
|
|
244
407
|
|
|
@@ -248,11 +411,11 @@ if (!config.orgId) {
|
|
|
248
411
|
}
|
|
249
412
|
|
|
250
413
|
.df-btn-text {
|
|
251
|
-
color:
|
|
414
|
+
color: ${config.fontColorDark || "#FFFFFF"}
|
|
252
415
|
}
|
|
253
416
|
|
|
254
417
|
.df-btn-text:before {
|
|
255
|
-
background-image: url('${origin + "/assets/chat-agent.jpg"}')
|
|
418
|
+
background-image: url('${config.logoDark || config.logo || origin + "/assets/chat-agent.jpg"}')
|
|
256
419
|
}
|
|
257
420
|
|
|
258
421
|
.df-btn:not(.df-closed) > .df-btn-text:before {
|
|
@@ -279,27 +442,6 @@ if (!config.orgId) {
|
|
|
279
442
|
|
|
280
443
|
document.head.appendChild(style);
|
|
281
444
|
|
|
282
|
-
// Language detection function
|
|
283
|
-
function getLanguage() {
|
|
284
|
-
// Check HTML lang attribute first
|
|
285
|
-
let lang = document.documentElement.lang || "";
|
|
286
|
-
|
|
287
|
-
// Fallback to browser language
|
|
288
|
-
if (!lang) {
|
|
289
|
-
lang = navigator.language || navigator.languages?.[0] || "en";
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Extract language code (e.g., "en" from "en-US")
|
|
293
|
-
lang = lang.split("-")[0].toLowerCase();
|
|
294
|
-
|
|
295
|
-
// Validate against supported languages
|
|
296
|
-
const supportedLangs = ["en", "de", "it", "fr", "es"];
|
|
297
|
-
return supportedLangs.includes(lang) ? lang : "de";
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Get the detected language
|
|
301
|
-
const detectedLang = getLanguage();
|
|
302
|
-
|
|
303
445
|
// Function to get chat URL based on environment
|
|
304
446
|
function getChatUrl() {
|
|
305
447
|
const env = config.env;
|
|
@@ -315,11 +457,12 @@ if (!config.orgId) {
|
|
|
315
457
|
}
|
|
316
458
|
}
|
|
317
459
|
|
|
318
|
-
|
|
460
|
+
// Create button HTML
|
|
461
|
+
const buttonHTML = `
|
|
319
462
|
<button class="df-btn df-closed" onclick="dfToggle()">
|
|
320
463
|
${
|
|
321
464
|
config.showNotification
|
|
322
|
-
?
|
|
465
|
+
? `<div class="df-notification">${config.hintMessage || "Click to check messages"}</div>`
|
|
323
466
|
: ""
|
|
324
467
|
}
|
|
325
468
|
<div class="df-btn-header">
|
|
@@ -329,7 +472,10 @@ if (!config.orgId) {
|
|
|
329
472
|
config.orgId
|
|
330
473
|
}" allow="microphone *"></iframe>
|
|
331
474
|
</button>
|
|
332
|
-
|
|
475
|
+
`;
|
|
476
|
+
|
|
477
|
+
// Insert button into DOM (works in async context unlike document.write)
|
|
478
|
+
document.body.insertAdjacentHTML('beforeend', buttonHTML);
|
|
333
479
|
|
|
334
480
|
let dfToggled = false;
|
|
335
481
|
let inactivityTimer = null;
|
|
@@ -586,4 +732,6 @@ if (!config.orgId) {
|
|
|
586
732
|
if (!isMobile) {
|
|
587
733
|
startInactivityTimer();
|
|
588
734
|
}
|
|
589
|
-
|
|
735
|
+
|
|
736
|
+
console.log("[OSW Widget] ✓ Widget initialized successfully!");
|
|
737
|
+
})();
|