'use strict'; const PERSONAL_INTAKE_MODES = ['allowlist_only', 'auto_enroll_review', 'auto_enroll_autopilot']; function normalizePersonalIntakeMode(value) { const mode = String(value || '').trim(); return PERSONAL_INTAKE_MODES.includes(mode) ? mode : 'allowlist_only'; } function messageTimestamp(raw) { const parsed = Number(raw); if (!Number.isFinite(parsed)) return 0; return parsed > 1e12 ? Math.floor(parsed / 1000) : parsed; } function roomIdOf(message = {}) { const candidates = [ message.fromRoomId, message.roomId, message.chatRoomId, message.room?.id, message.msgData?.fromRoomId, message.msgData?.roomId, ]; for (const value of candidates) { const normalized = String(value ?? '').trim(); if (normalized && !/^(?:0|null|undefined)$/i.test(normalized)) return normalized; } return ''; } function isGroupMessage(message = {}) { if (roomIdOf(message)) return true; if (message.isRoom === true || Number(message.isRoomNotice) === 1) return true; return /^(?:group|room)$/i.test(String(message.chatType || '').trim()); } function messageContent(message = {}) { const data = message.msgData || {}; const candidates = [message.content, data.content, data.text, data.value, data.content?.text, data.content?.content]; for (const value of candidates) { if (typeof value === 'string' && value.trim()) return value.trim(); } return ''; } function evaluatePolledMessage(message = {}, config = {}) { if (![0, 1, 2].includes(Number(message.msgType))) return { eligible: false, reason: 'unsupported_type' }; if (isGroupMessage(message)) return { eligible: false, reason: 'group_message', roomId: roomIdOf(message) }; const content = messageContent(message); const senderId = String(message.senderId || ''); if (!content || !senderId) return { eligible: false, reason: 'empty_message' }; if (senderId === String(config.selfUserId || '')) return { eligible: false, reason: 'self_message' }; const allowlisted = (config.allowedSenders || []).map(String).includes(senderId); const intakeMode = normalizePersonalIntakeMode(config.intakeMode); if (!allowlisted && intakeMode === 'allowlist_only') return { eligible: false, reason: 'not_allowlisted' }; const timestamp = messageTimestamp(message.timestamp); if (!timestamp) return { eligible: false, reason: 'invalid_timestamp' }; // 使用持久化游标恢复停机期间的积压消息;不要再按本次进程启动时间丢弃。 return { eligible: true, content, senderId, timestamp, allowlisted, unknownContact: !allowlisted, intakeMode }; } module.exports = { PERSONAL_INTAKE_MODES, normalizePersonalIntakeMode, messageTimestamp, roomIdOf, isGroupMessage, messageContent, evaluatePolledMessage, };