Files
broccolini-bot/scripts/lookup-with-dedicated-bot.js
2026-02-17 21:49:58 -06:00

184 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* User lookup using a dedicated minimal-permissions bot
*
* This bot:
* - Has NO server permissions
* - Only needs to be in the server
* - Uses separate token from main bot
* - Won't affect your main bot's rate limits
*
* Usage:
* LOOKUP_BOT_TOKEN=your_token node scripts/lookup-with-dedicated-bot.js <input_file> <output_file>
*/
const fs = require('fs');
const path = require('path');
const { Client, GatewayIntentBits } = require('discord.js');
// Load environment
require('dotenv').config({ path: path.join(__dirname, '../../.env') });
// Use dedicated bot token OR fall back to main bot
const TOKEN = process.env.MEMBER_BOT_TOKEN || process.env.LOOKUP_BOT_TOKEN || process.env.DISCORD_BOT_TOKEN;
if (!TOKEN) {
console.error('❌ Error: No bot token found');
console.error(' Set MEMBER_BOT_TOKEN in .env or use DISCORD_BOT_TOKEN');
process.exit(1);
}
const args = process.argv.slice(2);
if (args.length < 2) {
console.error('Usage: node scripts/lookup-with-dedicated-bot.js <input_file> <output_file>');
process.exit(1);
}
const inputFile = args[0];
const outputFile = args[1];
// Read user IDs
const userIds = fs.readFileSync(inputFile, 'utf-8')
.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0);
console.log(`✅ Loaded ${userIds.length} user IDs`);
// Load existing results
let results = {};
let processed = 0;
let errors = 0;
if (fs.existsSync(outputFile)) {
try {
const existing = JSON.parse(fs.readFileSync(outputFile, 'utf-8'));
results = existing.users || {};
processed = Object.keys(results).length;
errors = existing.errors || 0;
console.log(`📂 Found existing: ${processed} users`);
} catch (e) {
console.log(`⚠️ Starting fresh`);
}
}
// Create bot with MINIMAL intents
const client = new Client({
intents: [
GatewayIntentBits.Guilds // Only need this to stay in server
// NO other intents needed!
]
});
async function lookupUser(userId) {
if (results[userId]) return results[userId];
try {
const user = await client.users.fetch(userId);
return {
success: true,
id: user.id,
username: user.username,
globalName: user.globalName || user.username,
tag: user.tag,
bot: user.bot,
avatar: user.displayAvatarURL()
};
} catch (error) {
return {
success: false,
id: userId,
error: error.message,
username: null,
globalName: null,
tag: null,
bot: false
};
}
}
function saveResults() {
const output = {
timestamp: new Date().toISOString(),
total_users: userIds.length,
processed: processed,
successful: processed - errors,
errors: errors,
bot_type: (process.env.MEMBER_BOT_TOKEN || process.env.LOOKUP_BOT_TOKEN) ? 'dedicated' : 'main',
users: results
};
fs.writeFileSync(outputFile, JSON.stringify(output, null, 2));
}
async function processUsers() {
console.log('\n🚀 Starting lookups...');
const isDedicated = !!(process.env.MEMBER_BOT_TOKEN || process.env.LOOKUP_BOT_TOKEN);
console.log(` Bot type: ${isDedicated ? '✅ Dedicated lookup bot' : '⚠️ Main bot'}`);
console.log(` Rate: SLOW (1 user/second for safety)`);
console.log();
const startTime = Date.now();
const toProcess = userIds.filter(id => !results[id]);
console.log(` ${toProcess.length} users remaining\n`);
for (let i = 0; i < toProcess.length; i++) {
const userId = toProcess[i];
const result = await lookupUser(userId);
results[result.id] = result;
if (!result.success) errors++;
processed++;
// Save every 10 users for frequent updates
if (processed % 10 === 0) {
saveResults();
const elapsed = (Date.now() - startTime) / 1000;
const rate = (processed - (userIds.length - toProcess.length)) / elapsed;
const remaining = (toProcess.length - i - 1) / rate;
console.log(`💾 ${processed}/${userIds.length} (${errors} errors) - saved - ~${remaining.toFixed(0)}s left`);
}
// Very slow to avoid rate limits (1/second)
await new Promise(resolve => setTimeout(resolve, 1000));
}
saveResults();
const totalTime = (Date.now() - startTime) / 1000;
console.log(`\n${'='.repeat(60)}`);
console.log(`✅ Complete!`);
console.log(`${'='.repeat(60)}`);
console.log(` Time: ${totalTime.toFixed(1)}s`);
console.log(` Processed: ${processed}/${userIds.length}`);
console.log(` Successful: ${processed - errors}`);
console.log(` Errors: ${errors}`);
console.log(`\n💾 Saved to: ${outputFile}\n`);
process.exit(0);
}
client.once('ready', () => {
const isDedicated = !!(process.env.MEMBER_BOT_TOKEN || process.env.LOOKUP_BOT_TOKEN);
const botType = isDedicated ? 'DEDICATED LOOKUP BOT' : 'Main Bot';
console.log(`✅ Logged in as ${client.user.tag}`);
console.log(` Type: ${botType}`);
console.log();
processUsers();
});
client.on('error', (error) => {
console.error('❌ Error:', error.message);
});
process.on('SIGINT', () => {
console.log('\n\n⚠ Interrupted! Saving...');
saveResults();
console.log('✅ Saved. Resume by running same command.\n');
process.exit(0);
});
console.log('🔌 Connecting to Discord...');
client.login(TOKEN);