wineater-bot 1.7.4 → 1.8.0
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/wineater-chatbot.mjs +169 -137
- package/dist/wineater-chatbot.umd.js +10 -10
- package/package.json +1 -1
- package/src/index.js +17 -1
- package/src/js/analytics.js +10 -1
- package/src/js/auto-open.js +20 -0
- package/src/js/ui.js +24 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const E = `
|
|
2
2
|
@font-face {
|
|
3
3
|
font-family: 'Poppins';
|
|
4
4
|
src: url('https://fonts.googleapis.com/css2?family=Poppins:wght@400&display=swap');
|
|
@@ -277,48 +277,52 @@ const y = `
|
|
|
277
277
|
.typing-indicator.visible {
|
|
278
278
|
visibility: visible;
|
|
279
279
|
height: 50px;
|
|
280
|
-
}`,
|
|
281
|
-
|
|
282
|
-
document.head.appendChild(
|
|
283
|
-
function
|
|
284
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(
|
|
285
|
-
const
|
|
286
|
-
return (
|
|
280
|
+
}`, f = document.createElement("style");
|
|
281
|
+
f.textContent = E;
|
|
282
|
+
document.head.appendChild(f);
|
|
283
|
+
function I() {
|
|
284
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(n) {
|
|
285
|
+
const e = Math.random() * 16 | 0;
|
|
286
|
+
return (n === "x" ? e : e & 3 | 8).toString(16);
|
|
287
287
|
});
|
|
288
288
|
}
|
|
289
|
-
function
|
|
290
|
-
|
|
291
|
-
|
|
289
|
+
function u(n, e, t) {
|
|
290
|
+
console.log(n, t);
|
|
291
|
+
let o = "";
|
|
292
|
+
if (t) {
|
|
292
293
|
const i = /* @__PURE__ */ new Date();
|
|
293
|
-
i.setTime(i.getTime() +
|
|
294
|
+
i.setTime(i.getTime() + t * 24 * 60 * 60 * 1e3), o = "; expires=" + i.toUTCString();
|
|
294
295
|
}
|
|
295
|
-
document.cookie =
|
|
296
|
+
document.cookie = n + "=" + (e || "") + o + "; path=/; secure; samesite=strict";
|
|
296
297
|
}
|
|
297
|
-
function s(
|
|
298
|
-
const
|
|
299
|
-
for (let
|
|
300
|
-
let i =
|
|
298
|
+
function s(n) {
|
|
299
|
+
const e = n + "=", t = document.cookie.split(";");
|
|
300
|
+
for (let o = 0; o < t.length; o++) {
|
|
301
|
+
let i = t[o];
|
|
301
302
|
for (; i.charAt(0) === " "; )
|
|
302
303
|
i = i.substring(1, i.length);
|
|
303
|
-
if (i.indexOf(
|
|
304
|
-
return i.substring(
|
|
304
|
+
if (i.indexOf(e) === 0)
|
|
305
|
+
return i.substring(e.length, i.length);
|
|
305
306
|
}
|
|
306
307
|
return null;
|
|
307
308
|
}
|
|
308
|
-
function
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
function T(n) {
|
|
310
|
+
document.cookie = n + "=; Max-Age=-99999999;";
|
|
311
|
+
}
|
|
312
|
+
function P() {
|
|
313
|
+
const n = "uniqueUserID";
|
|
314
|
+
let e = s(n);
|
|
315
|
+
return e || (e = I(), u(n, e, 365)), e;
|
|
312
316
|
}
|
|
313
|
-
function
|
|
317
|
+
function r(n, e) {
|
|
314
318
|
fetch("https://api.wineater.com/proxy/track", {
|
|
315
319
|
method: "POST",
|
|
316
320
|
headers: {
|
|
317
321
|
"Content-Type": "application/json"
|
|
318
322
|
},
|
|
319
323
|
body: JSON.stringify({
|
|
320
|
-
event:
|
|
321
|
-
properties:
|
|
324
|
+
event: n,
|
|
325
|
+
properties: e
|
|
322
326
|
})
|
|
323
327
|
}).then((i) => {
|
|
324
328
|
i.ok || console.error("Mixpanel tracking failed", i);
|
|
@@ -326,80 +330,86 @@ function c(o, t) {
|
|
|
326
330
|
console.error("Mixpanel tracking error", i);
|
|
327
331
|
});
|
|
328
332
|
}
|
|
329
|
-
function
|
|
330
|
-
|
|
333
|
+
function b() {
|
|
334
|
+
r("Chatbot Opened", { distinct_id: s("uniqueUserID"), client: s("chatbotToken") });
|
|
331
335
|
}
|
|
332
|
-
function
|
|
333
|
-
|
|
336
|
+
function O(n) {
|
|
337
|
+
r("Chatbot Opened Auto", { distinct_id: s("uniqueUserID"), url: n, client: s("chatbotToken") });
|
|
334
338
|
}
|
|
335
|
-
function
|
|
336
|
-
|
|
339
|
+
function y() {
|
|
340
|
+
r("Chatbot Closed", { distinct_id: s("uniqueUserID"), client: s("chatbotToken") });
|
|
337
341
|
}
|
|
338
|
-
function
|
|
339
|
-
|
|
342
|
+
function A(n) {
|
|
343
|
+
r("Message Sent", { distinct_id: s("uniqueUserID"), message_content: n, client: s("chatbotToken") });
|
|
340
344
|
}
|
|
341
|
-
function
|
|
342
|
-
|
|
345
|
+
function S(n) {
|
|
346
|
+
r("Products Got", { distinct_id: s("uniqueUserID"), products: n, client: s("chatbotToken") });
|
|
343
347
|
}
|
|
344
|
-
function
|
|
345
|
-
|
|
346
|
-
o.classList.contains("visible") ? (u(), o.classList.remove("visible"), t.style.display = "flex") : (p(), o.classList.add("visible"), t.style.display = "none");
|
|
348
|
+
function B(n) {
|
|
349
|
+
r("Product Clicked", { distinct_id: s("uniqueUserID"), product_id: n, client: s("chatbotToken") });
|
|
347
350
|
}
|
|
348
|
-
|
|
349
|
-
|
|
351
|
+
const D = 3;
|
|
352
|
+
function w() {
|
|
353
|
+
const n = document.getElementById("chat-window"), e = document.getElementById("chat-icon");
|
|
354
|
+
n.classList.contains("visible") ? (y(), x(), e.style.display = "flex") : (b(), n.classList.add("visible"), e.style.display = "none");
|
|
355
|
+
}
|
|
356
|
+
function x() {
|
|
357
|
+
console.log("ghbdtn"), y(), document.getElementById("chat-window").classList.remove("visible");
|
|
358
|
+
let e = parseInt(s("chatCloseCount")) || 0;
|
|
359
|
+
e += 1, e >= D ? (console.log(e), u("disableAutoOpen", "true", 1), T("chatCloseCount")) : (console.log(e), u("chatCloseCount", e, 1));
|
|
350
360
|
}
|
|
351
|
-
function
|
|
352
|
-
|
|
361
|
+
function v(n = null) {
|
|
362
|
+
n ? O(n) : b(), document.getElementById("chat-window").classList.add("visible");
|
|
353
363
|
}
|
|
354
364
|
document.addEventListener("DOMContentLoaded", () => {
|
|
355
365
|
setupCloseButton(), setupOutsideClick();
|
|
356
366
|
});
|
|
357
|
-
const
|
|
358
|
-
class
|
|
359
|
-
constructor(
|
|
360
|
-
var
|
|
361
|
-
this.baseURL = "https://api.wineater.com/", this.store =
|
|
367
|
+
const L = ["climats", "telckel", "biobio", "weinpoint", "vinigrandi"], W = "OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";
|
|
368
|
+
class C {
|
|
369
|
+
constructor(e) {
|
|
370
|
+
var t;
|
|
371
|
+
this.baseURL = "https://api.wineater.com/", this.store = L.find((o) => window.location.href.includes(o)), this.token = ((t = window == null ? void 0 : window.wineaterData) == null ? void 0 : t.CLIENT_TOKEN) || W;
|
|
362
372
|
}
|
|
363
|
-
async getStoreConfig(
|
|
364
|
-
console.log(
|
|
373
|
+
async getStoreConfig(e) {
|
|
374
|
+
console.log(e);
|
|
365
375
|
try {
|
|
366
|
-
const
|
|
376
|
+
const t = await fetch(`${this.baseURL}stores/store`, {
|
|
367
377
|
method: "POST",
|
|
368
378
|
headers: {
|
|
369
379
|
"Content-Type": "application/json",
|
|
370
380
|
Authorization: `Bearer ${this.token}`
|
|
371
381
|
},
|
|
372
|
-
body: JSON.stringify({ store:
|
|
382
|
+
body: JSON.stringify({ store: e })
|
|
373
383
|
});
|
|
374
|
-
if (!
|
|
375
|
-
throw new Error(`HTTP error! Status: ${
|
|
376
|
-
return await
|
|
377
|
-
} catch (
|
|
378
|
-
throw console.error("Error fetching store configuration:",
|
|
384
|
+
if (!t.ok)
|
|
385
|
+
throw new Error(`HTTP error! Status: ${t.status}`);
|
|
386
|
+
return await t.json();
|
|
387
|
+
} catch (t) {
|
|
388
|
+
throw console.error("Error fetching store configuration:", t), t;
|
|
379
389
|
}
|
|
380
390
|
}
|
|
381
|
-
async getWineRecommendations(
|
|
391
|
+
async getWineRecommendations(e) {
|
|
382
392
|
console.log(window.location.href);
|
|
383
393
|
try {
|
|
384
|
-
const
|
|
394
|
+
const t = await fetch(`${this.baseURL}dish/recommendations`, {
|
|
385
395
|
method: "POST",
|
|
386
396
|
headers: {
|
|
387
397
|
"Content-Type": "application/json",
|
|
388
398
|
Authorization: `Bearer ${this.token}`
|
|
389
399
|
},
|
|
390
|
-
body: JSON.stringify({ text:
|
|
391
|
-
}),
|
|
392
|
-
if (!
|
|
393
|
-
throw new Error(`API call failed with status ${
|
|
394
|
-
return
|
|
395
|
-
} catch (
|
|
396
|
-
throw console.error("Fetching wine recommendations failed:",
|
|
400
|
+
body: JSON.stringify({ text: e, store: this.store ? this.store.toString().charAt(0).toUpperCase() + this.store.slice(1) : void 0 })
|
|
401
|
+
}), o = await t.json();
|
|
402
|
+
if (!t.ok)
|
|
403
|
+
throw new Error(`API call failed with status ${t.status}: ${o.message || "No additional error information"}`);
|
|
404
|
+
return o;
|
|
405
|
+
} catch (t) {
|
|
406
|
+
throw console.error("Fetching wine recommendations failed:", t.message), new Error(`Error in getWineRecommendations: ${t.message}`);
|
|
397
407
|
}
|
|
398
408
|
}
|
|
399
409
|
}
|
|
400
|
-
class
|
|
410
|
+
class M {
|
|
401
411
|
constructor() {
|
|
402
|
-
this.api = new
|
|
412
|
+
this.api = new C(), this.language = "en", this.translations = {
|
|
403
413
|
fr: {
|
|
404
414
|
welcomeMessage: "Sublimez votre expérience gastronomique. Il vous suffit de donner les détails de votre plat, et obtenez la recommandation de compagnon de vin idéale. Que voulez-vous manger?",
|
|
405
415
|
noResultsFound: "Aucun résultat trouvé.",
|
|
@@ -454,43 +464,43 @@ class S {
|
|
|
454
464
|
}
|
|
455
465
|
};
|
|
456
466
|
}
|
|
457
|
-
async fetchConfig(
|
|
467
|
+
async fetchConfig(e = "Demo") {
|
|
458
468
|
try {
|
|
459
|
-
const
|
|
460
|
-
this.language =
|
|
469
|
+
const t = await this.api.getStoreConfig(e);
|
|
470
|
+
this.language = t.lang;
|
|
461
471
|
} catch {
|
|
462
472
|
this.language = "en";
|
|
463
473
|
}
|
|
464
474
|
}
|
|
465
|
-
translate(
|
|
466
|
-
return this.translations[this.language][
|
|
475
|
+
translate(e) {
|
|
476
|
+
return this.translations[this.language][e] || e;
|
|
467
477
|
}
|
|
468
478
|
}
|
|
469
|
-
const a = new
|
|
470
|
-
class
|
|
479
|
+
const a = new M();
|
|
480
|
+
class R {
|
|
471
481
|
constructor() {
|
|
472
|
-
var
|
|
473
|
-
this.api = new
|
|
474
|
-
const
|
|
475
|
-
this.displayFirstMessage(
|
|
482
|
+
var t;
|
|
483
|
+
this.api = new C();
|
|
484
|
+
const e = ((t = window == null ? void 0 : window.wineaterData) == null ? void 0 : t.FIRST_MESSAGE_TEXT) || a.translate("welcomeMessage");
|
|
485
|
+
this.displayFirstMessage(e);
|
|
476
486
|
}
|
|
477
487
|
initialize() {
|
|
478
|
-
document.getElementById("send-button").addEventListener("click", () => this.handleUserInput()), document.getElementById("user-input").addEventListener("keypress", (
|
|
479
|
-
|
|
488
|
+
document.getElementById("send-button").addEventListener("click", () => this.handleUserInput()), document.getElementById("user-input").addEventListener("keypress", (o) => {
|
|
489
|
+
o.key === "Enter" && this.handleUserInput();
|
|
480
490
|
});
|
|
481
491
|
}
|
|
482
|
-
displayFirstMessage(
|
|
483
|
-
const
|
|
484
|
-
i.className = `message ${
|
|
492
|
+
displayFirstMessage(e, t = "api") {
|
|
493
|
+
const o = document.getElementById("message-container"), i = document.createElement("div");
|
|
494
|
+
i.className = `message ${t}`, i.textContent = e, o.appendChild(i), o.scrollTop = o.scrollHeight;
|
|
485
495
|
}
|
|
486
496
|
async handleUserInput() {
|
|
487
|
-
const
|
|
488
|
-
if (
|
|
489
|
-
this.displayMessage(
|
|
497
|
+
const e = document.getElementById("user-input"), t = e.value.trim();
|
|
498
|
+
if (t) {
|
|
499
|
+
this.displayMessage(t, "user"), e.value = "", this.showTypingIndicator();
|
|
490
500
|
try {
|
|
491
|
-
|
|
492
|
-
const
|
|
493
|
-
this.hideTypingIndicator(),
|
|
501
|
+
A(t);
|
|
502
|
+
const o = await this.api.getWineRecommendations(t);
|
|
503
|
+
this.hideTypingIndicator(), o && o.length ? this.displayResults(o) : this.displayMessage("No results found.", "api");
|
|
494
504
|
} catch {
|
|
495
505
|
this.hideTypingIndicator(), this.displayMessage(a.translate("somethingWentWrong"), "api");
|
|
496
506
|
}
|
|
@@ -502,44 +512,58 @@ class L {
|
|
|
502
512
|
hideTypingIndicator() {
|
|
503
513
|
document.getElementById("typing-indicator").classList.remove("visible");
|
|
504
514
|
}
|
|
505
|
-
displayMessage(
|
|
506
|
-
const
|
|
507
|
-
i.textContent =
|
|
515
|
+
displayMessage(e, t) {
|
|
516
|
+
const o = document.getElementById("message-container"), i = document.createElement("div");
|
|
517
|
+
i.textContent = e, i.className = "message " + t, o.appendChild(i), o.scrollTop = o.scrollHeight;
|
|
508
518
|
}
|
|
509
|
-
sendAnalytics(
|
|
510
|
-
console.log(
|
|
519
|
+
sendAnalytics(e) {
|
|
520
|
+
console.log(e), B(e);
|
|
511
521
|
}
|
|
512
|
-
displayResults(
|
|
513
|
-
const
|
|
514
|
-
|
|
522
|
+
displayResults(e) {
|
|
523
|
+
const t = document.getElementById("message-container");
|
|
524
|
+
S(e.map((o) => o.Title)), e.forEach((o) => {
|
|
515
525
|
const i = document.createElement("div");
|
|
516
526
|
i.className = "wine-item";
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
<strong>${
|
|
522
|
-
${a.translate("price")}: ${
|
|
523
|
-
${a.translate("region")}: ${
|
|
524
|
-
${a.translate("type")}: ${
|
|
525
|
-
<a href="${
|
|
526
|
-
`,
|
|
527
|
-
|
|
528
|
-
}), i.appendChild(
|
|
529
|
-
}),
|
|
527
|
+
const d = document.createElement("img");
|
|
528
|
+
d.src = o.Image, i.appendChild(d);
|
|
529
|
+
const c = document.createElement("div");
|
|
530
|
+
c.innerHTML = `
|
|
531
|
+
<strong>${o.Title}</strong><br>
|
|
532
|
+
${a.translate("price")}: ${o.Price}<br>
|
|
533
|
+
${a.translate("region")}: ${o.Region}<br>
|
|
534
|
+
${a.translate("type")}: ${o.Type}<br>
|
|
535
|
+
<a href="${o.Url}" target="_blank">${a.translate("moreInfo")}</a>
|
|
536
|
+
`, c.querySelector("a").addEventListener("click", (k) => {
|
|
537
|
+
k.preventDefault(), this.sendAnalytics(o.Title), window.open(o.Url, "_blank");
|
|
538
|
+
}), i.appendChild(c), t.appendChild(i), this.displayFirstMessage(o.Reason);
|
|
539
|
+
}), t.scrollTop = t.scrollHeight;
|
|
530
540
|
}
|
|
531
541
|
}
|
|
532
|
-
const
|
|
542
|
+
const l = {
|
|
543
|
+
PRODUCT_PAGES: /producto\/[^\/]+\/$/
|
|
544
|
+
// Matches any product page like 'producto/any-product-name/'
|
|
545
|
+
// CART_PAGE: /carrito\/$/ // Matches the cart page like 'carrito/'
|
|
546
|
+
};
|
|
547
|
+
var g, p;
|
|
548
|
+
const h = {
|
|
549
|
+
PRODUCT_PAGES: ((g = window.wineaterData) == null ? void 0 : g.PRODUCT_PAGES) || l.PRODUCT_PAGES,
|
|
550
|
+
CART_PAGE: ((p = window.wineaterData) == null ? void 0 : p.CART_PAGE) || (l == null ? void 0 : l.CART_PAGE)
|
|
551
|
+
};
|
|
552
|
+
function U() {
|
|
553
|
+
const n = window.location.href;
|
|
554
|
+
return console.log(h), !!(h.PRODUCT_PAGES.test(n) || h.CART_PAGE.test(n));
|
|
555
|
+
}
|
|
556
|
+
const _ = "OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";
|
|
533
557
|
document.addEventListener("DOMContentLoaded", () => {
|
|
534
|
-
window.toggleChatWindow =
|
|
558
|
+
window.toggleChatWindow = w, window.closeChatWindow = x, window.openChatWindow = v;
|
|
535
559
|
});
|
|
536
|
-
function
|
|
537
|
-
var
|
|
538
|
-
const
|
|
560
|
+
function z() {
|
|
561
|
+
var t;
|
|
562
|
+
const e = `
|
|
539
563
|
<div id="chatbot-container">
|
|
540
564
|
<div id="chat-icon" onclick="toggleChatWindow()">
|
|
541
565
|
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/chat-icon.svg" alt="Chat Icon"> <!-- Update the path to your logo image -->
|
|
542
|
-
<span>${((
|
|
566
|
+
<span>${((t = window == null ? void 0 : window.wineaterData) == null ? void 0 : t.BUTTON_TEXT) || a.translate("chatButton")}</span>
|
|
543
567
|
</div>
|
|
544
568
|
|
|
545
569
|
<div id="chat-window" class="hidden">
|
|
@@ -564,34 +588,42 @@ function P() {
|
|
|
564
588
|
</div>
|
|
565
589
|
</div>
|
|
566
590
|
`;
|
|
567
|
-
document.body.insertAdjacentHTML("beforeend",
|
|
591
|
+
document.body.insertAdjacentHTML("beforeend", e);
|
|
568
592
|
}
|
|
569
|
-
function
|
|
570
|
-
document.getElementById("close-btn").addEventListener("click",
|
|
593
|
+
function $() {
|
|
594
|
+
document.getElementById("close-btn").addEventListener("click", w);
|
|
571
595
|
}
|
|
572
|
-
function
|
|
573
|
-
window.addEventListener("click", function(
|
|
574
|
-
const
|
|
575
|
-
!
|
|
596
|
+
function j() {
|
|
597
|
+
window.addEventListener("click", function(n) {
|
|
598
|
+
const e = document.getElementById("chat-window"), t = document.getElementById("chat-icon");
|
|
599
|
+
!e.contains(n.target) && !t.contains(n.target) && (e.classList.remove("visible"), t.style.display = "flex");
|
|
576
600
|
});
|
|
577
601
|
}
|
|
578
|
-
function
|
|
579
|
-
console.log(
|
|
580
|
-
const
|
|
581
|
-
|
|
602
|
+
function N(n) {
|
|
603
|
+
console.log(n);
|
|
604
|
+
const e = document.getElementById("chat-icon"), t = document.getElementById("chat-window");
|
|
605
|
+
e.className = "", t.className = "", n === "right-center" ? (e.classList.add("chat-icon-right-center"), t.classList.add("right-center-aligned")) : e.classList.add("chat-icon-bottom-right");
|
|
606
|
+
}
|
|
607
|
+
function q(n = 1e4) {
|
|
608
|
+
setTimeout(() => {
|
|
609
|
+
v(window.location.href);
|
|
610
|
+
}, n);
|
|
582
611
|
}
|
|
583
|
-
|
|
612
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
613
|
+
!s("disableAutoOpen") && U() && q(1e4);
|
|
614
|
+
});
|
|
615
|
+
var m;
|
|
584
616
|
if (typeof window < "u") {
|
|
585
|
-
let
|
|
617
|
+
let n = ((m = window == null ? void 0 : window.wineaterData) == null ? void 0 : m.POSITION) || "bottom-right";
|
|
586
618
|
window.addEventListener("DOMContentLoaded", async () => {
|
|
587
|
-
var
|
|
588
|
-
const
|
|
589
|
-
let
|
|
590
|
-
|
|
619
|
+
var d;
|
|
620
|
+
const t = ["climats", "telckel", "biobio", "weinpoint", "vinigrandi"].find((c) => window.location.href.includes(c)) || null;
|
|
621
|
+
let o;
|
|
622
|
+
t && (o = t.charAt(0).toUpperCase() + t.slice(1), o === "Biobio" && (n = "right-center")), await a.fetchConfig(o || "Demo"), z(), $(), j(), N(n), u("chatbotToken", ((d = window.wineaterData) == null ? void 0 : d.CLIENT_TOKEN) || _, 365), P(), new R().initialize();
|
|
591
623
|
});
|
|
592
624
|
}
|
|
593
625
|
export {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
626
|
+
x as closeChatWindow,
|
|
627
|
+
v as openChatWindow,
|
|
628
|
+
w as toggleChatWindow
|
|
597
629
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(r,
|
|
1
|
+
(function(r,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(r=typeof globalThis<"u"?globalThis:r||self,c(r.WineaterChatbot={}))})(this,function(r){"use strict";var v,k,E;const c=`
|
|
2
2
|
@font-face {
|
|
3
3
|
font-family: 'Poppins';
|
|
4
4
|
src: url('https://fonts.googleapis.com/css2?family=Poppins:wght@400&display=swap');
|
|
@@ -277,17 +277,17 @@
|
|
|
277
277
|
.typing-indicator.visible {
|
|
278
278
|
visibility: visible;
|
|
279
279
|
height: 50px;
|
|
280
|
-
}`,
|
|
281
|
-
<strong>${
|
|
282
|
-
${a.translate("price")}: ${
|
|
283
|
-
${a.translate("region")}: ${
|
|
284
|
-
${a.translate("type")}: ${
|
|
285
|
-
<a href="${
|
|
286
|
-
`,
|
|
280
|
+
}`,y=document.createElement("style");y.textContent=c,document.head.appendChild(y);function T(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(n){const e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)})}function h(n,e,t){console.log(n,t);let o="";if(t){const i=new Date;i.setTime(i.getTime()+t*24*60*60*1e3),o="; expires="+i.toUTCString()}document.cookie=n+"="+(e||"")+o+"; path=/; secure; samesite=strict"}function s(n){const e=n+"=",t=document.cookie.split(";");for(let o=0;o<t.length;o++){let i=t[o];for(;i.charAt(0)===" ";)i=i.substring(1,i.length);if(i.indexOf(e)===0)return i.substring(e.length,i.length)}return null}function I(n){document.cookie=n+"=; Max-Age=-99999999;"}function P(){const n="uniqueUserID";let e=s(n);return e||(e=T(),h(n,e,365)),e}function d(n,e){fetch("https://api.wineater.com/proxy/track",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({event:n,properties:e})}).then(i=>{i.ok||console.error("Mixpanel tracking failed",i)}).catch(i=>{console.error("Mixpanel tracking error",i)})}function w(){d("Chatbot Opened",{distinct_id:s("uniqueUserID"),client:s("chatbotToken")})}function O(n){d("Chatbot Opened Auto",{distinct_id:s("uniqueUserID"),url:n,client:s("chatbotToken")})}function x(){d("Chatbot Closed",{distinct_id:s("uniqueUserID"),client:s("chatbotToken")})}function A(n){d("Message Sent",{distinct_id:s("uniqueUserID"),message_content:n,client:s("chatbotToken")})}function S(n){d("Products Got",{distinct_id:s("uniqueUserID"),products:n,client:s("chatbotToken")})}function B(n){d("Product Clicked",{distinct_id:s("uniqueUserID"),product_id:n,client:s("chatbotToken")})}const W=3;function p(){const n=document.getElementById("chat-window"),e=document.getElementById("chat-icon");n.classList.contains("visible")?(x(),m(),e.style.display="flex"):(w(),n.classList.add("visible"),e.style.display="none")}function m(){console.log("ghbdtn"),x(),document.getElementById("chat-window").classList.remove("visible");let e=parseInt(s("chatCloseCount"))||0;e+=1,e>=W?(console.log(e),h("disableAutoOpen","true",1),I("chatCloseCount")):(console.log(e),h("chatCloseCount",e,1))}function f(n=null){n?O(n):w(),document.getElementById("chat-window").classList.add("visible")}document.addEventListener("DOMContentLoaded",()=>{setupCloseButton(),setupOutsideClick()});const D=["climats","telckel","biobio","weinpoint","vinigrandi"],L="OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";class C{constructor(e){var t;this.baseURL="https://api.wineater.com/",this.store=D.find(o=>window.location.href.includes(o)),this.token=((t=window==null?void 0:window.wineaterData)==null?void 0:t.CLIENT_TOKEN)||L}async getStoreConfig(e){console.log(e);try{const t=await fetch(`${this.baseURL}stores/store`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({store:e})});if(!t.ok)throw new Error(`HTTP error! Status: ${t.status}`);return await t.json()}catch(t){throw console.error("Error fetching store configuration:",t),t}}async getWineRecommendations(e){console.log(window.location.href);try{const t=await fetch(`${this.baseURL}dish/recommendations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({text:e,store:this.store?this.store.toString().charAt(0).toUpperCase()+this.store.slice(1):void 0})}),o=await t.json();if(!t.ok)throw new Error(`API call failed with status ${t.status}: ${o.message||"No additional error information"}`);return o}catch(t){throw console.error("Fetching wine recommendations failed:",t.message),new Error(`Error in getWineRecommendations: ${t.message}`)}}}class M{constructor(){this.api=new C,this.language="en",this.translations={fr:{welcomeMessage:"Sublimez votre expérience gastronomique. Il vous suffit de donner les détails de votre plat, et obtenez la recommandation de compagnon de vin idéale. Que voulez-vous manger?",noResultsFound:"Aucun résultat trouvé.",somethingWentWrong:"Désolé, quelque chose a mal tourné.",chatButton:"Accorder le vin au dîner",inputPlaceholder:"ex., Salade de thon",sendButton:"Accorder",price:"Prix",region:"Région",type:"Type",reason:"Suggestion",moreInfo:"Plus d'infos"},es:{welcomeMessage:"Mejore su experiencia gastronómica. Solo proporcione los detalles de su plato y obtenga la recomendación de vino ideal. ¿Qué le gustaría comer?",noResultsFound:"No se encontraron resultados.",somethingWentWrong:"Lo sentimos, algo salió mal.",chatButton:"Maridaje ideal",inputPlaceholder:"ej., Ensalada de atún",sendButton:"Maridar",price:"Precio",region:"Región",type:"Tipo",reason:"Sugerencia",moreInfo:"Más info"},en:{welcomeMessage:"Enhance your dining experience. Just provide your dish details and get the ideal wine pairing. What would you like to eat?",noResultsFound:"No results found.",somethingWentWrong:"Sorry, something went wrong.",chatButton:"Pair wine with dinner",inputPlaceholder:"e.g., Tuna Salad",sendButton:"Pair",price:"Price",region:"Region",type:"Type",reason:"Suggestion",moreInfo:"More info"},de:{welcomeMessage:"Verbessern Sie Ihr kulinarisches Erlebnis. Geben Sie einfach die Details Ihres Gerichts an und erhalten Sie die ideale Weinempfehlung. Was möchten Sie essen?",noResultsFound:"Keine Ergebnisse gefunden.",somethingWentWrong:"Entschuldigung, etwas ist schief gelaufen.",chatButton:"Wein zum Abendessen",inputPlaceholder:"z.B., Thunfischsalat",sendButton:"Kombinieren",price:"Preis",region:"Region",type:"Typ",reason:"Anregung",moreInfo:"Mehr Info"}}}async fetchConfig(e="Demo"){try{const t=await this.api.getStoreConfig(e);this.language=t.lang}catch{this.language="en"}}translate(e){return this.translations[this.language][e]||e}}const a=new M;class R{constructor(){var t;this.api=new C;const e=((t=window==null?void 0:window.wineaterData)==null?void 0:t.FIRST_MESSAGE_TEXT)||a.translate("welcomeMessage");this.displayFirstMessage(e)}initialize(){document.getElementById("send-button").addEventListener("click",()=>this.handleUserInput()),document.getElementById("user-input").addEventListener("keypress",o=>{o.key==="Enter"&&this.handleUserInput()})}displayFirstMessage(e,t="api"){const o=document.getElementById("message-container"),i=document.createElement("div");i.className=`message ${t}`,i.textContent=e,o.appendChild(i),o.scrollTop=o.scrollHeight}async handleUserInput(){const e=document.getElementById("user-input"),t=e.value.trim();if(t){this.displayMessage(t,"user"),e.value="",this.showTypingIndicator();try{A(t);const o=await this.api.getWineRecommendations(t);this.hideTypingIndicator(),o&&o.length?this.displayResults(o):this.displayMessage("No results found.","api")}catch{this.hideTypingIndicator(),this.displayMessage(a.translate("somethingWentWrong"),"api")}}}showTypingIndicator(){document.getElementById("typing-indicator").classList.add("visible")}hideTypingIndicator(){document.getElementById("typing-indicator").classList.remove("visible")}displayMessage(e,t){const o=document.getElementById("message-container"),i=document.createElement("div");i.textContent=e,i.className="message "+t,o.appendChild(i),o.scrollTop=o.scrollHeight}sendAnalytics(e){console.log(e),B(e)}displayResults(e){const t=document.getElementById("message-container");S(e.map(o=>o.Title)),e.forEach(o=>{const i=document.createElement("div");i.className="wine-item";const l=document.createElement("img");l.src=o.Image,i.appendChild(l);const u=document.createElement("div");u.innerHTML=`
|
|
281
|
+
<strong>${o.Title}</strong><br>
|
|
282
|
+
${a.translate("price")}: ${o.Price}<br>
|
|
283
|
+
${a.translate("region")}: ${o.Region}<br>
|
|
284
|
+
${a.translate("type")}: ${o.Type}<br>
|
|
285
|
+
<a href="${o.Url}" target="_blank">${a.translate("moreInfo")}</a>
|
|
286
|
+
`,u.querySelector("a").addEventListener("click",F=>{F.preventDefault(),this.sendAnalytics(o.Title),window.open(o.Url,"_blank")}),i.appendChild(u),t.appendChild(i),this.displayFirstMessage(o.Reason)}),t.scrollTop=t.scrollHeight}}const g={PRODUCT_PAGES:/producto\/[^\/]+\/$/},b={PRODUCT_PAGES:((v=window.wineaterData)==null?void 0:v.PRODUCT_PAGES)||g.PRODUCT_PAGES,CART_PAGE:((k=window.wineaterData)==null?void 0:k.CART_PAGE)||(g==null?void 0:g.CART_PAGE)};function U(){const n=window.location.href;return console.log(b),!!(b.PRODUCT_PAGES.test(n)||b.CART_PAGE.test(n))}const _="OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";document.addEventListener("DOMContentLoaded",()=>{window.toggleChatWindow=p,window.closeChatWindow=m,window.openChatWindow=f});function z(){var t;const e=`
|
|
287
287
|
<div id="chatbot-container">
|
|
288
288
|
<div id="chat-icon" onclick="toggleChatWindow()">
|
|
289
289
|
<img src="https://landing-static.s3.eu-central-1.amazonaws.com/images/chat-icon.svg" alt="Chat Icon"> <!-- Update the path to your logo image -->
|
|
290
|
-
<span>${((
|
|
290
|
+
<span>${((t=window==null?void 0:window.wineaterData)==null?void 0:t.BUTTON_TEXT)||a.translate("chatButton")}</span>
|
|
291
291
|
</div>
|
|
292
292
|
|
|
293
293
|
<div id="chat-window" class="hidden">
|
|
@@ -311,4 +311,4 @@
|
|
|
311
311
|
</div>
|
|
312
312
|
</div>
|
|
313
313
|
</div>
|
|
314
|
-
`;document.body.insertAdjacentHTML("beforeend",
|
|
314
|
+
`;document.body.insertAdjacentHTML("beforeend",e)}function $(){document.getElementById("close-btn").addEventListener("click",p)}function j(){window.addEventListener("click",function(n){const e=document.getElementById("chat-window"),t=document.getElementById("chat-icon");!e.contains(n.target)&&!t.contains(n.target)&&(e.classList.remove("visible"),t.style.display="flex")})}function N(n){console.log(n);const e=document.getElementById("chat-icon"),t=document.getElementById("chat-window");e.className="",t.className="",n==="right-center"?(e.classList.add("chat-icon-right-center"),t.classList.add("right-center-aligned")):e.classList.add("chat-icon-bottom-right")}function q(n=1e4){setTimeout(()=>{f(window.location.href)},n)}if(document.addEventListener("DOMContentLoaded",()=>{!s("disableAutoOpen")&&U()&&q(1e4)}),typeof window<"u"){let n=((E=window==null?void 0:window.wineaterData)==null?void 0:E.POSITION)||"bottom-right";window.addEventListener("DOMContentLoaded",async()=>{var l;const t=["climats","telckel","biobio","weinpoint","vinigrandi"].find(u=>window.location.href.includes(u))||null;let o;t&&(o=t.charAt(0).toUpperCase()+t.slice(1),o==="Biobio"&&(n="right-center")),await a.fetchConfig(o||"Demo"),z(),$(),j(),N(n),h("chatbotToken",((l=window.wineaterData)==null?void 0:l.CLIENT_TOKEN)||_,365),P(),new R().initialize()})}r.closeChatWindow=m,r.openChatWindow=f,r.toggleChatWindow=p,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
// Import your CSS here
|
|
4
4
|
import './js/styles.js';
|
|
5
|
-
import { setCookie, setUniqueUserCookie } from './js/analytics.js';
|
|
5
|
+
import { setCookie, setUniqueUserCookie, getCookie } from './js/analytics.js';
|
|
6
6
|
|
|
7
7
|
// Import your JavaScript modules here
|
|
8
8
|
import { toggleChatWindow, closeChatWindow, openChatWindow } from './js/ui.js';
|
|
9
9
|
import { Chatbot } from './js/chatbot.js';
|
|
10
10
|
import './js/api.js';
|
|
11
11
|
import translator from './js/i18n.js';
|
|
12
|
+
import {shouldOpenChatAutomatically} from './js/auto-open.js'
|
|
12
13
|
|
|
13
14
|
const DEMO_TOKEN='OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL';
|
|
14
15
|
|
|
@@ -96,6 +97,21 @@ function toggleChatIconPosition(position) {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
function openChatAfterDelay(delay = 10000) { // delay is in milliseconds
|
|
101
|
+
setTimeout(() => {
|
|
102
|
+
openChatWindow(window.location.href); // Ensure openChatWindow is available globally
|
|
103
|
+
}, delay);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
107
|
+
// Check if auto-opening is disabled by cookie
|
|
108
|
+
const disableAutoOpen = getCookie('disableAutoOpen');
|
|
109
|
+
|
|
110
|
+
if (!disableAutoOpen && shouldOpenChatAutomatically()) {
|
|
111
|
+
openChatAfterDelay(10000); // 10-second delay
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
99
115
|
// If you want to initialize your chatbot automatically when the script is loaded
|
|
100
116
|
if (typeof window !== 'undefined') {
|
|
101
117
|
let position = window?.wineaterData?.POSITION || 'bottom-right';
|
package/src/js/analytics.js
CHANGED
|
@@ -11,6 +11,7 @@ function generateUUID() {
|
|
|
11
11
|
|
|
12
12
|
// Function to set a cookie
|
|
13
13
|
function setCookie(name, value, days) {
|
|
14
|
+
console.log(name, days);
|
|
14
15
|
let expires = "";
|
|
15
16
|
if (days) {
|
|
16
17
|
const date = new Date();
|
|
@@ -32,6 +33,10 @@ function getCookie(name) {
|
|
|
32
33
|
return null;
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
function deleteCookie(name) {
|
|
37
|
+
document.cookie = name + '=; Max-Age=-99999999;';
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
// Function to set a unique user identifier cookie
|
|
36
41
|
function setUniqueUserCookie() {
|
|
37
42
|
const cookieName = 'uniqueUserID';
|
|
@@ -71,6 +76,10 @@ function setUniqueUserCookie() {
|
|
|
71
76
|
trackEvent('Chatbot Opened', { distinct_id: getCookie('uniqueUserID'), client: getCookie('chatbotToken') });
|
|
72
77
|
}
|
|
73
78
|
|
|
79
|
+
function trackChatbotOpenAuto(url) {
|
|
80
|
+
trackEvent('Chatbot Opened Auto', { distinct_id: getCookie('uniqueUserID'), url, client: getCookie('chatbotToken') });
|
|
81
|
+
}
|
|
82
|
+
|
|
74
83
|
function trackChatbotClose() {
|
|
75
84
|
trackEvent('Chatbot Closed', { distinct_id: getCookie('uniqueUserID'), client: getCookie('chatbotToken') });
|
|
76
85
|
}
|
|
@@ -87,5 +96,5 @@ function setUniqueUserCookie() {
|
|
|
87
96
|
trackEvent('Product Clicked', { distinct_id: getCookie('uniqueUserID'), product_id: productId, client: getCookie('chatbotToken') });
|
|
88
97
|
}
|
|
89
98
|
|
|
90
|
-
export { setCookie, getCookie, setUniqueUserCookie, trackChatbotOpen, trackMessageSent, trackProductClick, trackChatbotClose, trackRecommendationsGet };
|
|
99
|
+
export { setCookie, getCookie, setUniqueUserCookie, trackChatbotOpen, trackMessageSent, trackProductClick, trackChatbotClose, trackRecommendationsGet, trackChatbotOpenAuto, deleteCookie };
|
|
91
100
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const DEFAULT_URL_PATTERNS = {
|
|
2
|
+
PRODUCT_PAGES: /producto\/[^\/]+\/$/, // Matches any product page like 'producto/any-product-name/'
|
|
3
|
+
// CART_PAGE: /carrito\/$/ // Matches the cart page like 'carrito/'
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
// Retrieve custom or default URL patterns from wineaterData
|
|
7
|
+
const urlPatterns = {
|
|
8
|
+
PRODUCT_PAGES: window.wineaterData?.PRODUCT_PAGES || DEFAULT_URL_PATTERNS.PRODUCT_PAGES,
|
|
9
|
+
CART_PAGE: window.wineaterData?.CART_PAGE || DEFAULT_URL_PATTERNS?.CART_PAGE
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function shouldOpenChatAutomatically() {
|
|
13
|
+
const currentURL = window.location.href;
|
|
14
|
+
console.log(urlPatterns);
|
|
15
|
+
|
|
16
|
+
if (urlPatterns.PRODUCT_PAGES.test(currentURL) || urlPatterns.CART_PAGE.test(currentURL)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
package/src/js/ui.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
|
|
2
|
-
import { trackChatbotOpen, trackChatbotClose } from './analytics.js';
|
|
2
|
+
import { trackChatbotOpen, trackChatbotClose, trackChatbotOpenAuto, setCookie, getCookie, deleteCookie } from './analytics.js';
|
|
3
|
+
|
|
4
|
+
const MAX_CHAT_CLOSURES = 3;
|
|
3
5
|
|
|
4
6
|
export function toggleChatWindow() {
|
|
5
7
|
const chatWindow = document.getElementById('chat-window');
|
|
6
8
|
const chatIcon = document.getElementById('chat-icon');
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
// Check if the chat window is currently visible
|
|
9
12
|
const isWindowOpen = chatWindow.classList.contains('visible');
|
|
10
13
|
|
|
11
14
|
if (isWindowOpen) {
|
|
12
15
|
trackChatbotClose();
|
|
13
|
-
|
|
16
|
+
closeChatWindow();
|
|
14
17
|
chatIcon.style.display = 'flex'; // Show the chat icon/button
|
|
15
18
|
} else {
|
|
16
19
|
trackChatbotOpen();
|
|
@@ -20,13 +23,30 @@ export function toggleChatWindow() {
|
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
export function closeChatWindow() {
|
|
26
|
+
console.log('ghbdtn');
|
|
23
27
|
trackChatbotClose();
|
|
24
28
|
const chatWindow = document.getElementById('chat-window');
|
|
25
29
|
chatWindow.classList.remove('visible');
|
|
30
|
+
|
|
31
|
+
let closeCount = parseInt(getCookie('chatCloseCount')) || 0;
|
|
32
|
+
closeCount += 1;
|
|
33
|
+
|
|
34
|
+
if (closeCount >= MAX_CHAT_CLOSURES) {
|
|
35
|
+
console.log(closeCount);
|
|
36
|
+
setCookie('disableAutoOpen', 'true', 1); // Disable auto-opening for 1 day
|
|
37
|
+
deleteCookie('chatCloseCount'); // Reset close count
|
|
38
|
+
} else {
|
|
39
|
+
console.log(closeCount);
|
|
40
|
+
setCookie('chatCloseCount', closeCount, 1); // Update the close count cookie
|
|
41
|
+
}
|
|
26
42
|
}
|
|
27
43
|
|
|
28
|
-
export function openChatWindow() {
|
|
29
|
-
|
|
44
|
+
export function openChatWindow(fromUrl = null) {
|
|
45
|
+
if (!!fromUrl) {
|
|
46
|
+
trackChatbotOpenAuto(fromUrl);
|
|
47
|
+
} else {
|
|
48
|
+
trackChatbotOpen();
|
|
49
|
+
}
|
|
30
50
|
const chatWindow = document.getElementById('chat-window');
|
|
31
51
|
chatWindow.classList.add('visible');
|
|
32
52
|
}
|