Describe what you changed

This commit is contained in:
samkintop
2026-02-22 19:05:08 -06:00
parent 7893f555fa
commit f189c43a85

View File

@@ -1,237 +1,237 @@
#!/usr/bin/env node
/**
* Discord user lookup WITH ROLES
*
* Fetches:
* - User info (username, display name, avatar)
* - Guild member info (roles, join date, server nickname)
* - All Palpocalypse server roles
*
* Requires: Server Members Intent enabled in Discord Developer Portal
*/
const fs = require('fs');
const path = require('path');
const { Client, GatewayIntentBits } = require('discord.js');
require('dotenv').config({ path: path.join(__dirname, '../../.env') });
const TOKEN = process.env.MEMBER_BOT_TOKEN || process.env.DISCORD_BOT_TOKEN;
const GUILD_ID = '798321161082896395'; // Indifferent Broccoli server
if (!TOKEN) {
console.error('❌ Error: No bot token found');
process.exit(1);
}
const args = process.argv.slice(2);
if (args.length < 2) {
console.error('Usage: node scripts/lookup-with-roles.js <input_file> <output_file>');
process.exit(1);
}
const inputFile = args[0];
const outputFile = args[1];
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`);
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`);
}
}
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers // Required for roles!
]
});
let guild = null;
async function lookupUserWithRoles(userId) {
if (results[userId]) return results[userId];
try {
// Fetch basic user info
const user = await client.users.fetch(userId);
// Try to fetch guild member (for roles)
let roles = [];
let serverNickname = null;
let joinedAt = null;
let isInServer = false;
try {
const member = await guild.members.fetch(userId);
isInServer = true;
serverNickname = member.nickname;
joinedAt = member.joinedAt ? member.joinedAt.toISOString() : null;
// Get all roles except @everyone
roles = member.roles.cache
.filter(role => role.name !== '@everyone')
.map(role => ({
id: role.id,
name: role.name,
color: role.hexColor,
position: role.position
}))
.sort((a, b) => b.position - a.position); // Highest role first
} catch (memberError) {
// User exists but not in this server
isInServer = false;
}
return {
success: true,
id: user.id,
username: user.username,
globalName: user.globalName || user.username,
tag: user.tag,
bot: user.bot,
avatar: user.displayAvatarURL(),
// Server-specific data
server_nickname: serverNickname,
joined_at: joinedAt,
in_server: isInServer,
roles: roles,
role_names: roles.map(r => r.name),
highest_role: roles[0]?.name || null
};
} catch (error) {
return {
success: false,
id: userId,
error: error.message,
username: null,
globalName: null,
roles: []
};
}
}
function saveResults() {
const output = {
timestamp: new Date().toISOString(),
total_users: userIds.length,
processed: processed,
successful: processed - errors,
errors: errors,
guild_id: GUILD_ID,
includes_roles: true,
users: results
};
fs.writeFileSync(outputFile, JSON.stringify(output, null, 2));
}
async function processUsers() {
console.log('\n🎭 Starting lookups WITH ROLES...');
console.log(` Guild ID: ${GUILD_ID}`);
console.log(` Rate: 1 user/second\n`);
// Fetch guild
guild = await client.guilds.fetch(GUILD_ID);
console.log(`✅ Connected to: ${guild.name}\n`);
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 lookupUserWithRoles(userId);
results[result.id] = result;
if (!result.success) errors++;
processed++;
// Save every 10 users
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;
// Show sample with roles
if (result.success && result.roles.length > 0) {
const rolePreview = result.role_names.slice(0, 2).join(', ');
console.log(`💾 ${processed}/${userIds.length} - ${result.globalName} [${rolePreview}] - ~${remaining.toFixed(0)}s left`);
} else {
console.log(`💾 ${processed}/${userIds.length} (${errors} errors) - ~${remaining.toFixed(0)}s left`);
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
saveResults();
const totalTime = (Date.now() - startTime) / 1000;
// Stats
const usersWithRoles = Object.values(results).filter(u => u.success && u.roles.length > 0).length;
const allRoleNames = new Set();
Object.values(results).forEach(u => {
if (u.success) {
u.role_names?.forEach(r => allRoleNames.add(r));
}
});
console.log(`\n${'='.repeat(70)}`);
console.log(`✅ Complete with Roles!`);
console.log(`${'='.repeat(70)}`);
console.log(` Time: ${totalTime.toFixed(1)}s`);
console.log(` Processed: ${processed}/${userIds.length}`);
console.log(` Successful: ${processed - errors}`);
console.log(` Users with roles: ${usersWithRoles}`);
console.log(` Unique roles found: ${allRoleNames.size}`);
console.log(`\n💾 Saved to: ${outputFile}\n`);
// Show some roles
if (allRoleNames.size > 0) {
console.log('📋 Sample roles found:');
Array.from(allRoleNames).slice(0, 10).forEach(r => console.log(`${r}`));
}
process.exit(0);
}
client.once('ready', () => {
console.log(`✅ Logged in as ${client.user.tag}\n`);
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);
#!/usr/bin/env node
/**
* Discord user lookup WITH ROLES
*
* Fetches:
* - User info (username, display name, avatar)
* - Guild member info (roles, join date, server nickname)
* - All Palpocalypse server roles
*
* Requires: Server Members Intent enabled in Discord Developer Portal
*/
const fs = require('fs');
const path = require('path');
const { Client, GatewayIntentBits } = require('discord.js');
require('dotenv').config({ path: path.join(__dirname, '../../.env') });
const TOKEN = process.env.MEMBER_BOT_TOKEN || process.env.DISCORD_BOT_TOKEN;
const GUILD_ID = '798321161082896395'; // Indifferent Broccoli server
if (!TOKEN) {
console.error('❌ Error: No bot token found');
process.exit(1);
}
const args = process.argv.slice(2);
if (args.length < 2) {
console.error('Usage: node scripts/lookup-with-roles.js <input_file> <output_file>');
process.exit(1);
}
const inputFile = args[0];
const outputFile = args[1];
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`);
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`);
}
}
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers // Required for roles!
]
});
let guild = null;
async function lookupUserWithRoles(userId) {
if (results[userId]) return results[userId];
try {
// Fetch basic user info
const user = await client.users.fetch(userId);
// Try to fetch guild member (for roles)
let roles = [];
let serverNickname = null;
let joinedAt = null;
let isInServer = false;
try {
const member = await guild.members.fetch(userId);
isInServer = true;
serverNickname = member.nickname;
joinedAt = member.joinedAt ? member.joinedAt.toISOString() : null;
// Get all roles except @everyone
roles = member.roles.cache
.filter(role => role.name !== '@everyone')
.map(role => ({
id: role.id,
name: role.name,
color: role.hexColor,
position: role.position
}))
.sort((a, b) => b.position - a.position); // Highest role first
} catch (memberError) {
// User exists but not in this server
isInServer = false;
}
return {
success: true,
id: user.id,
username: user.username,
globalName: user.globalName || user.username,
tag: user.tag,
bot: user.bot,
avatar: user.displayAvatarURL(),
// Server-specific data
server_nickname: serverNickname,
joined_at: joinedAt,
in_server: isInServer,
roles: roles,
role_names: roles.map(r => r.name),
highest_role: roles[0]?.name || null
};
} catch (error) {
return {
success: false,
id: userId,
error: error.message,
username: null,
globalName: null,
roles: []
};
}
}
function saveResults() {
const output = {
timestamp: new Date().toISOString(),
total_users: userIds.length,
processed: processed,
successful: processed - errors,
errors: errors,
guild_id: GUILD_ID,
includes_roles: true,
users: results
};
fs.writeFileSync(outputFile, JSON.stringify(output, null, 2));
}
async function processUsers() {
console.log('\n🎭 Starting lookups WITH ROLES...');
console.log(` Guild ID: ${GUILD_ID}`);
console.log(` Rate: 1 user/second\n`);
// Fetch guild
guild = await client.guilds.fetch(GUILD_ID);
console.log(`✅ Connected to: ${guild.name}\n`);
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 lookupUserWithRoles(userId);
results[result.id] = result;
if (!result.success) errors++;
processed++;
// Save every 10 users
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;
// Show sample with roles
if (result.success && result.roles.length > 0) {
const rolePreview = result.role_names.slice(0, 2).join(', ');
console.log(`💾 ${processed}/${userIds.length} - ${result.globalName} [${rolePreview}] - ~${remaining.toFixed(0)}s left`);
} else {
console.log(`💾 ${processed}/${userIds.length} (${errors} errors) - ~${remaining.toFixed(0)}s left`);
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
saveResults();
const totalTime = (Date.now() - startTime) / 1000;
// Stats
const usersWithRoles = Object.values(results).filter(u => u.success && u.roles.length > 0).length;
const allRoleNames = new Set();
Object.values(results).forEach(u => {
if (u.success) {
u.role_names?.forEach(r => allRoleNames.add(r));
}
});
console.log(`\n${'='.repeat(70)}`);
console.log(`✅ Complete with Roles!`);
console.log(`${'='.repeat(70)}`);
console.log(` Time: ${totalTime.toFixed(1)}s`);
console.log(` Processed: ${processed}/${userIds.length}`);
console.log(` Successful: ${processed - errors}`);
console.log(` Users with roles: ${usersWithRoles}`);
console.log(` Unique roles found: ${allRoleNames.size}`);
console.log(`\n💾 Saved to: ${outputFile}\n`);
// Show some roles
if (allRoleNames.size > 0) {
console.log('📋 Sample roles found:');
Array.from(allRoleNames).slice(0, 10).forEach(r => console.log(`${r}`));
}
process.exit(0);
}
client.once('ready', () => {
console.log(`✅ Logged in as ${client.user.tag}\n`);
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);