- Introduce Rooms in chat-sessions, as different clients received the same messages.

This commit is contained in:
Josako
2024-08-19 07:22:06 +02:00
parent 688f2300b9
commit 733f115e92
9 changed files with 175 additions and 42 deletions

View File

@@ -1,6 +1,6 @@
class EveAIChatWidget extends HTMLElement {
static get observedAttributes() {
return ['tenant-id', 'api-key', 'domain', 'language'];
return ['tenant-id', 'api-key', 'domain', 'language', 'languages'];
}
constructor() {
@@ -12,6 +12,8 @@ class EveAIChatWidget extends HTMLElement {
this.heartbeatInterval = null;
this.idleTime = 0; // in milliseconds
this.maxConnectionIdleTime = 1 * 60 * 60 * 1000; // 1 hours in milliseconds
this.languages = []
this.room = null;
console.log('EveAIChatWidget constructor called');
}
@@ -19,15 +21,17 @@ class EveAIChatWidget extends HTMLElement {
console.log('connectedCallback called');
this.innerHTML = this.getTemplate();
this.messagesArea = this.querySelector('.messages-area');
this.questionInput = this.querySelector('.question-area input');
this.questionInput = this.querySelector('.question-area textarea');
this.sendButton = this.querySelector('.send-icon');
this.languageSelect = this.querySelector('.language-select');
this.statusLine = this.querySelector('.status-line');
this.statusMessage = this.querySelector('.status-message');
this.connectionStatusIcon = this.querySelector('.connection-status-icon');
this.sendButton.addEventListener('click', () => this.handleSendMessage());
this.questionInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault(); // Prevent adding a new line
this.handleSendMessage();
}
});
@@ -38,6 +42,30 @@ class EveAIChatWidget extends HTMLElement {
}
}
populateLanguageDropdown() {
// Clear existing options
this.languageSelect.innerHTML = '';
console.log(`languages for options: ${this.languages}`)
// Populate with new options
this.languages.forEach(lang => {
const option = document.createElement('option');
option.value = lang;
option.textContent = lang.toUpperCase();
if (lang === this.currentLanguage) {
option.selected = true;
}
console.log(`Adding option for language: ${lang}`)
this.languageSelect.appendChild(option);
});
// Add event listener for language change
this.languageSelect.addEventListener('change', (e) => {
this.currentLanguage = e.target.value;
// You might want to emit an event or update the backend about the language change
});
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`attributeChangedCallback called: ${name} changed from ${oldValue} to ${newValue}`);
this.updateAttributes();
@@ -45,6 +73,9 @@ class EveAIChatWidget extends HTMLElement {
if (this.areAllAttributesSet() && !this.socket) {
console.log('All attributes set in attributeChangedCallback, initializing socket');
this.attributesSet = true;
console.log('All attributes are set, populating language dropdown');
this.populateLanguageDropdown();
console.log('All attributes are set, initializing socket')
this.initializeSocket();
}
}
@@ -54,11 +85,16 @@ class EveAIChatWidget extends HTMLElement {
this.apiKey = this.getAttribute('api-key');
this.domain = this.getAttribute('domain');
this.language = this.getAttribute('language');
const languageAttr = this.getAttribute('languages');
this.languages = languageAttr ? languageAttr.split(',') : [];
this.currentLanguage = this.language;
console.log('Updated attributes:', {
tenantId: this.tenantId,
apiKey: this.apiKey,
domain: this.domain,
language: this.language
language: this.language,
currentLanguage: this.currentLanguage,
languages: this.languages
});
}
@@ -67,13 +103,34 @@ class EveAIChatWidget extends HTMLElement {
const apiKey = this.getAttribute('api-key');
const domain = this.getAttribute('domain');
const language = this.getAttribute('language');
const languages = this.getAttribute('languages');
console.log('Checking if all attributes are set:', {
tenantId,
apiKey,
domain,
language
language,
languages
});
return tenantId && apiKey && domain && language;
return tenantId && apiKey && domain && language && languages;
}
createLanguageDropdown() {
const select = document.createElement('select');
select.id = 'languageSelect';
this.languages.forEach(lang => {
const option = document.createElement('option');
option.value = lang;
option.textContent = lang.toUpperCase();
if (lang === this.currentLanguage) {
option.selected = true;
}
select.appendChild(option);
});
select.addEventListener('change', (e) => {
this.currentLanguage = e.target.value;
// You might want to emit an event or update the backend about the language change
});
return select;
}
initializeSocket() {
@@ -81,15 +138,11 @@ class EveAIChatWidget extends HTMLElement {
console.log('Socket already initialized');
return;
}
if (!this.domain || this.domain === 'null') {
console.error('Domain attribute is missing or invalid');
this.setStatusMessage('EveAI Chat Widget needs further configuration by site administrator.');
return;
}
console.log(`Initializing socket connection to ${this.domain}`);
console.log(`Initializing socket connection to Evie`);
// Ensure apiKey is passed in the query parameters
this.socket = io(this.domain, {
this.socket = io('https://evie.askeveai.com', {
path: '/chat/socket.io/',
transports: ['websocket', 'polling'],
query: {
@@ -104,13 +157,17 @@ class EveAIChatWidget extends HTMLElement {
timeout: 20000 // Connection timeout
});
console.log(`Finished initializing socket connection to ${this.domain}`);
console.log(`Finished initializing socket connection to Evie`);
this.socket.on('connect', (data) => {
console.log('Socket connected OK');
this.setStatusMessage('Connected to EveAI.');
this.updateConnectionStatus(true);
this.startHeartbeat();
if (data.room) {
this.room = data.room;
console.log(`Joined room: ${this.room}`);
}
});
this.socket.on('authenticated', (data) => {
@@ -119,6 +176,10 @@ class EveAIChatWidget extends HTMLElement {
if (data.token) {
this.jwtToken = data.token; // Store the JWT token received from the server
}
if (data.room) {
this.room = data.room;
console.log(`Confirmed room: ${this.room}`);
}
});
this.socket.on('connect_error', (err) => {
@@ -243,9 +304,13 @@ class EveAIChatWidget extends HTMLElement {
return `
<div class="chat-container">
<div class="messages-area"></div>
<div class="disclaimer">Evie can make mistakes. Please double-check responses.</div>
<div class="question-area">
<input type="text" placeholder="Type your message here..." />
<i class="material-icons send-icon outlined">send</i>
<textarea placeholder="Type your message here..." rows="3"></textarea>
<div class="right-side">
<select class="language-select"></select>
<i class="material-icons send-icon outlined">send</i>
</div>
</div>
<div class="status-line">
<i class="material-icons connection-status-icon">link_off</i>
@@ -370,12 +435,15 @@ toggleFeedback(thumbsUp, thumbsDown, feedback, interactionId) {
console.error('JWT token is not available');
return;
}
const selectedLanguage = this.languageSelect.value;
console.log('Sending message to backend');
this.socket.emit('user_message', {
tenantId: this.tenantId,
token: this.jwtToken,
message,
language: this.language,
language: selectedLanguage,
timezone: this.userTimezone
});
this.setStatusMessage('Processing started ...')

View File

@@ -1,12 +1,13 @@
// static/js/eveai-sdk.js
class EveAI {
constructor(tenantId, apiKey, domain, language) {
constructor(tenantId, apiKey, domain, language, languages) {
this.tenantId = tenantId;
this.apiKey = apiKey;
this.domain = domain;
this.language = language;
this.languages = languages;
console.log('EveAI constructor:', { tenantId, apiKey, domain });
console.log('EveAI constructor:', { tenantId, apiKey, domain, language, languages });
}
initializeChat(containerId) {
@@ -19,6 +20,7 @@ class EveAI {
chatWidget.setAttribute('api-key', this.apiKey);
chatWidget.setAttribute('domain', this.domain);
chatWidget.setAttribute('language', this.language);
chatWidget.setAttribute('languages', this.languages);
});
} else {
console.error('Container not found');