"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const database_1 = require("../db/database"); const router = express_1.default.Router(); // Get widget configuration router.get('/config/:tenantId', async (req, res) => { try { const { tenantId } = req.params; // Get tenant info const tenant = await database_1.database.get('SELECT id, name, plan FROM tenants WHERE id = ?', [tenantId]); if (!tenant) { return res.status(404).json({ error: 'Tenant not found' }); } // Get widget configuration const config = await database_1.database.get('SELECT config FROM widget_configs WHERE tenant_id = ?', [tenantId]); const defaultConfig = { theme: { primaryColor: '#6366f1', backgroundColor: '#ffffff', textColor: '#374151', borderRadius: '12px' }, position: { bottom: '20px', right: '20px' }, size: 'medium', welcome: { title: `Hi! I'm ${tenant.name}'s AI assistant`, message: 'How can I help you today?', showAvatar: true }, features: { fileUpload: false, typing: true, ratings: true } }; const widgetConfig = config ? { ...defaultConfig, ...JSON.parse(config.config) } : defaultConfig; res.json({ tenantId, config: widgetConfig }); } catch (error) { console.error('Get widget config error:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Get widget script router.get('/script/:tenantId', async (req, res) => { try { const { tenantId } = req.params; // Verify tenant exists const tenant = await database_1.database.get('SELECT id FROM tenants WHERE id = ?', [tenantId]); if (!tenant) { return res.status(404).json({ error: 'Tenant not found' }); } const script = ` (function() { // MCP Chat Widget const TENANT_ID = '${tenantId}'; const API_URL = '${process.env.FRONTEND_URL || 'http://localhost:3001'}/api'; // Create widget container const widget = document.createElement('div'); widget.id = 'mcp-chat-widget'; widget.style.cssText = \` position: fixed; bottom: 20px; right: 20px; width: 350px; height: 500px; background: white; border-radius: 12px; box-shadow: 0 10px 25px rgba(0,0,0,0.1); z-index: 10000; display: none; flex-direction: column; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; border: 1px solid #e5e7eb; \`; // Create chat button const button = document.createElement('div'); button.id = 'mcp-chat-button'; button.style.cssText = \` position: fixed; bottom: 20px; right: 20px; width: 60px; height: 60px; background: linear-gradient(135deg, #6366f1, #8b5cf6); border-radius: 50%; cursor: pointer; z-index: 10001; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4); transition: transform 0.2s ease; \`; button.innerHTML = \` \`; button.onmouseover = () => button.style.transform = 'scale(1.05)'; button.onmouseout = () => button.style.transform = 'scale(1)'; // Widget header const header = document.createElement('div'); header.style.cssText = \` padding: 16px; background: linear-gradient(135deg, #6366f1, #8b5cf6); color: white; border-radius: 12px 12px 0 0; display: flex; justify-content: space-between; align-items: center; \`; header.innerHTML = \`

Chat Support

We're here to help!

\`; // Messages container const messages = document.createElement('div'); messages.id = 'mcp-messages'; messages.style.cssText = \` flex: 1; padding: 16px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; \`; // Input container const inputContainer = document.createElement('div'); inputContainer.style.cssText = \` padding: 16px; border-top: 1px solid #e5e7eb; display: flex; gap: 8px; \`; const input = document.createElement('input'); input.type = 'text'; input.placeholder = 'Type your message...'; input.style.cssText = \` flex: 1; padding: 12px; border: 1px solid #d1d5db; border-radius: 8px; outline: none; font-size: 14px; \`; const sendBtn = document.createElement('button'); sendBtn.textContent = 'Send'; sendBtn.style.cssText = \` padding: 12px 16px; background: #6366f1; color: white; border: none; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 500; \`; // Assemble widget inputContainer.appendChild(input); inputContainer.appendChild(sendBtn); widget.appendChild(header); widget.appendChild(messages); widget.appendChild(inputContainer); // Add to page document.body.appendChild(button); document.body.appendChild(widget); // Session management let sessionToken = null; let isVisible = false; // Toggle widget function toggleWidget() { isVisible = !isVisible; widget.style.display = isVisible ? 'flex' : 'none'; button.style.display = isVisible ? 'none' : 'flex'; if (isVisible && !sessionToken) { initializeSession(); } } // Initialize chat session async function initializeSession() { try { const response = await fetch(\`\${API_URL}/chat/sessions\`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ tenantId: TENANT_ID, domain: window.location.hostname, userAgent: navigator.userAgent }) }); const data = await response.json(); sessionToken = data.sessionToken; // Add welcome message addMessage('ai', 'Hello! How can I help you today?'); } catch (error) { console.error('Failed to initialize session:', error); addMessage('ai', 'Sorry, I\\'m having trouble connecting. Please try again later.'); } } // Send message async function sendMessage(message) { if (!sessionToken || !message.trim()) return; addMessage('user', message); input.value = ''; // Show typing indicator const typingEl = addMessage('ai', 'Typing...', true); try { const response = await fetch(\`\${API_URL}/chat/messages\`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionToken, message, tenantId: TENANT_ID }) }); const data = await response.json(); // Remove typing indicator typingEl.remove(); // Add AI response addMessage('ai', data.response); } catch (error) { typingEl.remove(); addMessage('ai', 'Sorry, I encountered an error. Please try again.'); } } // Add message to chat function addMessage(sender, text, isTyping = false) { const messageEl = document.createElement('div'); messageEl.style.cssText = \` max-width: 80%; padding: 12px 16px; border-radius: 18px; font-size: 14px; line-height: 1.4; \${sender === 'user' ? 'background: #6366f1; color: white; align-self: flex-end; margin-left: auto;' : 'background: #f3f4f6; color: #374151; align-self: flex-start;' } \${isTyping ? 'opacity: 0.7; font-style: italic;' : ''} \`; messageEl.textContent = text; messages.appendChild(messageEl); messages.scrollTop = messages.scrollHeight; return messageEl; } // Event listeners button.onclick = toggleWidget; header.querySelector('#mcp-close-btn').onclick = toggleWidget; sendBtn.onclick = () => sendMessage(input.value); input.onkeypress = (e) => { if (e.key === 'Enter') sendMessage(input.value); }; console.log('MCP Chat Widget loaded successfully'); })(); `; res.setHeader('Content-Type', 'application/javascript'); res.send(script); } catch (error) { console.error('Get widget script error:', error); res.status(500).json({ error: 'Internal server error' }); } }); exports.default = router; //# sourceMappingURL=widget.js.map