This commit is contained in:
Flatlogic Bot 2026-02-18 09:24:47 +00:00
parent eb4f306c8d
commit 68832bd914
2 changed files with 123 additions and 79 deletions

11
bot.log
View File

@ -1,11 +1,10 @@
[dotenv@17.3.1] injecting env (7) from .env -- tip: ⚙️ write to custom object with { processEnv: myObject } [dotenv@17.3.1] injecting env (7) from .env -- tip: 🔐 prevent committing .env to code: https://dotenvx.com/precommit
Dashboard running at http://localhost:8080 Keep-Alive server running on port 8080
Bot logged in as XiaoMao#2565 Bot logged in as XiaoMao#2565
Started refreshing application (/) commands. Mendaftarkan ulang slash commands (setelah reset)...
Scheduled sahur at 3:0 (node:7936) 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.
(node:7171) 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) (Use `node --trace-deprecation ...` to show where the warning was created)
Successfully reloaded application (/) commands. Berhasil mendaftarkan command: /join, /test_sahur
/home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:746 /home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:746
throw new Error( throw new Error(
^ ^

191
index.js
View File

@ -1,17 +1,13 @@
require('dotenv').config(); require('dotenv').config();
const { const { Client, GatewayIntentBits, REST, Routes, SlashCommandBuilder } = require('discord.js');
Client,
GatewayIntentBits,
REST,
Routes,
SlashCommandBuilder
} = require('discord.js');
const { const {
joinVoiceChannel, joinVoiceChannel,
createAudioPlayer, createAudioPlayer,
createAudioResource, createAudioResource,
AudioPlayerStatus, AudioPlayerStatus,
NoSubscriberBehavior NoSubscriberBehavior,
VoiceConnectionStatus,
enterState
} = require('@discordjs/voice'); } = require('@discordjs/voice');
const express = require('express'); const express = require('express');
const fs = require('fs'); const fs = require('fs');
@ -22,15 +18,18 @@ const DISCORD_TOKEN = process.env.DISCORD_TOKEN;
const CLIENT_ID = process.env.CLIENT_ID; const CLIENT_ID = process.env.CLIENT_ID;
const GUILD_ID = process.env.GUILD_ID; const GUILD_ID = process.env.GUILD_ID;
// Keep-Alive Server
const app = express(); const app = express();
const port = 8080; const port = 8080;
app.get('/', (req, res) => res.send('Bot Sahur is Alive! 🌙'));
app.listen(port, () => console.log(`Keep-Alive server running on port ${port}`));
// Discord Client // Discord Client
const client = new Client({ const client = new Client({
intents: [ intents: [
GatewayIntentBits.Guilds, GatewayIntentBits.Guilds,
GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildVoiceStates
] ]
}); });
let player = null; let player = null;
@ -39,36 +38,50 @@ let isLooping = false;
// Function to play local sahur.mp3 // Function to play local sahur.mp3
function playAudio() { function playAudio() {
if (!connection) return; try {
if (!connection) {
console.error('[Audio] Connection tidak ditemukan!');
return false;
}
const filePath = path.join(__dirname, 'sahur.mp3'); const filePath = path.join(__dirname, 'sahur.mp3');
if (!fs.existsSync(filePath)) { console.log(`[Audio] Memutar file dari: ${filePath}`);
console.error('File sahur.mp3 tidak ditemukan!');
return; if (!fs.existsSync(filePath)) {
console.error(`[Audio] File TIDAK ditemukan di: ${filePath}`);
return false;
}
if (!player) {
console.log('[Audio] Membuat player baru...');
player = createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Play,
},
});
player.on(AudioPlayerStatus.Idle, () => {
if (isLooping && connection) {
console.log('[Audio] Looping: Memutar ulang sahur.mp3');
playAudio();
}
});
player.on('error', error => {
console.error('[Audio] Player Error:', error.message);
console.error(error);
});
}
const resource = createAudioResource(filePath);
player.play(resource);
connection.subscribe(player);
console.log('[Audio] Berhasil memutar resource.');
return true;
} catch (error) {
console.error('[Audio] Exception di playAudio:', error);
return false;
} }
if (!player) {
player = createAudioPlayer({
behaviors: {
noSubscriber: NoSubscriberBehavior.Play,
},
});
player.on(AudioPlayerStatus.Idle, () => {
if (isLooping && connection) {
console.log('Looping: Memutar ulang sahur.mp3');
playAudio();
}
});
player.on('error', error => {
console.error('Error Audio Player:', error.message);
});
}
const resource = createAudioResource(filePath);
player.play(resource);
connection.subscribe(player);
} }
// Slash Commands Definition // Slash Commands Definition
@ -85,55 +98,87 @@ const rest = new REST({ version: '10' }).setToken(DISCORD_TOKEN);
async function registerCommands() { async function registerCommands() {
try { try {
console.log('Refreshing application (/) commands...'); console.log('Mendaftarkan ulang slash commands (setelah reset)...');
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), { body: commands }); await rest.put(
console.log('Commands registered successfully.'); Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID),
{ body: commands }
);
console.log('Berhasil mendaftarkan command: /join, /test_sahur');
} catch (error) { } catch (error) {
console.error('Error registering commands:', error); console.error('Gagal mendaftarkan command:', error);
} }
} }
client.on('ready', () => { client.once('ready', () => {
console.log(`Bot Online: ${client.user.tag}`); console.log(`Bot logged in as ${client.user.tag}`);
registerCommands(); registerCommands();
// Keep-Alive Ping // Simple Keep-Alive log every 15 minutes
setInterval(() => { setInterval(() => {
console.log(`[Keep-Alive] Bot still running at ${new Date().toISOString()}`); console.log(`[Keep-Alive] Bot active at ${new Date().toISOString()}`);
}, 10 * 60 * 1000); // Every 10 minutes }, 15 * 60 * 1000);
}); });
client.on('interactionCreate', async interaction => { client.on('interactionCreate', async interaction => {
if (!interaction.isChatInputCommand()) return; if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'join') { const { commandName } = interaction;
const voiceChannel = interaction.member.voice.channel;
if (!voiceChannel) { try {
return interaction.reply({ content: 'Kamu harus berada di Voice Channel!', ephemeral: true }); if (commandName === 'join') {
const member = interaction.member;
const voiceChannel = member.voice.channel;
if (!voiceChannel) {
return interaction.reply({ content: 'Kamu harus berada di Voice Channel!', ephemeral: true });
}
connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: interaction.guildId,
adapterCreator: interaction.guild.voiceAdapterCreator,
});
connection.on(VoiceConnectionStatus.Disconnected, async (oldState, newState) => {
try {
await Promise.race([
enterState(connection, VoiceConnectionStatus.Signalling, 5_000),
enterState(connection, VoiceConnectionStatus.Connecting, 5_000),
]);
} catch (error) {
console.error('[Voice] Gagal menyambung kembali:', error);
if (connection) connection.destroy();
connection = null;
}
});
await interaction.reply({ content: `Bot berhasil join ke ${voiceChannel.name}! ✅` });
} }
connection = joinVoiceChannel({ if (commandName === 'test_sahur') {
channelId: voiceChannel.id, if (!connection) {
guildId: interaction.guild.id, return interaction.reply({ content: 'Bot harus join ke Voice Channel dulu! Gunakan /join', ephemeral: true });
adapterCreator: interaction.guild.voiceAdapterCreator, }
});
await interaction.reply(`Berhasil join ke <#${voiceChannel.id}>`); isLooping = true;
} const success = playAudio();
if (interaction.commandName === 'test_sahur') { if (success) {
if (!connection) { await interaction.reply({ content: 'Memutar sahur.mp3 dalam mode loop... 🔁' });
return interaction.reply({ content: 'Gunakan /join terlebih dahulu!', ephemeral: true }); } else {
await interaction.reply({ content: 'Gagal memutar audio. Cek Logs untuk detailnya. ❌', ephemeral: true });
}
}
} catch (error) {
console.error(`[Interaction Error] Command: ${commandName}`, error);
const errorMsg = 'Terjadi kesalahan saat menjalankan command ini. Silakan coba lagi.';
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: errorMsg, ephemeral: true });
} else {
await interaction.reply({ content: errorMsg, ephemeral: true });
} }
isLooping = true;
playAudio();
await interaction.reply('Memutar sahur.mp3 (Loop aktif 🔁)');
} }
}); });
// Minimal Keep-Alive Web Server
app.get('/', (req, res) => res.send('Bot Sahur is Alive! 🌙'));
app.listen(port, () => console.log(`Keep-Alive server on port ${port}`));
client.login(DISCORD_TOKEN); client.login(DISCORD_TOKEN);