aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Discord Botları

Discord Müzik Botu Yapımı: discord.js ve Lavalink

Bir Discord müzik botu yazmak, ilk bakışta "kanala gir, şarkı çal" kadar basit görünür; ama sağlam bir kuyruk yönetimi, kesintisiz ses akışı ve birden çok sunucuda aynı anda çalışabilen bir mimari işin içine girince iş ciddileşir. Bu yazıda modern bir botu iki katmanla kuruyoruz: bot mantığı için discord.js, ses çözme ve akış için ise ayrı bir ses sunucusu olan Lavalink. Ayrıca yalnızca küçük botlar için @discordjs/voice ile yapılan doğrudan yaklaşımı da kısaca ele alıyoruz.

Neden Lavalink? @discordjs/voice ile farkı

@discordjs/voice, botun bir ses kanalına bağlanıp ham PCM/Opus akışı göndermesini sağlayan resmi kütüphanedir. Tek başına müzik çalmak için yeterlidir: bir akış kaynağı (örneğin ytdl-core veya play-dl) bulur, onu createAudioResource ile kaynağa çevirir ve bir AudioPlayer üzerinden çalarsınız. Bu yöntemin sorunu ölçeklenmedir: ses çözme ve transcoding işi botun bulunduğu Node sürecini ciddi şekilde yorar.

Lavalink ise bu ağır işi devralan, Java tabanlı bağımsız bir ses düğümüdür. Botunuz Lavalink'e "şu şarkıyı şu kanalda çal" diye WebSocket üzerinden komut yollar; tüm çözme/akış işini Lavalink yapar. Avantajları:

  • CPU yükü bottan ayrılır; tek düğüm yüzlerce sunucuya hizmet verebilir.
  • YouTube, SoundCloud, Bandcamp, Twitch ve HTTP kaynaklar için hazır eklenti desteği.
  • Bot yeniden başlasa bile oturum devamlılığı ve sağlam yeniden bağlanma.

Küçük, tek sunuculu bir hobi botu için @discordjs/voice fazlasıyla yeterli. Birden çok sunucuda 7/24 çalacaksanız Lavalink neredeyse zorunlu.

Projeyi kurmak ve botu kaydetmek

Önce bir Node.js projesi başlatın (Node 18+ önerilir) ve gerekli paketleri kurun:

mkdir muzik-bot && cd muzik-bot
npm init -y
npm install discord.js shoukaku dotenv

Burada shoukaku, discord.js ile Lavalink arasında konuşan olgun bir istemci kütüphanesidir (alternatif: lavalink-client, erela.js yerine bakım gören projeler). Discord Developer Portal'da bir uygulama oluşturup bir bot token alın ve .env dosyasına yazın. Botu sunucunuza davet ederken bot ve applications.commands kapsamlarını, ayrıca Connect ve Speak ses izinlerini verin.

Lavalink düğümünü çalıştırmak

Lavalink, çalıştırılabilir bir JAR olarak dağıtılır ve Java 17+ ister. Resmi sürümü indirip yanına bir application.yml koyun:

server:
  port: 2333
lavalink:
  server:
    password: "guclu-bir-sifre"

Ardından java -jar Lavalink.jar ile başlatın. YouTube kaynağı için güncel sürümlerde ayrı bir eklenti (örneğin youtube-source) yapılandırmanız gerekebilir; düğüm açılırken loglarda yüklenen kaynakları kontrol edin. Üretimde bu süreci systemd ya da Docker ile kalıcı hale getirin.

Botu Lavalink'e bağlamak

Shoukaku ile düğüm bağlantısı ve temel istemci şöyle kurulur:

const { Client, GatewayIntentBits } = require('discord.js');
const { Shoukaku, Connectors } = require('shoukaku');
require('dotenv').config();

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildVoiceStates,
  ],
});

const nodes = [{
  name: 'main',
  url: 'localhost:2333',
  auth: process.env.LAVALINK_PASSWORD,
}];

const shoukaku = new Shoukaku(new Connectors.DiscordJS(client), nodes);
shoukaku.on('error', (_, err) => console.error(err));

client.login(process.env.DISCORD_TOKEN);

Dikkat: ses durumlarını izleyebilmek için GuildVoiceStates intent'i şart. Bot, kullanıcının hangi kanalda olduğunu bu intent olmadan göremez.

Çalma kuyruğu mantığını kurmak

Asıl müzik deneyimini "kuyruk" belirler: aynı anda gelen istekleri sıraya almak, biten şarkıdan sonra otomatik geçmek ve kanal boşalınca ayrılmak. Her sunucu için ayrı bir kuyruk tutun. Basit bir play akışı:

async function play(interaction, query) {
  const node = shoukaku.options.nodeResolver(shoukaku.nodes);
  const result = await node.rest.resolve(`ytsearch:${query}`);
  if (!result || !result.data.length) {
    return interaction.reply('Sonuç bulunamadı.');
  }
  const track = result.data[0];

  const player = await shoukaku.joinVoiceChannel({
    guildId: interaction.guildId,
    channelId: interaction.member.voice.channelId,
    shardId: 0,
  });

  player.playTrack({ track: { encoded: track.encoded } });
  return interaction.reply(`Çalınıyor: **${track.info.title}**`);
}

Gerçek bir botta bunu bir kuyruk sınıfıyla sarmalarsınız: player.on('end', ...) olayında diziden bir sonraki parçayı çekip çalar, dizi boşsa belirli bir süre sonra shoukaku.leaveVoiceChannel ile kanaldan çıkarsınız. Kuyruğu Map<guildId, Queue> olarak bellekte tutmak çoğu bot için yeterlidir.

Slash komutlarını eklemek

Modern Discord botları metin tetikleyici yerine slash komutları kullanır. Komutları bir kez REST üzerinden kaydedip interactionCreate olayında işleyin:

const { SlashCommandBuilder, REST, Routes } = require('discord.js');

const commands = [
  new SlashCommandBuilder()
    .setName('play')
    .setDescription('Bir şarkı çal')
    .addStringOption(o =>
      o.setName('query').setDescription('Şarkı adı veya URL').setRequired(true)),
].map(c => c.toJSON());

const rest = new REST().setToken(process.env.DISCORD_TOKEN);
await rest.put(
  Routes.applicationCommands(process.env.CLIENT_ID),
  { body: commands },
);

Aynı şekilde skip, queue, pause, stop ve volume komutlarını ekleyin. play dışındaki komutlar kuyruk durumunu okuyup günceller; bu yüzden kuyruk yöneticinizi tek bir modülde toplamak kodun bakımını çok kolaylaştırır.

Sık karşılaşılan hatalar

  • Bot kanala giriyor ama ses yok: Genelde Lavalink düğümü kaynak çözemiyordur. Düğüm loglarını ve kaynak eklentisinin yüklendiğini kontrol edin.
  • "Used disallowed intents": Geliştirici portalında ilgili intent'leri açmayı unutmuşsunuzdur.
  • Bot davet edildi ama komut görünmüyor: Global komutların yayılması zaman alır; geliştirme sırasında belirli bir sunucuya (guild) kayıt yapmak anında çalışır.

Sık Sorulan Sorular

Lavalink şart mı, yoksa sadece discord.js yeter mi?

Tek sunucuda, ara sıra çalan bir bot için @discordjs/voice ve play-dl gibi bir kaynak yeterlidir. Birden çok sunucuda sürekli müzik çalacaksanız, CPU yükünü botun dışına taşıdığı için Lavalink çok daha kararlı bir deneyim sunar.

Telif hakkı açısından dikkat etmem gereken bir şey var mı?

Botların ses kaynağı ve platformların kullanım şartları zamanla değişir. Ticari ya da büyük ölçekli bir projede, çaldığınız içeriğin ilgili platformun şartlarına uygun olduğundan emin olun; mümkünse lisanslı API'leri tercih edin.

Botu nerede barındırmalıyım?

Düşük gecikme için bot ve Lavalink düğümünü tercihen aynı bölgedeki bir VPS'te çalıştırın. Ücretsiz "uyku moduna geçen" platformlar müzik botları için uygun değildir; sürekli çalışan bir sunucu gerekir.

Kendi müzik botunuzu mu istiyorsunuz? Kuyruk yönetimi, slash komutları ve Lavalink altyapısıyla baştan sona kurulmuş, sunucunuza özel bir bot için benimle iletişime geçin.

Devamı için