Autosave: 20260216-163403

This commit is contained in:
Flatlogic Bot 2026-02-16 16:34:03 +00:00
parent 12a425c3fc
commit fe99f09665
3 changed files with 86 additions and 158 deletions

38
bot.log
View File

@ -4,3 +4,41 @@ Started refreshing application (/) commands.
(node:8584) 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)
Successfully reloaded application (/) commands.
Interaction Error: Error: Error: Cannot find module '@discordjs/opus'
Require stack:
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/util/loader.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/Opus.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/index.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/index.js
- /home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js
- /home/ubuntu/executor/workspace/index.js
Error: Cannot find module 'node-opus'
Require stack:
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/util/loader.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/Opus.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/index.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/index.js
- /home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js
- /home/ubuntu/executor/workspace/index.js
Error: Cannot find module 'opusscript'
Require stack:
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/util/loader.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/Opus.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/index.js
- /home/ubuntu/executor/workspace/node_modules/prism-media/src/index.js
- /home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js
- /home/ubuntu/executor/workspace/index.js
at Object.loader [as require] (/home/ubuntu/executor/workspace/node_modules/prism-media/src/util/loader.js:12:9)
at loadOpus (/home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/Opus.js:17:17)
at new OpusStream (/home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/Opus.js:46:10)
at new Encoder (/home/ubuntu/executor/workspace/node_modules/prism-media/src/opus/Opus.js:149:5)
at Object.transformer (/home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:2224:24)
at /home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:2457:58
at Array.map (<anonymous>)
at createAudioResource (/home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:2457:39)
at Client.<anonymous> (/home/ubuntu/executor/workspace/index.js:138:30)
at Client.emit (node:events:518:28)
(node:8584) Warning: Supplying "ephemeral" for interaction response options is deprecated. Utilize flags instead.
Voice Connection Error: Error: No compatible encryption modes. Available include: aead_aes256_gcm_rtpsize, aead_xchacha20_poly1305_rtpsize
at chooseEncryptionMode (/home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:529:11)
at /home/ubuntu/executor/workspace/node_modules/@discordjs/voice/dist/index.js:721:21

View File

@ -2,6 +2,6 @@
"discord_token": "MTQ3MTkwOTE5Mzg4Njg1OTI5NA.GCEdpc.jMIxPFsquVAhp88x3dO-yWUFI7e1u1r8oIZTcw",
"guild_id": "1428530728706117632",
"voice_channel_id": "1457687430189682781",
"alarm_time": "23:27",
"alarm_time": "23:35",
"last_voice_channel": null
}

204
index.js
View File

@ -1,206 +1,96 @@
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 { 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');
function loadConfig() {
if (fs.existsSync(configPath)) {
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
}
return {};
}
const config = loadConfig();
const config = fs.existsSync(configPath) ? JSON.parse(fs.readFileSync(configPath, 'utf8')) : {};
const token = config.discord_token;
if (!token) {
console.error('No Discord Token found in data/config.json');
console.error('ERROR: discord_token not found in data/config.json');
process.exit(1);
}
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildVoiceStates,
]
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 playing. Bot will stay in the channel.');
console.log('Audio finished. Bot is staying in the channel (Stay 24/7).');
});
player.on('error', error => {
console.error('Audio Player Error:', error.message);
});
player.on('error', error => console.error('Audio Player Error:', error));
client.on('ready', async () => {
console.log(`Logged in as ${client.user.tag}`);
// Register commands
async function deployCommands(clientId) {
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());
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 {
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);
await rest.put(Routes.applicationCommands(clientId), { body: commands });
console.log('Slash commands deployed successfully.');
} catch (err) {
console.error('Failed to deploy commands:', err);
}
// 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,
selfMute: 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('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 {
if (interaction.commandName === 'testsahur') {
const member = interaction.member;
if (!member.voice.channel) {
return interaction.reply('Kamu harus berada di Voice Channel!');
}
const connection = joinVoiceChannel({
channelId: member.voice.channel.id,
guildId: interaction.guildId,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false,
});
const channel = member.voice.channel;
const gId = interaction.guildId;
const cId = channel.id;
connection.subscribe(player);
// 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);
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.reply(`File audio tidak ditemukan: ${audioPath}`);
return interaction.editReply('File ./assets/audio/sahur.mp3 tidak ditemukan!');
}
const resource = createAudioResource(audioPath, { inlineVolume: true });
resource.volume.setVolume(1.0);
resource.volume.setVolume(1.0); // Max Volume
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.');
return interaction.editReply('Memutar suara sahur... 🔊');
}
} 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 });
}
console.error('Error during interaction:', error);
return interaction.editReply('Terjadi kesalahan teknis.');
}
});
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, { inlineVolume: true });
resource.volume.setVolume(1.0);
player.play(resource);
}
} catch (e) {
console.error('Failed to trigger alarm VC:', e);
}
}
}
}
}, 30000); // Check every 30 seconds
client.login(token);