|
|
const Message = require('../models/Message');
|
|
|
const Conversation = require('../models/Conversation');
|
|
|
const { generateAIResponse } = require('../services/aiService');
|
|
|
const Joi = require('joi');
|
|
|
|
|
|
|
|
|
const sendMessageSchema = Joi.object({
|
|
|
conversationId: Joi.string().required(),
|
|
|
content: Joi.string().min(1).max(10000).required()
|
|
|
});
|
|
|
|
|
|
|
|
|
exports.sendMessage = async (req, res) => {
|
|
|
try {
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
const conversation = await Conversation.findOne({
|
|
|
_id: conversationId,
|
|
|
userId
|
|
|
});
|
|
|
|
|
|
if (!conversation) {
|
|
|
return res.status(404).json({ error: 'Conversation not found' });
|
|
|
}
|
|
|
|
|
|
|
|
|
const userMessage = new Message({
|
|
|
conversationId,
|
|
|
sender: 'user',
|
|
|
content
|
|
|
});
|
|
|
await userMessage.save();
|
|
|
|
|
|
|
|
|
conversation.messageCount += 1;
|
|
|
conversation.lastMessageAt = new Date();
|
|
|
|
|
|
|
|
|
if (conversation.messageCount === 1) {
|
|
|
conversation.title = content.substring(0, 50) + (content.length > 50 ? '...' : '');
|
|
|
}
|
|
|
|
|
|
await conversation.save();
|
|
|
|
|
|
|
|
|
const aiResponse = await generateAIResponse(content, conversationId);
|
|
|
|
|
|
const assistantMessage = new Message({
|
|
|
conversationId,
|
|
|
sender: 'assistant',
|
|
|
content: aiResponse.content,
|
|
|
metadata: aiResponse.metadata
|
|
|
});
|
|
|
await assistantMessage.save();
|
|
|
|
|
|
|
|
|
conversation.messageCount += 1;
|
|
|
conversation.lastMessageAt = new Date();
|
|
|
await conversation.save();
|
|
|
|
|
|
|
|
|
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' });
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
exports.getMessages = async (req, res) => {
|
|
|
try {
|
|
|
const { conversationId } = req.params;
|
|
|
const { page = 1, limit = 50 } = req.query;
|
|
|
const userId = req.userId;
|
|
|
|
|
|
|
|
|
const conversation = await Conversation.findOne({
|
|
|
_id: conversationId,
|
|
|
userId
|
|
|
});
|
|
|
|
|
|
if (!conversation) {
|
|
|
return res.status(404).json({ error: 'Conversation not found' });
|
|
|
}
|
|
|
|
|
|
|
|
|
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' });
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
exports.deleteMessage = async (req, res) => {
|
|
|
try {
|
|
|
const { messageId } = req.params;
|
|
|
const userId = req.userId;
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
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' });
|
|
|
}
|
|
|
}; |