From 2c48546b22db94b2c6ae95435986dd960355a50b Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 16 Feb 2026 16:20:35 +0000 Subject: [PATCH] V2 --- bot.log | 67 ++++++++++- data/config.json | 12 +- db/migrations/003_add_alarm_settings.sql | 3 + index.js | 140 +++++++++++++++++++---- index.php | 9 ++ 5 files changed, 198 insertions(+), 33 deletions(-) create mode 100644 db/migrations/003_add_alarm_settings.sql diff --git a/bot.log b/bot.log index 8b19fea..f263edb 100644 --- a/bot.log +++ b/bot.log @@ -1,4 +1,63 @@ -Logged in as AsepXiaoQin#6954 -(node:4352) 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 registered application commands. +Interaction Error: DiscordAPIError[10062]: Unknown interaction + at handleErrors (/home/ubuntu/executor/workspace/node_modules/@discordjs/rest/dist/index.js:762:13) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async BurstHandler.runRequest (/home/ubuntu/executor/workspace/node_modules/@discordjs/rest/dist/index.js:866:23) + at async _REST.request (/home/ubuntu/executor/workspace/node_modules/@discordjs/rest/dist/index.js:1307:22) + at async ChatInputCommandInteraction.reply (/home/ubuntu/executor/workspace/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:193:22) + at async Client. (/home/ubuntu/executor/workspace/index.js:68:13) { + requestBody: { files: [], json: { type: 4, data: [Object] } }, + rawError: { message: 'Unknown interaction', code: 10062 }, + code: 10062, + status: 404, + method: 'POST', + url: 'https://discord.com/api/v10/interactions/1472990887029248135/aW50ZXJhY3Rpb246MTQ3Mjk5MDg4NzAyOTI0ODEzNTp2V1dQTFpXN3IybjBtYmZNcjJxaW5qZnlBR1RQdVpKelhnYjdiRUtWQmI1YW9IbXpZS25WVzQzVVpEWVpSa2hVY3FlamhRYVdlaEt0dVlYRVI5bUNCMVM3bnNmUjZhbDBqZk1RdEhrYXB5R3p6VWZsbUNwQUl6RURGa3hkWEwzaw/callback?with_response=false' +} +(node:7629) Warning: Supplying "ephemeral" for interaction response options is deprecated. Utilize flags instead. +(Use `node --trace-warnings ...` to show where the warning was created) +node:events:496 + throw er; // Unhandled 'error' event + ^ + +DiscordAPIError[10062]: Unknown interaction + at handleErrors (/home/ubuntu/executor/workspace/node_modules/@discordjs/rest/dist/index.js:762:13) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async BurstHandler.runRequest (/home/ubuntu/executor/workspace/node_modules/@discordjs/rest/dist/index.js:866:23) + at async _REST.request (/home/ubuntu/executor/workspace/node_modules/@discordjs/rest/dist/index.js:1307:22) + at async ChatInputCommandInteraction.reply (/home/ubuntu/executor/workspace/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:193:22) + at async Client. (/home/ubuntu/executor/workspace/index.js:156:9) +Emitted 'error' event on Client instance at: + at emitUnhandledRejectionOrErr (node:events:401:10) + at process.processTicksAndRejections (node:internal/process/task_queues:92:21) { + requestBody: { + files: [], + json: { + type: 4, + data: { + content: '🔊 Memutar audio Sahur!', + tts: false, + nonce: undefined, + enforce_nonce: false, + embeds: undefined, + components: undefined, + username: undefined, + avatar_url: undefined, + allowed_mentions: undefined, + flags: undefined, + message_reference: undefined, + attachments: undefined, + sticker_ids: undefined, + thread_name: undefined, + applied_tags: undefined, + poll: undefined + } + } + }, + rawError: { message: 'Unknown interaction', code: 10062 }, + code: 10062, + status: 404, + method: 'POST', + url: 'https://discord.com/api/v10/interactions/1472990887029248135/aW50ZXJhY3Rpb246MTQ3Mjk5MDg4NzAyOTI0ODEzNTp2V1dQTFpXN3IybjBtYmZNcjJxaW5qZnlBR1RQdVpKelhnYjdiRUtWQmI1YW9IbXpZS25WVzQzVVpEWVpSa2hVY3FlamhRYVdlaEt0dVlYRVI5bUNCMVM3bnNmUjZhbDBqZk1RdEhrYXB5R3p6VWZsbUNwQUl6RURGa3hkWEwzaw/callback?with_response=false' +} + +Node.js v22.18.0 +ode.js v22.18.0 diff --git a/data/config.json b/data/config.json index 3c2f8ff..6f1afe5 100644 --- a/data/config.json +++ b/data/config.json @@ -1,6 +1,10 @@ { - "discord_token": "MTQ3MTkwOTE5Mzg4Njg1OTI5NA.GCEdpc.jMIxPFsquVAhp88x3dO-yWUFI7e1u1r8oIZTcw", - "guild_id": "1428530728706117632", - "voice_channel_id": "1457687430189682781", - "last_voice_channel": null + "discord_token": "MTQ3MTkwOTE5Mzg4Njg1OTI5NA.GCEdpc.jMIxPFsquVAhp88x3dO-yWUFI7e1u1r8oIZTcw", + "guild_id": "1428530728706117632", + "voice_channel_id": "1457687430189682781", + "alarm_time": "23:20", + "last_voice_channel": { + "guildId": "1428530728706117632", + "channelId": "1457687430189682781" + } } \ No newline at end of file diff --git a/db/migrations/003_add_alarm_settings.sql b/db/migrations/003_add_alarm_settings.sql new file mode 100644 index 0000000..d547b76 --- /dev/null +++ b/db/migrations/003_add_alarm_settings.sql @@ -0,0 +1,3 @@ +-- migrations/003_add_alarm_settings.sql +INSERT IGNORE INTO bot_settings (setting_key, setting_value) VALUES +('alarm_time', ''); diff --git a/index.js b/index.js index 6bbce76..1cef16a 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,6 @@ 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'); @@ -16,7 +18,6 @@ function loadConfig() { const config = loadConfig(); const token = config.discord_token; -const guildId = config.guild_id; if (!token) { console.error('No Discord Token found in data/config.json'); @@ -32,6 +33,10 @@ const client = new Client({ 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}`); @@ -39,29 +44,44 @@ client.on('ready', async () => { const commands = [ new SlashCommandBuilder() .setName('testsahur') - .setDescription('Memutar file audio sahur') + .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 registered application commands.'); + console.log('Successfully reloaded application (/) commands.'); } catch (error) { - console.error(error); + console.error('Error reloading commands:', error); } // Auto-reconnect to last voice channel - const lastVoice = config.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: client.guilds.cache.get(gId).voiceAdapterCreator, + adapterCreator: guild.voiceAdapterCreator, selfDeaf: false, }); @@ -77,33 +97,103 @@ function joinVC(gId, cId) { } }); + connection.on('error', error => { + console.error('Voice Connection Error:', error); + }); + connection.subscribe(player); } client.on('interactionCreate', async interaction => { if (!interaction.isChatInputCommand()) return; - if (interaction.commandName === 'testsahur') { - const member = interaction.member; - if (!member.voice.channel) { - return interaction.reply('Kamu harus berada di Voice Channel!'); + 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 }); } - - const channel = member.voice.channel; - const gId = interaction.guildId; - const cId = channel.id; - - // Save last channel - config.last_voice_channel = { guildId: gId, channelId: cId }; - fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); - - joinVC(gId, cId); - - const resource = createAudioResource(path.join(__dirname, 'assets/audio/sahur.mp3')); - player.play(resource); - - await interaction.reply('🔊 Memutar audio Sahur!'); } }); +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); diff --git a/index.php b/index.php index 4db2ba0..dbe02c8 100644 --- a/index.php +++ b/index.php @@ -17,16 +17,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $token = $_POST['discord_token'] ?? ''; $guild = $_POST['guild_id'] ?? ''; $channel = $_POST['voice_channel_id'] ?? ''; + $alarm = $_POST['alarm_time'] ?? ''; save_setting('discord_token', $token); save_setting('guild_id', $guild); save_setting('voice_channel_id', $channel); + save_setting('alarm_time', $alarm); // Also update JSON for the bot $config = [ 'discord_token' => $token, 'guild_id' => $guild, 'voice_channel_id' => $channel, + 'alarm_time' => $alarm, 'last_voice_channel' => json_decode(get_setting('last_voice_channel'), true) ?: null ]; if (!is_dir(__DIR__ . '/data')) mkdir(__DIR__ . '/data', 0775, true); @@ -38,6 +41,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $token = get_setting('discord_token'); $guildId = get_setting('guild_id'); $voiceId = get_setting('voice_channel_id'); +$alarmTime = get_setting('alarm_time'); ?> @@ -163,6 +167,11 @@ $voiceId = get_setting('voice_channel_id'); +
+ + +
Bot will automatically join the voice channel and play audio at this time.
+