const express = require('express'); const cors = require("cors"); const { MongoClient } = require('mongodb'); require('dotenv').config(); // Load .env variables const MONGO_URI = process.env.MONGO_URI; const DB_NAME = 'finral'; const COLLECTION_NAME = 'json'; const app = express(); app.use(cors()); const PORT = 7860; // GET /group/:id/users → returns group users app.get('/group/:id/users', async (req, res) => { const groupId = req.params.id; const filename = `data/groups/${groupId}.json`; const client = new MongoClient(MONGO_URI); try { await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); const doc = await collection.findOne({ filename }); if (!doc) { return res.status(404).json({ status: false, message: 'Group not found in MongoDB' }); } const groupData = doc.data; return res.json({ status: true, groupId, totalUsers: Object.keys(groupData.users || {}).length, users: groupData.users || {}, lastReset: groupData.lastReset || null }); } catch (err) { return res.status(500).json({ status: false, error: err.message }); } finally { await client.close(); } }); // GET /user/:id/pfp → fetch user PFP info from MongoDB (data/user_pfps.json) app.get('/user/:id/pfp', async (req, res) => { const userId = req.params.id; const filename = 'data/user_pfps.json'; const client = new MongoClient(MONGO_URI); try { await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); // Find the document for user_pfps const doc = await collection.findOne({ filename }); if (!doc || !doc.data || !doc.data[userId]) { return res.status(404).json({ status: false, message: 'User PFP not found' }); } const { shortCode, lastUpdated } = doc.data[userId]; // Convert shortCode: "00vpom-jpg" → "00vpom.jpg" const catboxUrl = `https://files.catbox.moe/${shortCode.replace(/-(\w+)$/, '.$1')}`; return res.json({ status: true, userId, shortCode, lastUpdated, catboxUrl }); } catch (err) { return res.status(500).json({ status: false, error: err.message }); } finally { await client.close(); } }); app.get('/user/:id/banner', async (req, res) => { const userId = req.params.id; const filename = 'data/user_banners.json'; const client = new MongoClient(MONGO_URI); try { await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); // Find the document for user_pfps const doc = await collection.findOne({ filename }); if (!doc || !doc.data || !doc.data[userId]) { return res.status(404).json({ status: false, message: 'User PFP not found' }); } const { shortCode, lastUpdated } = doc.data[userId]; // Convert shortCode: "00vpom-jpg" → "00vpom.jpg" const catboxUrl = `https://files.catbox.moe/${shortCode.replace(/-(\w+)$/, '.$1')}`; return res.json({ status: true, userId, shortCode, lastUpdated, catboxUrl }); } catch (err) { return res.status(500).json({ status: false, error: err.message }); } finally { await client.close(); } }); // GET /user/:chatid/nfts → Return all NFTs owned by a user, with holders count app.get('/user/:chatid/nfts', async (req, res) => { const userId = req.params.chatid; const filename = 'data/nfts.json'; const client = new MongoClient(MONGO_URI); try { await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); const doc = await collection.findOne({ filename }); if (!doc || !doc.data) { return res.status(404).json({ status: false, message: 'NFT data not found' }); } const nftData = doc.data; const userNFTs = nftData[userId]; if (!userNFTs || userNFTs.length === 0) { return res.status(404).json({ status: false, message: 'No NFTs found for this user' }); } // Calculate how many users hold each nftid const holdersCount = {}; for (const uid in nftData) { const ownedNFTs = nftData[uid]; for (const nft of ownedNFTs) { holdersCount[nft.nftid] = (holdersCount[nft.nftid] || 0) + 1; } } // Append holders count to each NFT the user owns const enrichedNFTs = userNFTs.map(nft => ({ ...nft, holders: holdersCount[nft.nftid] || 1 })); return res.json({ status: true, userId, totalNFTs: enrichedNFTs.length, nfts: enrichedNFTs }); } catch (err) { return res.status(500).json({ status: false, error: err.message }); } finally { await client.close(); } }); // ✅ NEW: GET /user/:id/info → Get user's global info across all groups app.get('/user/:id/info', async (req, res) => { const userId = req.params.id; const client = new MongoClient(MONGO_URI); try { await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); const groupDocs = await collection.find({ filename: { $regex: '^data/groups/' } }).toArray(); let totalXP = 0; let totalLevel = 0; let totalRoyalties = 0; let totalDailyMessages = 0; const groups = []; for (const doc of groupDocs) { const groupId = doc.filename.replace('data/groups/', '').replace('.json', ''); const groupUsers = doc.data.users || {}; if (groupUsers[userId]) { const userInfo = groupUsers[userId]; totalXP += userInfo.xp || 0; totalLevel += userInfo.level || 0; totalRoyalties += userInfo.royalties || 0; totalDailyMessages += userInfo.dailyMessages || 0; groups.push({ groupId, fullName: userInfo.fullName || null, username: userInfo.username || null, level: userInfo.level || 0, xp: userInfo.xp || 0, royalties: userInfo.royalties || 0, dailyMessages: userInfo.dailyMessages || 0 }); } } if (groups.length === 0) { return res.status(404).json({ status: false, message: 'User not found in any group' }); } return res.json({ status: true, userId, totalXP, totalLevel, totalRoyalties, totalDailyMessages, groups }); } catch (err) { return res.status(500).json({ status: false, error: err.message }); } finally { await client.close(); } }); app.get('/user/:id/theme', async (req, res) => { const userId = req.params.id; const filename = 'data/themes.json'; const client = new MongoClient(MONGO_URI); try { await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); // Find the document for themes.json const doc = await collection.findOne({ filename }); if (!doc || !doc.data || !doc.data[userId]) { return res.status(404).json({ status: false, message: 'User theme not found' }); } const { theme, lastUpdated } = doc.data[userId]; return res.json({ status: true, userId, theme, lastUpdated }); } catch (err) { return res.status(500).json({ status: false, error: err.message }); } finally { await client.close(); } }); app.get('/user/:id/mark', async (req, res) => { const userId = req.params.id; const filename = 'data/marks.json'; const client = new MongoClient(MONGO_URI); try { await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); // Find the document for marks.json const doc = await collection.findOne({ filename }); if (!doc || !doc.data || !doc.data[userId]) { return res.status(404).json({ status: false, message: 'User mark not found' }); } const { mark, url, lastUpdated } = doc.data[userId]; return res.json({ status: true, userId, mark, url, lastUpdated }); } catch (err) { return res.status(500).json({ status: false, error: err.message }); } finally { await client.close(); } }); // GET /group/:id/meta → returns group metadata from MongoDB (names.json) app.get('/group/:id/meta', async (req, res) => { const groupId = req.params.id; if (!groupId) { return res.status(400).json({ status: false, message: 'Group ID required' }); } const client = new MongoClient(MONGO_URI); try { await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); const doc = await collection.findOne({ filename: 'data/names.json' }); if (!doc || !doc.data || !doc.data[groupId]) { return res.status(404).json({ status: false, message: 'Group metadata not found' }); } const group = doc.data[groupId]; return res.json({ status: true, groupId, groupName: group.groupName, groupPic: group.groupPic || null, inviteLink: group.inviteLink || null, memberCount: group.memberCount || null, admins: group.admins || [] }); } catch (err) { return res.status(500).json({ status: false, error: err.message }); } finally { await client.close(); } }); app.listen(PORT, () => { console.log(`Express server running at http://localhost:${PORT}`); });