38481-vm/index.js
2026-02-17 07:49:55 +00:00

140 lines
5.0 KiB
JavaScript

process.env.FFMPEG_PATH = require('ffmpeg-static');
require('opusscript');
require('libsodium-wrappers');
const { Client, GatewayIntentBits, SlashCommandBuilder, Routes } = require('discord.js');
const { joinVoiceChannel, createAudioPlayer, createAudioResource, StreamType, getVoiceConnection } = require('@discordjs/voice');
const fs = require('fs');
const path = require('path');
const { REST } = require('@discordjs/rest');
// Load Config
const configPath = path.join(__dirname, 'data/config.json');
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
const token = config.discord_token;
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates]
});
const player = createAudioPlayer();
// Monitoring Status
player.on('stateChange', (oldState, newState) => {
console.log(`Status Player: ${newState.status}`);
});
player.on('error', error => {
console.log('ERROR AUDIO:', error.message);
});
client.on('ready', async () => {
console.log(`Bot Sahur Online: ${client.user.tag}`);
const commands = [
new SlashCommandBuilder().setName('join').setDescription('Perintah untuk bot masuk ke Voice Channel'),
new SlashCommandBuilder().setName('testsahur').setDescription('Perintah untuk memutar suara alarm sahur')
].map(cmd => cmd.toJSON());
const rest = new REST({ version: '10' }).setToken(token);
try {
await rest.put(Routes.applicationCommands(client.user.id), { body: commands });
console.log('Slash Commands Berhasil Didaftarkan.');
} catch (err) {
console.error('Gagal daftar command:', err);
}
});
client.on('interactionCreate', async interaction => {
if (!interaction.isChatInputCommand()) return;
// 1. PERINTAH JOIN (Hanya Masuk)
if (interaction.commandName === 'join') {
await interaction.deferReply();
const channel = interaction.member.voice.channel;
if (!channel) {
return interaction.editReply('❌ Kamu harus masuk ke Voice Channel dulu!');
}
const connection = joinVoiceChannel({
channelId: channel.id,
guildId: interaction.guildId,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false,
debug: true
});
// Keep-Alive Logic
connection.on('stateChange', (oldState, newState) => {
if (newState.status === 'disconnected') {
console.log('Bot terputus, mencoba masuk kembali...');
try {
joinVoiceChannel({
channelId: channel.id,
guildId: interaction.guildId,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false
});
} catch (e) {
console.log('Gagal rejoin:', e.message);
}
}
});
console.log('Bot masuk voice!');
await interaction.editReply('✅ Bot sudah masuk ke Voice Channel. Siap untuk /testsahur!');
}
// 2. PERINTAH TESTSAHUR (Auto-Join & Play)
if (interaction.commandName === 'testsahur') {
await interaction.deferReply();
let connection = getVoiceConnection(interaction.guildId);
const channel = interaction.member.voice.channel;
// Auto-Reconnect: Jika tidak ada koneksi, join dulu
if (!connection) {
if (!channel) {
return interaction.editReply('❌ Bot tidak di VC dan kamu juga tidak di VC. Join VC dulu!');
}
console.log('Connection tidak ditemukan, mencoba auto-join...');
connection = joinVoiceChannel({
channelId: channel.id,
guildId: interaction.guildId,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false
});
}
try {
const audioPath = path.join(process.cwd(), 'assets', 'audio', 'sahur.mp3');
console.log('Membaca file audio di:', audioPath);
if (!fs.existsSync(audioPath)) {
return interaction.editReply('❌ File audio tidak ditemukan!');
}
const resource = createAudioResource(audioPath, {
inputType: StreamType.Arbitrary,
inlineVolume: true
});
resource.volume.setVolume(1.5);
connection.subscribe(player);
player.play(resource);
console.log('Kabel audio tersambung dan suara diputar!');
await interaction.editReply('🔊 Sedang memutar alarm sahur (Auto-Connect Aktif)...');
} catch (error) {
console.log('ERROR AUDIO:', error.message);
await interaction.editReply('❌ Terjadi kesalahan: ' + error.message);
}
}
});
client.login(token);