Spaces:
Runtime error
Runtime error
File size: 2,623 Bytes
24727a3 a0a2b9e 24727a3 a0a2b9e 24727a3 a0a2b9e 24727a3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import { prisma } from '../../config/database.js'
import { saveMessage } from './chat.service.js'
import { STAFF_ROLES } from '../../lib/constants.js'
import { handleClientMessage } from './bot.service.js'
const msgRateLimiter = new Map()
function checkMsgRateLimit(userId) {
const now = Date.now()
const history = (msgRateLimiter.get(userId) || []).filter(t => now - t < 60000)
if (history.length >= 30) return false
msgRateLimiter.set(userId, [...history, now])
return true
}
setInterval(() => msgRateLimiter.clear(), 5 * 60 * 1000)
export function setupChatSocket(io) {
io.on('connection', (socket) => {
const userId = socket.userId
if (!userId) return socket.disconnect()
socket.join(`user:${userId}`)
socket.on('chat:join', async (conversationId) => {
try {
const conversation = await prisma.conversation.findUnique({
where: { id: conversationId },
include: { order: { select: { userId: true } } }
})
if (!conversation) return
const isAdmin = STAFF_ROLES.includes(socket.userRole)
const isOwner = conversation.order?.userId === userId
const isClient = conversation.clientId === userId
if (isAdmin || isOwner || isClient) {
socket.join(`conversation:${conversationId}`)
}
} catch { /* silently fail */ }
})
socket.on('chat:message', async (data) => {
try {
if (!checkMsgRateLimit(userId)) return
const { conversationId, content } = data || {}
if (!content?.trim() || typeof content !== 'string') return
if (content.length > 2000) return
const { message, ownerId } = await saveMessage(conversationId, userId, content.trim())
io.to(`conversation:${conversationId}`).emit('chat:newMessage', message)
if (ownerId !== userId) {
io.to(`user:${ownerId}`).emit('chat:newMessage', message)
}
// لو المرسل عميل (مش أدمن) — شوف لو محتاج رد تلقائي
if (!STAFF_ROLES.includes(socket.userRole)) {
const botMsg = await handleClientMessage(conversationId, content.trim())
if (botMsg) {
io.to(`conversation:${conversationId}`).emit('chat:newMessage', botMsg)
}
}
} catch { /* fail silently */ }
})
socket.on('typing', ({ conversationId, isTyping }) => {
if (!conversationId) return
const room = socket.rooms?.has(`conversation:${conversationId}`)
if (!room) return
socket.to(`conversation:${conversationId}`).emit('typing', { userId, isTyping })
})
})
}
|