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.
Files changed (2) hide show
  1. package/df-btn.js +206 -58
  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 {
@@ -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: .875rem;
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: 1rem;
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: white
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
- document.write(`
460
+ // Create button HTML
461
+ const buttonHTML = `
319
462
  <button class="df-btn df-closed" onclick="dfToggle()">
320
463
  ${
321
464
  config.showNotification
322
- ? '<div class="df-notification">Click to check messages</div>'
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
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aumera-on-screen-widget",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "description": "A lightweight, customizable chat widget for websites",
5
5
  "main": "df-btn.js",
6
6
  "scripts": {