Autosave: 20260218-022345
This commit is contained in:
parent
0e42ce02fa
commit
efb0d9f141
24
bot.log
24
bot.log
@ -1,8 +1,16 @@
|
||||
Bot Starting...
|
||||
[dotenv@17.3.1] injecting env (2) from .env -- tip: 🛠️ run anywhere with `dotenvx run -- yourcommand`
|
||||
Keep-Alive aktif di port 8080
|
||||
Bot logged in as XiaoMao#2565
|
||||
Memulai refresh slash commands...
|
||||
(node:20667) DeprecationWarning: The ready event has been renamed to clientReady to distinguish it from the gateway READY event and will only emit under that name in v15. Please use clientReady instead.
|
||||
(Use `node --trace-deprecation ...` to show where the warning was created)
|
||||
Berhasil mendaftarkan slash commands!
|
||||
[dotenv@17.3.1] injecting env (2) from .env -- tip: ⚙️ override existing env vars with { override: true }
|
||||
Logging in...
|
||||
✅ Server Keep-Alive aktif di port 8080
|
||||
Unhandled Rejection: Error [TokenInvalid]: An invalid token was provided.
|
||||
at WebSocketManager.connect (/home/ubuntu/executor/workspace/node_modules/discord.js/src/client/websocket/WebSocketManager.js:140:26)
|
||||
at Client.login (/home/ubuntu/executor/workspace/node_modules/discord.js/src/client/Client.js:229:21)
|
||||
at Object.<anonymous> (/home/ubuntu/executor/workspace/index.js:206:8)
|
||||
at Module._compile (node:internal/modules/cjs/loader:1688:14)
|
||||
at Object..js (node:internal/modules/cjs/loader:1820:10)
|
||||
at Module.load (node:internal/modules/cjs/loader:1423:32)
|
||||
at Function._load (node:internal/modules/cjs/loader:1246:12)
|
||||
at TracingChannel.traceSync (node:diagnostics_channel:322:14)
|
||||
at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
|
||||
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:171:5) {
|
||||
code: 'TokenInvalid'
|
||||
}
|
||||
|
||||
192
index.js
192
index.js
@ -1,17 +1,22 @@
|
||||
console.log('Bot Starting...');
|
||||
const { Client, GatewayIntentBits, EmbedBuilder, PermissionsBitField, REST, Routes, SlashCommandBuilder } = require('discord.js');
|
||||
const { DisTube } = require('distube');
|
||||
const { YtDlpPlugin } = require('@distube/yt-dlp');
|
||||
const { YouTubePlugin } = require('@distube/youtube');
|
||||
const { GoogleGenerativeAI } = require('@google/generative-ai');
|
||||
const express = require('express');
|
||||
require('dotenv').config();
|
||||
|
||||
// 1. Keep-Alive System
|
||||
// 1. Keep-Alive Server (Port 8080)
|
||||
const app = express();
|
||||
app.get('/', (req, res) => res.send('Bot Musik Online!'));
|
||||
app.listen(process.env.PORT || 8080, () => console.log('Keep-Alive aktif di port ' + (process.env.PORT || 8080)));
|
||||
app.get('/', (req, res) => res.send('Wizzy Bot is Online!'));
|
||||
const PORT = process.env.PORT || 8080;
|
||||
app.listen(PORT, () => console.log(`✅ Server Keep-Alive aktif di port ${PORT}`));
|
||||
|
||||
// 2. Discord Client Setup
|
||||
// 2. Gemini AI Setup
|
||||
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
|
||||
const model = genAI.getGenerativeModel({ model: 'gemini-1.5-flash' });
|
||||
|
||||
// 3. Discord Client Setup
|
||||
const client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
@ -21,7 +26,7 @@ const client = new Client({
|
||||
]
|
||||
});
|
||||
|
||||
// 3. DisTube Setup
|
||||
// 4. DisTube Setup (Music)
|
||||
const distube = new DisTube(client, {
|
||||
emitNewSongOnly: true,
|
||||
emitAddSongWhenCreatingQueue: false,
|
||||
@ -32,8 +37,15 @@ const distube = new DisTube(client, {
|
||||
]
|
||||
});
|
||||
|
||||
// 4. Slash Commands Definition
|
||||
// 5. Slash Commands Definition
|
||||
const commands = [
|
||||
new SlashCommandBuilder()
|
||||
.setName('wizzy')
|
||||
.setDescription('Tanya Wizzy (Gemini AI)')
|
||||
.addStringOption(option =>
|
||||
option.setName('prompt')
|
||||
.setDescription('Pertanyaanmu untuk Wizzy')
|
||||
.setRequired(true)),
|
||||
new SlashCommandBuilder()
|
||||
.setName('play')
|
||||
.setDescription('Putar musik dari judul atau link')
|
||||
@ -58,123 +70,137 @@ const commands = [
|
||||
.setDescription('Lanjutkan musik'),
|
||||
].map(command => command.toJSON());
|
||||
|
||||
// 5. Interaction Handling
|
||||
// 6. Interaction Handling (Slash Commands)
|
||||
client.on('interactionCreate', async interaction => {
|
||||
await interaction.deferReply().catch(e => console.error(e));
|
||||
console.log('--- COMMAND DITERIMA: ' + interaction.commandName + ' ---');
|
||||
// ⚡ INSTANT DEFER: Prevent 3s Timeout
|
||||
if (interaction.isChatInputCommand()) {
|
||||
await interaction.deferReply().catch(e => console.error('Defer Error:', e));
|
||||
}
|
||||
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
console.log(`--- Perintah masuk: /${interaction.commandName} ---`);
|
||||
|
||||
const { commandName } = interaction;
|
||||
|
||||
// --- WIZZY (GEMINI AI) HANDLER ---
|
||||
if (commandName === 'wizzy') {
|
||||
try {
|
||||
const userInput = interaction.options.getString('prompt') ?? 'Halo!';
|
||||
const result = await model.generateContent(userInput);
|
||||
const response = result.response.text();
|
||||
const reply = response.length > 1990 ? response.substring(0, 1990) + '...' : response;
|
||||
await interaction.editReply(reply);
|
||||
} catch (error) {
|
||||
console.error('❌ Gemini Error:', error);
|
||||
await interaction.editReply({ content: '⚠️ Wizzy mengalami error, coba lagi nanti.', ephemeral: true });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// --- MUSIC HANDLERS ---
|
||||
if (commandName === 'play') {
|
||||
try {
|
||||
const query = interaction.options.getString('query');
|
||||
|
||||
if (!interaction.member.voice.channel) {
|
||||
return interaction.editReply('Kamu harus berada di voice channel untuk menggunakan bot ini!');
|
||||
return interaction.editReply('Kamu harus berada di voice channel!');
|
||||
}
|
||||
|
||||
// Memberikan feedback awal
|
||||
await interaction.editReply({ content: `🔍 Sedang mencari lagu: **${query}**...` });
|
||||
|
||||
await interaction.editReply({ content: `🔍 Mencari: **${query}**...` });
|
||||
await distube.play(interaction.member.voice.channel, query, {
|
||||
textChannel: interaction.channel,
|
||||
member: interaction.member,
|
||||
interaction
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Play Error:', error);
|
||||
await interaction.editReply({ content: `❌ Terjadi kesalahan: ${error.message}` });
|
||||
await interaction.editReply({ content: `❌ Error: ${error.message}` });
|
||||
}
|
||||
|
||||
} else {
|
||||
// Untuk command lain, kita tetap gunakan try-catch global
|
||||
} else if (commandName === 'skip') {
|
||||
try {
|
||||
if (!interaction.member.voice.channel) {
|
||||
return interaction.editReply('Kamu harus berada di voice channel!');
|
||||
}
|
||||
|
||||
if (commandName === 'skip') {
|
||||
const queue = distube.getQueue(interaction.guild);
|
||||
if (!queue) return interaction.editReply('❌ Tidak ada lagu yang sedang diputar!');
|
||||
await distube.skip(interaction.guild);
|
||||
await interaction.editReply('⏭️ Lagu berhasil dilewati!');
|
||||
|
||||
} else if (commandName === 'stop') {
|
||||
await distube.stop(interaction.guild);
|
||||
await interaction.editReply('⏹️ Musik dihentikan!');
|
||||
|
||||
} else if (commandName === 'pause') {
|
||||
const queue = distube.getQueue(interaction.guild);
|
||||
if (!queue) return interaction.editReply('❌ Tidak ada antrean!');
|
||||
distube.pause(interaction.guild);
|
||||
await interaction.editReply('⏸️ Musik dijeda!');
|
||||
|
||||
} else if (commandName === 'resume') {
|
||||
const queue = distube.getQueue(interaction.guild);
|
||||
if (!queue) return interaction.editReply('❌ Tidak ada antrean!');
|
||||
distube.resume(interaction.guild);
|
||||
await interaction.editReply('▶️ Musik dilanjutkan!');
|
||||
|
||||
} else if (commandName === 'queue') {
|
||||
const queue = distube.getQueue(interaction.guild);
|
||||
if (!queue) return interaction.editReply('📭 Antrean kosong!');
|
||||
const q = queue.songs
|
||||
.map((song, i) => `${i === 0 ? '▶️' : `${i}.`} ${song.name}`)
|
||||
.join('\n');
|
||||
await interaction.editReply(`🎶 **Antrean:**\n${q.slice(0, 1900)}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Interaction Error:', error);
|
||||
if (interaction.deferred || interaction.replied) {
|
||||
await interaction.editReply({ content: `❌ Error: ${error.message}` });
|
||||
}
|
||||
}
|
||||
const queue = distube.getQueue(interaction.guild);
|
||||
if (!queue) return interaction.editReply('❌ Tidak ada lagu!');
|
||||
await distube.skip(interaction.guild);
|
||||
await interaction.editReply('⏭️ Lagu dilewati!');
|
||||
} catch (e) { await interaction.editReply(`❌ Error: ${e.message}`); }
|
||||
} else if (commandName === 'stop') {
|
||||
try {
|
||||
await distube.stop(interaction.guild);
|
||||
await interaction.editReply('⏹️ Musik berhenti!');
|
||||
} catch (e) { await interaction.editReply(`❌ Error: ${e.message}`); }
|
||||
} else if (commandName === 'pause') {
|
||||
try {
|
||||
distube.pause(interaction.guild);
|
||||
await interaction.editReply('⏸️ Musik dijeda!');
|
||||
} catch (e) { await interaction.editReply(`❌ Error: ${e.message}`); }
|
||||
} else if (commandName === 'resume') {
|
||||
try {
|
||||
distube.resume(interaction.guild);
|
||||
await interaction.editReply('▶️ Musik lanjut!');
|
||||
} catch (e) { await interaction.editReply(`❌ Error: ${e.message}`); }
|
||||
} else if (commandName === 'queue') {
|
||||
try {
|
||||
const queue = distube.getQueue(interaction.guild);
|
||||
if (!queue) return interaction.editReply('📭 Antrean kosong!');
|
||||
const q = queue.songs.map((song, i) => `${i === 0 ? '▶️' : `${i}.`} ${song.name}`).join('\n');
|
||||
await interaction.editReply(`🎶 **Antrean:**\n${q.slice(0, 1900)}`);
|
||||
} catch (e) { await interaction.editReply(`❌ Error: ${e.message}`); }
|
||||
}
|
||||
});
|
||||
|
||||
// 6. DisTube Events
|
||||
// 7. Message Handling (Prefix Command !wizzy)
|
||||
client.on('messageCreate', async (message) => {
|
||||
if (message.author.bot) return;
|
||||
if (!message.content.startsWith('!wizzy ')) return;
|
||||
|
||||
const userInput = message.content.slice(7).trim();
|
||||
if (!userInput) return message.reply('Tulis pertanyaanmu!');
|
||||
|
||||
await message.channel.sendTyping();
|
||||
try {
|
||||
const result = await model.generateContent(userInput);
|
||||
const response = result.response.text();
|
||||
const reply = response.length > 1990 ? response.substring(0, 1990) + '...' : response;
|
||||
await message.reply(reply);
|
||||
} catch (error) {
|
||||
console.error('❌ Error Gemini (Prefix):', error);
|
||||
await message.reply('⚠️ Terjadi error pada Wizzy!');
|
||||
}
|
||||
});
|
||||
|
||||
// 8. DisTube Events
|
||||
distube
|
||||
.on('playSong', (queue, song) => {
|
||||
queue.textChannel.send(`🎶 Sedang memutar: **${song.name}** - \`${song.formattedDuration}\`\nDiminta oleh: ${song.user}`);
|
||||
queue.textChannel.send(`🎶 Memutar: **${song.name}** (\`${song.formattedDuration}\`)`);
|
||||
})
|
||||
.on('addSong', (queue, song) => {
|
||||
queue.textChannel.send(`✅ Menambahkan **${song.name}** ke antrean!`);
|
||||
queue.textChannel.send(`✅ Ditambahkan: **${song.name}**`);
|
||||
})
|
||||
.on('error', (channel, e) => {
|
||||
if (channel && channel.send) {
|
||||
const errorMessage = e && e.message ? e.message.slice(0, 1900) : "Unknown Error";
|
||||
channel.send(`❌ Error: ${errorMessage}`).catch(console.error);
|
||||
}
|
||||
if (channel?.send) channel.send(`❌ DisTube Error: ${e.message.slice(0, 1000)}`);
|
||||
console.error('DisTube Error:', e);
|
||||
});
|
||||
|
||||
// 7. Client Ready & Command Registration
|
||||
// 9. Ready Event & Command Registration
|
||||
client.once('ready', async () => {
|
||||
console.log(`Bot logged in as ${client.user.tag}`);
|
||||
console.log(`✅ Wizzy aktif sebagai ${client.user.tag}`);
|
||||
console.log('Bot siap memproses perintah!');
|
||||
|
||||
// Register Global Slash Commands
|
||||
const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);
|
||||
try {
|
||||
console.log('Memulai refresh slash commands...');
|
||||
console.log('Registering slash commands...');
|
||||
await rest.put(
|
||||
Routes.applicationCommands(client.user.id),
|
||||
{ body: commands },
|
||||
);
|
||||
console.log('Berhasil mendaftarkan slash commands!');
|
||||
console.log('Successfully registered slash commands!');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
console.error('Registration Error:', error);
|
||||
}
|
||||
});
|
||||
|
||||
// 8. Global Error Handling (Anti-Crash)
|
||||
process.on('unhandledRejection', error => {
|
||||
console.error('Unhandled promise rejection:', error);
|
||||
});
|
||||
// 10. Anti-Crash
|
||||
process.on('unhandledRejection', e => console.error('Unhandled Rejection:', e));
|
||||
process.on('uncaughtException', e => console.error('Uncaught Exception:', e));
|
||||
|
||||
process.on('uncaughtException', error => {
|
||||
console.error('Uncaught exception:', error);
|
||||
});
|
||||
|
||||
client.login('MTQ3Mjc2ODQ4NTQ0NzY5NjY1MA.Gx78sk.NGDrdd51zwcDbqyVrupL78RlUZdUSgmGvzn3pw');
|
||||
// 11. Login
|
||||
console.log('Logging in...');
|
||||
client.login(process.env.DISCORD_TOKEN);
|
||||
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
"@discordjs/voice": "^0.19.0",
|
||||
"@distube/youtube": "^1.0.4",
|
||||
"@distube/yt-dlp": "^2.0.1",
|
||||
"@google/generative-ai": "^0.24.1",
|
||||
"@snazzah/davey": "^0.1.9",
|
||||
"discord-api-types": "^0.38.39",
|
||||
"discord.js": "^14.25.1",
|
||||
@ -340,6 +341,15 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/generative-ai": {
|
||||
"version": "0.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
|
||||
"integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz",
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
"@discordjs/voice": "^0.19.0",
|
||||
"@distube/youtube": "^1.0.4",
|
||||
"@distube/yt-dlp": "^2.0.1",
|
||||
"@google/generative-ai": "^0.24.1",
|
||||
"@snazzah/davey": "^0.1.9",
|
||||
"discord-api-types": "^0.38.39",
|
||||
"discord.js": "^14.25.1",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user