// ========================================== // ๐Ÿฆ… TITAN NEXUS SERVER v14.1 - TIME-AWARE ROYAL AI EDITION // ๐Ÿ›ก๏ธ SENTINEL MK2 ACTIVE | โšก SOCKET.IO RELAY | ๐ŸŽ›๏ธ ADMIN COMMAND CENTER // ๐Ÿ‘‘ ROYAL IMMUNITY SYSTEM | ๐Ÿง  GEMMA 4 AI | ๐Ÿ•ฐ๏ธ TIME-AWARE ENGINE // ๐Ÿ“… AUTOMATED CONTENT GENERATION & ROYAL REPORTS // ๐Ÿงฉ ANTI-DUPLICATE RIDDLE SYSTEM (riddle_history collection) // ========================================== const admin = require("firebase-admin"); const express = require("express"); const helmet = require("helmet"); const cors = require("cors"); const natural = require("natural"); const http = require("http"); const { Server } = require("socket.io"); const os = require("os"); const cron = require("node-cron"); const { GoogleGenerativeAI } = require("@google/generative-ai"); const https = require("https"); const { pipeline } = require("stream"); const { promisify } = require("util"); const streamPipeline = promisify(pipeline); const initExtensions = require('./server-extensions'); // ๐Ÿช™ Wallet + new admin endpoints // 1. CORE CONFIGURATION const app = express(); app.set('trust proxy', 2); const PORT = process.env.PORT || 7860; // ========================================== // ๐Ÿ”‘ ENVIRONMENT VARIABLES โ€” Hugging Face Secrets // Required secrets in HF Space settings: // FIREBASE_SERVICE_ACCOUNT โ†’ full serviceAccountKey.json content (JSON string) // GEMINI_API_KEY โ†’ Gemini API key // GROQ_API_KEY โ†’ Groq API key // ADMIN_ID โ†’ Firebase UID of the admin user // ========================================== // Validate all required secrets on startup const REQUIRED_ENV = ['FIREBASE_SERVICE_ACCOUNT', 'GEMINI_API_KEY', 'GROQ_API_KEY', 'ADMIN_ID', 'TITAN_GATEWAY_KEY', 'TITAN_RELAY_KEY']; const missingEnv = REQUIRED_ENV.filter(k => !process.env[k]); if (missingEnv.length > 0) { console.error(`\x1b[31m[FATAL] Missing required environment variables: ${missingEnv.join(', ')}\x1b[0m`); console.error('\x1b[31m[FATAL] Set them in Hugging Face Space โ†’ Settings โ†’ Repository secrets\x1b[0m'); process.exit(1); } // ๐Ÿ”‘ SECURITY & AUTHENTICATION let SERVICE_ACCOUNT; try { SERVICE_ACCOUNT = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT); } catch (e) { console.error('\x1b[31m[FATAL] FIREBASE_SERVICE_ACCOUNT is not valid JSON. Paste the full serviceAccountKey.json content.\x1b[0m'); process.exit(1); } const ADMIN_ID = process.env.ADMIN_ID; // ๐Ÿ‘‘ ROYAL IMMUNITY SYSTEM const ROYAL_FAMILY = [ process.env.ADMIN_ID, "jcVOBGfUpkVnZOI8CQ0HRelRsed2" ]; // ๐Ÿง  GEMINI AI CONFIGURATION const GEMINI_API_KEY = process.env.GEMINI_API_KEY; const genAI = new GoogleGenerativeAI(GEMINI_API_KEY); const geminiModel = genAI.getGenerativeModel({ model: "gemini-2.5-flash-lite" }); // ๐Ÿ“ˆ GROQ โ€” for news/stocks only const GROQ_API_KEY = process.env.GROQ_API_KEY; const GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"; const GROQ_MARKET_MODEL = "compound-beta"; // ๐Ÿ“ง EMAIL via Resend API (works on HF Spaces โ€” no SMTP blocking) // ๐Ÿ“ง EMAIL via Google Apps Script Mailer Bridge // HF Secrets required: MAILER_URL, MAILER_TOKEN const MAILER_URL = process.env.MAILER_URL; const MAILER_TOKEN = process.env.MAILER_TOKEN; async function sendTitanEmail(to, subject, htmlBody) { if (!MAILER_URL) throw new Error('MAILER_URL not set in HF Secrets'); if (!MAILER_TOKEN) throw new Error('MAILER_TOKEN not set in HF Secrets'); const toStr = Array.isArray(to) ? to.join(',') : to; const payload = JSON.stringify({ token: MAILER_TOKEN, to: toStr, subject, htmlBody }); // Google Apps Script redirects POST to GET โ€” use native https to handle this return new Promise((resolve, reject) => { const url = new URL(MAILER_URL); const options = { hostname: url.hostname, path: url.pathname + url.search, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) } }; function makeRequest(reqOptions, body, redirectCount = 0) { if (redirectCount > 5) return reject(new Error('Too many redirects')); const req = https.request(reqOptions, (res) => { // Handle Google's redirect (302/301) if ((res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307) && res.headers.location) { const redirectUrl = new URL(res.headers.location); res.resume(); // drain response // Follow redirect โ€” for 302 use GET (standard behavior) const newOpts = { hostname: redirectUrl.hostname, path: redirectUrl.pathname + redirectUrl.search, method: res.statusCode === 307 ? reqOptions.method : 'GET', headers: { 'Content-Type': 'application/json' } }; return makeRequest(newOpts, res.statusCode === 307 ? body : null, redirectCount + 1); } let d = ''; res.on('data', c => d += c); res.on('end', () => { try { // Try JSON parse first const parsed = JSON.parse(d); if (parsed.status !== 'success') reject(new Error(parsed.message || 'Non-success status')); else resolve(parsed); } catch { // If we get HTML but status is 2xx, treat as success (Google sometimes returns HTML on success) if (res.statusCode >= 200 && res.statusCode < 300) { resolve({ status: 'success', note: 'HTML response treated as success' }); } else { reject(new Error(`Non-JSON response (${res.statusCode}): ${d.slice(0, 100)}`)); } } }); }); req.setTimeout(20000, () => { req.destroy(); reject(new Error('Mailer timeout')); }); req.on('error', reject); if (body) req.write(body); req.end(); } makeRequest(options, payload); }); } // Server start time for uptime calculation const SERVER_START_TIME = Date.now(); // 2. FIREBASE INIT if (!admin.apps.length) { admin.initializeApp({ credential: admin.credential.cert(SERVICE_ACCOUNT), databaseURL: `https://${SERVICE_ACCOUNT.project_id}.firebaseio.com` }); } const db = admin.firestore(); // 3. MIDDLEWARE (Security first) app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"], fontSrc: ["'self'", "https://fonts.gstatic.com"], scriptSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:"], connectSrc: ["'self'"] } }, crossOriginEmbedderPolicy: false, hsts: { maxAge: 31536000, includeSubDomains: true } })); app.use(cors({ origin: true, credentials: true })); app.use(express.json({ limit: '30mb' })); app.use(express.urlencoded({ extended: true, limit: '30mb' })); // 4. HELPER: CONSOLE-ONLY LOGGING (no Firestore writes) async function logSys(mod, msg, type = 'info') { const timestamp = new Date().toISOString().replace('T', ' ').substring(0, 19); const colors = { info: '\x1b[36m', success: '\x1b[32m', warning: '\x1b[33m', error: '\x1b[31m', system: '\x1b[35m', cyber: '\x1b[34m', royal: '\x1b[95m', ai: '\x1b[96m' }; const reset = '\x1b[0m'; const color = colors[type] || colors.info; console.log(`${color}[${timestamp}] [${mod}]${reset} ${msg}`); } // ๐Ÿ”’ UID MASKER โ€” hides Firebase UIDs in public logs (shows first 4 + last 4 chars) function maskUid(uid) { if (!uid || uid.length < 10) return '****'; return uid.substring(0, 4) + 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข' + uid.substring(uid.length - 4); } // 5. SENTIMENT ANALYSIS async function analyzeSentiment(text) { try { const analyzer = new natural.SentimentAnalyzer('English', natural.PorterStemmer, 'afinn'); const tokenizer = new natural.WordTokenizer(); const tokens = tokenizer.tokenize(text); const sentiment = analyzer.getSentiment(tokens); return { score: sentiment, category: sentiment > 0.5 ? 'positive' : sentiment < -0.5 ? 'negative' : 'neutral', confidence: Math.abs(sentiment) }; } catch (e) { return { score: 0, category: 'neutral', confidence: 0 }; } } // 6. SENTINEL MK2 WITH ROYAL IMMUNITY class SentinelMK2 { constructor() { this.bannedPatterns = [ /hack(er|ing)?\s*guide/i, /crack\s*software/i, /bypass\s*security/i, /ddos\s*tool/i, /virus\s*generator/i, /credit\s*card\s*generator/i ]; this.suspiciousKeywords = ['password', 'login', 'admin', 'root', 'exploit', 'vulnerability']; this.userReputation = new Map(); this.reportPenalties = { 'spam': -5, 'harassment': -15, 'fake_identity': -10, 'fake identity': -10 }; } async analyzeComment(comment) { const analysis = { riskLevel: 'low', flags: [], action: 'none', confidence: 0 }; this.bannedPatterns.forEach(pattern => { if (pattern.test(comment.text)) { analysis.flags.push('banned_pattern'); analysis.riskLevel = 'critical'; analysis.confidence += 0.7; } }); const links = (comment.text.match(/https?:\/\/[^\s]+/g) || []).length; if (links > 2) { analysis.flags.push('excessive_links'); analysis.riskLevel = Math.max(analysis.riskLevel, 'high'); analysis.confidence += 0.3; } const sentiment = await analyzeSentiment(comment.text); if (sentiment.category === 'negative' && sentiment.confidence > 0.6) { analysis.flags.push('negative_sentiment'); analysis.riskLevel = Math.max(analysis.riskLevel, 'medium'); analysis.confidence += 0.2; } const userRep = this.userReputation.get(comment.userId) || 0; if (userRep < -5) { analysis.flags.push('low_reputation_user'); analysis.riskLevel = 'high'; analysis.confidence += 0.4; } if (analysis.riskLevel === 'critical') { analysis.action = 'delete_ban'; } else if (analysis.riskLevel === 'high') { analysis.action = 'delete_warn'; } else if (analysis.riskLevel === 'medium') { analysis.action = 'flag_review'; } return analysis; } async monitorComments() { logSys('SENTINEL_MK2', '๐Ÿ›ก๏ธ Advanced comment monitoring activated', 'system'); db.collectionGroup('comments').onSnapshot(async (snapshot) => { snapshot.docChanges().forEach(async (change) => { if (change.type === 'added') { const comment = change.doc.data(); const commentId = change.doc.id; // ๐Ÿ‘‘ ROYAL IMMUNITY CHECK if (ROYAL_FAMILY.includes(comment.userId)) { logSys('SENTINEL_MK2', `๐Ÿ‘‘ Royal user ${maskUid(comment.userId)} - Immunity shield active`, 'royal'); return; } if (comment.userId === ADMIN_ID) return; const analysis = await this.analyzeComment(comment); if (analysis.action !== 'none') { await this.handleViolation(comment, commentId, analysis); } await this.updateUserReputation(comment.userId, analysis); } }); }, (error) => { logSys('SENTINEL_MK2', `โš ๏ธ Listener Error (Backoff/Connection): ${error.message}`, 'error'); }); } async monitorReports() { logSys('SENTINEL_MK2', 'โš–๏ธ Real-Time Report & Ban System activated', 'system'); db.collection('reports') .where('status', '==', 'pending') .onSnapshot(async (snapshot) => { snapshot.docChanges().forEach(async (change) => { if (change.type === 'added') { const report = change.doc.data(); const reportId = change.doc.id; // ๐Ÿ‘‘ ROYAL IMMUNITY CHECK if (ROYAL_FAMILY.includes(report.reportedUserId)) { logSys('SENTINEL_MK2', `๐Ÿ‘‘ Report rejected - Royal immunity for ${maskUid(report.reportedUserId)}`, 'royal'); await db.collection('reports').doc(reportId).update({ status: 'rejected', reviewedAt: admin.firestore.FieldValue.serverTimestamp(), rejection_reason: 'Immunity Shield - Royal Family member', processedBy: 'SENTINEL_MK2_ROYAL_GUARD' }); return; } await this.processReport(report, reportId); } }); }, (error) => { logSys('SENTINEL_MK2', `โš ๏ธ Report Listener Error (Backoff/Connection): ${error.message}`, 'error'); }); } async processReport(report, reportId) { try { logSys('SENTINEL_MK2', `โš–๏ธ Processing report ${reportId} for user ${maskUid(report.reportedUserId)}`, 'info'); const reportType = (report.reason || report.type || 'spam').toLowerCase(); const penalty = this.reportPenalties[reportType] || -5; let reputation = this.userReputation.get(report.reportedUserId) || 100; reputation += penalty; this.userReputation.set(report.reportedUserId, reputation); await db.collection('user_reputation').doc(report.reportedUserId).set({ userId: report.reportedUserId, score: reputation, updatedAt: admin.firestore.FieldValue.serverTimestamp(), lastPenalty: { amount: penalty, reason: reportType, reportId } }, { merge: true }); logSys('SENTINEL_MK2', `๐Ÿ“‰ User ${maskUid(report.reportedUserId)} reputation: ${reputation} (${penalty} penalty)`, 'warning'); let aiVerdict = `Reputation updated: ${reputation} points`; let actionsTaken = []; if (reputation <= 50 && reputation > 0) { await db.collection('users').doc(report.reportedUserId).set({ isShadowBanned: true, shadowBanReason: `Low reputation (${reputation}) from report ${reportId}`, shadowBannedAt: admin.firestore.FieldValue.serverTimestamp() }, { merge: true }); aiVerdict = `SHADOW BAN applied. User reputation: ${reputation}`; actionsTaken.push('shadow_ban'); logSys('SENTINEL_MK2', `๐Ÿ‘ค User ${maskUid(report.reportedUserId)} shadow banned (reputation: ${reputation})`, 'warning'); } if (reputation <= 0) { try { await admin.auth().revokeRefreshTokens(report.reportedUserId); await db.collection('users').doc(report.reportedUserId).set({ banned: true, bannedAt: admin.firestore.FieldValue.serverTimestamp(), banReason: `Automatic ban: Reputation dropped to ${reputation}`, bannedBy: 'SENTINEL_MK2_AUTOMOD', reportId }, { merge: true }); await db.collection('banned_users').doc(report.reportedUserId).set({ userId: report.reportedUserId, bannedAt: admin.firestore.FieldValue.serverTimestamp(), reason: 'automatic_ban_reputation', finalReputation: reputation, reportId, violations: [reportType] }); aiVerdict = `PERMABAN applied. Reputation dropped to ${reputation}. Firebase token revoked.`; actionsTaken.push('permaban', 'token_revoked'); logSys('SENTINEL_MK2', `๐Ÿšจ PERMABAN user ${maskUid(report.reportedUserId)} (reputation: ${reputation})`, 'error'); } catch (authError) { logSys('SENTINEL_MK2', `Failed to revoke tokens for ${maskUid(report.reportedUserId)}: ${authError.message}`, 'error'); } } await db.collection('reports').doc(reportId).update({ status: 'reviewed', reviewedAt: admin.firestore.FieldValue.serverTimestamp(), ai_verdict: aiVerdict, actions_taken: actionsTaken, reputation_after: reputation, penalty_applied: penalty, processedBy: 'SENTINEL_MK2_AUTOMOD' }); logSys('SENTINEL_MK2', `โœ… Report ${reportId} processed. Verdict: ${aiVerdict}`, 'success'); } catch (error) { logSys('SENTINEL_MK2', `โŒ Failed to process report ${reportId}: ${error.message}`, 'error'); await db.collection('reports').doc(reportId).update({ status: 'error', error: error.message, processedAt: admin.firestore.FieldValue.serverTimestamp() }); } } async handleViolation(comment, commentId, analysis) { const commentRef = db.collection('comments').doc(commentId); switch (analysis.action) { case 'delete_ban': await commentRef.delete(); await db.collection('banned_users').doc(comment.userId).set({ userId: comment.userId, bannedAt: admin.firestore.FieldValue.serverTimestamp(), reason: 'automatic_ban', violation: analysis.flags.join(', '), commentPreview: comment.text.substring(0, 100) }); logSys('SENTINEL_MK2', `๐Ÿšจ BANNED user ${maskUid(comment.userId)} for critical violation`, 'error'); break; case 'delete_warn': await commentRef.delete(); await db.collection('user_warnings').doc(`${comment.userId}_${Date.now()}`).set({ userId: comment.userId, warnedAt: admin.firestore.FieldValue.serverTimestamp(), reason: analysis.flags.join(', '), commentId, action: 'comment_deleted' }); logSys('SENTINEL_MK2', `โš ๏ธ Warned user ${maskUid(comment.userId)}`, 'warning'); break; case 'flag_review': await commentRef.update({ flagged: true, flagReason: analysis.flags.join(', ') }); logSys('SENTINEL_MK2', `๐Ÿšฉ Flagged comment for review`, 'warning'); break; } await db.collection('security_logs').add({ action: analysis.action, userId: comment.userId, commentId, analysis, timestamp: admin.firestore.FieldValue.serverTimestamp() }); } async updateUserReputation(userId, analysis) { let reputation = this.userReputation.get(userId) || 0; switch (analysis.action) { case 'delete_ban': reputation -= 10; break; case 'delete_warn': reputation -= 3; break; case 'flag_review': reputation -= 1; break; default: reputation += 1; } this.userReputation.set(userId, reputation); if (reputation < -5) { await db.collection('user_reputation').doc(userId).set({ userId, score: reputation, updatedAt: admin.firestore.FieldValue.serverTimestamp() }, { merge: true }); } } } // 7. JANITOR MK2 WITH ROYAL IMMUNITY class JanitorMK2 { constructor() { this.messageRetentionDays = 30; } async cleanOldMessages() { const cutoff = new Date(Date.now() - this.messageRetentionDays * 24 * 60 * 60 * 1000); try { const snapshot = await db.collection('titan_news') .where('timestamp', '<', cutoff) .get(); if (!snapshot.empty) { const batch = db.batch(); snapshot.docs.forEach(doc => { const data = doc.data(); // ๐Ÿ‘‘ ROYAL IMMUNITY: Skip deletion if message is from royal family if (data.userId && ROYAL_FAMILY.includes(data.userId)) { logSys('JANITOR_MK2', `๐Ÿ‘‘ Preserving royal message from ${maskUid(data.userId)}`, 'royal'); return; } batch.delete(doc.ref); }); await batch.commit(); logSys('JANITOR_MK2', `๐Ÿงน Deleted ${snapshot.size} old messages (older than ${this.messageRetentionDays} days)`, 'info'); } } catch (error) { logSys('JANITOR_MK2', `โŒ Cleanup error: ${error.message}`, 'error'); } } } // 8. ๐Ÿ•ฐ๏ธ TIME-AWARE AI CONTENT GENERATOR (v14.0 Engine) /** * Calculates the exact Gregorian date string (long format). */ function getGregorianDateString(date) { return date.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); } /** * Calculates the exact Hijri date string using the Umm al-Qura calendar * via the native Intl API โ€” no external libraries required. */ function getHijriDateString(date) { try { return new Intl.DateTimeFormat('en-US-u-ca-islamic-umalqura', { day: 'numeric', month: 'long', year: 'numeric' }).format(date); } catch (e) { // Fallback if the locale is not supported in this Node.js build return 'Hijri date unavailable'; } } /** * ๐Ÿงฉ DAILY RIDDLE GENERATOR (Lightweight & Interactive) * v14.1 โ€” Anti-duplicate system: tracks last 30 riddles in Firestore */ async function generateRiddleContent() { try { logSys('TIME_AWARE_AI', '๐Ÿงฉ Generating daily riddle...', 'ai'); const today = new Date(); const gregorianDate = getGregorianDateString(today); const hijriDate = getHijriDateString(today); // โœ… FIX: Fetch last 30 riddles to avoid repetition let recentRiddles = []; try { const recentSnap = await db.collection('riddle_history') .orderBy('timestamp', 'desc') .limit(30) .get(); recentRiddles = recentSnap.docs.map(d => d.data().riddleEn || ''); logSys('TIME_AWARE_AI', `๐Ÿ“š Loaded ${recentRiddles.length} past riddles for dedup check`, 'info'); } catch (e) { logSys('TIME_AWARE_AI', 'โš ๏ธ Could not load riddle history (continuing anyway)', 'warning'); } const avoidSection = recentRiddles.length > 0 ? `\n- DO NOT repeat or closely resemble any of these recent riddles:\n${recentRiddles.map((r, i) => ` ${i + 1}. "${r}"`).join('\n')}` : ''; const categories = ['nature', 'technology', 'food', 'animals', 'everyday objects', 'science', 'history', 'mathematics', 'human body', 'space']; const category = categories[Math.floor(Math.random() * categories.length)]; const prompt = `You are Titan Nexus AI. Create ONE original, clever riddle about "${category}". Rules: - Must be genuinely clever and creative โ€” not a common or well-known riddle - Suitable for all ages - Include the answer clearly at the end after " โ€” answer: " - Avoid ANY special characters that break JSON (no quotes, apostrophes inside strings) - Date context: ${gregorianDate} / ${hijriDate}${avoidSection} Reply with ONLY valid JSON, nothing else: {"riddle":{"en":"[Write a creative riddle about ${category}] โ€” answer: [the answer]","ar":"[ุงูƒุชุจ ูุฒูˆุฑุฉ ู…ุจุชูƒุฑุฉ ุนู† ${category}] โ€” ุงู„ุฅุฌุงุจุฉ: [ุงู„ุฌูˆุงุจ]"}}`.trim(); const result = await geminiModel.generateContent(prompt); const response = await result.response; let text = response.text().trim(); // Aggressively clean the response text = text .replace(/^```json\s*/i, '') .replace(/^```\s*/i, '') .replace(/```\s*$/i, '') // Normalize Arabic/smart quotes to standard ASCII quotes .replace(/[\u201C\u201D\u201E\u201F\u2033\u2036\u00AB\u00BB]/g, '"') .replace(/[\u2018\u2019\u201A\u201B\u2032\u2035]/g, "'") .trim(); // Find the outermost JSON object const start = text.indexOf('{'); const end = text.lastIndexOf('}'); if (start === -1 || end === -1) throw new Error(`No JSON object found in: ${text.substring(0, 120)}`); let jsonStr = text.slice(start, end + 1).replace(/[\x00-\x1F\x7F]/g, ' '); let content; try { content = JSON.parse(jsonStr); } catch (pe) { const enM = jsonStr.match(/"en"\s*:\s*"((?:[^"\\]|\\.)*)"/); const arM = jsonStr.match(/"ar"\s*:\s*"((?:[^"\\]|\\.)*)"/); if (enM && arM) content = { riddle: { en: enM[1], ar: arM[1] } }; else throw new Error(`JSON parse failed: ${pe.message}`); } if (!content.riddle || !content.riddle.en || !content.riddle.ar) { throw new Error('Invalid riddle format from AI'); } // โœ… FIX: Save new riddle to history to prevent future duplicates try { await db.collection('riddle_history').add({ riddleEn: content.riddle.en, riddleAr: content.riddle.ar, timestamp: admin.firestore.FieldValue.serverTimestamp(), gregorianDate, hijriDate }); logSys('TIME_AWARE_AI', `๐Ÿ’พ Riddle saved to history`, 'info'); } catch (e) { logSys('TIME_AWARE_AI', 'โš ๏ธ Could not save riddle to history', 'warning'); } logSys('TIME_AWARE_AI', `โœ… Riddle generated successfully.`, 'success'); return content; } catch (error) { logSys('TIME_AWARE_AI', `โŒ Riddle generation failed: ${error.message}`, 'error'); // โœ… FIX: Fallback pool of 10 varied riddles instead of 1 hardcoded const fallbackRiddles = [ { en: "I have cities, but no houses. Mountains, but no trees. Water, but no fish. What am I? (A map)", ar: "ู„ุฏูŠ ู…ุฏู† ุจู„ุง ู…ู†ุงุฒู„ุŒ ูˆุฌุจุงู„ ุจู„ุง ุฃุดุฌุงุฑุŒ ูˆู…ูŠุงู‡ ุจู„ุง ุฃุณู…ุงูƒ. ู…ู† ุฃู†ุงุŸ (ุงู„ุฎุฑูŠุทุฉ)" }, { en: "The more you take, the more you leave behind. What am I? (Footsteps)", ar: "ูƒู„ู…ุง ุฃุฎุฐุช ู…ู†ูŠ ุงุฒุฏุฏุช. ู…ุง ุฃู†ุงุŸ (ุงู„ุฎุทูˆุงุช)" }, { en: "I speak without a mouth and hear without ears. I have no body, but I come alive with wind. What am I? (An echo)", ar: "ุฃุชูƒู„ู… ุจู„ุง ูู… ูˆุฃุณู…ุน ุจู„ุง ุฃุฐู†ูŠู†. ู…ุง ุฃู†ุงุŸ (ุงู„ุตุฏู‰)" }, { en: "I can fly without wings. I can cry without eyes. Wherever I go, darkness flies. What am I? (A cloud)", ar: "ุฃุทูŠุฑ ุจู„ุง ุฃุฌู†ุญุฉ ูˆุฃุจูƒูŠ ุจู„ุง ุนูŠูˆู†. ู…ุง ุฃู†ุงุŸ (ุงู„ุณุญุงุจุฉ)" }, { en: "I run, but I have no legs. I have a mouth, but I never talk. What am I? (A river)", ar: "ุฃุฌุฑูŠ ูˆู„ุง ุฃู…ู„ูƒ ู‚ุฏู…ูŠู†ุŒ ูˆู„ุฏูŠ ูู… ู„ูƒู†ู†ูŠ ู„ุง ุฃุชูƒู„ู…. ู…ุง ุฃู†ุงุŸ (ุงู„ู†ู‡ุฑ)" }, { en: "What has hands but cannot clap? (A clock)", ar: "ู…ุง ุงู„ุฐูŠ ู„ู‡ ูŠุฏุงู† ู„ูƒู† ู„ุง ูŠุตูู‚ุŸ (ุงู„ุณุงุนุฉ)" }, { en: "I get shorter as I grow older. What am I? (A candle)", ar: "ุฃุตูŠุฑ ุฃู‚ุตุฑ ูƒู„ู…ุง ูƒุจุฑุช. ู…ุง ุฃู†ุงุŸ (ุงู„ุดู…ุนุฉ)" }, { en: "I have a neck but no head, and I wear a cap. What am I? (A bottle)", ar: "ู„ุฏูŠ ุนู†ู‚ ุจู„ุง ุฑุฃุณ ูˆุฃุฑุชุฏูŠ ุบุทุงุกู‹. ู…ุง ุฃู†ุงุŸ (ุงู„ุฒุฌุงุฌุฉ)" }, { en: "What can you catch but not throw? (A cold)", ar: "ู…ุงุฐุง ูŠู…ูƒู†ูƒ ุฃู† ุชู„ุชู‚ุท ู„ูƒู† ู„ุง ุชุฑู…ูŠุŸ (ู†ุฒู„ุฉ ุงู„ุจุฑุฏ)" }, { en: "I have teeth but cannot eat. What am I? (A comb)", ar: "ู„ุฏูŠ ุฃุณู†ุงู† ู„ูƒู†ู†ูŠ ู„ุง ุขูƒู„. ู…ุง ุฃู†ุงุŸ (ุงู„ู…ุดุท)" } ]; const pick = fallbackRiddles[Math.floor(Math.random() * fallbackRiddles.length)]; return { riddle: pick }; } } // 9. ROYAL REPORT GENERATOR async function generateRoyalReport(stats) { try { logSys('GEMINI_AI', '๐Ÿ‘‘ Generating royal report...', 'ai'); const prompt = `You are generating a professional daily report for the administrators of Titan Nexus platform. Server Statistics: - Uptime: ${stats.uptime} - Memory Usage: ${stats.memory.percentage} - Online Users: ${stats.connections.registered} - Total Connections: ${stats.connections.total} - Platform: ${stats.platform} - Sentinel Status: ${stats.sentinel} Generate a concise, professional summary report. Respond ONLY with valid JSON โ€” no markdown, no backticks, no extra text. Required format: {"en":"English summary (2-3 sentences, professional tone)","ar":"ู…ู„ุฎุต ุจุงู„ุนุฑุจูŠุฉ"} Make it sound like a human executive summary, not a robot report.`; const result = await geminiModel.generateContent(prompt); const response = await result.response; let text = response.text().trim(); text = text .replace(/```json\s*/gi, '').replace(/```\s*/gi, '') .replace(/[\u201C\u201D\u201E\u201F\u2033\u2036\u00AB\u00BB]/g, '"') .replace(/[\u2018\u2019\u201A\u201B\u2032\u2035]/g, "'") .trim(); const start = text.indexOf('{'); const end = text.lastIndexOf('}'); if (start === -1 || end === -1) throw new Error('No JSON object found in AI response'); let rJson = text.slice(start, end + 1).replace(/[\x00-\x1F\x7F]/g, ' '); let report; try { report = JSON.parse(rJson); } catch (pe) { const enM = rJson.match(/"en"\s*:\s*"((?:[^"\\]|\\.)*)"/); const arM = rJson.match(/"ar"\s*:\s*"((?:[^"\\]|\\.)*)"/); if (enM && arM) report = { en: enM[1], ar: arM[1] }; else throw new Error(`Parse failed: ${pe.message}`); } if (!report.en || !report.ar) throw new Error('Missing en/ar fields in report'); logSys('GEMINI_AI', 'โœ… Royal report generated successfully', 'success'); return report; } catch (error) { logSys('GEMINI_AI', `โŒ Failed to generate royal report: ${error.message}`, 'error'); return { en: `Daily Report: Server uptime ${stats.uptime}. ${stats.connections.registered} users online. All systems operational.`, ar: `ุชู‚ุฑูŠุฑ ูŠูˆู…ูŠ: ูˆู‚ุช ุชุดุบูŠู„ ุงู„ุฎุงุฏู… ${stats.uptime}. ${stats.connections.registered} ู…ุณุชุฎุฏู… ู…ุชุตู„. ุฌู…ูŠุน ุงู„ุฃู†ุธู…ุฉ ุชุนู…ู„.` }; } } // ========================================== // ๐Ÿ“ˆ MARKET INTELLIGENCE ENGINE v2 (Split Requests) // Request 1: Gold + FX | Request 2: Stocks + Oil + BTC // ========================================== async function groqFetch(userPrompt, maxTokens = 150) { const body = JSON.stringify({ model: GROQ_MARKET_MODEL, messages: [{ role: "user", content: userPrompt }], temperature: 0.1, max_tokens: maxTokens }); return new Promise((resolve, reject) => { const url = new URL(GROQ_API_URL); const req = https.request({ hostname: url.hostname, path: url.pathname, method: 'POST', headers: { 'Authorization': `Bearer ${GROQ_API_KEY}`, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) } }, (res) => { let d = ''; res.on('data', c => d += c); res.on('end', () => res.statusCode >= 200 && res.statusCode < 300 ? resolve(d) : reject(new Error(`${res.statusCode}: ${d.slice(0, 200)}`))); }); req.setTimeout(40000, () => { req.destroy(); reject(new Error('Timeout')); }); req.on('error', reject); req.write(body); req.end(); }); } function parseJSON(raw) { const parsed = JSON.parse(raw); let text = (parsed.choices?.[0]?.message?.content || '') .replace(/```json\s*/gi, '').replace(/```\s*/gi, '') .replace(/[\u201C\u201D\u00AB\u00BB]/g, '"') .replace(/[\x00-\x1F\x7F]/g, ' ').trim(); const s = text.indexOf('{'), e = text.lastIndexOf('}'); if (s === -1 || e === -1) throw new Error('No JSON'); return JSON.parse(text.slice(s, e + 1)); } async function fetchMarketData() { logSys('MARKET_AI', '๐Ÿ“ก Fetching market data...', 'ai'); const ozToGram = 0.0321507; let goldUsdOz = 0, usdEgp = 50.9, eurEgp = 55.0, gbpEgp = 64.0, sarEgp = 13.6; let stocks = {}; // โ”€โ”€ Step 1: Exchange rates โ”€โ”€ try { const raw = await new Promise((resolve, reject) => { const req = https.request({ hostname: 'open.er-api.com', path: '/v6/latest/USD', method: 'GET' }, (res) => { let d = ''; res.on('data', c => d += c); res.on('end', () => resolve(d)); }); req.setTimeout(8000, () => { req.destroy(); reject(new Error('Timeout')); }); req.on('error', reject); req.end(); }); const fx = JSON.parse(raw); if (fx.rates?.EGP) { usdEgp = fx.rates.EGP; eurEgp = usdEgp / fx.rates.EUR; gbpEgp = usdEgp / fx.rates.GBP; sarEgp = usdEgp / fx.rates.SAR; logSys('MARKET_AI', `โœ… FX: 1 USD = ${usdEgp.toFixed(2)} EGP`, 'success'); } } catch (e) { logSys('MARKET_AI', `โš ๏ธ FX: ${e.message.slice(0,50)}`, 'warning'); } // โ”€โ”€ Step 2: Gold spot โ€” try multiple free APIs โ”€โ”€ const goldAPIs = [ { host: 'api.gold-api.com', path: '/price/XAU' }, { host: 'api.metals.live', path: '/v1/spot/gold' }, { host: 'data.fixer.io', path: '/api/latest?access_key=free&symbols=XAU,USD' }, ]; for (const api of goldAPIs) { if (goldUsdOz > 0) break; try { const raw = await new Promise((resolve, reject) => { const req = https.request({ hostname: api.host, path: api.path, method: 'GET' }, (res) => { let d = ''; res.on('data', c => d += c); res.on('end', () => resolve(d)); }); req.setTimeout(7000, () => { req.destroy(); reject(new Error('Timeout')); }); req.on('error', reject); req.end(); }); const g = JSON.parse(raw); // Handle different API response formats const candidate = parseFloat( g.price || g.gold || g.XAU || (g.rates?.XAU ? 1 / g.rates.XAU : 0) || (Array.isArray(g) ? (g[0]?.price || Object.values(g[0])[0]) : 0) ) || 0; if (candidate > 1000 && candidate < 10000) { // sanity check: gold is between $1000-$10000/oz goldUsdOz = candidate; logSys('MARKET_AI', `โœ… Gold spot: $${goldUsdOz.toFixed(2)}/oz (${api.host})`, 'success'); } } catch (e) { logSys('MARKET_AI', `โš ๏ธ Gold API ${api.host}: ${e.message.slice(0,40)}`, 'warning'); } } // โ”€โ”€ Step 3: Stocks via Groq llama (no web search = no 413) โ”€โ”€ try { const body = JSON.stringify({ model: 'llama-3.3-70b-versatile', messages: [{ role: 'user', content: 'Give approximate current market values: S&P500 index, NASDAQ composite, Dow Jones, EGX30 Egypt stock exchange, Bitcoin USD price, Brent crude oil USD/barrel. Reply JSON only: {"sp":"","nq":"","dj":"","eg":"","bt":"","br":""}' }], temperature: 0.1, max_tokens: 100 }); const raw = await new Promise((resolve, reject) => { const url = new URL(GROQ_API_URL); const req = https.request({ hostname: url.hostname, path: url.pathname, method: 'POST', headers: { 'Authorization': `Bearer ${GROQ_API_KEY}`, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) } }, (res) => { let d = ''; res.on('data', c => d += c); res.on('end', () => res.statusCode < 300 ? resolve(d) : reject(new Error(`${res.statusCode}: ${d.slice(0,100)}`))); }); req.setTimeout(15000, () => { req.destroy(); reject(new Error('Timeout')); }); req.on('error', reject); req.write(body); req.end(); }); stocks = parseJSON(raw); logSys('MARKET_AI', `โœ… Stocks: SP500=${stocks.sp} BTC=${stocks.bt}`, 'success'); } catch (e) { logSys('MARKET_AI', `โš ๏ธ Stocks: ${e.message.slice(0,80)}`, 'warning'); } // โ”€โ”€ Calculate gold prices โ”€โ”€ // Egypt local market: ~6-8% premium over international price const localPremium = 1.07; const g24Egp = goldUsdOz ? Math.round(goldUsdOz * usdEgp * ozToGram * localPremium) : 0; const g21Egp = g24Egp ? Math.round(g24Egp * 21 / 24) : 0; const g18Egp = g24Egp ? Math.round(g24Egp * 18 / 24) : 0; const g21Sar = goldUsdOz ? Math.round(goldUsdOz * 3.75 * ozToGram * 21 / 24) : 0; const g24Aed = goldUsdOz ? Math.round(goldUsdOz * 3.674 * ozToGram) : 0; return { gold: { egypt_21k: g21Egp ? g21Egp.toString() : 'N/A', egypt_24k: g24Egp ? g24Egp.toString() : 'N/A', egypt_18k: g18Egp ? g18Egp.toString() : 'N/A', global_usd_oz: goldUsdOz ? goldUsdOz.toFixed(2) : 'N/A', saudi_21k: g21Sar ? g21Sar.toString() : 'N/A', uae_24k: g24Aed ? g24Aed.toString() : 'N/A', trend: 'stable', change_pct: 'N/A' }, markets: { sp500: { v: stocks.sp || 'N/A', c: 'N/A', t: 'โžก๏ธ' }, nasdaq: { v: stocks.nq || 'N/A', c: 'N/A', t: 'โžก๏ธ' }, dow: { v: stocks.dj || 'N/A', c: 'N/A', t: 'โžก๏ธ' }, egx30: { v: stocks.eg || 'N/A', c: 'N/A', t: 'โžก๏ธ' }, brent: { v: stocks.br || 'N/A', c: 'N/A', t: 'โžก๏ธ' }, btc: { v: stocks.bt || 'N/A', c: 'N/A', t: 'โžก๏ธ' } }, fx: { usd_egp: usdEgp.toFixed(2), eur_egp: eurEgp.toFixed(2), gbp_egp: gbpEgp.toFixed(2), sar_egp: sarEgp.toFixed(2) }, summary: { en: 'Market data updated.', ar: 'ุชู… ุชุญุฏูŠุซ ุจูŠุงู†ุงุช ุงู„ุณูˆู‚.' } }; } // ========================================== // ๐Ÿ•Œ PRAYER TIMES NOTIFICATION (Cairo, Egypt) // ========================================== async function broadcastPrayerTimes() { try { const today = new Date(); const day = today.getDate(), month = today.getMonth() + 1, year = today.getFullYear(); // Aladhan API - free, no key needed const prayerData = await new Promise((resolve, reject) => { const req = https.request({ hostname: 'api.aladhan.com', path: `/v1/timingsByCity/${day}-${month}-${year}?city=Cairo&country=Egypt&method=5`, method: 'GET' }, (res) => { let d = ''; res.on('data', c => d += c); res.on('end', () => resolve(JSON.parse(d))); }); req.setTimeout(10000, () => { req.destroy(); reject(new Error('Timeout')); }); req.on('error', reject); req.end(); }); const t = prayerData.data?.timings; if (!t) throw new Error('No timings data'); const dateStr = getGregorianDateString(today); const hijriStr = getHijriDateString(today); const body = `๐Ÿ•Œ ู…ูˆุงู‚ูŠุช ุงู„ุตู„ุงุฉ โ€” ุงู„ู‚ุงู‡ุฑุฉ ๐Ÿ“… ${dateStr} | ๐ŸŒ™ ${hijriStr} โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” ๐ŸŒ… ุงู„ูุฌุฑ: ${t.Fajr} ๐ŸŒ„ ุงู„ุดุฑูˆู‚: ${t.Sunrise} โ˜€๏ธ ุงู„ุธู‡ุฑ: ${t.Dhuhr} ๐ŸŒค๏ธ ุงู„ุนุตุฑ: ${t.Asr} ๐ŸŒ† ุงู„ู…ุบุฑุจ: ${t.Maghrib} ๐ŸŒ™ ุงู„ุนุดุงุก: ${t.Isha} โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” ุชู‚ุจู„ ุงู„ู„ู‡ ุทุงุนุชูƒู… ๐Ÿคฒ`; await db.collection('notifications').add({ title: `๐Ÿ•Œ ู…ูˆุงู‚ูŠุช ุงู„ุตู„ุงุฉ โ€” ${dateStr}`, body, type: 'PRAYER_TIMES', userId: 'BROADCAST', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); io.emit('prayer_times', { title: `๐Ÿ•Œ ู…ูˆุงู‚ูŠุช ุงู„ุตู„ุงุฉ`, body, timings: t }); logSys('PRAYER', 'โœ… Prayer times broadcast sent', 'success'); } catch (e) { logSys('PRAYER', `โŒ Prayer times failed: ${e.message}`, 'error'); } } // ========================================== // ๐Ÿ’ก DAILY QUOTE / MOTIVATION (Gemini) // ========================================== async function broadcastDailyQuote() { try { const today = new Date(); const dateStr = getGregorianDateString(today); const hijriStr = getHijriDateString(today); const hour = today.getHours(); const period = hour < 12 ? 'ุตุจุงุญูŠุฉ' : 'ู…ุณุงุฆูŠุฉ'; const result = await geminiModel.generateContent( `ุงูƒุชุจ ุชุญูŠุฉ ${period} ุฌู…ูŠู„ุฉ ูˆุญูƒู…ุฉ ุฅุณู„ุงู…ูŠุฉ ู…ู„ู‡ู…ุฉ. ุฃุฌุจ ุจู€ JSON ูู‚ุท (ุจุฏูˆู† ุฃูŠ ู†ุต ุฎุงุฑุฌู‡): {"g":"[ุงูƒุชุจ ุงู„ุชุญูŠุฉ ู‡ู†ุง]","q":"[ุงูƒุชุจ ุงู„ุญูƒู…ุฉ ู‡ู†ุง]","s":"[ุงูƒุชุจ ุงู„ู…ุตุฏุฑ ู‡ู†ุง]"}` ); let text = result.response.text().trim() .replace(/```json\s*/gi, '').replace(/```\s*/gi, '') .replace(/[\u201C\u201D\u00AB\u00BB]/g, '"') .replace(/[\x00-\x1F\x7F]/g, ' '); const s = text.indexOf('{'), e = text.lastIndexOf('}'); if (s === -1) throw new Error('No JSON'); let q; try { q = JSON.parse(text.slice(s, e + 1)); } catch (pe) { // Regex fallback const gM = text.match(/"g"\s*:\s*"((?:[^"\\]|\\.)*)"/); const qM = text.match(/"q"\s*:\s*"((?:[^"\\]|\\.)*)"/); const sM = text.match(/"s"\s*:\s*"((?:[^"\\]|\\.)*)"/); q = { g: gM?.[1] || '', q: qM?.[1] || '', s: sM?.[1] || '' }; } const icon = hour < 12 ? '๐ŸŒ…' : '๐ŸŒ†'; const title = hour < 12 ? '๐ŸŒ… ุตุจุงุญ ุงู„ุฎูŠุฑ' : '๐ŸŒ† ู…ุณุงุก ุงู„ุฎูŠุฑ'; const body = `${icon} ${q.g || ''}\n\nโœจ "${q.q || ''}"\nโ€” ${q.s || ''}\n\n๐Ÿ“… ${dateStr} | ๐ŸŒ™ ${hijriStr}`; await db.collection('notifications').add({ title, body, type: 'DAILY_QUOTE', userId: 'BROADCAST', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); io.emit('daily_quote', { title, body }); logSys('QUOTE', 'โœ… Daily quote broadcast sent', 'success'); } catch (e) { logSys('QUOTE', `โŒ Daily quote failed: ${e.message}`, 'error'); } } // ========================================== // ๐Ÿ“ฐ ARABIC NEWS SUMMARY (Groq) // ========================================== async function broadcastArabicNews() { try { const dateStr = getGregorianDateString(new Date()); // Very short prompt to avoid 413 const raw = await groqFetch( `Top 3 Arab world news today. JSON: {"n":[{"t":"headline","s":"summary"},{"t":"","s":""},{"t":"","s":""}]}`, 250 ); const parsed = parseJSON(raw); const news = parsed.n || parsed.news || []; if (!news.length) throw new Error('No news items'); const icons = ['1๏ธโƒฃ','2๏ธโƒฃ','3๏ธโƒฃ']; const body = `๐Ÿ“ฐ ุฃุจุฑุฒ ุงู„ุฃุฎุจุงุฑ โ€” ${dateStr}\nโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\n` + news.slice(0, 3).map((n, i) => `${icons[i]} ${n.t || n.title || ''}\n ${n.s || n.summary || ''}`).join('\n\n') + '\nโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\nTitan Nexus News'; await db.collection('notifications').add({ title: `๐Ÿ“ฐ ุฃุฎุจุงุฑ ุงู„ูŠูˆู… โ€” ${dateStr}`, body, type: 'NEWS_SUMMARY', userId: 'BROADCAST', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); io.emit('news_update', { title: `๐Ÿ“ฐ ุฃุฎุจุงุฑ ุงู„ูŠูˆู…`, body }); logSys('NEWS', 'โœ… Arabic news broadcast sent', 'success'); } catch (e) { logSys('NEWS', `โŒ News broadcast failed: ${e.message}`, 'error'); } } function formatMarketNotification(data, dateStr, hijriStr, timeStr) { const g = data.gold || {}; const m = data.markets || {}; const c = data.fx || {}; const ti = (t) => t === 'up' ? '๐Ÿ“ˆ' : t === 'down' ? '๐Ÿ“‰' : 'โžก๏ธ'; const mRow = (label, obj) => `${label}: ${obj?.v || 'N/A'}`; const bodyEn = ` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿ“ˆ TITAN NEXUS MARKET REPORT โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ๐Ÿ“… ${dateStr} ๐ŸŒ™ ${hijriStr} โฐ ${timeStr} ๐Ÿฅ‡ โ•โ• GOLD PRICES โ•โ• ๐Ÿ‡ช๐Ÿ‡ฌ Egypt 21K โ€บ ${g.egypt_21k || 'N/A'} EGP/g ๐Ÿ‡ช๐Ÿ‡ฌ Egypt 24K โ€บ ${g.egypt_24k || 'N/A'} EGP/g ๐Ÿ‡ช๐Ÿ‡ฌ Egypt 18K โ€บ ${g.egypt_18k || 'N/A'} EGP/g ๐ŸŒ Global โ€บ $${g.global_usd_oz || 'N/A'} USD/oz ๐Ÿ‡ธ๐Ÿ‡ฆ Saudi 21K โ€บ ${g.saudi_21k || 'N/A'} SAR/g ๐Ÿ‡ฆ๐Ÿ‡ช UAE 24K โ€บ ${g.uae_24k || 'N/A'} AED/g ๐Ÿ“Š โ•โ• GLOBAL MARKETS โ•โ• ๐Ÿ‡บ๐Ÿ‡ธ S&P 500 โ€บ ${m.sp500?.v || 'N/A'} ๐Ÿ‡บ๐Ÿ‡ธ NASDAQ โ€บ ${m.nasdaq?.v || 'N/A'} ๐Ÿ‡บ๐Ÿ‡ธ Dow Jones โ€บ ${m.dow?.v || 'N/A'} ๐Ÿ‡ช๐Ÿ‡ฌ EGX 30 โ€บ ${m.egx30?.v || 'N/A'} ๐Ÿ›ข๏ธ Brent Oil โ€บ ${m.brent?.v || 'N/A'} USD/bbl โ‚ฟ Bitcoin โ€บ $${m.btc?.v || 'N/A'} ๐Ÿ’ฑ โ•โ• EXCHANGE RATES โ•โ• ๐Ÿ’ต USD โ€บ ${c.usd_egp || 'N/A'} EGP ๐Ÿ’ถ EUR โ€บ ${c.eur_egp || 'N/A'} EGP ๐Ÿ’ท GBP โ€บ ${c.gbp_egp || 'N/A'} EGP ๐Ÿ‡ธ๐Ÿ‡ฆ SAR โ€บ ${c.sar_egp || 'N/A'} EGP โšก Titan Nexus Market Intelligence `.trim(); const bodyAr = ` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿ“ˆ ุชู‚ุฑูŠุฑ ุงู„ุณูˆู‚ ุงู„ูŠูˆู…ูŠ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ๐Ÿ“… ${dateStr} ๐ŸŒ™ ${hijriStr} โฐ ${timeStr} ๐Ÿฅ‡ โ•โ• ุฃุณุนุงุฑ ุงู„ุฐู‡ุจ โ•โ• ๐Ÿ‡ช๐Ÿ‡ฌ ู…ุตุฑ ุนูŠุงุฑ 21 โ€บ ${g.egypt_21k || 'N/A'} ุฌู†ูŠู‡/ุฌุฑุงู… ๐Ÿ‡ช๐Ÿ‡ฌ ู…ุตุฑ ุนูŠุงุฑ 24 โ€บ ${g.egypt_24k || 'N/A'} ุฌู†ูŠู‡/ุฌุฑุงู… ๐Ÿ‡ช๐Ÿ‡ฌ ู…ุตุฑ ุนูŠุงุฑ 18 โ€บ ${g.egypt_18k || 'N/A'} ุฌู†ูŠู‡/ุฌุฑุงู… ๐ŸŒ ุนุงู„ู…ูŠ โ€บ $${g.global_usd_oz || 'N/A'} ุฏูˆู„ุงุฑ/ุฃูˆู‚ูŠุฉ ๐Ÿ‡ธ๐Ÿ‡ฆ ุงู„ุณุนูˆุฏูŠุฉ 21 โ€บ ${g.saudi_21k || 'N/A'} ุฑูŠุงู„/ุฌุฑุงู… ๐Ÿ‡ฆ๐Ÿ‡ช ุงู„ุฅู…ุงุฑุงุช 24 โ€บ ${g.uae_24k || 'N/A'} ุฏุฑู‡ู…/ุฌุฑุงู… ๐Ÿ“Š โ•โ• ุงู„ุฃุณูˆุงู‚ ุงู„ุนุงู„ู…ูŠุฉ โ•โ• ๐Ÿ‡บ๐Ÿ‡ธ S&P 500 โ€บ ${m.sp500?.v || 'N/A'} ๐Ÿ‡บ๐Ÿ‡ธ NASDAQ โ€บ ${m.nasdaq?.v || 'N/A'} ๐Ÿ‡บ๐Ÿ‡ธ ุฏุงูˆ ุฌูˆู†ุฒ โ€บ ${m.dow?.v || 'N/A'} ๐Ÿ‡ช๐Ÿ‡ฌ EGX 30 โ€บ ${m.egx30?.v || 'N/A'} ๐Ÿ›ข๏ธ ุจุฑู†ุช โ€บ ${m.brent?.v || 'N/A'} ุฏูˆู„ุงุฑ/ุจุฑู…ูŠู„ โ‚ฟ ุจูŠุชูƒูˆูŠู† โ€บ $${m.btc?.v || 'N/A'} ๐Ÿ’ฑ โ•โ• ุฃุณุนุงุฑ ุงู„ุตุฑู โ•โ• ๐Ÿ’ต ุฏูˆู„ุงุฑ โ€บ ${c.usd_egp || 'N/A'} ุฌู†ูŠู‡ ๐Ÿ’ถ ูŠูˆุฑูˆ โ€บ ${c.eur_egp || 'N/A'} ุฌู†ูŠู‡ ๐Ÿ’ท ุฅุณุชุฑู„ูŠู†ูŠ โ€บ ${c.gbp_egp || 'N/A'} ุฌู†ูŠู‡ ๐Ÿ‡ธ๐Ÿ‡ฆ ุฑูŠุงู„ โ€บ ${c.sar_egp || 'N/A'} ุฌู†ูŠู‡ โšก Titan Nexus Market Intelligence `.trim(); return { bodyEn, bodyAr }; } /** * Main function: fetch + format + broadcast market notification */ async function broadcastMarketUpdate() { logSys('MARKET_AI', '๐ŸŒ… Starting morning market broadcast...', 'system'); const today = new Date(); const dateStr = getGregorianDateString(today); const hijriStr = getHijriDateString(today); const timeStr = today.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); // Retry up to 3 times on failure, respecting 429 retry-after let data = null; for (let attempt = 1; attempt <= 3; attempt++) { data = await fetchMarketData(); if (data) break; if (attempt < 3) { // On 429 rate limit, wait longer (30s), otherwise 10s const waitMs = attempt === 1 ? 30000 : 60000; logSys('MARKET_AI', `โณ Waiting ${waitMs/1000}s before retry ${attempt + 1}...`, 'warning'); await new Promise(r => setTimeout(r, waitMs)); } } if (!data) { logSys('MARKET_AI', 'โŒ All attempts failed. Skipping market broadcast.', 'error'); return; } const { bodyEn, bodyAr } = formatMarketNotification(data, dateStr, hijriStr, timeStr); // Save to Firestore as broadcast notification await db.collection('notifications').add({ title: `๐Ÿ“ˆ ุชู‚ุฑูŠุฑ ุงู„ุณูˆู‚ ุงู„ูŠูˆู…ูŠ โ€” ${dateStr}`, titleEn: `๐Ÿ“ˆ Daily Market Report โ€” ${dateStr}`, body: bodyEn, bodyAr: bodyAr, type: 'MARKET_REPORT', userId: 'BROADCAST', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false, marketData: data, meta: { gregorianDate: dateStr, hijriDate: hijriStr, fetchedAt: timeStr, engine: 'GROQ_COMPOUND_MARKET_v1' } }); // Real-time push via Socket.IO to all connected clients io.emit('market_update', { title: `๐Ÿ“ˆ Daily Market Report โ€” ${dateStr}`, bodyEn, bodyAr, marketData: data, timestamp: new Date().toISOString() }); logSys('MARKET_AI', `โœ… Market report broadcast to ${io.sockets.sockets.size} connections`, 'success'); } // 10. ๐Ÿ“… CRON JOBS (v14.0 โ€” Lightweight Riddle Edition) function initCronJobs() { // โณ Every 6 hours โ€” Send a riddle only (lightweight, interactive) cron.schedule('0 */6 * * *', async () => { logSys('CRON', 'โณ 6-Hour cycle triggered โ€” Generating daily riddle...', 'system'); try { const content = await generateRiddleContent(); const riddleEn = content.riddle.en; const riddleAr = content.riddle.ar; // Save to Firestore notifications collection await db.collection('notifications').add({ title: `๐Ÿงฉ ูุฒูˆุฑุฉ Titan Nexus ุงู„ูŠูˆู…ูŠุฉ`, body: riddleEn, bodyAr: riddleAr, type: 'DAILY_RIDDLE', userId: 'BROADCAST', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false, meta: { gregorianDate: getGregorianDateString(new Date()), hijriDate: getHijriDateString(new Date()), engine: 'TIME_AWARE_v14_RIDDLE' } }); logSys('CRON', `โœ… Daily riddle broadcast sent.`, 'success'); } catch (error) { logSys('CRON', `โŒ 6-Hour riddle broadcast failed: ${error.message}`, 'error'); } }); // ๐ŸŒ™ Night Royal Report (11:59 PM daily) cron.schedule('59 23 * * *', async () => { logSys('CRON', '๐ŸŒ™ Royal report generation initiated', 'system'); try { const stats = getServerStats(); const report = await generateRoyalReport(stats); // Send to each royal family member for (const royalId of ROYAL_FAMILY) { await db.collection('notifications').add({ title: '๐Ÿ‘‘ Daily Royal Report', body: report.en, bodyAr: report.ar, type: 'ROYAL_REPORT', userId: royalId, timestamp: admin.firestore.FieldValue.serverTimestamp(), stats: stats }); logSys('CRON', `๐Ÿ‘‘ Royal report sent to ${royalId}`, 'royal'); } logSys('CRON', 'โœ… Royal reports sent to all family members', 'success'); } catch (error) { logSys('CRON', `โŒ Royal report failed: ${error.message}`, 'error'); } }); logSys('CRON', '๐Ÿ“… Automated schedules initialized (6h riddle + 11:59 PM royal report)', 'success'); // ๐ŸŒ… Morning Market Report โ€” 8:00 AM cron.schedule('0 8 * * *', async () => { logSys('CRON', '๐ŸŒ… Morning market broadcast triggered (08:00)', 'system'); try { await broadcastMarketUpdate(); } catch (e) { logSys('CRON', `โŒ Market: ${e.message}`, 'error'); } }); // ๐Ÿ”” Afternoon Market Update โ€” 3:00 PM cron.schedule('0 15 * * *', async () => { logSys('CRON', '๐Ÿ”” Afternoon market update triggered (15:00)', 'system'); try { await broadcastMarketUpdate(); } catch (e) { logSys('CRON', `โŒ Market: ${e.message}`, 'error'); } }); // ๐Ÿ•Œ Prayer Times โ€” 1:00 AM Cairo time (UTC+2) = 23:00 UTC previous day // If server runs on UTC: use '0 23 * * *' // If server runs on Cairo time: use '0 1 * * *' cron.schedule('0 1 * * *', async () => { logSys('CRON', '๐Ÿ•Œ Prayer times broadcast triggered (01:00 Cairo)', 'system'); try { await broadcastPrayerTimes(); } catch (e) { logSys('CRON', `โŒ Prayer: ${e.message}`, 'error'); } }); // ๐ŸŒ… Morning Quote โ€” Every day at 7:00 AM cron.schedule('0 7 * * *', async () => { logSys('CRON', '๐Ÿ’ก Morning quote triggered (07:00)', 'system'); try { await broadcastDailyQuote(); } catch (e) { logSys('CRON', `โŒ Quote: ${e.message}`, 'error'); } }); // ๐ŸŒ† Evening Quote โ€” Every day at 6:00 PM cron.schedule('0 18 * * *', async () => { logSys('CRON', '๐Ÿ’ก Evening quote triggered (18:00)', 'system'); try { await broadcastDailyQuote(); } catch (e) { logSys('CRON', `โŒ Quote: ${e.message}`, 'error'); } }); // ๐Ÿ“ฐ Arabic News โ€” Every day at 10:00 AM cron.schedule('0 10 * * *', async () => { logSys('CRON', '๐Ÿ“ฐ Arabic news broadcast triggered (10:00)', 'system'); try { await broadcastArabicNews(); } catch (e) { logSys('CRON', `โŒ News: ${e.message}`, 'error'); } }); } // ๐Ÿ† GAME MASTER โ€” Titan Gravity Top Players (Daily at 10:00 PM) cron.schedule('0 22 * * *', async () => { logSys('GAME_MASTER', '๐Ÿ† Calculating Titan Gravity top players...', 'system'); try { const snapshot = await db.collection('titan_ghosts') .orderBy('arcade_points', 'desc') .limit(3) .get(); if (snapshot.empty) { logSys('GAME_MASTER', 'โš ๏ธ No players found in rankings.', 'warning'); return; } const medals = ['๐Ÿฅ‡', '๐Ÿฅˆ', '๐Ÿฅ‰']; const titles = ['ุณูŠุฏ ุงู„ุฌุงุฐุจูŠุฉ (ุงู„ู…ุฑูƒุฒ ุงู„ุฃูˆู„)', 'ุงู„ูˆุตูŠู (ุงู„ู…ุฑูƒุฒ ุงู„ุซุงู†ูŠ)', 'ุงู„ู…ุญุงุฑุจ (ุงู„ู…ุฑูƒุฒ ุงู„ุซุงู„ุซ)']; const bonusPoints = [100, 50, 25]; const batch = db.batch(); let rank = 0; snapshot.forEach(doc => { const userId = doc.id; const userData = doc.data(); const currentPoints = userData.arcade_points || 0; if (currentPoints === 0) return; const msgEn = `Congratulations Champion! ๐Ÿฅณ\nYou achieved rank #${rank + 1} in Titan Gravity with ${currentPoints} points.\nReward: +${bonusPoints[rank]} Bonus Points!`; const msgAr = `ู…ุจุฑูˆูƒ ูŠุง ุจุทู„! ๐Ÿฅณ\nู„ู‚ุฏ ุญู‚ู‚ุช ${medals[rank]} ${titles[rank]} ููŠ ู„ุนุจุฉ Titan Gravity ุจุฑุตูŠุฏ ${currentPoints} ู†ู‚ุทุฉ.\nุงู„ุฌุงุฆุฒุฉ: +${bonusPoints[rank]} ู†ู‚ุทุฉ ุฅุถุงููŠุฉ!`; const notifRef = db.collection('notifications').doc(); batch.set(notifRef, { title: `${medals[rank]} ุชูƒุฑูŠู… ุงู„ุฃูˆุงุฆู„`, body: msgEn, bodyAr: msgAr, type: 'GAME_AWARD', userId: userId, timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false, rank: rank + 1 }); const userRef = db.collection('titan_ghosts').doc(userId); batch.update(userRef, { arcade_points: admin.firestore.FieldValue.increment(bonusPoints[rank]) }); logSys('GAME_MASTER', `๐Ÿ† Award sent to Rank #${rank + 1}: ${maskUid(userId)} (${currentPoints} pts)`, 'success'); rank++; }); await batch.commit(); logSys('GAME_MASTER', 'โœ… Top 3 players awarded & bonuses added.', 'success'); } catch (error) { logSys('GAME_MASTER', `โŒ Failed to award players: ${error.message}`, 'error'); } }); // 11. SOCKET.IO REAL-TIME RELAY const server = http.createServer(app); const io = new Server(server, { cors: { origin: "*", methods: ["GET", "POST"] } }); const onlineUsers = new Map(); async function sendPushNotification(targetId, payload) { try { if (!targetId || !payload) return; const userDoc = await db.collection('users').doc(targetId).get(); const fcmToken = userDoc.exists ? userDoc.data().fcmToken : null; if (!fcmToken) { logSys('PUSH', `No FCM token for user ${targetId}`, 'warning'); return; } const message = { token: fcmToken, notification: { title: payload.title || 'New message', body: payload.body || payload.msg || '' }, data: payload.data || {} }; await admin.messaging().send(message); logSys('PUSH', `๐Ÿ“ฒ Push sent to user ${targetId}`, 'success'); } catch (error) { logSys('PUSH', `โŒ Failed to send push to ${targetId}: ${error.message}`, 'error'); } } // 12. HELPER: Get Server Statistics function getServerStats() { const uptimeMs = Date.now() - SERVER_START_TIME; const uptimeHours = Math.floor(uptimeMs / (1000 * 60 * 60)); const uptimeMinutes = Math.floor((uptimeMs % (1000 * 60 * 60)) / (1000 * 60)); const memUsage = process.memoryUsage(); const heapUsedMB = (memUsage.heapUsed / 1024 / 1024).toFixed(2); const heapTotalMB = (memUsage.heapTotal / 1024 / 1024).toFixed(2); const cpuLoad = os.loadavg(); const totalSocketConnections = io.sockets.sockets.size; return { uptime: `${uptimeHours}h ${uptimeMinutes}m`, uptimeMs, memory: { heapUsed: `${heapUsedMB} MB`, heapTotal: `${heapTotalMB} MB`, percentage: ((memUsage.heapUsed / memUsage.heapTotal) * 100).toFixed(1) + '%' }, connections: { registered: onlineUsers.size, total: totalSocketConnections }, cpuLoad: { '1min': cpuLoad[0].toFixed(2), '5min': cpuLoad[1].toFixed(2), '15min': cpuLoad[2].toFixed(2) }, sentinel: 'Active', platform: os.platform(), nodeVersion: process.version }; } // 13. FIRESTORE DEAD DROP COMMAND SYSTEM async function writeBlackboxResponse(message, level = 'SUCCESS', data = null) { try { await db.collection('titan_blackbox').add({ type: 'CMD_RES', message, level, data, ts: admin.firestore.FieldValue.serverTimestamp() }); logSys('BLACKBOX', `๐Ÿ“ Response written: ${message}`, 'info'); } catch (error) { logSys('BLACKBOX', `โŒ Failed to write response: ${error.message}`, 'error'); } } // ========================================== // ๐Ÿงน SWEEPER โ€” Orphaned Data Cleanup Engine // Paginates all Firebase Auth users, cross-references // titan_ghosts, then batch-deletes orphaned records // across 5 collections in safe โ‰ค450-op chunks. // ========================================== async function sweepOrphanedData() { logSys('SWEEPER', '๐Ÿ” Starting orphaned data sweep...', 'system'); // โ”€โ”€ Step 1: Build the full valid-UID Set from Firebase Auth โ”€โ”€ const validUids = new Set(); let pageToken; try { do { const listResult = await admin.auth().listUsers(1000, pageToken); listResult.users.forEach(userRecord => validUids.add(userRecord.uid)); pageToken = listResult.pageToken; } while (pageToken); logSys('SWEEPER', `โœ… Loaded ${validUids.size} valid UIDs from Firebase Auth`, 'info'); } catch (e) { logSys('SWEEPER', `โŒ Failed to list Auth users: ${e.message}`, 'error'); throw new Error(`Auth pagination failed: ${e.message}`); } // โ”€โ”€ Step 2: Fetch titan_ghosts as the source-of-truth roster โ”€โ”€ let ghostsSnapshot; try { ghostsSnapshot = await db.collection('titan_ghosts').get(); logSys('SWEEPER', `๐Ÿ“‹ Fetched ${ghostsSnapshot.size} docs from titan_ghosts`, 'info'); } catch (e) { logSys('SWEEPER', `โŒ Failed to fetch titan_ghosts: ${e.message}`, 'error'); throw new Error(`Firestore read failed: ${e.message}`); } // โ”€โ”€ Step 3: Identify orphaned UIDs โ”€โ”€ const orphanedUids = []; ghostsSnapshot.forEach(doc => { if (!validUids.has(doc.id)) { orphanedUids.push(doc.id); } }); if (orphanedUids.length === 0) { logSys('SWEEPER', 'โœ… No orphaned records found. Database is clean.', 'success'); return { success: true, message: 'No orphaned records found. Database is clean.', orphansFound: 0, docsDeleted: 0 }; } logSys('SWEEPER', `โš ๏ธ Found ${orphanedUids.length} orphaned UID(s) โ€” beginning batch delete`, 'warning'); // โ”€โ”€ Step 4: Batch-delete across 5 collections with chunk safety โ”€โ”€ // Firestore hard limit: 500 ops/batch. We commit at 450 to stay well clear. const COLLECTIONS = ['titan_ghosts', 'titan_keys', 'users', 'user_reputation', 'welcome_sent']; const CHUNK_LIMIT = 450; let currentBatch = db.batch(); let opsInCurrentBatch = 0; let totalDocsDeleted = 0; let batchesCommitted = 0; try { for (const uid of orphanedUids) { for (const collectionName of COLLECTIONS) { const docRef = db.collection(collectionName).doc(uid); currentBatch.delete(docRef); opsInCurrentBatch++; totalDocsDeleted++; // Commit and start a fresh batch before hitting the 500-op wall if (opsInCurrentBatch >= CHUNK_LIMIT) { await currentBatch.commit(); batchesCommitted++; logSys('SWEEPER', `๐Ÿ“ฆ Committed batch #${batchesCommitted} (${opsInCurrentBatch} ops)`, 'info'); currentBatch = db.batch(); opsInCurrentBatch = 0; } } } // Commit any remaining operations in the final partial batch if (opsInCurrentBatch > 0) { await currentBatch.commit(); batchesCommitted++; logSys('SWEEPER', `๐Ÿ“ฆ Committed final batch #${batchesCommitted} (${opsInCurrentBatch} ops)`, 'info'); } } catch (e) { logSys('SWEEPER', `โŒ Batch delete failed: ${e.message}`, 'error'); throw new Error(`Batch delete failed: ${e.message}`); } const report = { success: true, message: `Sweep complete. Removed ${orphanedUids.length} orphaned user(s).`, orphansFound: orphanedUids.length, docsDeleted: totalDocsDeleted, batchesCommitted, collectionsSwept: COLLECTIONS, orphanedUids: orphanedUids.map(uid => maskUid(uid)) // masked for safe logging }; logSys('SWEEPER', `โœ… Sweep complete โ€” ${orphanedUids.length} orphans, ${totalDocsDeleted} docs deleted across ${batchesCommitted} batch(es)`, 'success'); return report; } async function processAdminCommand(docId, commandData) { try { const { adminKey, command } = commandData; if (adminKey !== ADMIN_ID) { await writeBlackboxResponse('Access denied. Invalid admin credentials.', 'HIGH'); logSys('DEAD_DROP', `โŒ Unauthorized access attempt (docId: ${docId})`, 'error'); return; } logSys('DEAD_DROP', `๐ŸŽ›๏ธ Processing command: ${command}`, 'system'); const parts = command.trim().split(/\s+/); const cmd = parts[0].toLowerCase(); const args = parts.slice(1); switch (cmd) { case '/stats': { const stats = getServerStats(); const report = ` โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ•‘ ๐ŸŽ›๏ธ TITAN NEXUS SERVER STATISTICS โ•‘ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โฑ๏ธ UPTIME: ${stats.uptime} ๐Ÿ’พ MEMORY USAGE: โ€ข Heap Used: ${stats.memory.heapUsed} โ€ข Heap Total: ${stats.memory.heapTotal} โ€ข Usage: ${stats.memory.percentage} ๐Ÿ”Œ CONNECTIONS: โ€ข Registered Users: ${stats.connections.registered} โ€ข Total Sockets: ${stats.connections.total} โš™๏ธ SYSTEM LOAD (CPU): โ€ข 1 min: ${stats.cpuLoad['1min']} โ€ข 5 min: ${stats.cpuLoad['5min']} โ€ข 15 min: ${stats.cpuLoad['15min']} ๐Ÿ›ก๏ธ SECURITY: โ€ข Sentinel MK2: ${stats.sentinel} ๐Ÿ‘‘ ROYAL FAMILY: โ€ข Protected Members: ${ROYAL_FAMILY.length} ๐Ÿ–ฅ๏ธ PLATFORM: โ€ข OS: ${stats.platform} โ€ข Node: ${stats.nodeVersion} ๐Ÿ•ฐ๏ธ TIME-AWARE ENGINE: โ€ข Gregorian: ${getGregorianDateString(new Date())} โ€ข Hijri: ${getHijriDateString(new Date())} Generated: ${new Date().toISOString()} `.trim(); await writeBlackboxResponse('Server statistics generated', 'SYSTEM', { report, stats }); logSys('DEAD_DROP', '๐Ÿ“Š Stats report generated and written to blackbox', 'success'); break; } case '/notify': { if (args.length < 2) { await writeBlackboxResponse('Usage: /notify [uid] [message]', 'HIGH'); break; } const targetUid = args[0]; const message = args.slice(1).join(' '); await db.collection('notifications').add({ userId: targetUid, message, sentBy: 'ADMIN_SYSTEM', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); const targetSocketId = onlineUsers.get(targetUid); if (targetSocketId) { io.to(targetSocketId).emit('admin_notification', { message, timestamp: new Date().toISOString() }); } await sendPushNotification(targetUid, { title: 'Admin Notification', body: message, data: { type: 'admin_notification' } }); await writeBlackboxResponse( `Notification sent to user ${targetUid}`, 'SUCCESS', { online: !!targetSocketId, pushSent: true } ); logSys('DEAD_DROP', `๐Ÿ“ฌ Notification sent to ${maskUid(targetUid)}`, 'success'); break; } case '/ban': { if (args.length < 2) { await writeBlackboxResponse('Usage: /ban [uid] [reason]', 'HIGH'); break; } const targetUid = args[0]; const reason = args.slice(1).join(' '); // ๐Ÿ‘‘ ROYAL IMMUNITY CHECK if (ROYAL_FAMILY.includes(targetUid)) { await writeBlackboxResponse( `Cannot ban user ${targetUid} - Royal Immunity Shield`, 'HIGH', { royalProtection: true } ); logSys('DEAD_DROP', `๐Ÿ‘‘ Ban attempt blocked - Royal immunity for ${maskUid(targetUid)}`, 'royal'); break; } await admin.auth().updateUser(targetUid, { disabled: true }); await admin.auth().revokeRefreshTokens(targetUid); await db.collection('banned_users').doc(targetUid).set({ userId: targetUid, bannedAt: admin.firestore.FieldValue.serverTimestamp(), reason, bannedBy: ADMIN_ID, method: 'admin_command_deaddrop' }); await db.collection('users').doc(targetUid).set({ banned: true, bannedAt: admin.firestore.FieldValue.serverTimestamp(), banReason: reason, bannedBy: ADMIN_ID }, { merge: true }); const targetSocketId = onlineUsers.get(targetUid); if (targetSocketId) { io.to(targetSocketId).emit('force_logout', { reason: 'Account has been banned', timestamp: new Date().toISOString() }); io.sockets.sockets.get(targetSocketId)?.disconnect(true); onlineUsers.delete(targetUid); } await writeBlackboxResponse( `User ${targetUid} banned successfully`, 'SUCCESS', { reason, wasOnline: !!targetSocketId, disconnected: !!targetSocketId } ); logSys('DEAD_DROP', `๐Ÿšซ User ${maskUid(targetUid)} banned: ${reason}`, 'warning'); break; } case '/clear': { if (args[0] !== 'logs') { await writeBlackboxResponse('Usage: /clear logs', 'HIGH'); break; } const cutoffDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); const snapshot = await db.collection('titan_blackbox') .where('ts', '<', cutoffDate) .limit(500) .get(); if (snapshot.empty) { await writeBlackboxResponse('No old logs found to clear', 'SYSTEM'); break; } const batch = db.batch(); snapshot.docs.forEach(doc => batch.delete(doc.ref)); await batch.commit(); await writeBlackboxResponse( `Cleared ${snapshot.size} old log entries`, 'SUCCESS', { deleted: snapshot.size, olderThan: '7 days' } ); logSys('DEAD_DROP', `๐Ÿ—‘๏ธ Cleared ${snapshot.size} old logs`, 'info'); break; } case '/broadcast': { if (args.length === 0) { await writeBlackboxResponse('Usage: /broadcast [message]', 'HIGH'); break; } const message = args.join(' '); await db.collection('notifications').add({ title: '๐Ÿ“ข ุชู†ุจูŠู‡ ุนุงู…', body: message, bodyAr: message, type: 'SYSTEM_BROADCAST', userId: 'BROADCAST', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); io.emit('receive_direct', { from: 'SYSTEM', msg: message, isSystem: true, timestamp: new Date().toISOString() }); await writeBlackboxResponse( 'Broadcast sent to all users & saved to DB', 'SUCCESS', { recipients: io.sockets.sockets.size, message } ); logSys('DEAD_DROP', `๐Ÿ“ข Broadcast sent to ${io.sockets.sockets.size} connections`, 'success'); break; } case '/sweep-orphans': { logSys('DEAD_DROP', '๐Ÿงน /sweep-orphans triggered via Dead Drop', 'system'); const sweepResult = await sweepOrphanedData(); const sweepReport = ` โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ•‘ ๐Ÿงน ORPHAN SWEEP REPORT โ•‘ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• ${sweepResult.orphansFound === 0 ? 'โœ… Database is clean โ€” no orphaned records found.' : `โš ๏ธ Orphaned UIDs found: ${sweepResult.orphansFound} ๐Ÿ—‘๏ธ Total docs deleted: ${sweepResult.docsDeleted} ๐Ÿ“ฆ Batches committed: ${sweepResult.batchesCommitted} ๐Ÿ“‚ Collections swept: ${sweepResult.collectionsSwept.join(', ')} Orphaned UIDs (masked): ${sweepResult.orphanedUids.map(u => ` โ€ข ${u}`).join('\n')}`} Generated: ${new Date().toISOString()} `.trim(); await writeBlackboxResponse(sweepResult.message, 'SUCCESS', { ...sweepResult, report: sweepReport }); logSys('DEAD_DROP', `๐Ÿงน Sweep report written to blackbox`, 'success'); break; } default: { await writeBlackboxResponse( `Unknown command: ${cmd}`, 'HIGH', { availableCommands: ['/notify', '/ban', '/clear logs', '/broadcast', '/stats', '/sweep-orphans'] } ); logSys('DEAD_DROP', `โ“ Unknown command attempted: ${cmd}`, 'warning'); } } } catch (error) { logSys('DEAD_DROP', `โŒ Command error: ${error.message}`, 'error'); await writeBlackboxResponse( `Command execution failed: ${error.message}`, 'HIGH' ); } } async function initCommandReader() { logSys('DEAD_DROP', '๐Ÿ“ก Firestore Dead Drop Command Reader initialized', 'system'); db.collection('pending_bot_actions') .where('status', '==', 'pending') .onSnapshot(async (snapshot) => { snapshot.docChanges().forEach(async (change) => { if (change.type === 'added') { const docId = change.doc.id; const data = change.doc.data(); try { await db.collection('pending_bot_actions').doc(docId).update({ status: 'processing', processedAt: admin.firestore.FieldValue.serverTimestamp() }); logSys('DEAD_DROP', `๐Ÿ“ฅ New command received (docId: ${docId})`, 'info'); await processAdminCommand(docId, data); await db.collection('pending_bot_actions').doc(docId).delete(); logSys('DEAD_DROP', `โœ… Command processed and deleted (docId: ${docId})`, 'success'); } catch (error) { logSys('DEAD_DROP', `โŒ Failed to process command ${docId}: ${error.message}`, 'error'); await db.collection('pending_bot_actions').doc(docId).update({ status: 'error', error: error.message, errorAt: admin.firestore.FieldValue.serverTimestamp() }); } } }); }, (error) => { logSys('DEAD_DROP', `โš ๏ธ Listener Error: ${error.message}`, 'error'); }); } // 14. SOCKET.IO CONNECTION HANDLER io.on('connection', (socket) => { logSys('SOCKET', `๐Ÿ”Œ New connection: ${socket.id}`, 'cyber'); socket.on('register', (userId) => { if (!userId) return; onlineUsers.set(userId, socket.id); if (ROYAL_FAMILY.includes(userId)) { logSys('SOCKET', `๐Ÿ‘‘ Royal user ${maskUid(userId)} registered (socket: ${socket.id})`, 'royal'); } else { logSys('SOCKET', `โœ… User ${maskUid(userId)} registered (socket: ${socket.id})`, 'success'); } }); socket.on('send_direct', async (data) => { const { to, msg } = data; if (!to || !msg) return; const targetSocketId = onlineUsers.get(to); if (targetSocketId) { io.to(targetSocketId).emit('receive_direct', { from: socket.id, msg, timestamp: new Date().toISOString() }); logSys('SOCKET', `๐Ÿ“จ Relayed DM to online user ${to}`, 'info'); } else { logSys('SOCKET', `๐Ÿ“ฒ User ${to} offline, sending push`, 'info'); await sendPushNotification(to, { title: 'New direct message', body: typeof msg === 'string' ? msg : JSON.stringify(msg), data: { sender: socket.id, ...msg } }); } }); socket.on('admin_cmd', async (payload) => { try { const { adminKey, command } = payload; if (adminKey !== ADMIN_ID) { socket.emit('cmd_res', { success: false, error: 'Access denied. Invalid admin credentials.', timestamp: new Date().toISOString() }); logSys('ADMIN_CMD', `โŒ Unauthorized access attempt from socket ${socket.id}`, 'error'); return; } logSys('ADMIN_CMD', `๐ŸŽ›๏ธ Command received: ${command}`, 'system'); const parts = command.trim().split(/\s+/); const cmd = parts[0].toLowerCase(); const args = parts.slice(1); switch (cmd) { case '/notify': { if (args.length < 2) { socket.emit('cmd_res', { success: false, error: 'Usage: /notify [uid] [message]' }); break; } const targetUid = args[0]; const message = args.slice(1).join(' '); await db.collection('notifications').add({ userId: targetUid, message, sentBy: 'ADMIN_SYSTEM', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); const targetSocketId = onlineUsers.get(targetUid); if (targetSocketId) { io.to(targetSocketId).emit('admin_notification', { message, timestamp: new Date().toISOString() }); } await sendPushNotification(targetUid, { title: 'Admin Notification', body: message, data: { type: 'admin_notification' } }); socket.emit('cmd_res', { success: true, message: `Notification sent to user ${targetUid}`, details: { online: !!targetSocketId, pushSent: true } }); logSys('ADMIN_CMD', `๐Ÿ“ฌ Notification sent to ${maskUid(targetUid)}`, 'success'); break; } case '/ban': { if (args.length < 2) { socket.emit('cmd_res', { success: false, error: 'Usage: /ban [uid] [reason]' }); break; } const targetUid = args[0]; const reason = args.slice(1).join(' '); // ๐Ÿ‘‘ ROYAL IMMUNITY CHECK if (ROYAL_FAMILY.includes(targetUid)) { socket.emit('cmd_res', { success: false, error: `Cannot ban user ${targetUid} - Royal Immunity Shield`, royalProtection: true }); logSys('ADMIN_CMD', `๐Ÿ‘‘ Ban attempt blocked - Royal immunity for ${maskUid(targetUid)}`, 'royal'); break; } await admin.auth().updateUser(targetUid, { disabled: true }); await admin.auth().revokeRefreshTokens(targetUid); await db.collection('banned_users').doc(targetUid).set({ userId: targetUid, bannedAt: admin.firestore.FieldValue.serverTimestamp(), reason, bannedBy: ADMIN_ID, method: 'admin_command' }); await db.collection('users').doc(targetUid).set({ banned: true, bannedAt: admin.firestore.FieldValue.serverTimestamp(), banReason: reason, bannedBy: ADMIN_ID }, { merge: true }); const targetSocketId = onlineUsers.get(targetUid); if (targetSocketId) { io.to(targetSocketId).emit('force_logout', { reason: 'Account has been banned', timestamp: new Date().toISOString() }); io.sockets.sockets.get(targetSocketId)?.disconnect(true); onlineUsers.delete(targetUid); } socket.emit('cmd_res', { success: true, message: `User ${targetUid} banned successfully`, details: { reason, wasOnline: !!targetSocketId, disconnected: !!targetSocketId } }); logSys('ADMIN_CMD', `๐Ÿšซ User ${maskUid(targetUid)} banned: ${reason}`, 'warning'); break; } case '/clear': { if (args[0] !== 'logs') { socket.emit('cmd_res', { success: false, error: 'Usage: /clear logs' }); break; } const cutoffDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); const snapshot = await db.collection('titan_blackbox') .where('timestamp', '<', cutoffDate) .limit(500) .get(); if (snapshot.empty) { socket.emit('cmd_res', { success: true, message: 'No old logs found to clear' }); break; } const batch = db.batch(); snapshot.docs.forEach(doc => batch.delete(doc.ref)); await batch.commit(); socket.emit('cmd_res', { success: true, message: `Cleared ${snapshot.size} old log entries`, details: { deleted: snapshot.size, olderThan: '7 days' } }); logSys('ADMIN_CMD', `๐Ÿ—‘๏ธ Cleared ${snapshot.size} old logs`, 'info'); break; } case '/broadcast': { if (args.length === 0) { socket.emit('cmd_res', { success: false, error: 'Usage: /broadcast [message]' }); break; } const message = args.join(' '); io.emit('receive_direct', { from: 'SYSTEM', msg: message, isSystem: true, timestamp: new Date().toISOString() }); socket.emit('cmd_res', { success: true, message: 'Broadcast sent to all users', details: { recipients: io.sockets.sockets.size, message } }); logSys('ADMIN_CMD', `๐Ÿ“ข Broadcast sent to ${io.sockets.sockets.size} connections`, 'success'); break; } case '/stats': { const stats = getServerStats(); const report = ` โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ•‘ ๐ŸŽ›๏ธ TITAN NEXUS SERVER STATISTICS โ•‘ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โฑ๏ธ UPTIME: ${stats.uptime} ๐Ÿ’พ MEMORY USAGE: โ€ข Heap Used: ${stats.memory.heapUsed} โ€ข Heap Total: ${stats.memory.heapTotal} โ€ข Usage: ${stats.memory.percentage} ๐Ÿ”Œ CONNECTIONS: โ€ข Registered Users: ${stats.connections.registered} โ€ข Total Sockets: ${stats.connections.total} โš™๏ธ SYSTEM LOAD (CPU): โ€ข 1 min: ${stats.cpuLoad['1min']} โ€ข 5 min: ${stats.cpuLoad['5min']} โ€ข 15 min: ${stats.cpuLoad['15min']} ๐Ÿ›ก๏ธ SECURITY: โ€ข Sentinel MK2: ${stats.sentinel} ๐Ÿ‘‘ ROYAL FAMILY: โ€ข Protected Members: ${ROYAL_FAMILY.length} ๐Ÿ•ฐ๏ธ TIME-AWARE ENGINE: โ€ข Gregorian: ${getGregorianDateString(new Date())} โ€ข Hijri: ${getHijriDateString(new Date())} ๐Ÿ–ฅ๏ธ PLATFORM: โ€ข OS: ${stats.platform} โ€ข Node: ${stats.nodeVersion} Generated: ${new Date().toISOString()} `.trim(); socket.emit('cmd_res', { success: true, message: 'Server statistics', report, data: stats }); logSys('ADMIN_CMD', '๐Ÿ“Š Stats report generated', 'info'); break; } case '/sweep-orphans': { logSys('ADMIN_CMD', '๐Ÿงน /sweep-orphans triggered via Socket.IO', 'system'); const sweepResult = await sweepOrphanedData(); socket.emit('cmd_res', { success: true, message: sweepResult.message, details: sweepResult }); logSys('ADMIN_CMD', `๐Ÿงน Sweep complete โ€” ${sweepResult.orphansFound} orphans, ${sweepResult.docsDeleted} docs deleted`, 'success'); break; } default: { socket.emit('cmd_res', { success: false, error: `Unknown command: ${cmd}`, availableCommands: ['/notify', '/ban', '/clear logs', '/broadcast', '/stats', '/sweep-orphans'] }); logSys('ADMIN_CMD', `โ“ Unknown command attempted: ${cmd}`, 'warning'); } } } catch (error) { logSys('ADMIN_CMD', `โŒ Command error: ${error.message}`, 'error'); socket.emit('cmd_res', { success: false, error: `Command execution failed: ${error.message}`, timestamp: new Date().toISOString() }); } }); socket.on('disconnect', () => { let disconnectedUserId = null; for (const [userId, sockId] of onlineUsers.entries()) { if (sockId === socket.id) { disconnectedUserId = userId; onlineUsers.delete(userId); break; } } if (disconnectedUserId) { const logType = ROYAL_FAMILY.includes(disconnectedUserId) ? 'royal' : 'warning'; const icon = ROYAL_FAMILY.includes(disconnectedUserId) ? '๐Ÿ‘‘' : '๐Ÿ”ด'; logSys('SOCKET', `${icon} User ${maskUid(disconnectedUserId)} disconnected`, logType); } else { logSys('SOCKET', `๐Ÿ”ด Socket ${socket.id} disconnected (unregistered)`, 'info'); } }); }); // ๐Ÿ“Œ ADMIN DASHBOARD (BUILT-IN) app.use(express.static('public')); // ู„ุฎุฏู…ุฉ ุฃูŠ ู…ู„ูุงุช ุฅุถุงููŠุฉ (ุงุฎุชูŠุงุฑูŠ) app.get('/admin', (req, res) => { res.sendFile(__dirname + '/admin.html'); }); // 15. HEALTH & STATUS ENDPOINTS app.get('/', (req, res) => { const stats = getServerStats(); res.json({ service: 'TITAN NEXUS โ€“ Time-Aware Royal AI Edition', status: 'operational', version: '14.0', security: 'Sentinel MK2 active', realtime: 'Socket.io relay active', adminCenter: 'Dead Drop Command System active', ai: 'Gemini AI + Time-Aware Engine active', royalFamily: ROYAL_FAMILY.length, onlineUsers: onlineUsers.size, uptime: stats.uptime, memory: stats.memory.percentage, timeAware: { gregorian: getGregorianDateString(new Date()), hijri: getHijriDateString(new Date()) } }); }); app.get('/ping', (req, res) => res.send('pong')); app.get('/stats', (req, res) => { const stats = getServerStats(); res.json({ ...stats, timeAware: { gregorian: getGregorianDateString(new Date()), hijri: getHijriDateString(new Date()) } }); }); // ๐Ÿ” AUTH DEBUG โ€” checks if a key matches ADMIN_ID (temporary, remove after debugging) app.post('/admin/check-auth', (req, res) => { const { adminKey } = req.body; if (!adminKey) return res.json({ ok: false, reason: 'no_key' }); const match = adminKey === ADMIN_ID; const adminLen = ADMIN_ID ? ADMIN_ID.length : 0; const keyLen = adminKey.length; res.json({ ok: match, reason: match ? 'matched' : 'mismatch', keyLength: keyLen, adminIdLength: adminLen, adminIdSet: !!ADMIN_ID, firstFour: ADMIN_ID ? ADMIN_ID.substring(0, 4) : 'NOT_SET' }); }); // ๐Ÿ†• ADMIN COMMAND HTTP ENDPOINT (for web dashboard) app.post('/api/admin/command', async (req, res) => { try { const { adminKey, command } = req.body; if (!adminKey || !command) { return res.status(400).json({ success: false, error: 'Missing adminKey or command' }); } if (adminKey !== ADMIN_ID) { logSys('HTTP_ADMIN', `โŒ Auth failed โ€” key_len=${adminKey.length} admin_id_len=${ADMIN_ID ? ADMIN_ID.length : 'UNSET'} admin_id_set=${!!ADMIN_ID}`, 'error'); return res.status(403).json({ success: false, error: 'Invalid admin credentials' }); } logSys('HTTP_ADMIN', `๐ŸŽ›๏ธ HTTP command received: ${command}`, 'system'); const parts = command.trim().split(/\s+/); const cmd = parts[0].toLowerCase(); const args = parts.slice(1); // Reuse same command logic as elsewhere const executeCommand = async () => { switch (cmd) { case '/stats': { const stats = getServerStats(); return { success: true, message: 'Server statistics retrieved', stats, report: ` Uptime: ${stats.uptime} Memory: ${stats.memory.percentage} Online Users: ${stats.connections.registered} CPU Load: ${stats.cpuLoad['1min']} / ${stats.cpuLoad['5min']} / ${stats.cpuLoad['15min']} Platform: ${stats.platform} `.trim() }; } case '/notify': { if (args.length < 2) throw new Error('Usage: /notify [uid] [message]'); const targetUid = args[0]; const message = args.slice(1).join(' '); await db.collection('notifications').add({ userId: targetUid, message, sentBy: 'ADMIN_SYSTEM', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); const targetSocketId = onlineUsers.get(targetUid); if (targetSocketId) { io.to(targetSocketId).emit('admin_notification', { message, timestamp: new Date().toISOString() }); } await sendPushNotification(targetUid, { title: 'Admin Notification', body: message, data: { type: 'admin_notification' } }); return { success: true, message: `Notification sent to user ${targetUid}`, details: { online: !!targetSocketId, pushSent: true } }; } case '/ban': { if (args.length < 2) throw new Error('Usage: /ban [uid] [reason]'); const targetUid = args[0]; const reason = args.slice(1).join(' '); if (ROYAL_FAMILY.includes(targetUid)) { return { success: false, error: `Cannot ban user ${targetUid} - Royal Immunity Shield`, royalProtection: true }; } await admin.auth().updateUser(targetUid, { disabled: true }); await admin.auth().revokeRefreshTokens(targetUid); await db.collection('banned_users').doc(targetUid).set({ userId: targetUid, bannedAt: admin.firestore.FieldValue.serverTimestamp(), reason, bannedBy: ADMIN_ID, method: 'admin_command_http' }); await db.collection('users').doc(targetUid).set({ banned: true, bannedAt: admin.firestore.FieldValue.serverTimestamp(), banReason: reason, bannedBy: ADMIN_ID }, { merge: true }); const targetSocketId = onlineUsers.get(targetUid); if (targetSocketId) { io.to(targetSocketId).emit('force_logout', { reason: 'Account has been banned', timestamp: new Date().toISOString() }); io.sockets.sockets.get(targetSocketId)?.disconnect(true); onlineUsers.delete(targetUid); } return { success: true, message: `User ${targetUid} banned successfully`, details: { reason, wasOnline: !!targetSocketId } }; } case '/clear': { if (args[0] !== 'logs') throw new Error('Usage: /clear logs'); const cutoffDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); const snapshot = await db.collection('titan_blackbox') .where('ts', '<', cutoffDate) .limit(500) .get(); if (snapshot.empty) { return { success: true, message: 'No old logs found to clear' }; } const batch = db.batch(); snapshot.docs.forEach(doc => batch.delete(doc.ref)); await batch.commit(); return { success: true, message: `Cleared ${snapshot.size} old log entries`, details: { deleted: snapshot.size, olderThan: '7 days' } }; } case '/broadcast': { if (args.length === 0) throw new Error('Usage: /broadcast [message]'); const message = args.join(' '); await db.collection('notifications').add({ title: '๐Ÿ“ข ุชู†ุจูŠู‡ ุนุงู…', body: message, bodyAr: message, type: 'SYSTEM_BROADCAST', userId: 'BROADCAST', timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); io.emit('receive_direct', { from: 'SYSTEM', msg: message, isSystem: true, timestamp: new Date().toISOString() }); return { success: true, message: `Broadcast sent to ${io.sockets.sockets.size} connections`, details: { recipients: io.sockets.sockets.size } }; } case '/sweep-orphans': { logSys('HTTP_ADMIN', '๐Ÿงน /sweep-orphans triggered via HTTP', 'system'); const sweepResult = await sweepOrphanedData(); return { success: true, message: sweepResult.message, details: sweepResult }; } default: throw new Error(`Unknown command: ${cmd}. Available: /stats, /notify, /ban, /clear logs, /broadcast, /sweep-orphans`); } }; const result = await executeCommand(); res.json(result); } catch (error) { logSys('HTTP_ADMIN', `โŒ Command error: ${error.message}`, 'error'); res.status(500).json({ success: false, error: error.message }); } }); // ========================================== // ๐ŸŽ‰ WELCOME MANAGER โ€” Event-Driven via Firestore // Replaces the former POST /auth/welcome HTTP endpoint. // Listens on the `pending_welcomes` collection. The frontend // writes a document there on new-user registration; this // listener fires, processes the welcome, then deletes the doc // so the collection stays empty (zero ongoing read cost). // ========================================== function initWelcomeManager() { db.collection('pending_welcomes').onSnapshot(snapshot => { snapshot.docChanges().forEach(async change => { if (change.type !== 'added') return; const doc = change.doc; const uid = doc.id; const { email, displayName } = doc.data(); if (!uid || !email) { logSys('WELCOME', `โš ๏ธ Skipping malformed pending_welcomes doc (missing uid/email)`, 'warning'); await doc.ref.delete().catch(() => {}); return; } // โ”€โ”€ Dedup: skip if welcome already sent โ”€โ”€ try { const welcomeRef = db.collection('welcome_sent').doc(uid); const sent = await welcomeRef.get(); if (sent.exists) { logSys('WELCOME', `โญ๏ธ Welcome already sent for ${maskUid(uid)}, skipping`, 'info'); await doc.ref.delete().catch(() => {}); return; } // Mark as sent immediately to prevent any race condition await welcomeRef.set({ sentAt: admin.firestore.FieldValue.serverTimestamp(), email }); } catch (e) { logSys('WELCOME', `โš ๏ธ Firestore welcome_sent check failed: ${e.message}`, 'warning'); // Continue โ€” don't block the welcome on a metadata failure } const name = displayName || 'ุนุฒูŠุฒูŠ ุงู„ู…ุณุชุฎุฏู…'; const today = new Date(); const dateStr = getGregorianDateString(today); const hijriStr = getHijriDateString(today); // โ”€โ”€ 1. In-app Notification โ”€โ”€ const notifBody = `ู…ุฑุญุจุงู‹ ุจูƒ ููŠ Titan Connect ูŠุง ${name}! ๐ŸŽ‰ ุฃู†ุช ุงู„ุขู† ุฌุฒุก ู…ู† ู…ุฌุชู…ุนู†ุง ุงู„ู…ุชู…ูŠุฒ. ุงูƒุชุดู ู…ุง ูŠู†ุชุธุฑูƒ: ๐Ÿ” ุดุงุช ูˆุฎุฒู†ุฉ ู…ุดูุฑุฉ ุชู…ุงู…ุงู‹ ๐Ÿ“ก ู†ู‚ู„ ู…ู„ูุงุช P2P ู…ุจุงุดุฑ ุจุฏูˆู† ุฎูˆุงุฏู… ๐ŸŽฌ ุณูŠู†ู…ุง ู…ุน ุชุฑุฌู…ุฉ ุฐูƒูŠุฉ ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ ๐Ÿ“š ุงู„ุงู†ุบู…ุงุณ โ€” ุชุนู„ู‘ู… ุงู„ุฅู†ุฌู„ูŠุฒูŠ ุจุงู„ู‚ุตุต ๐Ÿ‘ฅ ุฌุฑูˆุจุงุช ูˆู…ุฌุชู…ุนุงุช ุญูŠุฉ ู†ุชู…ู†ู‰ ู„ูƒ ุชุฌุฑุจุฉ ู…ู…ุชุนุฉ! ๐ŸŒŸ`; try { await db.collection('notifications').add({ title: '๐ŸŽ‰ ุฃู‡ู„ุงู‹ ุจูƒ ููŠ Titan Connect!', body: notifBody, type: 'WELCOME', userId: uid, timestamp: admin.firestore.FieldValue.serverTimestamp(), read: false }); // Real-time push to user's socket if online io.emit('welcome_notification', { uid, title: '๐ŸŽ‰ ุฃู‡ู„ุงู‹ ุจูƒ!', body: notifBody }); logSys('WELCOME', `โœ… In-app notification sent to ${maskUid(uid)}`, 'success'); } catch (e) { logSys('WELCOME', `โš ๏ธ Notification failed: ${e.message}`, 'warning'); } // โ”€โ”€ 2. Welcome Email โ”€โ”€ if (MAILER_URL && MAILER_TOKEN) { const htmlBody = `
👑

TITAN CONNECT

WELCOME TO THE FAMILY

ุงู„ุณู„ุงู… ุนู„ูŠูƒู… ูˆุฑุญู…ุฉ ุงู„ู„ู‡ 🌙

ู…ุฑุญุจุงู‹ ${name}ุŒ
ูŠุณุนุฏู†ุง ุงู†ุถู…ุงู…ูƒ ุฅู„ู‰ Titan Connect โ€” ุงู„ุชุทุจูŠู‚ ุงู„ุฐูŠ ุตู…ู…ู†ุงู‡ ู„ูŠูƒูˆู† ุฃูƒุซุฑ ู…ู† ู…ุฌุฑุฏ ุชุทุจูŠู‚.

✨ ู…ุง ูŠู†ุชุธุฑูƒ ุจุฏุงุฎู„ู‡

🔐

ุดุงุช ูˆุฎุฒู†ุฉ ู…ุดูุฑุฉ ุชู…ุงู…ุงู‹

ู…ุญุงุฏุซุงุชูƒ ู„ุง ูŠุตู„ ุฅู„ูŠู‡ุง ุฃุญุฏ โ€” ุญุชู‰ ู†ุญู†

📡

ู†ู‚ู„ ู…ู„ูุงุช P2P ู…ุจุงุดุฑ

ุจุฏูˆู† ุฎูˆุงุฏู… ูˆุณูŠุทุฉ โ€” ู…ู† ุฌู‡ุงุฒูƒ ู…ุจุงุดุฑุฉ

🎬

ุณูŠู†ู…ุง + ุชุฑุฌู…ุฉ ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ

ุดุงู‡ุฏ ูˆุชุฑุฌู… ุงู„ููŠุฏูŠูˆู‡ุงุช ูˆุฃู†ุดุฆ ู…ู„ูุงุช ุชุฑุฌู…ุฉ

📚

ุงู„ุงู†ุบู…ุงุณ โ€” ุชุนู„ู‘ู… ุงู„ุฅู†ุฌู„ูŠุฒูŠ ุจุงู„ู‚ุตุต

ุทุฑูŠู‚ุฉ ุชุนู„ู… ู…ุฎุชู„ูุฉ ูˆู…ู…ุชุนุฉ

👥

ุฌุฑูˆุจุงุช ูˆู…ุฌุชู…ุนุงุช ุญูŠุฉ

ุชูˆุงุตู„ ููŠ ู…ุณุงุญุฉ ุขู…ู†ุฉ ูˆู…ุดูุฑุฉ

ุงุจุฏุฃ ุฑุญู„ุชูƒ ←

ู…ุน ุชุญูŠุงุชูŠ โ€” ู…ุญู…ูˆุฏ ุญุณู†
ุงู„ู…ุทูˆุฑ ูˆุงู„ู…ุคุณุณุŒ Titan Connect

TITAN NEXUS · ROYAL COMMS SYSTEM

📅 ${dateStr} | 🌙 ${hijriStr}

`; try { await sendTitanEmail(email, '๐ŸŽ‰ ุฃู‡ู„ุงู‹ ุจูƒ ููŠ Titan Connect!', htmlBody); logSys('WELCOME', `โœ… Welcome email sent to ${email.slice(0,4)}***`, 'success'); } catch (e) { logSys('WELCOME', `โš ๏ธ Welcome email failed: ${e.message.slice(0,80)}`, 'warning'); } } // โ”€โ”€ CLEANUP: delete the processed doc so pending_welcomes stays empty โ”€โ”€ try { await doc.ref.delete(); logSys('WELCOME', `๐Ÿ—‘๏ธ Cleaned up pending_welcomes/${maskUid(uid)}`, 'info'); } catch (e) { logSys('WELCOME', `โš ๏ธ Failed to delete pending_welcomes doc: ${e.message}`, 'warning'); } }); }, err => { logSys('WELCOME', `โŒ pending_welcomes listener error: ${err.message}`, 'error'); }); logSys('WELCOME', '๐Ÿ‘‚ Welcome Manager listening on pending_welcomes queue', 'success'); } // 15.5. MANUAL TRIGGER ENDPOINTS app.post('/admin/market-now', async (req, res) => { const { adminKey } = req.body; if (adminKey !== ADMIN_ID) return res.status(403).json({ success: false, error: 'Unauthorized' }); logSys('HTTP_ADMIN', '๐Ÿ“ˆ Manual market broadcast triggered via HTTP', 'system'); broadcastMarketUpdate(); res.json({ success: true, message: 'Market report fetch initiated.' }); }); app.post('/admin/prayer-now', async (req, res) => { const { adminKey } = req.body; if (adminKey !== ADMIN_ID) return res.status(403).json({ success: false, error: 'Unauthorized' }); broadcastPrayerTimes(); res.json({ success: true, message: 'Prayer times broadcast initiated.' }); }); app.post('/admin/quote-now', async (req, res) => { const { adminKey } = req.body; if (adminKey !== ADMIN_ID) return res.status(403).json({ success: false, error: 'Unauthorized' }); broadcastDailyQuote(); res.json({ success: true, message: 'Daily quote broadcast initiated.' }); }); app.post('/admin/news-now', async (req, res) => { const { adminKey } = req.body; if (adminKey !== ADMIN_ID) return res.status(403).json({ success: false, error: 'Unauthorized' }); broadcastArabicNews(); res.json({ success: true, message: 'News broadcast initiated.' }); }); // ========================================== // ๐Ÿ“ง EMAIL SENDING ENDPOINT (Google Apps Script Mailer Bridge) // HF Secrets: MAILER_URL, MAILER_TOKEN // ========================================== app.post('/admin/send-email', async (req, res) => { const { adminKey, subject, body, targetEmail, logoUrl, // optional: URL to image shown at top buttonText, // optional: CTA button label buttonUrl, // optional: CTA button URL pdfUrl, // optional: URL to a PDF (linked as button, not attachment โ€” Apps Script limitation) accentColor // optional: hex color e.g. "#63b3ed" } = req.body; if (adminKey !== ADMIN_ID) return res.status(403).json({ success: false, error: 'Unauthorized' }); if (!subject || !body) return res.status(400).json({ success: false, error: 'subject and body are required' }); if (!MAILER_URL || !MAILER_TOKEN) return res.status(500).json({ success: false, error: 'MAILER_URL and MAILER_TOKEN must be set in HF Secrets' }); try { let recipients = []; if (targetEmail) { recipients = [targetEmail]; } else { logSys('EMAIL', '๐Ÿ“‹ Fetching all user emails from Firebase Auth...', 'system'); let pageToken; do { const result = await admin.auth().listUsers(1000, pageToken); result.users.forEach(user => { if (user.email) recipients.push(user.email); }); pageToken = result.pageToken; } while (pageToken); } if (!recipients.length) return res.status(404).json({ success: false, error: 'No email recipients found' }); logSys('EMAIL', `๐Ÿ“ง Sending to ${recipients.length} recipients...`, 'system'); const accent = accentColor || '#63b3ed'; const accentDark = '#0f2044'; // โ”€โ”€ Professional HTML Email Template โ”€โ”€ const logoSection = logoUrl ? `Logo` : ''; const ctaButton = (buttonText && buttonUrl) ? ` ${buttonText} โ†’ ` : ` Open Titan App โ†’ `; const pdfSection = pdfUrl ? ` ๐Ÿ“Ž Download PDF ` : ''; const htmlBody = ` ${subject}
${logoSection ? `${logoSection}
` : ''}
๐Ÿ‘‘

Titan App

Royal Notification System

${body}
${ctaButton} ${pdfSection}

TITAN NEXUS ยท POWERED BY ROYAL AI

You received this because you are a registered Titan App user

`; let sent = 0, failed = 0; for (let i = 0; i < recipients.length; i++) { const email = recipients[i]; try { await sendTitanEmail(email, subject, htmlBody); sent++; if (sent % 5 === 0) logSys('EMAIL', `๐Ÿ“จ Progress: ${sent}/${recipients.length}`, 'system'); } catch (err) { logSys('EMAIL', `โš ๏ธ Failed ${email.slice(0,6)}***: ${err.message.slice(0,60)}`, 'warning'); failed++; } if (i < recipients.length - 1) await new Promise(r => setTimeout(r, 300)); } logSys('EMAIL', `โœ… Done: ${sent} sent, ${failed} failed, ${recipients.length} total`, 'success'); res.json({ success: true, sent, failed, total: recipients.length }); } catch (error) { logSys('EMAIL', `โŒ Email error: ${error.message}`, 'error'); res.status(500).json({ success: false, error: error.message }); } }); // ========================================== // ๐Ÿ” AUTHENTICATED GATEWAY PROXY (v14.4) // Route: /api/gateway-proxy/* // // Security model: // 1. Client sends Firebase ID Token in `Authorization: Bearer ` // 2. We verify the token with Firebase Admin โ€” 403 if invalid/missing // 3. We forward the request to the real Titan Gateway, injecting the // server-side TITAN_GATEWAY_KEY so the frontend never sees it. // 4. The gateway response is streamed back transparently. // // Supports: // โ€ข GET requests (query-string forwarded as-is) // โ€ข POST requests with JSON body // โ€ข POST requests with multipart/form-data (file uploads) // ========================================== const TITAN_GATEWAY_BASE = 'https://m-hv1-titan-gateway.hf.space'; // โ”€โ”€ Relay is now merged into titan-messenger (no longer a standalone Space) โ”€โ”€ // Path prefix changed from root /upload-chunk // to /relay/upload-chunk const TITAN_CLOUD_RELAY_BASE = 'https://m-hv1-titan-messenger.hf.space/relay'; // โ”€โ”€ Middleware: verify Firebase ID Token โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ async function requireFirebaseAuth(req, res, next) { const authHeader = req.headers['authorization'] || ''; const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : null; if (!token) { logSys('PROXY', `โŒ Missing Authorization header from ${req.ip}`, 'error'); return res.status(403).json({ error: 'Forbidden: missing Authorization header' }); } try { const decoded = await admin.auth().verifyIdToken(token); req.titanUid = decoded.uid; // available in handler if needed next(); } catch (err) { logSys('PROXY', `โŒ Invalid Firebase ID Token: ${err.message}`, 'error'); return res.status(403).json({ error: 'Forbidden: invalid or expired token' }); } } // โ”€โ”€ Helper: forward a request to the real gateway / relay โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ // Handles JSON, FormData (multipart), and GET. // Returns a Node http.ClientRequest-compatible response that we can pipe. function forwardToUpstream(upstreamUrl, req, extraHeaders = {}) { return new Promise((resolve, reject) => { const parsed = new URL(upstreamUrl); const contentType = req.headers['content-type'] || ''; const isMultipart = contentType.includes('multipart/form-data'); const isGet = req.method === 'GET'; // โ”€โ”€ For JSON/urlencoded: Express has already consumed the stream via express.json(), // so req.pipe() sends an empty body -> gateway returns 422. // Solution: re-serialise from req.body (already parsed by Express). // โ”€โ”€ For multipart (FormData): Express does NOT parse it, stream is intact -> pipe directly. // โ”€โ”€ For GET: no body. let bodyBuffer = null; let finalContentType = contentType; if (!isGet && !isMultipart) { const bodyStr = JSON.stringify(req.body ?? {}); bodyBuffer = Buffer.from(bodyStr, 'utf8'); finalContentType = 'application/json'; } const headers = { ...((!isGet && finalContentType) ? { 'Content-Type': finalContentType } : {}), ...(bodyBuffer ? { 'Content-Length': bodyBuffer.byteLength } : {}), 'X-Titan-Key': process.env.TITAN_GATEWAY_KEY, ...extraHeaders, }; const options = { hostname: parsed.hostname, port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80), path: parsed.pathname + (parsed.search || ''), method: req.method, headers, }; const upstreamReq = https.request(options, (upstreamRes) => { resolve(upstreamRes); }); upstreamReq.on('error', reject); upstreamReq.setTimeout(120000, () => { upstreamReq.destroy(); reject(new Error('Upstream request timed out')); }); if (isGet) { upstreamReq.end(); } else if (isMultipart) { // Stream raw multipart body directly โ€” Express has not touched it req.pipe(upstreamReq); } else { // Write the re-serialised JSON body upstreamReq.write(bodyBuffer); upstreamReq.end(); } }); } // โ”€โ”€ PROXY: Titan Gateway โ†’ /api/gateway-proxy/* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ // Preserves all original paths, e.g.: // /api/gateway-proxy/api/v1/translate โ†’ https://m-hv1-titan-gateway.hf.space/api/v1/translate app.use('/api/gateway-proxy', requireFirebaseAuth, async (req, res) => { // Strip the /api/gateway-proxy prefix to get the real downstream path const downstreamPath = req.path; // e.g. /api/v1/translate const queryString = req.url.includes('?') ? req.url.slice(req.url.indexOf('?')) : ''; const upstreamUrl = `${TITAN_GATEWAY_BASE}${downstreamPath}${queryString}`; logSys('PROXY', `[${req.titanUid?.slice(0, 8)}โ€ฆ] ${req.method} ${upstreamUrl}`, 'info'); try { const upstreamRes = await forwardToUpstream(upstreamUrl, req); // Mirror status + headers (minus hop-by-hop headers) res.status(upstreamRes.statusCode); const hopByHop = new Set(['connection', 'keep-alive', 'transfer-encoding', 'trailer', 'upgrade', 'proxy-authorization', 'proxy-authenticate', 'te']); Object.entries(upstreamRes.headers).forEach(([k, v]) => { if (!hopByHop.has(k.toLowerCase())) res.setHeader(k, v); }); // Stream response body back to client upstreamRes.pipe(res); } catch (err) { logSys('PROXY', `โŒ Gateway proxy error: ${err.message}`, 'error'); if (!res.headersSent) { res.status(502).json({ error: `Gateway proxy failed: ${err.message}` }); } } }); // โ”€โ”€ PROXY: Titan Cloud Relay โ†’ /api/relay-proxy/* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ // Handles upload-chunk / download-chunk for the media relay. // Relay is now merged into titan-messenger under the /relay prefix: // /api/relay-proxy/upload-chunk โ†’ https://m-hv1-titan-messenger.hf.space/relay/upload-chunk // /api/relay-proxy/download-chunk โ†’ https://m-hv1-titan-messenger.hf.space/relay/download-chunk app.use('/api/relay-proxy', requireFirebaseAuth, async (req, res) => { const downstreamPath = req.path; const queryString = req.url.includes('?') ? req.url.slice(req.url.indexOf('?')) : ''; const upstreamUrl = `${TITAN_CLOUD_RELAY_BASE}${downstreamPath}${queryString}`; logSys('PROXY', `[RELAY][${req.titanUid?.slice(0, 8)}โ€ฆ] ${req.method} ${upstreamUrl}`, 'info'); try { const upstreamRes = await forwardToUpstream(upstreamUrl, req, { 'x-titan-type' : req.headers['x-titan-type'] || '', // Forward the user's Firebase token โ€” cloudRelay.js verifyies it 'Authorization' : req.headers['authorization'] || '', // The cloud-relay server uses TITAN_API_KEY (TITAN_RELAY_KEY in Nexus env) 'X-Titan-Key' : process.env.TITAN_RELAY_KEY || process.env.TITAN_GATEWAY_KEY, }); res.status(upstreamRes.statusCode); const hopByHop = new Set(['connection', 'keep-alive', 'transfer-encoding', 'trailer', 'upgrade', 'proxy-authorization', 'proxy-authenticate', 'te']); Object.entries(upstreamRes.headers).forEach(([k, v]) => { if (!hopByHop.has(k.toLowerCase())) res.setHeader(k, v); }); upstreamRes.pipe(res); } catch (err) { logSys('PROXY', `โŒ Relay proxy error: ${err.message}`, 'error'); if (!res.headersSent) { res.status(502).json({ error: `Relay proxy failed: ${err.message}` }); } } }); // 16. BOOT SEQUENCE server.listen(PORT, async () => { console.log(`\n\x1b[36mโ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—\x1b[0m`); console.log(`\x1b[36mโ•‘ ๐Ÿ›ก๏ธ TITAN NEXUS v14.4 - ROYAL COMMS EDITION โ•‘\x1b[0m`); console.log(`\x1b[36mโ•‘ โšก Socket.IO | Sentinel MK2 | Janitor MK2 | Email Engine โ•‘\x1b[0m`); console.log(`\x1b[36mโ•‘ ๐Ÿ“ก Dead Drop | ๐Ÿง  Gemini 3 | Free Gold APIs | Groq Stocks โ•‘\x1b[0m`); console.log(`\x1b[36mโ•‘ ๐Ÿ•Œ Prayer | ๐Ÿ’ก Quote | ๐Ÿ“ฐ News | ๐Ÿ“ˆ Market | ๐Ÿ“ง Email โ•‘\x1b[0m`); console.log(`\x1b[36mโ•‘ ๐Ÿ” Auth Gateway Proxy | Relay Proxy | Firebase ID Token Guard โ•‘\x1b[0m`); console.log(`\x1b[36mโ•‘ ๐Ÿ‘‘ Royal Immunity | ๐Ÿš€ Port: ${PORT} โ•‘\x1b[0m`); console.log(`\x1b[36mโ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•\x1b[0m\n`); // Log current date context logSys('CORE', `๐Ÿ—“๏ธ Gregorian: ${getGregorianDateString(new Date())}`, 'ai'); logSys('CORE', `๐ŸŒ™ Hijri: ${getHijriDateString(new Date())}`, 'ai'); // Activate Sentinel const sentinel = new SentinelMK2(); sentinel.monitorComments(); sentinel.monitorReports(); logSys('CORE', '๐Ÿ›ก๏ธ Sentinel MK2 armed (Royal Immunity active)', 'success'); // Activate Janitor const janitor = new JanitorMK2(); setInterval(() => janitor.cleanOldMessages(), 60 * 60 * 1000); logSys('CORE', '๐Ÿงน Janitor MK2 scheduled: hourly (Royal preservation enabled)', 'success'); // Activate Dead Drop Command Reader initCommandReader(); logSys('CORE', '๐Ÿ“ก Firestore Dead Drop Command Reader activated', 'success'); // Activate Event-Driven Welcome Manager (replaces POST /auth/welcome) initWelcomeManager(); logSys('CORE', '๐ŸŽ‰ Welcome Manager activated (pending_welcomes queue listener)', 'success'); // Initialize AI Cron Jobs (6h riddle broadcasts + 11:59 PM royal reports) initCronJobs(); logSys('CORE', '๐Ÿง  Time-Aware AI automation initialized (Riddle-only mode)', 'success'); logSys('CORE', '๐Ÿ“… Scheduled: Every 6h riddle, 8 AM & 3 PM market report, 10 PM game awards, 11:59 PM royal reports', 'success'); logSys('CORE', '๐Ÿ“ˆ Market Intelligence: Groq Compound (web search) โ€” Gold EGP/SAR/AED/USD + Global Indices', 'ai'); // Warm-up reputation cache try { const repSnapshot = await db.collection('user_reputation').limit(100).get(); repSnapshot.docs.forEach(doc => { const data = doc.data(); sentinel.userReputation.set(data.userId, data.score || 100); }); logSys('CORE', `๐Ÿ“Š Loaded ${repSnapshot.size} user reputations`, 'info'); } catch (e) { logSys('CORE', 'โš ๏ธ Could not preload reputations', 'warning'); } logSys('CORE', `๐Ÿ‘‘ Royal Family protection active for ${ROYAL_FAMILY.length} members`, 'royal'); logSys('CORE', '๐ŸŽ›๏ธ Admin Command Center (Socket + Dead Drop + HTTP) initialized', 'success'); // ๐Ÿช™ Extensions: Wallet/Coins + new admin commands + cleanup crons initExtensions(app, io, db, admin, { ADMIN_ID, ROYAL_FAMILY, onlineUsers, logSys, maskUid, getServerStats }); logSys('CORE', 'โœ… Nexus v14.2 operational. Market Intelligence Edition ready.', 'success'); });