import { Client, GatewayIntentBits, EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle } from 'discord.js'; import { joinVoiceChannel, createAudioPlayer, createAudioResource, VoiceConnectionStatus, AudioPlayerStatus } from '@discordjs/voice'; import ytdl from 'ytdl-core'; import { google } from 'googleapis'; import fetch from 'node-fetch'; // Node.js yerel fetch kullanımı import dotenv from 'dotenv'; dotenv.config(); // dotenv'i bir kez yükleyin // Discord Client const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent ] }); const PREFIX = 'g!'; const YOUTUBE_API_KEY = process.env.YOUTUBE_API_KEY; const LOG_CHANNEL_ID = process.env.LOG_CHANNEL_ID; const youtube = google.youtube({ version: 'v3', auth: YOUTUBE_API_KEY }); let connection; let player; let musicPlaying = false; let paused = false; let disconnectTimeout; client.once('ready', () => { console.log(`Logged in as ${client.user.tag}!`); }); client.on('messageCreate', async (message) => { if (!message.content.startsWith(PREFIX) || message.author.bot) return; const args = message.content.slice(PREFIX.length).trim().split(/ +/); const command = args.shift().toLowerCase(); if (command === 'muzik') { if (!message.member.voice.channel) { return message.reply('Lütfen bir ses kanalına katılın.'); } const query = args.join(' '); if (!query) { return message.reply('Lütfen bir şarkı adı girin veya YouTube linki sağlayın.'); } if (query.startsWith('https://www.youtube.com/')) { const videoUrl = query; playMusic(videoUrl, message); } else { try { const response = await youtube.search.list({ part: 'snippet', q: query, maxResults: 5, type: 'video' }); const videos = response.data.items; if (!videos.length) { return message.reply('Hiçbir sonuç bulunamadı.'); } let replyText = 'Arama Sonuçları:\n'; videos.forEach((video, index) => { replyText += `${index + 1}. ${video.snippet.title}\n`; }); const buttons = new ActionRowBuilder() .addComponents( ...videos.map((video, index) => new ButtonBuilder() .setCustomId(`play_${index}`) .setLabel(`${index + 1}`) .setStyle(ButtonStyle.Primary) ) ); const embed = new EmbedBuilder() .setColor('#0099ff') .setTitle('Şarkı Seçenekleri') .setDescription(replyText); const msg = await message.channel.send({ embeds: [embed], components: [buttons] }); const filter = (interaction) => interaction.isButton() && interaction.user.id === message.author.id; const collector = msg.createMessageComponentCollector({ filter, time: 20000 }); collector.on('collect', async (interaction) => { if (!interaction.customId.startsWith('play_')) return; const index = parseInt(interaction.customId.split('_')[1]); if (isNaN(index) || index < 0 || index >= videos.length) { return interaction.reply('Geçersiz seçim.'); } const video = videos[index]; const videoUrl = `https://www.youtube.com/watch?v=${video.id.videoId}`; // Müzik çalmaya başla playMusic(videoUrl, message); await interaction.reply(`Şu şarkıyı çalıyorum: ${video.snippet.title}`); // Butonları bir kez tıklanabilir yapmak için msg.edit({ components: [] }); }); collector.on('end', collected => { msg.edit({ components: [] }); }); } catch (error) { console.error('Arama hatası:', error); return message.reply('Bir hata oluştu. Lütfen tekrar deneyin.'); } } } else if (command === 'durdur') { if (player && musicPlaying) { player.pause(); paused = true; musicPlaying = false; message.reply('Müzik durduruldu.'); sendLog('info', 'Müzik durduruldu.', message); } else { message.reply('Şu anda çalan bir müzik yok.'); } } else if (command === 'baslat') { if (player && paused) { player.unpause(); paused = false; musicPlaying = true; message.reply('Müzik kaldığı yerden devam ediyor.'); sendLog('info', 'Müzik devam ediyor.', message); } else { message.reply('Devam edilecek durdurulmuş bir müzik yok.'); } } else if (command === 'kapat') { if (connection) { player.stop(); connection.destroy(); connection = null; musicPlaying = false; paused = false; message.reply('Müzik durduruldu ve ses kanalından çıkarıldı.'); sendLog('info', 'Müzik durduruldu ve ses kanalından çıkıldı.', message); } else { message.reply('Bağlı bir ses kanalı yok.'); } } else if (command === 'komutlar') { const embed = new EmbedBuilder() .setColor('#0099ff') .setTitle('Bot Komutları') .setDescription(` **g!muzik [şarkı adı/linki]**: YouTube'dan müzik çalar. **g!durdur**: Şu anki müziği durdurur. **g!baslat**: Durdurulan müziği devam ettirir. **g!kapat**: Müzik çalmayı durdurur ve ses kanalından çıkar. `); message.channel.send({ embeds: [embed] }); } }); async function playMusic(videoUrl, message) { if (!message.member.voice.channel) { return message.reply('Lütfen bir ses kanalına katılın.'); } if (connection && connection.state.status === VoiceConnectionStatus.Ready) { startPlaying(videoUrl); return; } connection = joinVoiceChannel({ channelId: message.member.voice.channel.id, guildId: message.guild.id, adapterCreator: message.guild.voiceAdapterCreator, }); connection.on(VoiceConnectionStatus.Ready, () => { startPlaying(videoUrl); }); connection.on(VoiceConnectionStatus.Disconnected, () => { clearTimeout(disconnectTimeout); sendLog('warn', 'Bağlantı kesildi.', message); }); connection.on('error', (error) => { console.error('Bağlantı hatası:', error); sendLog('error', `Bağlantı hatası: ${error.message}`, message); }); disconnectTimeout = setTimeout(() => { if (connection && connection.state.status !== VoiceConnectionStatus.Ready) { connection.destroy(); connection = null; } }, 3 * 60 * 1000); // 3 dakika } function startPlaying(videoUrl) { if (player) { player.stop(); } player = createAudioPlayer(); const resource = createAudioResource(ytdl(videoUrl, { filter: 'audioonly' }), { inlineVolume: true }); player.play(resource); connection.subscribe(player); player.on(AudioPlayerStatus.Idle, () => { if (connection) { connection.destroy(); connection = null; } }); player.on('error', (error) => { console.error('Player hatası:', error); sendLog('error', `Player hatası: ${error.message}`, null); }); } async function sendLog(level, message, context) { const logChannel = client.channels.cache.get(LOG_CHANNEL_ID); if (!logChannel) return; const embed = new EmbedBuilder() .setColor(level === 'error' ? '#ff0000' : (level === 'warn' ? '#ffff00' : '#00ff00')) .setTitle(`[${level.toUpperCase()}] Log`) .setDescription(message) .setFooter({ text: context ? `User: ${context.author.tag} | Channel: ${context.channel.name}` : '' }); try { await logChannel.send({ embeds: [embed] }); } catch (error) { console.error('Log gönderme hatası:', error); } } client.login(process.env.DISCORD_TOKEN);