Skip to content

Instantly share code, notes, and snippets.

@AliAryanTech
Created March 29, 2025 11:49
Show Gist options
  • Save AliAryanTech/a8073fa8163740405e3763dde03048f1 to your computer and use it in GitHub Desktop.
Save AliAryanTech/a8073fa8163740405e3763dde03048f1 to your computer and use it in GitHub Desktop.
Umm
const express = require('express')
const cors = require('cors')
const fs = require('fs-extra')
const crypto = require('crypto')
const { join } = require('path')
const verification = new Map()
const FILE = 'sessions.json'
const sessions = fs.existsSync(FILE) ? fs.readJsonSync(FILE) : {}
module.exports = class Server {
constructor(client) {
this.client = client
this.app.use(cors({
origin: "*",
credentials: true
}), express.json())
this.app.use((req, res, next) => {
res.set('Access-Control-Allow-Origin', '*')
res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization')
res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
next()
})
this.app.use('/', express.static(this.path))
this.app.get('/wa/qr', async (req, res) => {
const { session } = req.query
if (!session || !this.client || this.client.config.session !== req.query.session)
return void res.status(404).setHeader('Content-Type', 'text/plain').send('Invalid Session').end()
if (!this.client || !this.client.QR)
return void res
.status(404)
.setHeader('Content-Type', 'text/plain')
.send(
this.client.condition === 'connected'
? 'You are already connected to WhatsApp'
: 'QR not generated'
)
.end()
res.status(200).contentType('image/png').send(this.client.QR)
})
this.app.all('/request', async (req, res) => {
const { phone } = req.method === 'GET' ? req.query : req.body
if (!phone) return res.json({ success: false, message: 'No phone' })
const jid = await this.client.isOnWhatsApp(phone)
if (!jid) return res.status(404).json({ success: false, message: 'Not on WhatsApp' })
if (verification.has(jid)) return res.json({ success: false, message: `Wait ${((verification.get(jid).expiration - Date.now()) / 1000).toFixed(0)}s` })
const code = Math.floor(100000 + Math.random() * 900000)
verification.set(jid, { code, expiration: Date.now() + 120000 })
await this.client.sendMessage(jid, { text: `Your OTP is ${code}` })
console.log(code)
setTimeout(() => verification.delete(jid), 120000)
res.json({ success: true, message: 'Check WhatsApp!' })
})
this.app.all('/verify', async (req, res) => {
const { phone, code } = req.method === 'GET' ? req.query : req.body
if (!phone || !code) return res.json({ success: false, message: 'Missing data' })
const jid = await this.client.isOnWhatsApp(phone)
if (!jid) return res.status(404).json({ success: false, message: 'Not on WhatsApp' })
const stored = verification.get(jid)
if (!stored || Date.now() > stored.expiration || parseInt(code) !== stored.code)
return res.status(400).json({ success: false, message: 'Invalid/Expired Code' })
verification.delete(jid)
const token = crypto.randomBytes(32).toString('base64')
this.addAuth(token, { jid, expiration: Date.now() + 604800000, token })
await this.client.sendMessage(this.client.config.adminsGroup, { text: `@${jid.split('@')[0]} Logged in Website.`, mentions: [jid] })
res.json(sessions[token])
})
this.app.all(['/getUser', '/get-status', '/cards', '/profile'], async (req, res) => {
const { phone } = req.method === 'GET' ? req.query : req.body
if (!phone) return res.json({ success: false, message: 'No phone' })
const jid = await this.client.isOnWhatsApp(phone)
const user = jid && await this.client.DB.user.get(jid) && await this.client.DB.getUser(jid)
if (!user) return res.status(404).json({ success: false, message: 'User not found' })
const path = req.path.slice(1)
const { id, name, username, about, pfp, reaction, exp, level, wallet, bank, clan, gems, quizWins, moonstone, popularity, vault, ban, deck, coll, party, pc, afk, premium, status_updates = {} } = user
if (path === 'get-status')
return res.json({ success: true, status_updates: Object.fromEntries(Object.entries(status_updates || {}).filter(([k]) => /^\d/.test(k))) })
if (path === 'cards') return res.json({ success: true, deck, coll })
const bio = await this.client.fetchStatus(jid).then(res => res?.status).catch(() => null)
const pfpUrl = await this.client
.profilePictureUrl(jid, 'image')
.catch(() => 'https://upload.wikimedia.org/wikipedia/commons/a/ac/Default_pfp.jpg')
const cards = coll.concat(deck)
res.json({
id, name, username, bio, about, reaction, exp, level, wallet, bank, clan, gems,
quizWins, moonstone, vault, ban, afk, premium, popularity: popularity?.count ?? 0,
pfp: pfp?.custom ? pfp?.url : pfpUrl,
pokemon: party.length + pc.length,
cards: cards.length,
frame: 1
})
})
this.app.all('/updateUser', async (req, res) => {
const [session, error] = this.authCheck(req, res)
if (error) return error
const { jid, field, method, update } = req.method === 'GET' ? req.query : req.body
if (!field || !method || !update) return res.status(400).json({ success: false, message: 'Missing fields' })
if (!['inc', 'set'].includes(method)) return res.status(400).json({ success: false, message: 'Invalid method' })
if (!jid.includes(session.jid.split('@')[0])) return res.json({ success: false, message: 'Not authorized' })
await this.client.DB.updateUser(jid, field, method, update)
res.json({ success: true, message: 'Updated' })
})
this.app.all('/transfer-card', async (req, res) => {
const [session, error] = this.authCheck(req, res)
if (error) return error
const { jid, type, index } = req.method === 'GET' ? req.query : req.body
if (!['deck', 'coll'].includes(type) || !Number.isInteger(Number(index)) || index < 0)
return res.status(400).json({ success: false, message: 'Invalid input' })
if (!jid.includes(session.jid.split('@')[0])) return res.json({ success: false, message: 'Not authorized' })
const user = await this.client.DB.getUser(jid)
const source = type === 'deck' ? user.deck : user.coll;
if (index >= source.length)
return res.status(400).json({ success: false, message: 'Index out of bounds' })
if (type === 'coll' && user.deck.length >= 12)
return res.status(400).json({ success: false, message: 'Deck full' })
const card = source.splice(index, 1)[0];
(type === 'deck' ? user.coll : user.deck).push(card)
await this.client.DB.updateUser(jid, 'deck', 'set', user.deck)
await this.client.DB.updateUser(jid, 'coll', 'set', user.coll)
res.json({
success: true,
deck: user.deck,
coll: user.coll
})
})
this.app.all('/top-lb', async (req, res) => {
const { category = 'exp' } = req.method === 'GET' ? req.query : req.body
const sort = {
exp: (a, b) => b.exp - a.exp,
moonstone: (a, b) => (b.moonstone || 0) + (b.vault || 0) - (a.moonstone || 0) - (a.vault || 0),
auction: (a, b) => b.auctionsWon - a.auctionsWon,
wallet: (a, b) => b.wallet - a.wallet,
bank: (a, b) => b.bank - a.bank,
pokemon: (a, b) => (b.party?.length || 0) + (b.pc?.length || 0) - (a.party?.length || 0) - (a.pc?.length || 0),
cards: (a, b) => (b.deck?.length || 0) + (b.coll?.length || 0) - (a.deck?.length || 0) - (a.coll?.length || 0),
quiz: (a, b) => b.quizWins - a.quizWins,
clanpoints: (a, b) => (b.clan?.clanpoints || 0) - (a.clan?.clanpoints || 0),
popularity: (a, b) => (b.popularity?.count || 0) - (a.popularity?.count || 0)
}[category] || ((a, b) => b.exp - a.exp)
const users = (await this.client.DB.user.all())
.map(x => x.value?.whatsapp?.net)
.filter(u => u && u.id)
.sort(sort)
.slice(0, 10);
res.json(await Promise.all(users.map(async u => ({
id: u.id,
name: u.name,
phone: u.id ? u.id.split('@')[0] : null,
pfp: u.custom ? u.url : await this.client.profilePictureUrl(u.id, 'image').catch(() => null),
exp: u.exp,
popularity: u.popularity?.count || 0,
clan: u.clan?.clanpoints || 0,
level: u.level,
pokemon: (u.party?.length || 0) + (u.pc?.length || 0),
cards: (u.deck?.length || 0) + (u.coll?.length || 0),
quizWins: u.quizWins
}))))
})
this.app.all('/set-status', async (req, res) => {
const [session, error] = this.authCheck(req, res)
if (error) return error
const { jid, type, update } = req.method === 'GET' ? req.query : req.body
if (!jid || !type || !update) return res.status(400).json({ success: false, message: 'Missing fields' })
if (!jid.includes(session.jid.split('@')[0]) && type === 'post') return res.json({ success: false, message: 'Unauthorized post' })
await this.client.DB.statusUpdate(jid, type, update)
if (type === 'post') await this.client.sendMessage('[email protected]', { text: `@${jid.split('@')[0]} Posted a Status.\n\nLink: https://eclipsebot.net/status/${jid.split('@')[0]}`, mentions: [jid] })
res.json({ success: true, message: 'Updated' })
})
this.app.all('*', (req, res) => res.sendStatus(404))
const port = client.config.session === 'ASUNA' ? 53579 : client.config.PORT;
this.app.listen(port, () => console.log(`Server started on PORT: ${port}`));
}
path = join(__dirname, '..', '..', 'public')
app = express()
addAuth = (token, data) => {
const existing = Object.keys(sessions).filter(t => sessions[t].jid === data.jid)
if (existing.length >= 3) delete sessions[existing[0]]
sessions[token] = data
fs.writeJsonSync(FILE, sessions, { spaces: 4 })
}
authCheck = (req, res) => {
const token = req.headers.authorization?.replace('Bearer ', '')
if (!token || !sessions[token])
return [null, res.status(401).json({ success: false, message: 'Invalid Token' })]
const session = sessions[token]
if (Date.now() > session.expiration) {
delete sessions[token]
fs.writeJsonSync(FILE, sessions, { spaces: 4 })
return [null, res.status(401).json({ success: false, message: 'Session Expired' })]
}
return [session, null]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment