clawdbot-workspace/create-discord-bot.js

161 lines
4.4 KiB
JavaScript

#!/usr/bin/env node
/**
* Create Discord Bot Programmatically
*
* Usage: node create-discord-bot.js <bot_name>
*
* Requires:
* - Discord user account token (from discord.com login)
* - 2FA enabled on Discord account
*/
const https = require('https');
// Discord API base URL
const DISCORD_API_HOST = 'discord.com';
const DISCORD_API_BASE = '/api/v10';
// User token (should be passed as env var or arg)
const USER_TOKEN = process.env.DISCORD_USER_TOKEN;
/**
* Make a request to Discord API
*/
function discordRequest(method, endpoint, data = null) {
return new Promise((resolve, reject) => {
const path = `${DISCORD_API_BASE}${endpoint}`;
const options = {
hostname: DISCORD_API_HOST,
port: 443,
path: path,
method: method,
headers: {
'Authorization': USER_TOKEN,
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'application/json',
}
};
console.log(`Request: ${method} https://${DISCORD_API_HOST}${path}`);
const req = https.request(options, (res) => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => {
console.log(`Response status: ${res.statusCode}`);
try {
const json = body ? JSON.parse(body) : {};
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(json);
} else {
reject(new Error(`Discord API error ${res.statusCode}: ${JSON.stringify(json)}`));
}
} catch (e) {
reject(new Error(`Failed to parse response: ${e.message}\nResponse: ${body.substring(0, 500)}`));
}
});
});
req.on('error', (error) => {
console.error('Request error:', error.message);
reject(error);
});
if (data) {
req.write(JSON.stringify(data));
}
req.end();
});
}
/**
* Create a new Discord application
*/
async function createApplication(name, description = '') {
const appData = {
name: name,
description: description || `Created by Clawdbot automated bot creator`,
flags: 0,
install_params: {
scopes: ['bot', 'applications.commands'],
permissions: '2147483647'
}
};
console.log(`Creating application: ${name}...`);
return await discordRequest('POST', '/applications', appData);
}
/**
* Add a bot user to an application
*/
async function addBotToApplication(applicationId, botUsername) {
const botData = {
username: botUsername || 'Bot'
};
console.log(`Adding bot to application ${applicationId}...`);
return await discordRequest('POST', `/applications/${applicationId}/bot`, botData);
}
/**
* Main function
*/
async function main() {
const botName = process.argv[2] || 'Buba Bot';
if (!USER_TOKEN) {
console.error('Error: DISCORD_USER_TOKEN environment variable is required');
console.error('Usage: DISCORD_USER_TOKEN=xxx node create-discord-bot.js <bot_name>');
process.exit(1);
}
try {
console.log('=== Discord Bot Creator ===');
console.log(`Bot name: ${botName}`);
console.log(`Token: ${USER_TOKEN.substring(0, 10)}...`);
console.log('');
// Step 1: Create application
const application = await createApplication(botName);
console.log(`✓ Application created: ${application.name}`);
console.log(` Application ID: ${application.id}\n`);
// Step 2: Add bot to application
const bot = await addBotToApplication(application.id, botName);
console.log(`✓ Bot added to application`);
console.log(` Bot ID: ${bot.id}`);
console.log(` Bot Username: ${bot.username}`);
console.log(` Bot Token: ${bot.token}`);
console.log(` ⚠️ Save this token! You won't see it again.\n`);
// Step 3: Generate OAuth2 URL for bot invite
const inviteUrl = `https://discord.com/api/oauth2/authorize?client_id=${application.id}&permissions=2147483647&scope=bot%20applications.commands`;
console.log(`✓ Invite URL: ${inviteUrl}\n`);
// Step 4: Output config snippet
console.log('=== Clawdbot Config Snippet ===');
console.log(`{
"id": "${botName.toLowerCase().replace(/\s+/g, '-')}",
"token": "${bot.token}",
"identity": {
"name": "${botName}",
"theme": "AI Assistant",
"emoji": "🤖"
}
}`);
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
}
if (require.main === module) {
main();
}