155 lines
4.4 KiB
JavaScript
155 lines
4.4 KiB
JavaScript
// --- ENCRYPTION & AUDIO CONFIG ---
|
|
// Wajib di baris paling atas agar enkripsi Discord terdeteksi dengan benar
|
|
require('libsodium-wrappers');
|
|
const ffmpeg = require('ffmpeg-static');
|
|
process.env.FFMPEG_PATH = ffmpeg;
|
|
|
|
// --- DAVE PROTOCOL FIX ---
|
|
try {
|
|
require('@snazzah/davey');
|
|
} catch (e) {
|
|
console.warn('Warning: @snazzah/davey not found, but is recommended for DAVE protocol.');
|
|
}
|
|
|
|
const http = require('http');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// --- KEEP ALIVE ---
|
|
// Membuat server sederhana agar bot merespons ping dari sistem
|
|
// Port 8080 digunakan untuk internal health check
|
|
http.createServer((req, res) => {
|
|
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
res.write('Bot is Online and Healthy');
|
|
res.end();
|
|
}).listen(8080, '0.0.0.0', () => {
|
|
console.log('Keep-Alive server is running on port 8080');
|
|
});
|
|
|
|
// --- ERROR HANDLING ---
|
|
// Mencegah bot mati jika terjadi error yang tidak terduga
|
|
process.on('unhandledRejection', error => {
|
|
console.error('Unhandled promise rejection:', error);
|
|
});
|
|
|
|
process.on('uncaughtException', error => {
|
|
console.error('Uncaught exception:', error);
|
|
});
|
|
|
|
const {
|
|
Client,
|
|
GatewayIntentBits
|
|
} = require('discord.js');
|
|
const {
|
|
joinVoiceChannel,
|
|
createAudioPlayer,
|
|
createAudioResource,
|
|
AudioPlayerStatus,
|
|
VoiceConnectionStatus,
|
|
getVoiceConnection
|
|
} = require('@discordjs/voice');
|
|
|
|
// --- CONFIGURATION ---
|
|
let TOKEN, CLIENT_ID;
|
|
try {
|
|
const config = require('./config.json');
|
|
TOKEN = config.DISCORD_TOKEN;
|
|
CLIENT_ID = config.DISCORD_CLIENT_ID;
|
|
} catch (err) {
|
|
console.warn('Warning: config.json not found. Using environment variables if available.');
|
|
TOKEN = process.env.DISCORD_TOKEN;
|
|
CLIENT_ID = process.env.DISCORD_CLIENT_ID;
|
|
}
|
|
|
|
if (!TOKEN) {
|
|
console.error('ERROR: DISCORD_TOKEN is missing. Please set it in the dashboard.');
|
|
}
|
|
|
|
const client = new Client({
|
|
intents: [
|
|
GatewayIntentBits.Guilds,
|
|
GatewayIntentBits.GuildVoiceStates,
|
|
]
|
|
});
|
|
|
|
// Helper function to join voice
|
|
function connectToVoice(interaction) {
|
|
const member = interaction.member;
|
|
const voiceChannel = member.voice.channel;
|
|
|
|
if (!voiceChannel) {
|
|
throw new Error('Kamu harus berada di Voice Channel untuk menggunakan perintah ini!');
|
|
}
|
|
|
|
return joinVoiceChannel({
|
|
channelId: voiceChannel.id,
|
|
guildId: interaction.guildId,
|
|
adapterCreator: interaction.guild.voiceAdapterCreator,
|
|
selfDeaf: false,
|
|
selfMute: false,
|
|
});
|
|
}
|
|
|
|
client.on('clientReady', () => {
|
|
console.log(`Logged in as ${client.user.tag}!`);
|
|
console.log('Bot Status: Online');
|
|
});
|
|
|
|
client.on('interactionCreate', async interaction => {
|
|
if (!interaction.isChatInputCommand()) return;
|
|
|
|
const { commandName } = interaction;
|
|
|
|
if (commandName === 'join') {
|
|
await interaction.deferReply();
|
|
try {
|
|
connectToVoice(interaction);
|
|
await interaction.editReply('Berhasil masuk ke Voice Channel!');
|
|
} catch (error) {
|
|
await interaction.editReply({ content: error.message, ephemeral: true });
|
|
}
|
|
}
|
|
|
|
if (commandName === 'sahur') {
|
|
await interaction.deferReply();
|
|
|
|
try {
|
|
let connection = getVoiceConnection(interaction.guild.id);
|
|
|
|
if (!connection) {
|
|
connection = connectToVoice(interaction);
|
|
}
|
|
|
|
const player = createAudioPlayer();
|
|
const resource = createAudioResource(path.join(process.cwd(), 'sahur.mp3'));
|
|
|
|
connection.subscribe(player);
|
|
player.play(resource);
|
|
|
|
console.log('Bot Status: Playing');
|
|
await interaction.editReply('🔊 Sedang memutar alarm sahur!');
|
|
|
|
player.on(AudioPlayerStatus.Idle, () => {
|
|
console.log('Bot Status: Finished playing (Idle)');
|
|
});
|
|
|
|
player.on('error', e => {
|
|
console.error('ERROR_AUDIO:', e.message);
|
|
interaction.followUp({ content: 'Terjadi kesalahan saat memutar audio.', ephemeral: true });
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('ERROR:', error);
|
|
await interaction.editReply(error.message || 'Gagal memutar audio.');
|
|
}
|
|
}
|
|
});
|
|
|
|
if (TOKEN) {
|
|
client.login(TOKEN).catch(err => {
|
|
console.error('Login failed:', err.message);
|
|
});
|
|
} else {
|
|
console.log('Bot Status: Waiting for token setup...');
|
|
}
|