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

Discord Global Komut vs Guild Komut: Tam Karşılaştırma

Discord botu yazarken karşılaşılan ilk kafa karıştırıcı kararlardan biri şudur: bir slash komutunu discord global komut olarak mı yoksa belirli bir sunucuya (guild) bağlı komut olarak mı kaydetmeli? İkisi de aynı koddan doğar, aynı şekilde tetiklenir; ama kayıt yöntemleri, güncelleme süreleri ve kullanım senaryoları birbirinden epey ayrılır. Bu yazıda discord.js ile her iki yöntemi gerçek kod üzerinden gösteriyor, hangisini ne zaman seçeceğini netleştiriyorum.

Global komut nedir, guild komut nedir?

Bir global komut, botunun davet edildiği tüm sunucularda ve hatta DM'lerde (eğer izin verdiysen) görünür. Tek bir kayıt yaparsın, botun her yerde aynı komutu sunar. Bir guild komutu ise yalnızca kaydı yaptığın belirli sunucuda görünür; o sunucunun dışında o komut yokmuş gibi davranır.

Discord API tarafında ayrım iki ayrı uç noktadan gelir:

  • Global: PUT /applications/{application.id}/commands
  • Guild: PUT /applications/{application.id}/guilds/{guild.id}/commands

discord.js bu uç noktaları Routes.applicationCommands() ve Routes.applicationGuildCommands() yardımcılarıyla sarmalar.

En kritik fark: güncelleme süresi

Pratikte iki yöntemi ayıran en önemli nokta, komutu kaydettikten sonra Discord istemcisinde ne zaman göründüğüdür:

  • Guild komutları neredeyse anında güncellenir. Kaydı yaptıktan saniyeler sonra slash menüsünde belirir. Bu yüzden geliştirme ve test için idealdir.
  • Global komutlar yayılır (propagation). Discord bunları önbelleğe alır; bir değişikliğin tüm istemcilere ulaşması genelde hızlıdır ama en kötü durumda bir saate kadar sürebilir. Yeni bir komut eklemek ya da açıklamasını değiştirmek anında görünmeyebilir.

Bu tek fark bile çoğu mimari kararı belirler: aktif geliştirirken global'e güvenip "neden görünmüyor?" diye saatlerce beklemek istemezsin.

discord.js ile komut kaydı (REST)

Komutlar genelde ayrı bir deploy-commands.js betiğiyle kaydedilir; bot her açıldığında değil, yalnızca komutlar değiştiğinde çalıştırırsın. İşte guild'e kayıt yapan bir örnek (discord.js v14):

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

const commands = [
  new SlashCommandBuilder()
    .setName('ping')
    .setDescription('Botun gecikmesini gösterir'),
].map(c => c.toJSON());

const rest = new REST({ version: '10' }).setToken(process.env.TOKEN);

(async () => {
  await rest.put(
    Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.GUILD_ID),
    { body: commands },
  );
  console.log('Guild komutları kaydedildi.');
})();

Aynı betiği global yapmak için tek değişiklik, route'u değiştirip GUILD_ID'yi düşürmektir:

await rest.put(
  Routes.applicationCommands(process.env.CLIENT_ID),
  { body: commands },
);

Dikkat: put metodu üzerine yazar. Gönderdiğin dizi, o kapsamdaki (global ya da o guild) komutların tamamının yeni hali olur. Bir komutu diziden çıkarırsan, bir sonraki put onu siler. Bu davranış kasıtlıdır ve idempotent kayıt sağlar.

Hangisini ne zaman kullanmalı?

Genel bir kural olarak şu yaklaşımı öneriyorum:

  • Geliştirme sırasında guild komutu kullan. Kendi test sunucuna kaydet; her değişiklik anında görünür, saatlerce yayılma beklemezsin.
  • Yayına alırken (production) global komut kullan. Bot birçok sunucuda çalışacaksa, komutları tek tek her guild'e kaydetmek mantıksız; global tek seferde her yere ulaşır.
  • Sunucuya özel komutlar için guild komutunu kalıcı tut. Yalnızca tek bir topluluğa ait yönetim komutları, özel etkinlik komutları gibi şeyler global olmamalı.

Birçok ciddi proje ikisini birden kullanır: kullanıcıya açık komutlar global, yalnızca destek/yönetim sunucusunda çalışan komutlar guild kapsamında.

Sık yapılan hatalar

  • Komutun çift görünmesi. Aynı komutu hem global hem de test sunucuna guild olarak kaydedersen, o sunucuda iki kopya görürsün. Test bitince guild kaydını temizle (boş dizi ile put at).
  • "Komut görünmüyor" paniği. Global kayıtta değişiklik anında yansımaz; gerçekten bir saat beklemeden "çalışmıyor" deme. Hızlı test için geçici olarak guild'e kaydet.
  • Kayıt ile dinleme karıştırmak. Komutu kaydetmek (REST put) ile gelen etkileşimi dinlemek (interactionCreate olayı) iki ayrı iştir. Kayıt yapmadan dinlersen komut menüde çıkmaz; dinlemeden kaydedersen tıklandığında "Bu etkileşim başarısız oldu" hatası alırsın.
  • Yanlış CLIENT_ID. Bu, botun değil uygulamanın ID'sidir (çoğu botta aynıdır ama kavramsal olarak uygulama ID'si esastır).

Sık Sorulan Sorular

Global komut gerçekten bir saat sürüyor mu?

Genelde çok daha hızlıdır ve değişiklik dakikalar içinde yansır. Ancak Discord bir saatlik bir üst sınır garanti eder; özellikle yeni eklenen komutlarda önbellek nedeniyle gecikme yaşanabilir. Bu yüzden test için global'e güvenmek yerine guild kullanmak daha sağlıklıdır.

Bir komutu önce guild'de test edip sonra global yapabilir miyim?

Evet, en yaygın iş akışı budur. Geliştirme sırasında guild'e kaydedersin, hazır olunca global betiğini çalıştırırsın. Sadece çift görünmemesi için test guild kaydını temizlemeyi unutma.

Komutu silmek için ne yapmalıyım?

İlgili route'a boş bir dizi ile put atmak o kapsamdaki tüm komutları siler. Tek bir komutu silmek istersen ID ile rest.delete() kullanabilir ya da diziden çıkarıp tekrar put edebilirsin.

Discord botun için komut mimarisini doğru kurmak mı istiyorsun? Global/guild kapsamı, izinler ve yayılma stratejisini projene göre planlayıp kurarım. Bir bot projen varsa benimle iletişime geç.

Bu kategorideki tüm yazılar →

Devamı için