wineater-bot 1.4.1 → 1.4.2
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 +97 -44
- package/dist/wineater-chatbot.umd.js +5 -5
- package/package.json +1 -1
- package/src/index.js +2 -0
- package/src/js/analytics.js +67 -0
- package/src/js/chatbot.js +9 -2
- package/src/js/ui.js +7 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const f = `
|
|
2
2
|
@font-face {
|
|
3
3
|
font-family: 'Poppins';
|
|
4
4
|
src: url('https://fonts.googleapis.com/css2?family=Poppins:wght@400&display=swap');
|
|
@@ -273,27 +273,75 @@ const g = `
|
|
|
273
273
|
.typing-indicator.visible {
|
|
274
274
|
visibility: visible;
|
|
275
275
|
height: 50px;
|
|
276
|
-
}`,
|
|
277
|
-
|
|
278
|
-
document.head.appendChild(
|
|
279
|
-
function
|
|
280
|
-
|
|
281
|
-
|
|
276
|
+
}`, p = document.createElement("style");
|
|
277
|
+
p.textContent = f;
|
|
278
|
+
document.head.appendChild(p);
|
|
279
|
+
function b(n, t, e) {
|
|
280
|
+
let o = "";
|
|
281
|
+
if (e) {
|
|
282
|
+
const i = /* @__PURE__ */ new Date();
|
|
283
|
+
i.setTime(i.getTime() + e * 24 * 60 * 60 * 1e3), o = "; expires=" + i.toUTCString();
|
|
284
|
+
}
|
|
285
|
+
document.cookie = n + "=" + (t || "") + o + "; path=/; secure; samesite=strict";
|
|
286
|
+
}
|
|
287
|
+
function r(n) {
|
|
288
|
+
const e = `; ${document.cookie}`.split(`; ${n}=`);
|
|
289
|
+
if (e.length === 2)
|
|
290
|
+
return e.pop().split(";").shift();
|
|
291
|
+
}
|
|
292
|
+
function d(n, t) {
|
|
293
|
+
const e = "6f3d90d5b02720f58de3663e3ef675fe", o = "https://api.mixpanel.com/track", i = {
|
|
294
|
+
event: n,
|
|
295
|
+
properties: {
|
|
296
|
+
token: e,
|
|
297
|
+
...t
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
fetch(o, {
|
|
301
|
+
method: "POST",
|
|
302
|
+
headers: {
|
|
303
|
+
"Content-Type": "application/json"
|
|
304
|
+
},
|
|
305
|
+
body: JSON.stringify(i)
|
|
306
|
+
}).then((s) => {
|
|
307
|
+
s.ok || console.error("Mixpanel tracking failed", s);
|
|
308
|
+
}).catch((s) => {
|
|
309
|
+
console.error("Mixpanel tracking error", s);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
function g() {
|
|
313
|
+
d("Chatbot Opened", { distinct_id: r("chatbotToken") });
|
|
282
314
|
}
|
|
283
315
|
function h() {
|
|
284
|
-
|
|
316
|
+
d("Chatbot Closed", { distinct_id: r("chatbotToken") });
|
|
317
|
+
}
|
|
318
|
+
function y(n) {
|
|
319
|
+
d("Message Sent", { distinct_id: r("chatbotToken"), message_content: n });
|
|
320
|
+
}
|
|
321
|
+
function w(n) {
|
|
322
|
+
d("Message Sent", { distinct_id: r("chatbotToken"), products: n });
|
|
323
|
+
}
|
|
324
|
+
function x(n) {
|
|
325
|
+
d("Product Clicked", { distinct_id: r("chatbotToken"), product_id: n });
|
|
285
326
|
}
|
|
286
327
|
function u() {
|
|
287
|
-
document.getElementById("chat-window").
|
|
328
|
+
const n = document.getElementById("chat-window"), t = document.getElementById("chat-icon");
|
|
329
|
+
n.classList.contains("visible") ? (h(), n.classList.remove("visible"), t.style.display = "flex") : (g(), n.classList.add("visible"), t.style.display = "none");
|
|
330
|
+
}
|
|
331
|
+
function v() {
|
|
332
|
+
h(), document.getElementById("chat-window").classList.remove("visible");
|
|
333
|
+
}
|
|
334
|
+
function k() {
|
|
335
|
+
g(), document.getElementById("chat-window").classList.add("visible");
|
|
288
336
|
}
|
|
289
337
|
document.addEventListener("DOMContentLoaded", () => {
|
|
290
338
|
setupCloseButton(), setupOutsideClick();
|
|
291
339
|
});
|
|
292
|
-
const
|
|
293
|
-
class
|
|
340
|
+
const C = ["climats", "telckel", "biobio", "weinpoint"], E = "OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";
|
|
341
|
+
class m {
|
|
294
342
|
constructor(t) {
|
|
295
343
|
var e;
|
|
296
|
-
this.baseURL = "https://api.wineater.com/", this.store =
|
|
344
|
+
this.baseURL = "https://api.wineater.com/", this.store = C.find((o) => window.location.href.includes(o)), this.token = ((e = window == null ? void 0 : window.wineaterData) == null ? void 0 : e.CLIENT_TOKEN) || E;
|
|
297
345
|
}
|
|
298
346
|
async getStoreConfig(t) {
|
|
299
347
|
console.log(t);
|
|
@@ -332,9 +380,9 @@ class p {
|
|
|
332
380
|
}
|
|
333
381
|
}
|
|
334
382
|
}
|
|
335
|
-
class
|
|
383
|
+
class I {
|
|
336
384
|
constructor() {
|
|
337
|
-
this.api = new
|
|
385
|
+
this.api = new m(), this.language = "en", this.translations = {
|
|
338
386
|
fr: {
|
|
339
387
|
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?",
|
|
340
388
|
noResultsFound: "Aucun résultat trouvé.",
|
|
@@ -383,10 +431,10 @@ class y {
|
|
|
383
431
|
return this.translations[this.language][t] || t;
|
|
384
432
|
}
|
|
385
433
|
}
|
|
386
|
-
const
|
|
387
|
-
class
|
|
434
|
+
const a = new I();
|
|
435
|
+
class T {
|
|
388
436
|
constructor() {
|
|
389
|
-
this.api = new
|
|
437
|
+
this.api = new m(), this.displayFirstMessage(a.translate("welcomeMessage"));
|
|
390
438
|
}
|
|
391
439
|
initialize() {
|
|
392
440
|
document.getElementById("send-button").addEventListener("click", () => this.handleUserInput()), document.getElementById("user-input").addEventListener("keypress", (o) => {
|
|
@@ -402,10 +450,11 @@ class b {
|
|
|
402
450
|
if (e) {
|
|
403
451
|
this.displayMessage(e, "user"), t.value = "", this.showTypingIndicator();
|
|
404
452
|
try {
|
|
453
|
+
y(e);
|
|
405
454
|
const o = await this.api.getWineRecommendations(e);
|
|
406
455
|
this.hideTypingIndicator(), o && o.length ? this.displayResults(o) : this.displayMessage("No results found.", "api");
|
|
407
456
|
} catch {
|
|
408
|
-
this.hideTypingIndicator(), this.displayMessage(
|
|
457
|
+
this.hideTypingIndicator(), this.displayMessage(a.translate("somethingWentWrong"), "api");
|
|
409
458
|
}
|
|
410
459
|
}
|
|
411
460
|
}
|
|
@@ -419,33 +468,36 @@ class b {
|
|
|
419
468
|
const o = document.getElementById("message-container"), i = document.createElement("div");
|
|
420
469
|
i.textContent = t, i.className = "message " + e, o.appendChild(i), o.scrollTop = o.scrollHeight;
|
|
421
470
|
}
|
|
471
|
+
sendAnalytics(t) {
|
|
472
|
+
x(t);
|
|
473
|
+
}
|
|
422
474
|
displayResults(t) {
|
|
423
475
|
const e = document.getElementById("message-container");
|
|
424
|
-
t.forEach((o) => {
|
|
476
|
+
w(t.map((o) => o.Title)), t.forEach((o) => {
|
|
425
477
|
const i = document.createElement("div");
|
|
426
478
|
i.className = "wine-item";
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
const
|
|
430
|
-
|
|
479
|
+
const s = document.createElement("img");
|
|
480
|
+
s.src = o.Image, i.appendChild(s);
|
|
481
|
+
const c = document.createElement("div");
|
|
482
|
+
c.innerHTML = `
|
|
431
483
|
<strong>${o.Title}</strong><br>
|
|
432
|
-
${
|
|
433
|
-
${
|
|
434
|
-
${
|
|
435
|
-
<a href="${o.Url}" target="_blank">${
|
|
436
|
-
`, i.appendChild(
|
|
484
|
+
${a.translate("price")}: ${o.Price}<br>
|
|
485
|
+
${a.translate("region")}: ${o.Region}<br>
|
|
486
|
+
${a.translate("type")}: ${o.Type}<br>
|
|
487
|
+
<a href="${o.Url}" onclick="sendAnalytics(${o.Title})" target="_blank">${a.translate("moreInfo")}</a>
|
|
488
|
+
`, i.appendChild(c), e.appendChild(i);
|
|
437
489
|
}), e.scrollTop = e.scrollHeight;
|
|
438
490
|
}
|
|
439
491
|
}
|
|
440
492
|
document.addEventListener("DOMContentLoaded", () => {
|
|
441
|
-
window.toggleChatWindow =
|
|
493
|
+
window.toggleChatWindow = u, window.closeChatWindow = v, window.openChatWindow = k;
|
|
442
494
|
});
|
|
443
|
-
function
|
|
495
|
+
function B() {
|
|
444
496
|
const n = `
|
|
445
497
|
<div id="chatbot-container">
|
|
446
498
|
<div id="chat-icon" onclick="toggleChatWindow()">
|
|
447
499
|
<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 -->
|
|
448
|
-
<span>${
|
|
500
|
+
<span>${a.translate("chatButton")}</span>
|
|
449
501
|
</div>
|
|
450
502
|
|
|
451
503
|
<div id="chat-window" class="hidden">
|
|
@@ -462,39 +514,40 @@ function w() {
|
|
|
462
514
|
<span></span><span></span><span></span>
|
|
463
515
|
</div>
|
|
464
516
|
<div id="input-container">
|
|
465
|
-
<input type="text" id="user-input" placeholder="${
|
|
466
|
-
<button id="send-button">${
|
|
517
|
+
<input type="text" id="user-input" placeholder="${a.translate("inputPlaceholder")}">
|
|
518
|
+
<button id="send-button">${a.translate("sendButton")}</button>
|
|
467
519
|
</div>
|
|
468
520
|
</div>
|
|
469
521
|
</div>
|
|
470
522
|
`;
|
|
471
523
|
document.body.insertAdjacentHTML("beforeend", n);
|
|
472
524
|
}
|
|
473
|
-
function
|
|
474
|
-
document.getElementById("close-btn").addEventListener("click",
|
|
525
|
+
function L() {
|
|
526
|
+
document.getElementById("close-btn").addEventListener("click", u);
|
|
475
527
|
}
|
|
476
|
-
function
|
|
528
|
+
function P() {
|
|
477
529
|
window.addEventListener("click", function(n) {
|
|
478
530
|
const t = document.getElementById("chat-window"), e = document.getElementById("chat-icon");
|
|
479
531
|
!t.contains(n.target) && !e.contains(n.target) && (t.classList.remove("visible"), e.style.display = "flex");
|
|
480
532
|
});
|
|
481
533
|
}
|
|
482
|
-
function
|
|
534
|
+
function W(n) {
|
|
483
535
|
console.log(n);
|
|
484
536
|
const t = document.getElementById("chat-icon"), e = document.getElementById("chat-window");
|
|
485
537
|
t.className = "", e.className = "", n === "right-center" ? (t.classList.add("chat-icon-right-center"), e.classList.add("right-center-aligned")) : t.classList.add("chat-icon-bottom-right");
|
|
486
538
|
}
|
|
487
|
-
var
|
|
539
|
+
var l;
|
|
488
540
|
if (typeof window < "u") {
|
|
489
|
-
const n = ((
|
|
541
|
+
const n = ((l = window.wineaterData) == null ? void 0 : l.POSITION) || "bottom-right";
|
|
490
542
|
window.addEventListener("DOMContentLoaded", async () => {
|
|
491
|
-
|
|
543
|
+
var s;
|
|
544
|
+
const e = ["climats", "telckel", "biobio", "weinpoint"].find((c) => window.location.href.includes(c)) || null;
|
|
492
545
|
let o;
|
|
493
|
-
e && (o = e.charAt(0).toUpperCase() + e.slice(1)), await
|
|
546
|
+
e && (o = e.charAt(0).toUpperCase() + e.slice(1)), await a.fetchConfig(o || null), B(), L(), P(), W(n), b("chatbotToken", (s = window.wineaterData) == null ? void 0 : s.CLIENT_TOKEN, 365), new T().initialize();
|
|
494
547
|
});
|
|
495
548
|
}
|
|
496
549
|
export {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
550
|
+
v as closeChatWindow,
|
|
551
|
+
k as openChatWindow,
|
|
552
|
+
u as toggleChatWindow
|
|
500
553
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(r,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(r=typeof globalThis<"u"?globalThis:r||self,d(r.WineaterChatbot={}))})(this,function(r){"use strict";var w;const d=`
|
|
2
2
|
@font-face {
|
|
3
3
|
font-family: 'Poppins';
|
|
4
4
|
src: url('https://fonts.googleapis.com/css2?family=Poppins:wght@400&display=swap');
|
|
@@ -273,13 +273,13 @@
|
|
|
273
273
|
.typing-indicator.visible {
|
|
274
274
|
visibility: visible;
|
|
275
275
|
height: 50px;
|
|
276
|
-
}`,
|
|
276
|
+
}`,g=document.createElement("style");g.textContent=d,document.head.appendChild(g);function x(n,t,e){let o="";if(e){const i=new Date;i.setTime(i.getTime()+e*24*60*60*1e3),o="; expires="+i.toUTCString()}document.cookie=n+"="+(t||"")+o+"; path=/; secure; samesite=strict"}function c(n){const e=`; ${document.cookie}`.split(`; ${n}=`);if(e.length===2)return e.pop().split(";").shift()}function l(n,t){const e="6f3d90d5b02720f58de3663e3ef675fe",o="https://api.mixpanel.com/track",i={event:n,properties:{token:e,...t}};fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}).then(a=>{a.ok||console.error("Mixpanel tracking failed",a)}).catch(a=>{console.error("Mixpanel tracking error",a)})}function u(){l("Chatbot Opened",{distinct_id:c("chatbotToken")})}function m(){l("Chatbot Closed",{distinct_id:c("chatbotToken")})}function v(n){l("Message Sent",{distinct_id:c("chatbotToken"),message_content:n})}function k(n){l("Message Sent",{distinct_id:c("chatbotToken"),products:n})}function C(n){l("Product Clicked",{distinct_id:c("chatbotToken"),product_id:n})}function h(){const n=document.getElementById("chat-window"),t=document.getElementById("chat-icon");n.classList.contains("visible")?(m(),n.classList.remove("visible"),t.style.display="flex"):(u(),n.classList.add("visible"),t.style.display="none")}function f(){m(),document.getElementById("chat-window").classList.remove("visible")}function b(){u(),document.getElementById("chat-window").classList.add("visible")}document.addEventListener("DOMContentLoaded",()=>{setupCloseButton(),setupOutsideClick()});const E=["climats","telckel","biobio","weinpoint"],I="OuhXJRleF6sROjsQZPWx1yqjrL6APeJxmHswqyOBWbgIqtXcht3MDadvI9DtOOoL";class y{constructor(t){var e;this.baseURL="https://api.wineater.com/",this.store=E.find(o=>window.location.href.includes(o)),this.token=((e=window==null?void 0:window.wineaterData)==null?void 0:e.CLIENT_TOKEN)||I}async getStoreConfig(t){console.log(t);try{const e=await fetch(`${this.baseURL}stores/store`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({store:t})});if(!e.ok)throw new Error(`HTTP error! Status: ${e.status}`);return await e.json()}catch(e){throw console.error("Error fetching store configuration:",e),e}}async getWineRecommendations(t){console.log(window.location.href);try{const e=await fetch(`${this.baseURL}dish/recommendations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({text:t,store:this.store?this.store.toString().charAt(0).toUpperCase()+this.store.slice(1):void 0})}),o=await e.json();if(!e.ok)throw new Error(`API call failed with status ${e.status}: ${o.message||"No additional error information"}`);return o}catch(e){throw console.error("Fetching wine recommendations failed:",e.message),new Error(`Error in getWineRecommendations: ${e.message}`)}}}class T{constructor(){this.api=new y,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",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:"Maridar vino con cena",inputPlaceholder:"ej., Ensalada de atún",sendButton:"Maridar",price:"Precio",region:"Región",type:"Tipo",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",moreInfo:"More info"}}}async fetchConfig(t){if(t){const e=await this.api.getStoreConfig(t);this.language=e.lang}}translate(t){return this.translations[this.language][t]||t}}const s=new T;class B{constructor(){this.api=new y,this.displayFirstMessage(s.translate("welcomeMessage"))}initialize(){document.getElementById("send-button").addEventListener("click",()=>this.handleUserInput()),document.getElementById("user-input").addEventListener("keypress",o=>{o.key==="Enter"&&this.handleUserInput()})}displayFirstMessage(t,e="api"){const o=document.getElementById("message-container"),i=document.createElement("div");i.className=`message ${e}`,i.textContent=t,o.appendChild(i),o.scrollTop=o.scrollHeight}async handleUserInput(){const t=document.getElementById("user-input"),e=t.value.trim();if(e){this.displayMessage(e,"user"),t.value="",this.showTypingIndicator();try{v(e);const o=await this.api.getWineRecommendations(e);this.hideTypingIndicator(),o&&o.length?this.displayResults(o):this.displayMessage("No results found.","api")}catch{this.hideTypingIndicator(),this.displayMessage(s.translate("somethingWentWrong"),"api")}}}showTypingIndicator(){document.getElementById("typing-indicator").classList.add("visible")}hideTypingIndicator(){document.getElementById("typing-indicator").classList.remove("visible")}displayMessage(t,e){const o=document.getElementById("message-container"),i=document.createElement("div");i.textContent=t,i.className="message "+e,o.appendChild(i),o.scrollTop=o.scrollHeight}sendAnalytics(t){C(t)}displayResults(t){const e=document.getElementById("message-container");k(t.map(o=>o.Title)),t.forEach(o=>{const i=document.createElement("div");i.className="wine-item";const a=document.createElement("img");a.src=o.Image,i.appendChild(a);const p=document.createElement("div");p.innerHTML=`
|
|
277
277
|
<strong>${o.Title}</strong><br>
|
|
278
278
|
${s.translate("price")}: ${o.Price}<br>
|
|
279
279
|
${s.translate("region")}: ${o.Region}<br>
|
|
280
280
|
${s.translate("type")}: ${o.Type}<br>
|
|
281
|
-
<a href="${o.Url}" target="_blank">${s.translate("moreInfo")}</a>
|
|
282
|
-
`,i.appendChild(
|
|
281
|
+
<a href="${o.Url}" onclick="sendAnalytics(${o.Title})" target="_blank">${s.translate("moreInfo")}</a>
|
|
282
|
+
`,i.appendChild(p),e.appendChild(i)}),e.scrollTop=e.scrollHeight}}document.addEventListener("DOMContentLoaded",()=>{window.toggleChatWindow=h,window.closeChatWindow=f,window.openChatWindow=b});function L(){const n=`
|
|
283
283
|
<div id="chatbot-container">
|
|
284
284
|
<div id="chat-icon" onclick="toggleChatWindow()">
|
|
285
285
|
<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 -->
|
|
@@ -305,4 +305,4 @@
|
|
|
305
305
|
</div>
|
|
306
306
|
</div>
|
|
307
307
|
</div>
|
|
308
|
-
`;document.body.insertAdjacentHTML("beforeend",n)}function
|
|
308
|
+
`;document.body.insertAdjacentHTML("beforeend",n)}function W(){document.getElementById("close-btn").addEventListener("click",h)}function P(){window.addEventListener("click",function(n){const t=document.getElementById("chat-window"),e=document.getElementById("chat-icon");!t.contains(n.target)&&!e.contains(n.target)&&(t.classList.remove("visible"),e.style.display="flex")})}function S(n){console.log(n);const t=document.getElementById("chat-icon"),e=document.getElementById("chat-window");t.className="",e.className="",n==="right-center"?(t.classList.add("chat-icon-right-center"),e.classList.add("right-center-aligned")):t.classList.add("chat-icon-bottom-right")}if(typeof window<"u"){const n=((w=window.wineaterData)==null?void 0:w.POSITION)||"bottom-right";window.addEventListener("DOMContentLoaded",async()=>{var a;const e=["climats","telckel","biobio","weinpoint"].find(p=>window.location.href.includes(p))||null;let o;e&&(o=e.charAt(0).toUpperCase()+e.slice(1)),await s.fetchConfig(o||null),L(),W(),P(),S(n),x("chatbotToken",(a=window.wineaterData)==null?void 0:a.CLIENT_TOKEN,365),new B().initialize()})}r.closeChatWindow=f,r.openChatWindow=b,r.toggleChatWindow=h,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// Import your CSS here
|
|
4
4
|
import './js/styles.js';
|
|
5
|
+
import { setCookie } from './js/analytics.js';
|
|
5
6
|
|
|
6
7
|
// Import your JavaScript modules here
|
|
7
8
|
import { toggleChatWindow, closeChatWindow, openChatWindow } from './js/ui.js';
|
|
@@ -104,6 +105,7 @@ if (typeof window !== 'undefined') {
|
|
|
104
105
|
setupCloseButton();
|
|
105
106
|
setupOutsideClick();
|
|
106
107
|
toggleChatIconPosition(position);
|
|
108
|
+
setCookie('chatbotToken', window.wineaterData?.CLIENT_TOKEN, 365);
|
|
107
109
|
const myChatbot = new Chatbot();
|
|
108
110
|
myChatbot.initialize();
|
|
109
111
|
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// analytics.js
|
|
2
|
+
|
|
3
|
+
function setCookie(name, value, days) {
|
|
4
|
+
let expires = "";
|
|
5
|
+
if (days) {
|
|
6
|
+
const date = new Date();
|
|
7
|
+
date.setTime(date.getTime() + (days*24*60*60*1000));
|
|
8
|
+
expires = "; expires=" + date.toUTCString();
|
|
9
|
+
}
|
|
10
|
+
document.cookie = name + "=" + (value || "") + expires + "; path=/; secure; samesite=strict";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getCookie(name) {
|
|
14
|
+
const value = `; ${document.cookie}`;
|
|
15
|
+
const parts = value.split(`; ${name}=`);
|
|
16
|
+
if (parts.length === 2) return parts.pop().split(';').shift();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Функция для отправки событий в Mixpanel
|
|
20
|
+
function trackEvent(event, properties) {
|
|
21
|
+
const token = '6f3d90d5b02720f58de3663e3ef675fe'; // Замените на ваш Mixpanel токен
|
|
22
|
+
const endpoint = 'https://api.mixpanel.com/track';
|
|
23
|
+
const data = {
|
|
24
|
+
event: event,
|
|
25
|
+
properties: {
|
|
26
|
+
token: token,
|
|
27
|
+
...properties
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
fetch(endpoint, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json'
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify(data)
|
|
37
|
+
}).then(response => {
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
console.error('Mixpanel tracking failed', response);
|
|
40
|
+
}
|
|
41
|
+
}).catch(error => {
|
|
42
|
+
console.error('Mixpanel tracking error', error);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function trackChatbotOpen() {
|
|
47
|
+
trackEvent('Chatbot Opened', { distinct_id: getCookie('chatbotToken') });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function trackChatbotClose() {
|
|
51
|
+
trackEvent('Chatbot Closed', { distinct_id: getCookie('chatbotToken') });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function trackMessageSent(message) {
|
|
55
|
+
trackEvent('Message Sent', { distinct_id: getCookie('chatbotToken'), message_content: message });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function trackRecommendationsGet(products) {
|
|
59
|
+
trackEvent('Message Sent', { distinct_id: getCookie('chatbotToken'), products: products });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function trackProductClick(productId) {
|
|
63
|
+
trackEvent('Product Clicked', { distinct_id: getCookie('chatbotToken'), product_id: productId });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { setCookie, getCookie, trackChatbotOpen, trackMessageSent, trackProductClick, trackChatbotClose, trackRecommendationsGet };
|
|
67
|
+
|
package/src/js/chatbot.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// chatbot.js
|
|
2
2
|
import { Api } from './api.js';
|
|
3
3
|
import translator from './i18n.js';
|
|
4
|
+
import { trackMessageSent, trackProductClick, trackRecommendationsGet } from './analytics.js';
|
|
4
5
|
|
|
5
6
|
export class Chatbot {
|
|
6
7
|
constructor() {
|
|
@@ -43,8 +44,9 @@ export class Chatbot {
|
|
|
43
44
|
this.showTypingIndicator();
|
|
44
45
|
|
|
45
46
|
try {
|
|
47
|
+
trackMessageSent(userInput);
|
|
46
48
|
const results = await this.api.getWineRecommendations(userInput);
|
|
47
|
-
|
|
49
|
+
|
|
48
50
|
// Hide the loader
|
|
49
51
|
this.hideTypingIndicator();
|
|
50
52
|
|
|
@@ -80,8 +82,13 @@ export class Chatbot {
|
|
|
80
82
|
messageContainer.scrollTop = messageContainer.scrollHeight;
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
sendAnalytics(product) {
|
|
86
|
+
trackProductClick(product);
|
|
87
|
+
}
|
|
88
|
+
|
|
83
89
|
displayResults(wines) {
|
|
84
90
|
const messageContainer = document.getElementById('message-container');
|
|
91
|
+
trackRecommendationsGet(wines.map(value => value.Title));
|
|
85
92
|
wines.forEach(wine => {
|
|
86
93
|
const wineDiv = document.createElement('div');
|
|
87
94
|
wineDiv.className = 'wine-item';
|
|
@@ -96,7 +103,7 @@ export class Chatbot {
|
|
|
96
103
|
${translator.translate('price')}: ${wine.Price}<br>
|
|
97
104
|
${translator.translate('region')}: ${wine.Region}<br>
|
|
98
105
|
${translator.translate('type')}: ${wine.Type}<br>
|
|
99
|
-
<a href="${wine.Url}" target="_blank">${translator.translate('moreInfo')}</a>
|
|
106
|
+
<a href="${wine.Url}" onclick="sendAnalytics(${wine.Title})" target="_blank">${translator.translate('moreInfo')}</a>
|
|
100
107
|
`;
|
|
101
108
|
wineDiv.appendChild(contentDiv);
|
|
102
109
|
|
package/src/js/ui.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
|
|
2
|
+
import { trackChatbotOpen, trackChatbotClose } from './analytics.js';
|
|
3
|
+
|
|
1
4
|
export function toggleChatWindow() {
|
|
2
5
|
const chatWindow = document.getElementById('chat-window');
|
|
3
6
|
const chatIcon = document.getElementById('chat-icon');
|
|
@@ -6,20 +9,24 @@ export function toggleChatWindow() {
|
|
|
6
9
|
const isWindowOpen = chatWindow.classList.contains('visible');
|
|
7
10
|
|
|
8
11
|
if (isWindowOpen) {
|
|
12
|
+
trackChatbotClose();
|
|
9
13
|
chatWindow.classList.remove('visible');
|
|
10
14
|
chatIcon.style.display = 'flex'; // Show the chat icon/button
|
|
11
15
|
} else {
|
|
16
|
+
trackChatbotOpen();
|
|
12
17
|
chatWindow.classList.add('visible');
|
|
13
18
|
chatIcon.style.display = 'none'; // Hide the chat icon/button
|
|
14
19
|
}
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
export function closeChatWindow() {
|
|
23
|
+
trackChatbotClose();
|
|
18
24
|
const chatWindow = document.getElementById('chat-window');
|
|
19
25
|
chatWindow.classList.remove('visible');
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
export function openChatWindow() {
|
|
29
|
+
trackChatbotOpen();
|
|
23
30
|
const chatWindow = document.getElementById('chat-window');
|
|
24
31
|
chatWindow.classList.add('visible');
|
|
25
32
|
}
|