Spaces:
Sleeping
Sleeping
; | |
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 uuid_1 = require("uuid"); | |
const axios_1 = __importDefault(require("axios")); | |
const database_1 = require("../db/database"); | |
const auth_1 = require("../middleware/auth"); | |
const router = express_1.default.Router(); | |
// Create a new chat session (authenticated - for tenant dashboard) | |
router.post('/sessions', auth_1.authenticateToken, async (req, res) => { | |
try { | |
const { tenantId } = req.user; | |
const { domain, userAgent } = req.body; | |
const userIp = req.ip || req.connection.remoteAddress; | |
// 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' }); | |
} | |
// Generate session token | |
const sessionToken = (0, uuid_1.v4)(); | |
// Create chat session | |
const result = await database_1.database.run('INSERT INTO chat_sessions (tenant_id, domain, user_ip, user_agent, session_token) VALUES (?, ?, ?, ?, ?)', [tenantId, domain, userIp, userAgent, sessionToken]); | |
// Log analytics event | |
await database_1.database.run('INSERT INTO analytics_events (tenant_id, event_type, event_data) VALUES (?, ?, ?)', [tenantId, 'chat_session_started', JSON.stringify({ sessionId: result.lastID, domain })]); | |
res.status(201).json({ | |
sessionId: result.lastID, | |
sessionToken, | |
tenantId, | |
message: 'Chat session created successfully' | |
}); | |
} | |
catch (error) { | |
console.error('Create session error:', error); | |
res.status(500).json({ error: 'Internal server error' }); | |
} | |
}); | |
// Create a new chat session (public - for widget) | |
router.post('/public/sessions', async (req, res) => { | |
try { | |
const { tenantId, domain, userAgent } = req.body; | |
const userIp = req.ip || req.connection.remoteAddress; | |
if (!tenantId) { | |
return res.status(400).json({ error: 'Tenant ID is required' }); | |
} | |
// 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' }); | |
} | |
// Generate session token | |
const sessionToken = (0, uuid_1.v4)(); | |
// Create chat session | |
const result = await database_1.database.run('INSERT INTO chat_sessions (tenant_id, domain, user_ip, user_agent, session_token) VALUES (?, ?, ?, ?, ?)', [tenantId, domain, userIp, userAgent, sessionToken]); | |
// Log analytics event | |
await database_1.database.run('INSERT INTO analytics_events (tenant_id, event_type, event_data) VALUES (?, ?, ?)', [tenantId, 'chat_session_started', JSON.stringify({ sessionId: result.lastID, domain })]); | |
res.status(201).json({ | |
sessionId: result.lastID, | |
sessionToken, | |
message: 'Chat session created successfully' | |
}); | |
} | |
catch (error) { | |
console.error('Create session error:', error); | |
res.status(500).json({ error: 'Internal server error' }); | |
} | |
}); | |
// Send a message and get AI response | |
router.post('/messages', async (req, res) => { | |
try { | |
const { sessionToken, message, tenantId } = req.body; | |
if (!sessionToken || !message || !tenantId) { | |
return res.status(400).json({ error: 'Session token, message, and tenant ID are required' }); | |
} | |
// Get chat session | |
const session = await database_1.database.get('SELECT * FROM chat_sessions WHERE session_token = ? AND tenant_id = ?', [sessionToken, tenantId]); | |
if (!session) { | |
return res.status(404).json({ error: 'Chat session not found' }); | |
} | |
// Save user message | |
await database_1.database.run('INSERT INTO chat_messages (session_id, sender, message) VALUES (?, ?, ?)', [session.id, 'user', message]); | |
// Get chat history for context | |
const chatHistory = await database_1.database.query('SELECT sender, message, timestamp FROM chat_messages WHERE session_id = ? ORDER BY timestamp ASC', [session.id]); | |
// Get tenant's knowledge base | |
const knowledgeBase = await database_1.database.query('SELECT name, type, source FROM knowledge_base WHERE tenant_id = ? AND status = "active"', [tenantId]); | |
try { | |
// Call MCP server for AI response | |
const mcpResponse = await axios_1.default.post(`${process.env.MCP_SERVER_URL}/chat`, { | |
message, | |
history: chatHistory, | |
knowledge_base: knowledgeBase, | |
tenant_id: tenantId | |
}, { | |
headers: { | |
'Authorization': `Bearer ${process.env.MCP_AUTH_TOKEN}`, | |
'Content-Type': 'application/json' | |
}, | |
timeout: 30000 // 30 second timeout | |
}); | |
const aiResponse = mcpResponse.data.response || 'I apologize, but I encountered an issue processing your request.'; | |
// Save AI response | |
await database_1.database.run('INSERT INTO chat_messages (session_id, sender, message, metadata) VALUES (?, ?, ?, ?)', [session.id, 'ai', aiResponse, JSON.stringify({ | |
model: mcpResponse.data.model || 'gemini-1.5-flash', | |
confidence: mcpResponse.data.confidence || 0.8 | |
})]); | |
// Log analytics event | |
await database_1.database.run('INSERT INTO analytics_events (tenant_id, event_type, event_data) VALUES (?, ?, ?)', [tenantId, 'message_sent', JSON.stringify({ | |
sessionId: session.id, | |
messageLength: message.length, | |
responseLength: aiResponse.length | |
})]); | |
res.json({ | |
response: aiResponse, | |
messageId: session.id, | |
timestamp: new Date().toISOString() | |
}); | |
} | |
catch (mcpError) { | |
console.error('MCP Server error:', mcpError); | |
// Fallback response if MCP server is down | |
const fallbackResponse = "I'm sorry, but I'm experiencing technical difficulties at the moment. Please try again in a few minutes or contact support if the issue persists."; | |
await database_1.database.run('INSERT INTO chat_messages (session_id, sender, message, metadata) VALUES (?, ?, ?, ?)', [session.id, 'ai', fallbackResponse, JSON.stringify({ error: 'mcp_server_unavailable' })]); | |
res.json({ | |
response: fallbackResponse, | |
messageId: session.id, | |
timestamp: new Date().toISOString(), | |
error: 'Service temporarily unavailable' | |
}); | |
} | |
} | |
catch (error) { | |
console.error('Send message error:', error); | |
res.status(500).json({ error: 'Internal server error' }); | |
} | |
}); | |
// Get chat history | |
router.get('/sessions/:sessionToken/history', async (req, res) => { | |
try { | |
const { sessionToken } = req.params; | |
const { tenantId } = req.query; | |
if (!tenantId) { | |
return res.status(400).json({ error: 'Tenant ID is required' }); | |
} | |
// Get session | |
const session = await database_1.database.get('SELECT * FROM chat_sessions WHERE session_token = ? AND tenant_id = ?', [sessionToken, tenantId]); | |
if (!session) { | |
return res.status(404).json({ error: 'Chat session not found' }); | |
} | |
// Get messages | |
const messages = await database_1.database.query('SELECT sender, message, metadata, timestamp FROM chat_messages WHERE session_id = ? ORDER BY timestamp ASC', [session.id]); | |
res.json({ | |
sessionId: session.id, | |
messages, | |
session: { | |
started_at: session.started_at, | |
resolved: session.resolved, | |
rating: session.rating | |
} | |
}); | |
} | |
catch (error) { | |
console.error('Get history error:', error); | |
res.status(500).json({ error: 'Internal server error' }); | |
} | |
}); | |
// Rate conversation | |
router.post('/sessions/:sessionToken/rate', async (req, res) => { | |
try { | |
const { sessionToken } = req.params; | |
const { rating, feedback, tenantId } = req.body; | |
if (!tenantId || rating === undefined) { | |
return res.status(400).json({ error: 'Tenant ID and rating are required' }); | |
} | |
if (rating < 1 || rating > 5) { | |
return res.status(400).json({ error: 'Rating must be between 1 and 5' }); | |
} | |
// Update session | |
await database_1.database.run('UPDATE chat_sessions SET rating = ?, feedback = ?, resolved = TRUE WHERE session_token = ? AND tenant_id = ?', [rating, feedback, sessionToken, tenantId]); | |
// Log analytics event | |
await database_1.database.run('INSERT INTO analytics_events (tenant_id, event_type, event_data) VALUES (?, ?, ?)', [tenantId, 'conversation_rated', JSON.stringify({ | |
sessionToken, | |
rating, | |
hasFeedback: !!feedback | |
})]); | |
res.json({ message: 'Rating submitted successfully' }); | |
} | |
catch (error) { | |
console.error('Rate conversation error:', error); | |
res.status(500).json({ error: 'Internal server error' }); | |
} | |
}); | |
// End chat session | |
router.post('/sessions/:sessionToken/end', async (req, res) => { | |
try { | |
const { sessionToken } = req.params; | |
const { tenantId } = req.body; | |
if (!tenantId) { | |
return res.status(400).json({ error: 'Tenant ID is required' }); | |
} | |
// Update session | |
await database_1.database.run('UPDATE chat_sessions SET ended_at = CURRENT_TIMESTAMP WHERE session_token = ? AND tenant_id = ?', [sessionToken, tenantId]); | |
// Log analytics event | |
await database_1.database.run('INSERT INTO analytics_events (tenant_id, event_type, event_data) VALUES (?, ?, ?)', [tenantId, 'chat_session_ended', JSON.stringify({ sessionToken })]); | |
res.json({ message: 'Chat session ended successfully' }); | |
} | |
catch (error) { | |
console.error('End session error:', error); | |
res.status(500).json({ error: 'Internal server error' }); | |
} | |
}); | |
exports.default = router; | |
//# sourceMappingURL=chat.js.map |