html: < /p> < /> < /p> < /p> < /p>
html: < /p>
Код: Выделить всё
// Emoji collection
const emojis = [
'😊', '😂', '🤣', '😍', '🥰', '😘', '😉', '😎',
'🤔', '😐', '😑', '🙄', '😴', '😵', '🤯', '😱',
'😭', '😢', '😤', '😡', '🤬', '😈', '👿', '💀',
'👍', '👎', '👌', '✌️', '🤞', '🤟', '🤘', '👏',
'🙌', '👐', '🤲', '🙏', '✍️', '💪', '🦾', '🦵',
'🧠', '🫀', '🫁', '🦷', '🦴', '👀', '👁️', '👅',
'❤️', '🧡', '💛', '💚', '💙', '💜', '🤍', '🖤',
'💔', '❣️', '💕', '💞', '💓', '💗', '💖', '💘',
'⚡', '🔥', '💥', '✨', '💫', '⭐', '🌟', '🎉'
];
// Global variables
const webhookUrl = 'https://hook.eu2.make.com/xxxxxxxx';
let lastUserMessage = '';
let threadId = localStorage.getItem('threadId') || null;
// DOM elements
const chatContainer = document.getElementById('chatContainer');
const chatMessages = document.getElementById('chatMessages');
const chatInput = document.getElementById('chatInput');
const sendButton = document.getElementById('sendButton');
const emojiButton = document.getElementById('emojiButton');
const emojiPicker = document.getElementById('emojiPicker');
const emojiGrid = document.getElementById('emojiGrid');
// UUID validation function
function isValidUUID(str) {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
return uuidRegex.test(str);
}
// Get greeting based on time
function getTimeBasedGreeting() {
const hour = new Date().getHours();
if (hour >= 5 && hour < 12) {
return 'בוקר טוב! במה אוכל לעזור לך היום?';
} else if (hour >= 12 && hour < 17) {
return 'צהריים טובים! במה אוכל לעזור לך היום?';
} else if (hour >= 17 && hour < 19) {
return 'אחר צהריים טובים! במה אוכל לעזור לך היום?';
} else if (hour >= 19 && hour < 21) {
return 'ערב טוב! במה אוכל לעזור לך?';
} else {
return 'לילה טוב! במה אוכל לעזור לך היום?';
}
}
// Initialize chat
function initChat() {
setTimeout(() => {
addMessage(getTimeBasedGreeting(), false);
}, 500);
initEmojiPicker();
// Focus on input when chat loads
setTimeout(() => chatInput.focus(), 300);
}
// Initialize emoji picker
function initEmojiPicker() {
emojiGrid.innerHTML = '';
emojis.forEach(emoji => {
const emojiItem = document.createElement('div');
emojiItem.className = 'emoji-item';
emojiItem.textContent = emoji;
emojiItem.onclick = () => {
chatInput.value += emoji;
chatInput.focus();
emojiPicker.classList.remove('show');
};
emojiGrid.appendChild(emojiItem);
});
}
// Convert URLs, emails, and phone numbers to clickable links
function linkifyText(text) {
// URL pattern - matches http/https URLs
const urlPattern = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g;
// Email pattern
const emailPattern = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g;
// Phone pattern (Israeli format and international)
const phonePattern = /(\+972|0)[-\s]?[1-9][-\s]?[0-9]{3}[-\s]?[0-9]{4}|\b\d{2,3}[-\s]?\d{7,8}\b/g;
// Replace URLs
text = text.replace(urlPattern, (url) => {
return `[url=${url}]${url}[/url]`;
});
// Replace emails
text = text.replace(emailPattern, (email) => {
return `[url=mailto:${email}]${email}[/url]`;
});
// Replace phone numbers
text = text.replace(phonePattern, (phone) => {
const cleanPhone = phone.replace(/[-\s]/g, '');
return `[url=tel:${cleanPhone}]${phone}[/url]`;
});
return text;
}
// Add message to chat
function addMessage(message, isUser = false) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${isUser ? 'user' : 'ai'}`;
const avatar = document.createElement('div');
avatar.className = 'message-avatar';
avatar.textContent = isUser ? '👤' : '🤖';
const bubble = document.createElement('div');
bubble.className = 'message-bubble';
// Apply linkification to the message
const linkedMessage = linkifyText(message);
bubble.innerHTML = linkedMessage;
messageDiv.appendChild(avatar);
messageDiv.appendChild(bubble);
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// Show typing indicator
function showTypingIndicator() {
const typingDiv = document.createElement('div');
typingDiv.className = 'message ai';
typingDiv.id = 'typingIndicator';
const avatar = document.createElement('div');
avatar.className = 'message-avatar';
avatar.textContent = '🤖';
const typingBubble = document.createElement('div');
typingBubble.className = 'typing-indicator show';
typingBubble.innerHTML = `
`;
typingDiv.appendChild(avatar);
typingDiv.appendChild(typingBubble);
chatMessages.appendChild(typingDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// Hide typing indicator
function hideTypingIndicator() {
const typingIndicator = document.getElementById('typingIndicator');
if (typingIndicator) {
typingIndicator.remove();
}
}
// Parse server response - handles both JSON and text formats
function parseServerResponse(responseText) {
console.log('📄 Raw response:', responseText);
// First, try to parse as JSON
try {
const jsonData = JSON.parse(responseText);
console.log('✅ Parsed as JSON:', jsonData);
// Extract threadId if present
if (jsonData.threadId) {
threadId = jsonData.threadId;
localStorage.setItem('threadId', threadId);
console.log('💾 Saved threadId from JSON:', threadId);
}
// Return the message
return jsonData.reply || jsonData.message || jsonData.response || jsonData.answer || jsonData.text || 'תגובה לא מובנת';
} catch (jsonError) {
console.log('📝 Not JSON, parsing as text with UUID');
// Look for UUID pattern at the end of the response
const words = responseText.trim().split(/\s+/);
const lastWord = words[words.length - 1];
if (isValidUUID(lastWord)) {
// Found UUID at the end
threadId = lastWord;
localStorage.setItem('threadId', threadId);
console.log('💾 Saved threadId from text:', threadId);
// Return message without the UUID
const messageWithoutUUID = words.slice(0, -1).join(' ');
return messageWithoutUUID || 'תגובה ריקה';
} else {
// No UUID found, return the entire response
return responseText;
}
}
}
// Send message to webhook
async function sendMessage(message, context = '') {
try {
console.log('🚀 Sending message:', { message, context, threadId });
const payload = {
message: message,
context: context,
threadId: threadId,
timestamp: new Date().toISOString(),
source: 'interkum_chat'
};
console.log('📦 Payload:', JSON.stringify(payload, null, 2));
const response = await fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(payload)
});
console.log('📡 Response status:', response.status);
console.log('📡 Response ok:', response.ok);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// Get response as text
const responseText = await response.text();
// Parse the response using our new function
const parsedMessage = parseServerResponse(responseText);
console.log('✅ Final message:', parsedMessage);
return parsedMessage;
} catch (error) {
console.error('❌ Error sending message:', error);
if (error.name === 'TypeError' && error.message.includes('fetch')) {
return 'שגיאת רשת: לא ניתן להתחבר לשרת. בדוק את החיבור לאינטרנט.';
}
return `שגיאה: ${error.message}`;
}
}
// Handle sending message
async function handleSendMessage() {
const message = chatInput.value.trim();
if (!message) return;
sendButton.disabled = true;
addMessage(message, true);
chatInput.value = '';
showTypingIndicator();
try {
const response = await sendMessage(message, lastUserMessage);
hideTypingIndicator();
addMessage(response, false);
lastUserMessage = message;
} catch (error) {
hideTypingIndicator();
addMessage('שגיאה בקבלת תשובה. אנא נסה שוב.', false);
console.error('Error in handleSendMessage:', error);
}
sendButton.disabled = false;
}
// Auto-resize textarea
function autoResize() {
chatInput.style.height = 'auto';
chatInput.style.height = Math.min(chatInput.scrollHeight, 120) + 'px';
}
function addMessage(message, isUser = false) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${isUser ? 'user' : 'ai'}`;
const avatar = document.createElement('div');
avatar.className = 'message-avatar';
avatar.textContent = isUser ? '👤' : '🤖';
const bubble = document.createElement('div');
bubble.className = 'message-bubble';
// Apply linkification to the message
const linkedMessage = linkifyText(message);
bubble.innerHTML = linkedMessage;
messageDiv.appendChild(avatar);
messageDiv.appendChild(bubble);
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
// שמירת ההודעה במאגר של Wix
if (typeof saveChatMessage === 'function' && threadId) {
saveChatMessage(threadId, message, isUser);
}
}
// עדכון הפונקציה handleSendMessage לכלול שמירה:
async function handleSendMessage() {
const message = chatInput.value.trim();
if (!message) return;
sendButton.disabled = true;
addMessage(message, true);
chatInput.value = '';
showTypingIndicator();
try {
const response = await sendMessage(message, lastUserMessage);
hideTypingIndicator();
addMessage(response, false);
lastUserMessage = message;
} catch (error) {
hideTypingIndicator();
addMessage('שגיאה בקבלת תשובה. אנא נסה שוב.', false);
console.error('Error in handleSendMessage:', error);
}
sendButton.disabled = false;
}
// פונקציה לטעינת היסטוריה בתחילת הצ'אט
function addMessage(message, isUser = false) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${isUser ? 'user' : 'ai'}`;
const avatar = document.createElement('div');
avatar.className = 'message-avatar';
avatar.textContent = isUser ? '👤' : '🤖';
const bubble = document.createElement('div');
bubble.className = 'message-bubble';
bubble.innerHTML = linkifyText(message);
messageDiv.appendChild(avatar);
messageDiv.appendChild(bubble);
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
// שליחת ההודעה ל-Wix
window.parent.postMessage({
type: 'SAVE_MESSAGE',
data: {
threadId: threadId,
message: {
text: message,
isUser: isUser,
createdAt: new Date().toISOString()
}
}
}, 'https://8eliav.wixstudio.com/my-site-5');
}
// Event listeners
sendButton.addEventListener('click', handleSendMessage);
chatInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSendMessage();
}
});
chatInput.addEventListener('input', autoResize);
emojiButton.addEventListener('click', (e) => {
e.stopPropagation();
emojiPicker.classList.toggle('show');
});
document.addEventListener('click', (e) => {
if (!emojiPicker.contains(e.target) && !emojiButton.contains(e.target)) {
emojiPicker.classList.remove('show');
}
});
// Initialize chat
initChat();
< /code>
code velo wix: < /p>
$w.onReady(() => {
$w("#myWidget").onMessage((event) => {
const { type, data } = event;
if(type === "AREAS_SELECTED") {
console.log("קיבלנו אזורים מהווידג'ט:", data);
// כאן תטפל בנתונים שקיבלת
}
});
});Подробнее здесь: https://stackoverflow.com/questions/797 ... ix-page-to