Komut izinleri
Komut izinleri, botunun komutlarını bir sunucuda kimin görüp çalıştırabileceğini ve hangi kanallarda kullanılabileceğini söyleyen kurallardır: kuralları sunucunun yöneticileri koyar, botun okur.
Kimin işi
| Kişi | Ne yapar |
|---|---|
| Sunucu yöneticisi | Kuralları koyar, değiştirir ve kaldırır. ManageGuild ve ManageRoles izinlerinin ikisi de gerekir. |
| Geliştirici | default_member_permissions ile komutun varsayılanını seçer, kuralları okur ve değişince olay alır. Kural yazamaz. |
Kuralı sunucu uygular: kişinin kullanamayacağı komut ona listede gösterilmez ve çalıştırılırsa botuna hiç ulaşmaz.
Sunucu yöneticisi için
Nereden açılır
- Sunucunun adına tıkla ve Sunucu ayarları'nı aç.
- Soldaki Bot komutları sekmesine gir. Sekme yalnız
ManageGuildileManageRolesizinlerinin ikisi birden sende varsa görünür. - Bot kutusundan bir bot seç. Altındaki Komut izinleri kartında önce Tüm komutlar satırı gelir: botun bütün komutlarına uyan kurallar. Altında her komut kendi satırındadır; satırda komutun açıklaması, kural yokken kimin kullanabildiği (
default_member_permissions) ve bugünkü kuralların özeti yazar. - Satırdaki Düzenle'ye bas. Rol, Üye ya da Kanal seç, hedefi seç (aramak için yazabilirsin), Kural ekle'ye bas. Yeni kural İzin ver olarak eklenir; yanındaki kutudan Engelle'ye çevirebilirsin. Varsayılan ya da çöp kutusu kuralı kaldırır: o hedef için komutun varsayılanı geçerli olur.
- Kaydet'e bas. Kaydetmeden önce kuralların özeti çıkar ("İzin ver: @Moderatör · Engelle: @herkes, #genel" gibi); onaylayınca kaydedilir. Kişilerin uygulamaları değişikliği en geç 60 saniyede görür: komut listelerinden kaybolur ve çalıştırılamaz.
Listeyi okuyan rota ManageGuild ister, kural değiştirmek ManageGuild ile ManageRoles'ü birlikte ister; sekme ikisi birden olmadan görünmez. Komutun istediği bir izin sende yoksa kaydederken "Bu izin sende olmadığı için bu komutu açamazsın." yazar (aşağıda Sende olmayan yetkiyi açamazsın). Her değişiklik denetim kaydına "Komut izni güncelleme" olarak düşer: kimin, hangi komutta, eski ve yeni kuralları.
Kural türleri
type | Hedef | id |
|---|---|---|
1 | Rol | Sunucunun bir rolünün ID'si; sunucunun kendi ID'si @everyone demektir |
2 | Üye | Sunucunun bir üyesinin kullanıcı ID'si |
3 | Kanal | Sunucunun bir kanalının ID'si; 0 tüm kanallar demektir |
Bir komutta ve Tüm komutlar satırında ayrı ayrı en çok 100 kural olur. Aynı hedef bir listede iki kez geçemez. Başka sunucunun rolü ya da kanalı, üye olmayan bir kişi 400 validation_failed döner.
Hangi kural kazanır
Sunucu, kişi bir komutu açınca ve çalıştırınca bu sırayla bakar:
- Sunucunun sahibi ve
Administratorizni olanlar her komutu her kanalda kullanır. Hiçbir kural onları durdurmaz. - Kişinin o kanalda
UseApplicationCommandsizni yoksa ya da zaman aşımındaysa orada hiçbir komutu kullanamaz. - Kanal kuralı: önce komutun kendi kuralları, orada kanal kuralı yoksa Tüm komutlar kuralları. İçlerinde önce o kanalın kuralı, yoksa "tüm kanallar" (
0). Bulunan kural engelse komut o kanalda kullanılamaz. Hiç kanal kuralı yoksa her kanal açıktır. - Kişi kuralı: önce komutun kendi kuralları, sonra Tüm komutlar kuralları. Her birinde önce kişinin kendi kuralı, sonra rolleri (rollerinden biri izin veriyorsa izin, hepsi engelliyorsa engel), sonra
@everyone. İlk bulunan karar verir. Bir istisna: Tüm komutlar'daki bir izin,default_member_permissionsdeğeri olan komutu açmaz; o komutta 5. adıma geçilir. Tüm komutlar'daki engel ise her komutta geçerlidir. - Hiç kişi kuralı yoksa komutun
default_member_permissionsdeğeri karar verir.
Komutun kendi kuralı Tüm komutlar kuralını ezer. Örneğin Tüm komutlar'da @everyone engelli ama /yardım'da @everyone izinliyse, herkes /yardım'ı kullanır, botun diğer komutlarını kullanamaz.
Dört örnek
| İstek | Nereye | Kurallar |
|---|---|---|
| Herkes kullansın ama #genel'de olmasın | Komuta ya da Tüm komutlar'a | Kanal #genel: Engelle |
| Yalnız Moderatör | Komuta | @everyone: Engelle; rol Moderatör: İzin ver |
| Bir kişi hariç | Komuta | O üye: Engelle |
| Yalnız yönetici | Komuta | @everyone: Engelle. Sahip ve Administrator zaten geçer |
"Bir kişi hariç" kişi kuralı olduğu için rolden önce gelir: o kişinin Moderatör rolü olsa bile engellenir. "Yalnız Moderatör"de Moderatör olmayan herkes @everyone kuralına düşer.
Komutları bir kanalda tamamen kapatmak
UseApplicationCommands artık denetlenir. Kanalın izin ayarlarında bir rolden bu izni kaldırırsan o roldeki kişiler o kanalda hiçbir botun hiçbir komutunu görmez ve çalıştıramaz. Bütün sunucuda kapatmak için Roller'de @everyone rolünden kaldır. Yeni sunucularda @everyone bu izinle başlar.
Sende olmayan yetkiyi açamazsın
Bir komutun default_member_permissions değeri varsa, örneğin BanMembers, o komutun kurallarını değiştirmek için bu izinlere senin de sahip olman gerekir; yoksa 403 command_permission_escalation alırsın. Değeri "0" olan komutun kurallarını yalnızca sahip ve Administrator değiştirir. Tüm komutlar satırında bu, botun bütün komutlarının izinleri demektir. Sebep: aksi halde yalnızca ManageGuild izni olan biri /ban'ı herkese açabilirdi. Aynı sebeple Tüm komutlar kuralı yalnızca varsayılan izni olmayan komutları açar; bot sonradan BanMembers isteyen bir komut eklese de o komut kendiliğinden açılmaz. Yetki isteyen bir komutu bir role açmak için kuralı o komutun kendisine koy.
Geliştirici için
Varsayılan: default_member_permissions
Sunucu bir kural koyana dek komutu kimin kullanacağını Komutlar sayfasındaki default_member_permissions söyler. Bir kişi kuralı varsayılanın önüne geçer: yönetici /ban'ı bir role açabilir, herkese açık bir komutu bir role kapatabilir. Varsayılanı yetki isteyen komutlar için doğru seç; ama tek güvencen o olmasın.
Bot neden kural yazamaz
Kim neyi kullanır, sunucunun kararıdır. Bot kendi komutunu herkese açabilseydi sunucu bu kararı kaybederdi. Bu yüzden kural yazma rotası yalnızca kişinin oturumuyla çalışır; bot token'ıyla 403 bot_forbidden döner. Botun kuralları okur ve değişince olay alır.
Kuralları okumak
curl "https://noluyo.net/api/v1/applications/$APPLICATION_ID/guilds/$GUILD_ID/commands/permissions" \
-H "Authorization: Bot $BOT_TOKEN"
Yanıt, kuralı olan her komut için bir kayıttır. id uygulamanın ID'siyse kayıt Tüm komutlar kurallarıdır:
[
{
"id": "111540000000000000",
"application_id": "111540000000000000",
"guild_id": "111500000000000000",
"permissions": [{ "type": 1, "id": "111500000000000000", "allow": false }]
},
{
"id": "111560000000000000",
"application_id": "111540000000000000",
"guild_id": "111500000000000000",
"permissions": [
{ "type": 1, "id": "111520000000000000", "allow": true },
{ "type": 3, "id": "0", "allow": false }
]
}
]
| Rota | Ne döner |
|---|---|
GET .../guilds/{guild_id}/commands/permissions | Botun o sunucudaki bütün kuralları; kuralı olmayan komut listede yok |
GET .../guilds/{guild_id}/commands/{command_id}/permissions | Bir komutun kuralları, yoksa boş liste; Tüm komutlar kuralları burada yok |
İkisi de read sınıfındadır. Bot o sunucunun üyesi değilse 403 missing_access döner.
Alanlar
| Alan | Tür | Anlamı |
|---|---|---|
id | ID | Komut; Tüm komutlar kurallarında uygulamanın ID'si |
application_id | ID | Uygulaman |
guild_id | ID | Sunucu |
permissions[].type | tam sayı | 1 rol, 2 üye, 3 kanal |
permissions[].id | ID | Hedef; rol olarak sunucunun ID'si @everyone, kanal olarak 0 tüm kanallar |
permissions[].allow | evet/hayır | true izin verir, false engeller |
Değişince: APPLICATION_COMMAND_PERMISSIONS_UPDATE
Bir yönetici kuralları değiştirince botuna APPLICATION_COMMAND_PERMISSIONS_UPDATE gelir. Gövdesi yukarıdaki kayıtlardan biridir ve kümenin tamamını taşır; boş permissions kuralların kaldırıldığını söyler. Intent istemez, yalnızca botuna gider. Kuralları sunucu zaten uygular; olayı yalnızca bilgi için kullan, örneğin bir kayıt kanalına yazmak için.
Tam örnek: kuralları okuyan betik
Node.js 22 veya üstü yeter, ek paket gerekmez. Betik bir sunucudaki kuralları okur ve okunur biçimde yazar:
const API = "https://noluyo.net/api/v1";
const { BOT_TOKEN, APPLICATION_ID, GUILD_ID } = process.env;
if (!BOT_TOKEN || !APPLICATION_ID || !GUILD_ID) throw new Error("BOT_TOKEN, APPLICATION_ID ve GUILD_ID tanımlı olmalı");
const headers = { Authorization: `Bot ${BOT_TOKEN}` };
const get = async (path) => {
for (;;) {
const res = await fetch(API + path, { headers });
const data = await res.json();
if (res.status === 429) {
await new Promise((done) => setTimeout(done, data.retry_after * 1000));
continue;
}
if (!res.ok) throw new Error(`${res.status} ${data.code}: ${data.message}`);
return data;
}
};
const names = new Map();
for (const c of await get(`/applications/${APPLICATION_ID}/commands`)) names.set(c.id, c.name);
for (const c of await get(`/applications/${APPLICATION_ID}/guilds/${GUILD_ID}/commands`)) names.set(c.id, c.name);
const kinds = { 1: "rol", 2: "üye", 3: "kanal" };
for (const entry of await get(`/applications/${APPLICATION_ID}/guilds/${GUILD_ID}/commands/permissions`)) {
const title = entry.id === APPLICATION_ID ? "Tüm komutlar" : `/${names.get(entry.id) ?? entry.id}`;
console.log(title);
for (const p of entry.permissions) {
let target = `${kinds[p.type]} ${p.id}`;
if (p.type === 1 && p.id === GUILD_ID) target = "@everyone";
if (p.type === 3 && p.id === "0") target = "tüm kanallar";
console.log(` ${target}: ${p.allow ? "izin" : "engel"}`);
}
}
Çalıştırmak için:
BOT_TOKEN='kopyaladigin_token' APPLICATION_ID='uygulama id degeri' GUILD_ID='sunucu id degeri' node kurallar.mjs
Limitler
| Konu | Değer |
|---|---|
| Kural | Komut başına 100; Tüm komutlar için ayrıca 100 |
| Kural yazma | Kişi ve sunucu başına dakikada 10 |
| Kural okuma | read sınıfı: 5 saniyede 30 istek |
| Yayılma | Kişilerin uygulamaları en geç 60 saniyede |
Hatalar
| Kod | Ne oldu | Ne yap |
|---|---|---|
missing_permissions | Kural değiştiren kişide ManageGuild ve ManageRoles birlikte yok | Kişiye iki izni de veren bir rol ver. |
command_permission_escalation | Kişi komutun default_member_permissions bitlerine sahip değil | Kuralı o izinlere sahip biri, sahip ya da bir Administrator değiştirsin. |
validation_failed, permissions[0].id: invalid | Hedef bu sunucunun değil, iki kez geçiyor ya da ID geçersiz | Bu sunucunun rolünü, kanalını ya da üyesini seç; tüm kanallar için 0. |
validation_failed, permissions: too_long | 100'den çok kural | Kişi kuralları yerine rol kullan. |
unknown_application | Bot bu sunucuda değil ya da kapatılmış | Botu sunucuya ekle. |
unknown_command | Komut yok ya da başka sunucunun komutu | Global komutu ya da bu sunucunun komutunu seç. |
bot_forbidden | Bot kural yazmaya çalıştı | Bot yazamaz; sunucunun yöneticisinden iste. |
missing_access | Okuyan bot o sunucunun üyesi değil | Botu sunucuya ekle. |
rate_limited | Dakikada 10 değişikliği aştın | retry_after kadar bekle. |