97 lines
3.3 KiB
JavaScript
97 lines
3.3 KiB
JavaScript
process.env.FFMPEG_PATH = require('ffmpeg-static');
|
|
const { Client, GatewayIntentBits, SlashCommandBuilder, Routes } = require('discord.js');
|
|
const { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus } = require('@discordjs/voice');
|
|
const { REST } = require('@discordjs/rest');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Load Discord Token
|
|
const configPath = path.join(__dirname, 'data/config.json');
|
|
const config = fs.existsSync(configPath) ? JSON.parse(fs.readFileSync(configPath, 'utf8')) : {};
|
|
const token = config.discord_token;
|
|
|
|
if (!token) {
|
|
console.error('ERROR: discord_token not found in data/config.json');
|
|
process.exit(1);
|
|
}
|
|
|
|
const client = new Client({
|
|
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates]
|
|
});
|
|
|
|
const player = createAudioPlayer();
|
|
|
|
// Stay 24/7 Logic: Do nothing when idle (prevents automatic leave)
|
|
player.on(AudioPlayerStatus.Idle, () => {
|
|
console.log('Audio finished. Bot is staying in the channel (Stay 24/7).');
|
|
});
|
|
|
|
player.on('error', error => console.error('Audio Player Error:', error));
|
|
|
|
async function deployCommands(clientId) {
|
|
const commands = [
|
|
new SlashCommandBuilder().setName('join').setDescription('Bot masuk ke Voice Channel user'),
|
|
new SlashCommandBuilder().setName('testsahur').setDescription('Memutar file sahur secara instan')
|
|
].map(cmd => cmd.toJSON());
|
|
|
|
const rest = new REST({ version: '10' }).setToken(token);
|
|
try {
|
|
await rest.put(Routes.applicationCommands(clientId), { body: commands });
|
|
console.log('Slash commands deployed successfully.');
|
|
} catch (err) {
|
|
console.error('Failed to deploy commands:', err);
|
|
}
|
|
}
|
|
|
|
client.on('ready', async () => {
|
|
console.log(`Bot logged in as ${client.user.tag}`);
|
|
await deployCommands(client.user.id);
|
|
});
|
|
|
|
client.on('interactionCreate', async interaction => {
|
|
if (!interaction.isChatInputCommand()) return;
|
|
|
|
// Anti-Timeout logic
|
|
if (!interaction.deferred) await interaction.deferReply();
|
|
|
|
const { commandName, member } = interaction;
|
|
|
|
if (!member.voice.channel) {
|
|
return interaction.editReply('Silakan masuk ke Voice Channel terlebih dahulu!');
|
|
}
|
|
|
|
try {
|
|
const connection = joinVoiceChannel({
|
|
channelId: member.voice.channel.id,
|
|
guildId: interaction.guildId,
|
|
adapterCreator: interaction.guild.voiceAdapterCreator,
|
|
selfDeaf: false,
|
|
selfMute: false,
|
|
});
|
|
|
|
connection.subscribe(player);
|
|
|
|
if (commandName === 'join') {
|
|
return interaction.editReply('Sudah join! 🎵');
|
|
}
|
|
|
|
if (commandName === 'testsahur') {
|
|
const audioPath = path.join(__dirname, 'assets/audio/sahur.mp3');
|
|
if (!fs.existsSync(audioPath)) {
|
|
return interaction.editReply('File ./assets/audio/sahur.mp3 tidak ditemukan!');
|
|
}
|
|
|
|
const resource = createAudioResource(audioPath, { inlineVolume: true });
|
|
resource.volume.setVolume(1.0); // Max Volume
|
|
player.play(resource);
|
|
|
|
return interaction.editReply('Memutar suara sahur... 🔊');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error during interaction:', error);
|
|
return interaction.editReply('Terjadi kesalahan teknis.');
|
|
}
|
|
});
|
|
|
|
client.login(token);
|