| require('dotenv').config(); |
|
|
| |
| const dns = require('node:dns'); |
| dns.setDefaultResultOrder('ipv4first'); |
|
|
| const { |
| Client, |
| GatewayIntentBits, |
| Partials, |
| } = require('discord.js'); |
|
|
| |
| const required = ['BOT_TOKEN', 'OWNER_ID']; |
| console.log(' π ENV CHECK:', required.map(k => `${k}=${process.env[k] ? 'β
' : 'β'}`).join(' | ')); |
| for (const key of required) { |
| if (!process.env[key] || process.env[key].includes('YOUR_')) { |
| console.error(`β Missing or placeholder env var: ${key}`); |
| console.error(' Please fill in your .env file before starting.'); |
| process.exit(1); |
| } |
| } |
|
|
| |
| const client = new Client({ |
| intents: [ |
| GatewayIntentBits.Guilds, |
| GatewayIntentBits.GuildMembers, |
| GatewayIntentBits.GuildMessages, |
| GatewayIntentBits.GuildMessageReactions, |
| GatewayIntentBits.DirectMessages, |
| GatewayIntentBits.MessageContent, |
| GatewayIntentBits.GuildPresences, |
| ], |
| partials: [ |
| Partials.Message, |
| Partials.Channel, |
| Partials.Reaction, |
| Partials.User, |
| Partials.GuildMember, |
| ], |
| }); |
|
|
| |
| const events = [ |
| require('./events/ready'), |
| require('./events/messageCreate'), |
| require('./events/messageReactionAdd'), |
| require('./events/messageReactionRemove'), |
| require('./events/guildMemberUpdate'), |
| require('./events/guildMemberAdd'), |
| require('./events/guildMemberRemove'), |
| require('./events/interactionCreate'), |
| ]; |
|
|
| for (const event of events) { |
| if (event.once) { |
| client.once(event.name, (...args) => event.execute(client, ...args)); |
| } else { |
| client.on(event.name, (...args) => event.execute(client, ...args)); |
| } |
| } |
|
|
| |
| client.on('error', (err) => { |
| console.error('[Client Error]', err); |
| }); |
|
|
| process.on('unhandledRejection', (err) => { |
| console.error('[Unhandled Rejection]', err); |
| }); |
|
|
| process.on('uncaughtException', (err) => { |
| console.error('[Uncaught Exception]', err); |
| process.exit(1); |
| }); |
|
|
| |
| const http = require('http'); |
| const PORT = process.env.PORT || 3001; |
|
|
| http.createServer((req, res) => { |
| res.writeHead(200, { 'Content-Type': 'application/json' }); |
| res.end(JSON.stringify({ |
| status: 'alive', |
| bot: client.user?.tag || 'starting...', |
| uptime: Math.floor(process.uptime()) + 's', |
| })); |
| }).listen(PORT, () => { |
| console.log(` π Keep-alive server on port ${PORT}`); |
| }); |
|
|
| |
| const token = process.env.BOT_TOKEN; |
| console.log(` π Token: ${token ? token.slice(0, 10) + '...' + token.slice(-5) : 'MISSING'}`); |
|
|
| async function startBot(retryCount = 0) { |
| if (retryCount > 10) { |
| console.error('β MAX RETRIES REACHED. Bot failed to connect.'); |
| process.exit(1); |
| } |
|
|
| console.log(` β³ Connecting to Discord... (Attempt ${retryCount + 1})`); |
| |
| const loginTimeout = setTimeout(() => { |
| console.error('β LOGIN TIMED OUT after 60s β Discord gateway unreachable'); |
| }, 60000); |
|
|
| try { |
| await client.login(token); |
| clearTimeout(loginTimeout); |
| console.log(' β
Login promise resolved'); |
| } catch (err) { |
| clearTimeout(loginTimeout); |
| console.error(`β LOGIN FAILED: ${err.message}`); |
| |
| if (err.message.includes('ENOTFOUND') || err.message.includes('EAI_AGAIN')) { |
| console.log(' π‘ DNS/Network error detected. Retrying in 10s...'); |
| setTimeout(() => startBot(retryCount + 1), 10000); |
| } else { |
| console.error(' β οΈ Non-network error. Exiting.'); |
| process.exit(1); |
| } |
| } |
| } |
|
|
| |
| client.on('debug', (info) => { |
| if (info.includes('Gateway')) console.log(`[DEBUG] ${info}`); |
| }); |
|
|
| startBot(); |
|
|