wineater-bot 3.2.1 → 3.4.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 +2265 -3036
- package/dist/wineater-chatbot.umd.js +252 -773
- package/index.html +1 -1
- package/package.json +1 -1
- package/src/index.js +1 -95
- package/src/js/i18n.js +29 -0
- package/src/js/widget-styles.js +183 -2
- package/src/js/widget.js +130 -271
- package/src/css/styles.css +0 -239
- package/src/js/auto-open.js +0 -64
- package/src/js/barConfig.js +0 -54
- package/src/js/chatbot.js +0 -140
- package/src/js/styles.js +0 -651
- package/src/js/ui.js +0 -107
package/src/js/auto-open.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { Api } from './api.js';
|
|
2
|
-
import { openChatWindowWithDishes, setAutoOpenTimer } from './ui.js'; // Import updated UI logic for opening chat with dishes
|
|
3
|
-
|
|
4
|
-
const api = new Api();
|
|
5
|
-
|
|
6
|
-
const DEFAULT_URL_PATTERNS = {
|
|
7
|
-
PRODUCT_PAGES: /producto\/[^\/]+\/$/, // Matches any product page like 'producto/any-product-name/'
|
|
8
|
-
// CART_PAGE: /carrito\/$/ // Matches the cart page like 'carrito/'
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const DEFAULT_URL_ANTI_PATTERNS = {
|
|
12
|
-
FESTIVAL_PAGES: /festival/, // Matches any URL containing 'festival'
|
|
13
|
-
TASTING_PAGES: /tasting/ // Matches any URL containing 'tasting'
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const urlAntiPatterns = {
|
|
17
|
-
FESTIVAL_PAGES: window.wineaterData?.FESTIVAL_PAGES || DEFAULT_URL_ANTI_PATTERNS.FESTIVAL_PAGES,
|
|
18
|
-
TASTING_PAGES: window.wineaterData?.TASTING_PAGES || DEFAULT_URL_ANTI_PATTERNS.TASTING_PAGES
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
// Retrieve custom or default URL patterns from wineaterData
|
|
22
|
-
const urlPatterns = {
|
|
23
|
-
PRODUCT_PAGES: window.wineaterData?.PRODUCT_PAGES || DEFAULT_URL_PATTERNS.PRODUCT_PAGES,
|
|
24
|
-
CART_PAGE: window.wineaterData?.CART_PAGE || DEFAULT_URL_PATTERNS?.CART_PAGE
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export async function shouldOpenChatAutomatically() {
|
|
28
|
-
const currentURL = window.location.href;
|
|
29
|
-
// Check if the current URL matches any of the anti-patterns
|
|
30
|
-
for (const [key, regex] of Object.entries(urlAntiPatterns)) {
|
|
31
|
-
if (regex.test(currentURL)) {
|
|
32
|
-
return false; // Do not open chat if URL matches an anti-pattern
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Check if the current URL matches any of the patterns
|
|
37
|
-
for (const [key, regex] of Object.entries(urlPatterns)) {
|
|
38
|
-
if (regex.test(currentURL)) {
|
|
39
|
-
try {
|
|
40
|
-
// Get meta title and description from the document
|
|
41
|
-
// const metaTitle = document.querySelector('meta[name="title"]')?.getAttribute('content') || document.title;
|
|
42
|
-
// const metaDescription = document.querySelector('meta[name="description"]')?.getAttribute('content') || '';
|
|
43
|
-
|
|
44
|
-
// Fetch dishes based on meta data
|
|
45
|
-
// const dishes = await api.getPossibleDishesWithMeta(metaTitle, metaDescription);
|
|
46
|
-
|
|
47
|
-
console.log(dishes);
|
|
48
|
-
|
|
49
|
-
const timer = setTimeout(() => {
|
|
50
|
-
openChatWindow(); // Открыть чат с блюдами через 15 секунд
|
|
51
|
-
}, 15000); // 15000 миллисекунд = 15 секунд
|
|
52
|
-
|
|
53
|
-
// Сохраняем таймер, чтобы можно было его сбросить при ручном открытии чата
|
|
54
|
-
setAutoOpenTimer(timer);
|
|
55
|
-
return true; // Chat opens with dish recommendations
|
|
56
|
-
} catch (error) {
|
|
57
|
-
console.error('Error fetching dishes:', error);
|
|
58
|
-
return false; // Do not open chat if fetching dishes fails
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return false; // Default to not opening chat if no patterns match
|
|
64
|
-
}
|
package/src/js/barConfig.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// barConfig.js
|
|
2
|
-
|
|
3
|
-
export const barConfig = {
|
|
4
|
-
barName: "LENEZ",
|
|
5
|
-
dishGroups: [
|
|
6
|
-
{
|
|
7
|
-
groupTitle: "Entradas",
|
|
8
|
-
dishes: [
|
|
9
|
-
"Pimientos rojo asado y aceite de oliva con ajo confitado",
|
|
10
|
-
"Ensalada de arúgula y parmesano",
|
|
11
|
-
"Tomate hierloom aliñado",
|
|
12
|
-
"Aceitunas LENEZ",
|
|
13
|
-
"Papatinaz",
|
|
14
|
-
"Croquetas | hongos de temporada | jamón serrano",
|
|
15
|
-
"Carpaccio Cesar",
|
|
16
|
-
"Torreznos",
|
|
17
|
-
"Calamares fritos"
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
groupTitle: "Bocadillos",
|
|
22
|
-
dishes: [
|
|
23
|
-
"Brioche de pollo frito, col y salsa macha",
|
|
24
|
-
"Baguette de calamares rebozados en salsa brava",
|
|
25
|
-
"Hogaza de cola de res en recado negro y cebollas encurtidas"
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
groupTitle: "Embutidos",
|
|
30
|
-
dishes: [
|
|
31
|
-
"Jamón Ibérico de bellota",
|
|
32
|
-
"Lomo ibérico",
|
|
33
|
-
"Chorizo ibérico",
|
|
34
|
-
"Plato mixto iberico"
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
groupTitle: "Quesos",
|
|
39
|
-
dishes: [
|
|
40
|
-
"Selección de quesos (D’Affinois, Brie Ermitage, Manchego semi curado, Roquefort)"
|
|
41
|
-
]
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
groupTitle: "Postres",
|
|
45
|
-
dishes: [
|
|
46
|
-
"Ate con queso manchego semi curado",
|
|
47
|
-
"Gelato de nata con balsámico",
|
|
48
|
-
"Gelato de ron con pasas y “El candado”, Valdespino PX",
|
|
49
|
-
"Gelato Dua Lipa",
|
|
50
|
-
"Créme Brûlée al Orange"
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
};
|
package/src/js/chatbot.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
// chatbot.js
|
|
2
|
-
import { Api } from './api.js';
|
|
3
|
-
import translator from './i18n.js';
|
|
4
|
-
import { trackMessageSent, trackProductClick, trackRecommendationsGet } from './analytics.js';
|
|
5
|
-
|
|
6
|
-
export class Chatbot {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.api = new Api(); // Instantiate the Api class
|
|
9
|
-
const firstMessageText = window?.wineaterData?.FIRST_MESSAGE_TEXT || translator.translate('welcomeMessage');
|
|
10
|
-
this.displayFirstMessage(firstMessageText);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
initialize() {
|
|
14
|
-
// Attach event listeners
|
|
15
|
-
const sendButton = document.getElementById('send-button');
|
|
16
|
-
sendButton.addEventListener('click', () => this.handleUserInput());
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const userInputField = document.getElementById('user-input');
|
|
20
|
-
userInputField.addEventListener('keypress', (event) => {
|
|
21
|
-
if (event.key === 'Enter') {
|
|
22
|
-
this.handleUserInput();
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
displayFirstMessage(message, sender = 'api') {
|
|
28
|
-
const messageContainer = document.getElementById('message-container');
|
|
29
|
-
const messageDiv = document.createElement('div');
|
|
30
|
-
messageDiv.className = `message ${sender}`;
|
|
31
|
-
messageDiv.textContent = message;
|
|
32
|
-
messageContainer.appendChild(messageDiv);
|
|
33
|
-
messageContainer.scrollTop = messageContainer.scrollHeight; // Scroll to the latest message
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async handleUserInput() {
|
|
37
|
-
const inputField = document.getElementById('user-input');
|
|
38
|
-
const userInput = inputField.value.trim();
|
|
39
|
-
if (!userInput) return;
|
|
40
|
-
|
|
41
|
-
this.displayMessage(userInput, 'user');
|
|
42
|
-
inputField.value = '';
|
|
43
|
-
|
|
44
|
-
// Show the loader
|
|
45
|
-
this.showTypingIndicator();
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
trackMessageSent(userInput);
|
|
49
|
-
const results = await this.api.getWineRecommendations(userInput);
|
|
50
|
-
|
|
51
|
-
// Hide the loader
|
|
52
|
-
this.hideTypingIndicator();
|
|
53
|
-
|
|
54
|
-
if (results && results.length) {
|
|
55
|
-
this.displayResults(results);
|
|
56
|
-
} else {
|
|
57
|
-
this.displayMessage('No results found.', 'api');
|
|
58
|
-
}
|
|
59
|
-
} catch (error) {
|
|
60
|
-
// Hide the loader
|
|
61
|
-
this.hideTypingIndicator();
|
|
62
|
-
|
|
63
|
-
this.displayMessage(translator.translate('somethingWentWrong'), 'api');
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
showTypingIndicator() {
|
|
68
|
-
const typingIndicator = document.getElementById('typing-indicator');
|
|
69
|
-
typingIndicator.classList.add('visible');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
hideTypingIndicator() {
|
|
73
|
-
const typingIndicator = document.getElementById('typing-indicator');
|
|
74
|
-
typingIndicator.classList.remove('visible');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
displayMessage(message, type) {
|
|
78
|
-
const messageContainer = document.getElementById('message-container');
|
|
79
|
-
const messageDiv = document.createElement('div');
|
|
80
|
-
messageDiv.textContent = message;
|
|
81
|
-
messageDiv.className = 'message ' + type;
|
|
82
|
-
messageContainer.appendChild(messageDiv);
|
|
83
|
-
messageContainer.scrollTop = messageContainer.scrollHeight;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
sendAnalytics(product) {
|
|
87
|
-
console.log(product);
|
|
88
|
-
trackProductClick(product);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
displayResults(wines) {
|
|
92
|
-
console.log(wines);
|
|
93
|
-
const messageContainer = document.getElementById('message-container');
|
|
94
|
-
trackRecommendationsGet(wines.map(value => value.Title));
|
|
95
|
-
wines.forEach(wine => {
|
|
96
|
-
|
|
97
|
-
const recDiv = document.createElement('div');
|
|
98
|
-
recDiv.className = 'wine-recommendation';
|
|
99
|
-
|
|
100
|
-
const wineDiv = document.createElement('div');
|
|
101
|
-
wineDiv.className = 'wine-item';
|
|
102
|
-
recDiv.appendChild(wineDiv);
|
|
103
|
-
|
|
104
|
-
const image = document.createElement('img');
|
|
105
|
-
image.src = wine.Image;
|
|
106
|
-
wineDiv.appendChild(image);
|
|
107
|
-
|
|
108
|
-
console.log(wineDiv, 'wine div');
|
|
109
|
-
|
|
110
|
-
const contentDiv = document.createElement('div');
|
|
111
|
-
contentDiv.innerHTML = `
|
|
112
|
-
<strong>${wine.Title}</strong><br>
|
|
113
|
-
${translator.translate('price')}: ${wine.Price}<br>
|
|
114
|
-
${translator.translate('region')}: ${wine.Region}<br>
|
|
115
|
-
${translator.translate('type')}: ${wine.Type}<br>
|
|
116
|
-
<a href="${wine.Url}" target="_blank">${translator.translate('moreInfo')}</a>
|
|
117
|
-
`;
|
|
118
|
-
|
|
119
|
-
// Add click event listener to the link
|
|
120
|
-
const link = contentDiv.querySelector('a');
|
|
121
|
-
link.addEventListener('click', (event) => {
|
|
122
|
-
event.preventDefault(); // Prevent the default link behavior
|
|
123
|
-
this.sendAnalytics(wine.Title); // Call sendAnalytics when clicked
|
|
124
|
-
window.open(wine.Url, '_blank'); // Open the link in a new tab
|
|
125
|
-
});
|
|
126
|
-
wineDiv.appendChild(contentDiv);
|
|
127
|
-
|
|
128
|
-
const reasonDiv = document.createElement('div');
|
|
129
|
-
reasonDiv.className = 'wine-description';
|
|
130
|
-
reasonDiv.innerHTML = wine.Reason;
|
|
131
|
-
recDiv.appendChild(reasonDiv);
|
|
132
|
-
// const suggestionDiv = document.createElement('div');
|
|
133
|
-
// suggestionDiv.innerHTML = `${translator.translate('reason')}: ${wine.Reason}<br>`;
|
|
134
|
-
// wineDiv.appendChild(suggestionDiv);
|
|
135
|
-
console.log(recDiv);
|
|
136
|
-
messageContainer.appendChild(recDiv);
|
|
137
|
-
});
|
|
138
|
-
messageContainer.scrollTop = messageContainer.scrollHeight;
|
|
139
|
-
}
|
|
140
|
-
}
|