aumera-on-screen-widget 0.0.14 → 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.
Files changed (2) hide show
  1. package/df-btn.js +203 -56
  2. package/package.json +1 -1
package/df-btn.js CHANGED
@@ -1,30 +1,192 @@
1
- const wrapper = document.querySelector("#df-btn");
2
- const config = {
3
- src: wrapper.getAttribute("src"),
4
- orgId: wrapper.getAttribute("orgId"),
5
- env: wrapper.getAttribute("env"),
6
- width: wrapper.getAttribute("width"),
7
- height: wrapper.getAttribute("height"),
8
- openText: wrapper.getAttribute("openText"),
9
- closeText: wrapper.getAttribute("closeText"),
10
- background: wrapper.getAttribute("background"),
11
- backgroundDark: wrapper.getAttribute("backgroundDark"),
12
- logo: wrapper.getAttribute("logo"),
13
- logoDark: wrapper.getAttribute("logoDark"),
14
- position: wrapper.getAttribute("position") || "right",
15
- animation: wrapper.getAttribute("animation") || "message",
16
- shakeDuration: parseInt(wrapper.getAttribute("shakeDuration")) || 3000,
17
- shakeInterval: parseInt(wrapper.getAttribute("shakeInterval")) || 1000,
18
- shakeAmplitude: parseInt(wrapper.getAttribute("shakeAmplitude")) || 10,
19
- shakeFrequency: parseInt(wrapper.getAttribute("shakeFrequency")) || 1,
20
- showNotification: wrapper.getAttribute("showNotification") === "true",
21
- };
22
-
23
- const origin = config.src.substring(0, config.src.lastIndexOf("/"));
24
-
25
- if (!config.orgId) {
26
- console.warn("Please specify your organization ID in attributes!");
27
- } else {
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 {
@@ -85,7 +247,7 @@ if (!config.orgId) {
85
247
 
86
248
  .df-btn-text {
87
249
  min-width: 56px;
88
- color: #3c4043;
250
+ color: ${config.fontColor || "#3c4043"};
89
251
  display: inline-flex;
90
252
  align-items: center;
91
253
  font-weight: 500;
@@ -106,7 +268,7 @@ if (!config.orgId) {
106
268
  background-position: center;
107
269
  background-repeat: no-repeat;
108
270
  background-size: cover;
109
- background-image: url('${origin + "/assets/chat-agent.jpg"}');
271
+ background-image: url('${config.logo || origin + "/assets/chat-agent.jpg"}');
110
272
  border-radius: 50%;
111
273
  width: 32px;
112
274
  height: 32px;
@@ -249,11 +411,11 @@ if (!config.orgId) {
249
411
  }
250
412
 
251
413
  .df-btn-text {
252
- color: white
414
+ color: ${config.fontColorDark || "#FFFFFF"}
253
415
  }
254
416
 
255
417
  .df-btn-text:before {
256
- background-image: url('${origin + "/assets/chat-agent.jpg"}')
418
+ background-image: url('${config.logoDark || config.logo || origin + "/assets/chat-agent.jpg"}')
257
419
  }
258
420
 
259
421
  .df-btn:not(.df-closed) > .df-btn-text:before {
@@ -280,27 +442,6 @@ if (!config.orgId) {
280
442
 
281
443
  document.head.appendChild(style);
282
444
 
283
- // Language detection function
284
- function getLanguage() {
285
- // Check HTML lang attribute first
286
- let lang = document.documentElement.lang || "";
287
-
288
- // Fallback to browser language
289
- if (!lang) {
290
- lang = navigator.language || navigator.languages?.[0] || "en";
291
- }
292
-
293
- // Extract language code (e.g., "en" from "en-US")
294
- lang = lang.split("-")[0].toLowerCase();
295
-
296
- // Validate against supported languages
297
- const supportedLangs = ["en", "de", "it", "fr", "es"];
298
- return supportedLangs.includes(lang) ? lang : "de";
299
- }
300
-
301
- // Get the detected language
302
- const detectedLang = getLanguage();
303
-
304
445
  // Function to get chat URL based on environment
305
446
  function getChatUrl() {
306
447
  const env = config.env;
@@ -316,11 +457,12 @@ if (!config.orgId) {
316
457
  }
317
458
  }
318
459
 
319
- document.write(`
460
+ // Create button HTML
461
+ const buttonHTML = `
320
462
  <button class="df-btn df-closed" onclick="dfToggle()">
321
463
  ${
322
464
  config.showNotification
323
- ? '<div class="df-notification">Click to check messages</div>'
465
+ ? `<div class="df-notification">${config.hintMessage || "Click to check messages"}</div>`
324
466
  : ""
325
467
  }
326
468
  <div class="df-btn-header">
@@ -330,7 +472,10 @@ if (!config.orgId) {
330
472
  config.orgId
331
473
  }" allow="microphone *"></iframe>
332
474
  </button>
333
- `);
475
+ `;
476
+
477
+ // Insert button into DOM (works in async context unlike document.write)
478
+ document.body.insertAdjacentHTML('beforeend', buttonHTML);
334
479
 
335
480
  let dfToggled = false;
336
481
  let inactivityTimer = null;
@@ -587,4 +732,6 @@ if (!config.orgId) {
587
732
  if (!isMobile) {
588
733
  startInactivityTimer();
589
734
  }
590
- }
735
+
736
+ console.log("[OSW Widget] ✓ Widget initialized successfully!");
737
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aumera-on-screen-widget",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "description": "A lightweight, customizable chat widget for websites",
5
5
  "main": "df-btn.js",
6
6
  "scripts": {