Bir botun en kritik kısımlarından biri, kimin hangi komutu çalıştırabileceğini belirleyen discord bot yetki mekanizmasıdır. ban, kick ya da sunucu ayarlarını değiştiren bir komutu herkese açık bırakmak felakettir. Bu yazıda discord.js v14 ile katmanlı bir yetki sistemi kuracağız: hem Discord'un kendi permission modelini kullanacak, hem de belirli rolleri gerektiren özel akışlar tasarlayacağız. Amacımız yetkisiz kullanımı sessizce değil, kullanıcıya net bir geri bildirimle engellemek.
Discord'da yetki nasıl çalışır?
Discord'da iki ayrı kavramı karıştırmamak önemlidir:
- Permission (izin):
BanMembers,ManageGuild,KickMembersgibi Discord'un tanımladığı atomik yetkilerdir. Bir üyenin efektif izinleri, sahip olduğu tüm rollerin izinlerinin birleşiminden oluşur. - Rol (role): Sunucuya özel, ismi ve rengi olan gruplardır. "Moderatör" veya "VIP" gibi roller senin kurgun; Discord onları tanımaz, sadece taşıdıkları izinleri bilir.
İyi bir yetki sistemi bu ikisini birlikte kullanır: kaba filtreyi Discord'un izin bayraklarıyla, ince ayarı ise kendi rol mantığınla yaparsın.
İlk savunma hattı: setDefaultMemberPermissions
Bir slash komutunu tanımlarken hangi iznin gerekli olduğunu doğrudan Discord'a bildirebilirsin. Bu sayede izni olmayan kullanıcılar komutu menüde dahi göremez — en temiz koruma budur, çünkü kontrol Discord tarafında yapılır.
// commands/moderation/ban.js
const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('ban')
.setDescription('Bir üyeyi sunucudan yasaklar')
.addUserOption((o) =>
o.setName('uye').setDescription('Yasaklanacak üye').setRequired(true))
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers),
async execute(interaction) {
// ...
},
};
Burada setDefaultMemberPermissions komutu yalnızca BanMembers iznine sahip rollere gösterir. Bu varsayılan bir başlangıç noktasıdır; sunucu yöneticileri Discord'un "Entegrasyonlar" ayarlarından bunu rol veya kanal bazında ezebilir. Yine de buna tek başına güvenme — kodun içinde de doğrulama yapmalısın.
Kod içinde permission doğrulaması
Discord'un arayüz filtresine ek olarak, komut çalışırken çağıran kişinin iznini sunucu tarafında tekrar kontrol etmek güvenliğin temelidir. interaction.memberPermissions bir PermissionsBitField döndürür ve .has() ile sorgulanır.
async execute(interaction) {
if (!interaction.memberPermissions.has(PermissionFlagsBits.BanMembers)) {
return interaction.reply({
content: 'Bu komutu kullanmak için **Üyeleri Yasakla** iznine ihtiyacın var.',
ephemeral: true,
});
}
// yetki tamam, işleme devam
}
ephemeral: true sayesinde uyarı mesajını yalnızca komutu çağıran kişi görür; kanal yetkisiz deneme mesajlarıyla dolmaz.
Rol gerektiren akışlar
Bazen bir komut belirli bir Discord iznine değil, senin tanımladığın bir role bağlıdır — örneğin yalnızca "Destek Ekibi" rolüne sahip kişiler ticket kapatabilsin. Üyenin rollerini interaction.member.roles.cache üzerinden kontrol edersin. Rolü ID ile sorgulamak, isimle sorgulamaktan çok daha güvenilirdir çünkü roller yeniden adlandırılabilir.
const DESTEK_ROL_ID = '123456789012345678';
async execute(interaction) {
const yetkili = interaction.member.roles.cache.has(DESTEK_ROL_ID);
if (!yetkili) {
return interaction.reply({
content: 'Bu işlemi yalnızca Destek Ekibi yapabilir.',
ephemeral: true,
});
}
// ticket kapatma akışı...
}
Birden fazla rolden herhangi birini kabul etmek istersen, izin verilen ID'leri bir diziye koyup some ile kontrol edebilirsin:
const IZINLI_ROLLER = ['111...', '222...'];
const yetkili = IZINLI_ROLLER.some((id) => interaction.member.roles.cache.has(id));
Tekrarı önle: yeniden kullanılabilir bir yetki katmanı
Her komutun başına aynı if bloklarını kopyalamak hataya açıktır. Daha temiz bir yaklaşım, komut dosyasına bir yetki sözleşmesi eklemek ve kontrolü merkezî interactionCreate event'inde yapmaktır. Komut yalnızca gereksinimini bildirir, doğrulamayı handler üstlenir.
// commands/moderation/clear.js
module.exports = {
data: /* ...SlashCommandBuilder... */,
permissions: [PermissionFlagsBits.ManageMessages], // gereken izinler
roles: ['MOD_ROL_ID'], // gereken roller (opsiyonel)
async execute(interaction) { /* ... */ },
};
// events/interactionCreate.js içinde
const command = interaction.client.commands.get(interaction.commandName);
if (!command) return;
// izin kontrolü
if (command.permissions?.length) {
const eksik = command.permissions.filter(
(p) => !interaction.memberPermissions.has(p));
if (eksik.length) {
return interaction.reply({
content: 'Bu komut için gerekli izinlere sahip değilsin.',
ephemeral: true,
});
}
}
// rol kontrolü
if (command.roles?.length) {
const uygun = command.roles.some(
(id) => interaction.member.roles.cache.has(id));
if (!uygun) {
return interaction.reply({
content: 'Bu komutu kullanma yetkin yok.',
ephemeral: true,
});
}
}
await command.execute(interaction);
Artık yeni bir korumalı komut eklemek için tek yapman gereken dosyaya permissions veya roles alanını yazmaktır; tekrar eden kontrol kodu tek bir yerde yaşar.
Botun kendi izinlerini unutma
Sık yapılan bir hata: kullanıcı yetkili olsa bile, botun kendisinin işlemi yapacak izni olmayabilir. Botu yasaklamadan önce rol hiyerarşisini ve botun izinlerini kontrol et, aksi halde API hatayla döner.
const hedef = interaction.options.getMember('uye');
const me = interaction.guild.members.me;
if (!me.permissions.has(PermissionFlagsBits.BanMembers)) {
return interaction.reply({
content: 'Yasaklama iznim yok. Lütfen botun rol izinlerini kontrol et.',
ephemeral: true,
});
}
if (hedef && hedef.roles.highest.position >= me.roles.highest.position) {
return interaction.reply({
content: 'Bu üye benden daha yüksek bir role sahip, işlem yapamam.',
ephemeral: true,
});
}
Discord'da bir üye, ancak kendi en yüksek rolünün altındaki rollere sahip üyeler üzerinde işlem yapabilir. Bu kural bota da uygulanır; bu yüzden botun rolünü rol listesinde yeterince yukarı taşımayı unutma.
Sık Sorulan Sorular
setDefaultMemberPermissions yeterli değil mi, neden kodda da kontrol edeyim?
Çünkü setDefaultMemberPermissions yalnızca arayüz görünürlüğünü etkiler ve sunucu yöneticileri tarafından ezilebilir. Gerçek güvenlik kararı kod içinde, sunucu tarafında verilmelidir. İki katman birlikte hem temiz bir kullanıcı deneyimi hem de güvenilir bir koruma sağlar.
Rolü isimle mi yoksa ID ile mi kontrol etmeliyim?
Her zaman ID ile. Rol isimleri değiştirilebilir veya aynı isimde birden fazla rol olabilir; ID ise benzersiz ve kalıcıdır. ID'yi Discord'da Geliştirici Modu açıkken role sağ tıklayıp kopyalayabilirsin.
Yetki yapılandırmasını koddan ayırabilir miyim?
Evet, ölçek büyüdükçe rol ID'lerini ve komut izinlerini bir veritabanında veya config dosyasında tutmak iyi bir fikirdir. Böylece her sunucu kendi rollerini tanımlayabilir ve yetki değiştirmek için kod dağıtmana gerek kalmaz.
Botunun yetki sistemi sızdırıyor mu, yoksa baştan mı kurmak istiyorsun? Permission ve rol kontrolünü, bot izin hiyerarşisini ve merkezî bir yetki katmanını birlikte sağlam bir temele oturtabiliriz. Benimle iletişime geç, botunu güvenli hale getirelim.