200 lines
6.8 KiB
JavaScript
200 lines
6.8 KiB
JavaScript
process.env.FFMPEG_PATH = require('ffmpeg-static');
|
|
console.log('Bot starting...');
|
|
|
|
const { Client, GatewayIntentBits, SlashCommandBuilder, Routes } = require('discord.js');
|
|
const { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus, VoiceConnectionStatus, entersState } = require('@discordjs/voice');
|
|
const { REST } = require('@discordjs/rest');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const configPath = path.join(__dirname, 'data/config.json');
|
|
|
|
function loadConfig() {
|
|
if (fs.existsSync(configPath)) {
|
|
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
}
|
|
return {};
|
|
}
|
|
|
|
const config = loadConfig();
|
|
const token = config.discord_token;
|
|
|
|
if (!token) {
|
|
console.error('No Discord Token found in data/config.json');
|
|
process.exit(1);
|
|
}
|
|
|
|
const client = new Client({
|
|
intents: [
|
|
GatewayIntentBits.Guilds,
|
|
GatewayIntentBits.GuildVoiceStates,
|
|
]
|
|
});
|
|
|
|
const player = createAudioPlayer();
|
|
|
|
player.on('error', error => {
|
|
console.error('Audio Player Error:', error.message);
|
|
});
|
|
|
|
client.on('ready', async () => {
|
|
console.log(`Logged in as ${client.user.tag}`);
|
|
|
|
// Register commands
|
|
const commands = [
|
|
new SlashCommandBuilder()
|
|
.setName('testsahur')
|
|
.setDescription('Memutar file audio sahur'),
|
|
new SlashCommandBuilder()
|
|
.setName('join')
|
|
.setDescription('Menyuruh bot join ke voice channel kamu'),
|
|
new SlashCommandBuilder()
|
|
.setName('stop')
|
|
.setDescription('Menghentikan pemutaran audio')
|
|
].map(command => command.toJSON());
|
|
|
|
const rest = new REST({ version: '10' }).setToken(token);
|
|
try {
|
|
console.log('Started refreshing application (/) commands.');
|
|
await rest.put(Routes.applicationCommands(client.user.id), { body: commands });
|
|
console.log('Successfully reloaded application (/) commands.');
|
|
} catch (error) {
|
|
console.error('Error reloading commands:', error);
|
|
}
|
|
|
|
// Auto-reconnect to last voice channel
|
|
const currentConfig = loadConfig();
|
|
const lastVoice = currentConfig.last_voice_channel;
|
|
if (lastVoice && lastVoice.guildId && lastVoice.channelId) {
|
|
console.log(`Auto-rejoining channel ${lastVoice.channelId}`);
|
|
joinVC(lastVoice.guildId, lastVoice.channelId);
|
|
}
|
|
});
|
|
|
|
function joinVC(gId, cId) {
|
|
const guild = client.guilds.cache.get(gId);
|
|
if (!guild) {
|
|
console.error(`Guild ${gId} not found in cache`);
|
|
return;
|
|
}
|
|
|
|
const connection = joinVoiceChannel({
|
|
channelId: cId,
|
|
guildId: gId,
|
|
adapterCreator: guild.voiceAdapterCreator,
|
|
selfDeaf: false,
|
|
});
|
|
|
|
connection.on(VoiceConnectionStatus.Disconnected, async () => {
|
|
try {
|
|
await Promise.race([
|
|
entersState(connection, VoiceConnectionStatus.Signalling, 5_000),
|
|
entersState(connection, VoiceConnectionStatus.Connecting, 5_000),
|
|
]);
|
|
} catch (error) {
|
|
console.log('Connection lost, attempting to reconnect...');
|
|
setTimeout(() => joinVC(gId, cId), 5000);
|
|
}
|
|
});
|
|
|
|
connection.on('error', error => {
|
|
console.error('Voice Connection Error:', error);
|
|
});
|
|
|
|
connection.subscribe(player);
|
|
}
|
|
|
|
client.on('interactionCreate', async interaction => {
|
|
if (!interaction.isChatInputCommand()) return;
|
|
|
|
try {
|
|
if (interaction.commandName === 'testsahur') {
|
|
const member = interaction.member;
|
|
if (!member.voice.channel) {
|
|
return interaction.reply('Kamu harus berada di Voice Channel!');
|
|
}
|
|
|
|
const channel = member.voice.channel;
|
|
const gId = interaction.guildId;
|
|
const cId = channel.id;
|
|
|
|
// Save last channel
|
|
const currentConfig = loadConfig();
|
|
currentConfig.last_voice_channel = { guildId: gId, channelId: cId };
|
|
fs.writeFileSync(configPath, JSON.stringify(currentConfig, null, 2));
|
|
|
|
joinVC(gId, cId);
|
|
|
|
const audioPath = path.join(__dirname, 'assets/audio/sahur.mp3');
|
|
if (!fs.existsSync(audioPath)) {
|
|
return interaction.reply(`File audio tidak ditemukan: ${audioPath}`);
|
|
}
|
|
|
|
const resource = createAudioResource(audioPath);
|
|
player.play(resource);
|
|
|
|
await interaction.reply('🔊 Memutar audio Sahur!');
|
|
} else if (interaction.commandName === 'join') {
|
|
const member = interaction.member;
|
|
if (!member.voice.channel) {
|
|
return interaction.reply('Kamu harus berada di Voice Channel!');
|
|
}
|
|
|
|
const channel = member.voice.channel;
|
|
const gId = interaction.guildId;
|
|
const cId = channel.id;
|
|
|
|
// Save last channel
|
|
const currentConfig = loadConfig();
|
|
currentConfig.last_voice_channel = { guildId: gId, channelId: cId };
|
|
fs.writeFileSync(configPath, JSON.stringify(currentConfig, null, 2));
|
|
|
|
joinVC(gId, cId);
|
|
await interaction.reply('✅ Bot telah bergabung ke Voice Channel!');
|
|
} else if (interaction.commandName === 'stop') {
|
|
player.stop();
|
|
await interaction.reply('🛑 Audio dihentikan.');
|
|
}
|
|
} catch (error) {
|
|
console.error('Interaction Error:', error);
|
|
if (interaction.replied || interaction.deferred) {
|
|
await interaction.followUp({ content: 'Terjadi kesalahan saat menjalankan command!', ephemeral: true });
|
|
} else {
|
|
await interaction.reply({ content: 'Terjadi kesalahan saat menjalankan command!', ephemeral: true });
|
|
}
|
|
}
|
|
});
|
|
|
|
let lastAlarmMinute = -1;
|
|
setInterval(() => {
|
|
const now = new Date();
|
|
const currentMinute = now.getMinutes();
|
|
|
|
if (currentMinute !== lastAlarmMinute) {
|
|
lastAlarmMinute = currentMinute;
|
|
|
|
const currentTime = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
|
|
const currentConfig = loadConfig();
|
|
|
|
if (currentConfig.alarm_time === currentTime) {
|
|
console.log(`Alarm triggered at ${currentTime}`);
|
|
const lastVoice = currentConfig.last_voice_channel;
|
|
|
|
if (lastVoice && lastVoice.guildId && lastVoice.channelId) {
|
|
try {
|
|
joinVC(lastVoice.guildId, lastVoice.channelId);
|
|
const audioPath = path.join(__dirname, 'assets/audio/sahur.mp3');
|
|
if (fs.existsSync(audioPath)) {
|
|
const resource = createAudioResource(audioPath);
|
|
player.play(resource);
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to trigger alarm VC:', e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, 30000); // Check every 30 seconds
|
|
|
|
client.login(token);
|