API key working, CORS working, SocketIO working (but no JWT), Chat client v1, Session implemented (server side)
This commit is contained in:
77
static/css/eveai-chat-style.css
Normal file
77
static/css/eveai-chat-style.css
Normal file
@@ -0,0 +1,77 @@
|
||||
/* eveai_chat.css */
|
||||
:root {
|
||||
--user-message-bg: #d1e7dd; /* Default user message background color */
|
||||
--bot-message-bg: #ffffff; /* Default bot message background color */
|
||||
--chat-bg: #f8f9fa; /* Default chat background color */
|
||||
--algorithm-color-default: #ccc; /* Default algorithm indicator color */
|
||||
--algorithm-color-alg1: #f00; /* Algorithm 1 color */
|
||||
--algorithm-color-alg2: #0f0; /* Algorithm 2 color */
|
||||
--algorithm-color-alg3: #00f; /* Algorithm 3 color */
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background-color: var(--chat-bg);
|
||||
}
|
||||
|
||||
.messages-area {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 10px;
|
||||
background-color: var(--bot-message-bg);
|
||||
}
|
||||
|
||||
.message {
|
||||
max-width: 90%;
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.message.user {
|
||||
margin-left: auto;
|
||||
background-color: var(--user-message-bg);
|
||||
}
|
||||
|
||||
.message.bot {
|
||||
background-color: var(--bot-message-bg);
|
||||
}
|
||||
|
||||
.message-icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message-icons i {
|
||||
margin-left: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.question-area {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: var(--user-message-bg);
|
||||
}
|
||||
|
||||
.question-area input {
|
||||
flex: 1;
|
||||
border: none;
|
||||
padding: 10px;
|
||||
border-radius: 15px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.question-area button {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: #007bff;
|
||||
}
|
||||
172
static/js/eveai-chat-widget.js
Normal file
172
static/js/eveai-chat-widget.js
Normal file
@@ -0,0 +1,172 @@
|
||||
// static/js/eveai-chat-widget.js
|
||||
class EveAIChatWidget extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['tenant-id', 'api-key', 'domain'];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.socket = null; // Initialize socket to null
|
||||
this.attributesSet = false; // Flag to check if all attributes are set
|
||||
console.log('EveAIChatWidget constructor called');
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
console.log('connectedCallback called');
|
||||
this.innerHTML = this.getTemplate();
|
||||
this.messagesArea = this.querySelector('.messages-area');
|
||||
this.questionInput = this.querySelector('.question-area input');
|
||||
|
||||
this.querySelector('.question-area button').addEventListener('click', () => this.handleSendMessage());
|
||||
|
||||
if (this.areAllAttributesSet() && !this.socket) {
|
||||
console.log('Attributes already set in connectedCallback, initializing socket');
|
||||
this.initializeSocket();
|
||||
}
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
console.log(`attributeChangedCallback called: ${name} changed from ${oldValue} to ${newValue}`);
|
||||
this.updateAttributes();
|
||||
console.log('Current attributes:', {
|
||||
tenantId: this.getAttribute('tenant-id'),
|
||||
apiKey: this.getAttribute('api-key'),
|
||||
domain: this.getAttribute('domain')
|
||||
});
|
||||
|
||||
if (this.areAllAttributesSet() && !this.socket) {
|
||||
console.log('All attributes set in attributeChangedCallback, initializing socket');
|
||||
this.attributesSet = true;
|
||||
this.initializeSocket();
|
||||
}
|
||||
}
|
||||
|
||||
updateAttributes() {
|
||||
console.log('Updating attributes:');
|
||||
this.tenantId = this.getAttribute('tenant-id');
|
||||
this.apiKey = this.getAttribute('api-key');
|
||||
this.domain = this.getAttribute('domain');
|
||||
console.log('Updated attributes:', {
|
||||
tenantId: this.tenantId,
|
||||
apiKey: this.apiKey,
|
||||
domain: this.domain
|
||||
});
|
||||
}
|
||||
|
||||
areAllAttributesSet() {
|
||||
const tenantId = this.getAttribute('tenant-id');
|
||||
const apiKey = this.getAttribute('api-key');
|
||||
const domain = this.getAttribute('domain');
|
||||
console.log('Checking if all attributes are set:', {
|
||||
tenantId,
|
||||
apiKey,
|
||||
domain
|
||||
});
|
||||
return tenantId && apiKey && domain;
|
||||
}
|
||||
|
||||
initializeSocket() {
|
||||
if (this.socket) {
|
||||
console.log('Socket already initialized');
|
||||
return;
|
||||
}
|
||||
if (!this.domain || this.domain === 'null') {
|
||||
console.error('Domain attribute is missing or invalid');
|
||||
return;
|
||||
}
|
||||
console.log(`Initializing socket connection to ${this.domain}`);
|
||||
|
||||
const token = 'Bearer ' + this.apiKey
|
||||
|
||||
// Include tenantId in query parameters
|
||||
this.socket = io(this.domain, {
|
||||
path: '/chat/socket.io/',
|
||||
transports: ['websocket', 'polling'],
|
||||
auth: {
|
||||
token: token // Add the token to the authentication object
|
||||
},
|
||||
query: {
|
||||
tenantId: this.tenantId,
|
||||
// apiKey: this.apiKey
|
||||
},
|
||||
});
|
||||
|
||||
this.socket.on('connect', () => {
|
||||
console.log('Socket connected');
|
||||
});
|
||||
|
||||
this.socket.on('connect_error', (err) => {
|
||||
console.error('Socket connection error:', err);
|
||||
});
|
||||
|
||||
this.socket.on('connect_timeout', () => {
|
||||
console.error('Socket connection timeout')
|
||||
});
|
||||
|
||||
this.socket.on('disconnect', () => {
|
||||
console.log('Socket disconnected');
|
||||
});
|
||||
|
||||
this.socket.on('bot_response', (data) => {
|
||||
if (data.tenantId === this.tenantId) {
|
||||
this.addMessage(data.message, 'bot', data.messageId, data.algorithm);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getTemplate() {
|
||||
return `
|
||||
<div class="chat-container">
|
||||
<div class="messages-area"></div>
|
||||
<div class="question-area">
|
||||
<input type="text" placeholder="Type your message here..." />
|
||||
<button>Send</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
addMessage(text, type = 'user', id = null, algorithm = 'default') {
|
||||
const message = document.createElement('div');
|
||||
message.classList.add('message', type);
|
||||
message.innerHTML = `
|
||||
<p>${text}</p>
|
||||
${type === 'bot' ? `
|
||||
<div class="message-icons">
|
||||
<span class="algorithm-indicator" style="background-color: var(--algorithm-color-${algorithm});"></span>
|
||||
<i class="material-icons" onclick="handleFeedback('${id}', 'up')">thumb_up</i>
|
||||
<i class="material-icons" onclick="handleFeedback('${id}', 'down')">thumb_down</i>
|
||||
</div>` : ''}
|
||||
`;
|
||||
this.messagesArea.appendChild(message);
|
||||
this.messagesArea.scrollTop = this.messagesArea.scrollHeight;
|
||||
}
|
||||
|
||||
handleSendMessage() {
|
||||
console.log('handleSendMessage called');
|
||||
const message = this.questionInput.value.trim();
|
||||
if (message) {
|
||||
this.addMessage(message, 'user');
|
||||
this.questionInput.value = '';
|
||||
this.sendMessageToBackend(message);
|
||||
}
|
||||
}
|
||||
|
||||
sendMessageToBackend(message) {
|
||||
console.log('sendMessageToBackend called');
|
||||
if (!this.socket) {
|
||||
console.error('Socket is not initialized');
|
||||
return;
|
||||
}
|
||||
console.log('Sending message to backend');
|
||||
this.socket.emit('user_message', { tenantId: this.tenantId, apiKey: this.apiKey, message });
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('eveai-chat-widget', EveAIChatWidget);
|
||||
|
||||
function handleFeedback(messageId, feedback) {
|
||||
// Send feedback to the backend
|
||||
console.log(`Feedback for ${messageId}: ${feedback}`);
|
||||
// Implement the actual feedback mechanism
|
||||
}
|
||||
29
static/js/eveai-sdk.js
Normal file
29
static/js/eveai-sdk.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// static/js/eveai-sdk.js
|
||||
class EveAI {
|
||||
constructor(tenantId, apiKey, domain) {
|
||||
this.tenantId = tenantId;
|
||||
this.apiKey = apiKey;
|
||||
this.domain = domain;
|
||||
console.log('EveAI constructor:', { tenantId, apiKey, domain });
|
||||
}
|
||||
|
||||
initializeChat(containerId) {
|
||||
const container = document.getElementById(containerId);
|
||||
if (container) {
|
||||
container.innerHTML = '<eveai-chat-widget></eveai-chat-widget>';
|
||||
customElements.whenDefined('eveai-chat-widget').then(() => {
|
||||
const chatWidget = container.querySelector('eveai-chat-widget');
|
||||
chatWidget.setAttribute('tenant-id', this.tenantId);
|
||||
chatWidget.setAttribute('api-key', this.apiKey);
|
||||
chatWidget.setAttribute('domain', this.domain);
|
||||
console.log('Attributes set in chat widget:', {
|
||||
tenantId: chatWidget.getAttribute('tenant-id'),
|
||||
apiKey: chatWidget.getAttribute('api-key'),
|
||||
domain: chatWidget.getAttribute('domain')
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error('Container not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user