CHAINR / backend /src /controllers /chatController.js
chainr-ai's picture
Upload 8536 files
4888678 verified
const Message = require('../models/Message');
const Conversation = require('../models/Conversation');
const { generateAIResponse } = require('../services/aiService');
const Joi = require('joi');
// Validation schema
const sendMessageSchema = Joi.object({
conversationId: Joi.string().required(),
content: Joi.string().min(1).max(10000).required()
});
// Send message
exports.sendMessage = async (req, res) => {
try {
// Validate input
const { error } = sendMessageSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
const { conversationId, content } = req.body;
const userId = req.userId;
// Verify conversation belongs to user
const conversation = await Conversation.findOne({
_id: conversationId,
userId
});
if (!conversation) {
return res.status(404).json({ error: 'Conversation not found' });
}
// Create user message
const userMessage = new Message({
conversationId,
sender: 'user',
content
});
await userMessage.save();
// Update conversation
conversation.messageCount += 1;
conversation.lastMessageAt = new Date();
// Update title if it's the first message
if (conversation.messageCount === 1) {
conversation.title = content.substring(0, 50) + (content.length > 50 ? '...' : '');
}
await conversation.save();
// Generate AI response
const aiResponse = await generateAIResponse(content, conversationId);
const assistantMessage = new Message({
conversationId,
sender: 'assistant',
content: aiResponse.content,
metadata: aiResponse.metadata
});
await assistantMessage.save();
// Update conversation message count
conversation.messageCount += 1;
conversation.lastMessageAt = new Date();
await conversation.save();
// Emit to socket if available
const io = req.app.get('socketio');
if (io) {
io.to(`user_${userId}`).emit('newMessage', {
userMessage,
assistantMessage
});
}
res.json({
userMessage,
assistantMessage
});
} catch (error) {
console.error('Send message error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
// Get messages for a conversation
exports.getMessages = async (req, res) => {
try {
const { conversationId } = req.params;
const { page = 1, limit = 50 } = req.query;
const userId = req.userId;
// Verify conversation belongs to user
const conversation = await Conversation.findOne({
_id: conversationId,
userId
});
if (!conversation) {
return res.status(404).json({ error: 'Conversation not found' });
}
// Get messages with pagination
const messages = await Message.find({ conversationId })
.sort({ createdAt: 1 })
.limit(limit * 1)
.skip((page - 1) * limit);
const total = await Message.countDocuments({ conversationId });
res.json({
messages,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total,
pages: Math.ceil(total / limit)
}
});
} catch (error) {
console.error('Get messages error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
// Delete message
exports.deleteMessage = async (req, res) => {
try {
const { messageId } = req.params;
const userId = req.userId;
// Find message and verify ownership
const message = await Message.findById(messageId).populate({
path: 'conversationId',
select: 'userId'
});
if (!message) {
return res.status(404).json({ error: 'Message not found' });
}
if (message.conversationId.userId.toString() !== userId) {
return res.status(403).json({ error: 'Unauthorized' });
}
await Message.findByIdAndDelete(messageId);
// Update conversation message count
await Conversation.findByIdAndUpdate(message.conversationId._id, {
$inc: { messageCount: -1 }
});
res.json({ message: 'Message deleted successfully' });
} catch (error) {
console.error('Delete message error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};