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

Discord Reaction Role (Otorol) Botu Nasıl Kurulur

Bir Discord reaction role sistemi, üyelerin bir mesaja tepki (emoji) ya da butona tıklayarak kendilerine rol almasını sağlar. "Renk rolleri", "bildirim rolleri" ya da "oyun ilgisi" gibi rolleri tek tek dağıtmak yerine, üyeye seçimi bırakırsınız; sunucu daha düzenli, moderasyon yükü daha hafif olur. Bu rehberde otorol mantığını sıfırdan kuracağız: önce klasik emoji tepkisiyle, sonra da bugün önerilen modern buton yaklaşımıyla. Kod örnekleri discord.js v14 ve Node.js içindir.

Hangi yöntem: emoji tepkisi mi, buton mu?

İki temel yaklaşım var ve farklarını bilmek önemli:

  • Reaction (emoji) yöntemi: Üye mesajdaki emojiye tıklar, bot messageReactionAdd olayını dinler ve rolü verir; emoji kaldırılınca rolü alır. Klasik ve tanıdık, ama bot'un mesaj tepki içeriğini görebilmesi için ek intent ister ve emoji yönetimi kırılgandır.
  • Buton yöntemi: Mesaja gömülü butonlar koyarsınız, üye tıklar, bot interactionCreate ile rolü açıp kapatır (toggle). Daha temiz, mobilde daha güvenilir ve Discord'un yönlendirdiği modern yoldur.

Yeni projeler için buton yöntemini öneriyorum. Yine de eski sunucularda hâlâ çok yaygın olduğu için emoji yöntemini de göstereceğim.

Gerekli izinler ve intent ayarları

Bot, rolleri yönetebilmek için Manage Roles (Rolleri Yönet) iznine ihtiyaç duyar. Bir altın kural daha var: bot'un kendi rolü, dağıtacağı rollerin üstünde olmalı. Discord, bir botun yalnızca kendi en yüksek rolünün altındaki rolleri verebilmesine izin verir. Bu yüzden Sunucu Ayarları > Roller'den bot rolünü hedef rollerin üstüne taşıyın.

İstemciyi oluştururken doğru intent'leri seçin. Buton yöntemi için Guilds yeterlidir; emoji yöntemi ayrıca GuildMessageReactions ister:

const { Client, GatewayIntentBits, Partials } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessageReactions, // sadece emoji yöntemi için
  ],
  partials: [Partials.Message, Partials.Channel, Partials.Reaction],
});

partials önemlidir: bot çevrimdışıyken eklenmiş eski mesajlardaki tepkileri yakalayabilmek için gereklidir, aksi halde bot yeniden başladıktan sonra o tepkiler yok sayılır.

Buton ile otorol kurulumu

Önce, içinde rol butonları olan bir mesaj gönderiyoruz. Her butonun customId değerine vereceğimiz rolün ID'sini gömüyoruz ki tıklamada hangi rolün istendiğini bilelim:

const { ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');

// Bir komut/handler içinden çağrılır
async function sendRolePanel(channel) {
  const row = new ActionRowBuilder().addComponents(
    new ButtonBuilder()
      .setCustomId('role:123456789012345678') // hedef rol ID'si
      .setLabel('Etkinlik Bildirimi')
      .setStyle(ButtonStyle.Primary),
    new ButtonBuilder()
      .setCustomId('role:987654321098765432')
      .setLabel('Duyurular')
      .setStyle(ButtonStyle.Secondary),
  );

  await channel.send({
    content: 'Bir butona tıklayarak rolü al/bırak:',
    components: [row],
  });
}

Şimdi tıklamaları dinleyip rolü açıp kapatıyoruz (toggle). Üyede rol varsa alıyor, yoksa veriyoruz:

client.on('interactionCreate', async (interaction) => {
  if (!interaction.isButton()) return;
  if (!interaction.customId.startsWith('role:')) return;

  const roleId = interaction.customId.split(':')[1];
  const member = interaction.member;

  try {
    if (member.roles.cache.has(roleId)) {
      await member.roles.remove(roleId);
      await interaction.reply({ content: 'Rol kaldırıldı.', ephemeral: true });
    } else {
      await member.roles.add(roleId);
      await interaction.reply({ content: 'Rol verildi!', ephemeral: true });
    }
  } catch (err) {
    console.error(err);
    await interaction.reply({
      content: 'Rolü ayarlayamadım. Yetkilerimi ve rol sıralamasını kontrol et.',
      ephemeral: true,
    });
  }
});

ephemeral: true cevabı yalnızca tıklayan üyeye gösterir, kanalı spam'lamaz. try/catch ise rol hiyerarşisi yanlışsa düzgün bir hata mesajı verir; sessizce çökmek yerine kullanıcıyı bilgilendirir.

Klasik emoji tepkisiyle otorol

Emoji yöntemini tercih ederseniz, panel mesajının ID'sini ve emoji–rol eşleşmesini bir yerde tutmanız gerekir. Küçük sunucularda basit bir nesne yeterli; büyük projelerde bunu veritabanına (örneğin SQLite) taşırsınız:

const PANEL_MESSAGE_ID = '111111111111111111';
const map = {
  '🔴': '123456789012345678', // kırmızı rolü
  '🟢': '987654321098765432', // yeşil rolü
};

client.on('messageReactionAdd', async (reaction, user) => {
  if (user.bot) return;
  if (reaction.message.id !== PANEL_MESSAGE_ID) return;
  if (reaction.partial) await reaction.fetch();

  const roleId = map[reaction.emoji.name];
  if (!roleId) return;

  const member = await reaction.message.guild.members.fetch(user.id);
  await member.roles.add(roleId).catch(console.error);
});

client.on('messageReactionRemove', async (reaction, user) => {
  if (user.bot) return;
  if (reaction.message.id !== PANEL_MESSAGE_ID) return;
  if (reaction.partial) await reaction.fetch();

  const roleId = map[reaction.emoji.name];
  if (!roleId) return;

  const member = await reaction.message.guild.members.fetch(user.id);
  await member.roles.remove(roleId).catch(console.error);
});

Dikkat: özel (custom) emojilerde reaction.emoji.name yerine reaction.emoji.id ile eşleştirme yapmalısınız, çünkü isimler değişebilir ama ID sabittir.

Güvenlik ve sık yapılan hatalar

  • Rol sıralaması: En sık görülen sorun budur. Bot rolü hedef rolün altındaysa "Missing Permissions" hatası alırsınız.
  • Yönetilen (managed) roller: Bot/entegrasyon rolleri veya Nitro Booster rolü manuel verilemez; bunları panele koymayın.
  • Yetki yükseltme: Panele asla Manage Roles, Administrator gibi tehlikeli izinleri olan rolleri koymayın; aksi halde herkes kendini yetkili yapabilir.
  • Mesaj ID'sini sabitleyin: Tüm tepkilere değil, yalnızca panel mesajına tepki veren kontrolü unutmayın, yoksa bot her mesaja tepki üretir.

Sık Sorulan Sorular

Reaction role botu için hangi intent'ler gerekir?

Buton yöntemi için Guilds yeterlidir. Emoji yöntemi ayrıca GuildMessageReactions intent'ini ister ve bot çevrimdışıyken eklenen tepkileri yakalamak için partials ayarını eklemeniz gerekir.

Bot rolü neden hedef rolün üstünde olmalı?

Discord güvenlik kuralı gereği bir bot, yalnızca kendi en yüksek rolünün altında kalan rolleri verebilir/alabilir. Bot rolünü Sunucu Ayarları > Roller'den dağıtacağı rollerin üstüne taşımazsanız "Missing Permissions" hatası alırsınız.

Üye bot kapalıyken tepki verirse ne olur?

Buton yönteminde sorun olmaz çünkü etkileşim bot tekrar açılınca işlenir. Emoji yönteminde ise partials tanımlamadıysanız o tepkiyi kaçırırsınız; bu yüzden buton yöntemi daha güvenilirdir.

Sunucunuza temiz, güvenli bir otorol sistemi mi istiyorsunuz? Buton tabanlı, veritabanı destekli ve hata yönetimi sağlam bir Discord botu kurabilirim. Projeniz için benimle iletişime geçin.

Devamı için