Discord'da İnteraktif Düğmeler: Geliştiriciler İçin Kapsamlı Rehber
Bir Discord bot mesajına düğme eklemek için İnteraktif Bileşenler (Interactive Components) API'sini kullanmanız gerekir. Normal metin göndermek yerine, bot ActionRow öğelerini içeren ve düğmeler (Button) barındıran bir mesaj oluşturur. Kullanıcı bir düğmeye tıkladığında bir interaction olayı tetiklenir; botun bu olayı yakalaması, doğrulaması ve işlemesi, ardından mesajı güncellemesi veya bir yanıt göndermesi gerekir.
Bu rehber, Python (discord.py) ve JavaScript (discord.js) projelerinizde düğmeleri uygulamanıza, yaygın hatalardan kaçınmanıza ve API limitlerine uymanıza yardımcı olacaktır.
Temel Fark: Düğmeler mesaj metninin bir parçası değildir. Bunlar, Discord istemcisi tarafından mesajın altında render edilen ayrı UI öğeleridir. Sunucunuzda veya bot barındırma hizmetinizde aktif olay işleme gerektirirler.
İnteraktif bileşenlerin mimarisi
Düğmelerle çalışma üç ana aşamadan oluşur:
- Oluşturma: Bir düğme nesnesi (stil, etiket, ID) oluşturma ve bunu bir eylem satırına (
ActionRow) yerleştirme. - Gönderme: Oluşturulan bileşeni mesaj gönderilirken (
send) veya düzenlenirken (edit) mesaja bağlama. - İşleme: Etkileşim olayını (
interactionCreate) dinleme. Bot, tıklanan düğmenincustom_iddeğerini kontrol eder ve ilgili kodu yürütür.
Discord API Sınırlamaları
- Bir eylem satırında (
ActionRow) maksimum 5 düğme. - Bir mesajda maksimum 5 satır.
- Toplamda: Tek bir mesajda en fazla 25 düğme.
custom_id(benzersiz tanımlayıcı) uzunluğu 100 karakteri aşmamalıdır.
Python ile Uygulama (discord.py kütüphanesi)
Modern discord.py sürümlerinde (2.0+) View sistemi kullanılır. Bu, düğme durumunun bir sınıfta saklandığı nesne yönelimli bir yaklaşımdır.
Adım 1: View Sınıfı Oluşturma
import discord
from discord.ui import Button, View
class MyView(View):
def __init__(self):
super().__init__(timeout=60) # Düğmeler 60 saniye sonra kaybolacak
@discord.ui.button(label="Bana Tıkla", style=discord.ButtonStyle.primary)
async def first_button_callback(self, interaction: discord.Interaction, button: Button):
await interaction.response.send_message("İlk düğmeye tıkladınız!", ephemeral=True)
# Ephemeral=True yanıtı sadece tıklayana görünür kılar
@discord.ui.button(label="Dur", style=discord.ButtonStyle.danger)
async def stop_button_callback(self, interaction: discord.Interaction, button: Button):
self.stop() # Etkileşim beklemeyi durdurur
await interaction.response.edit_message(content="Eylem durduruldu.", view=None)
Adım 2: Düğmeli Mesaj Gönderme
@bot.command()
async def test_buttons(ctx):
view = MyView()
await ctx.send("Bir eylem seçin:", view=view)
Bellek sızıntılarını önlemek için View yapıcısında timeout kullanın. Kullanıcı uzun süre düğmelere tıklamazsa, View nesnesi otomatik olarak yok edilecektir.
JavaScript ile Uygulama (discord.js v14+ kütüphanesi)
discord.js sürüm 14 ve üstünde bileşenler oluşturucular (Builders) aracılığıyla oluşturulur. İşleme, global bir olay dinleyicisi üzerinden gerçekleşir.
Adım 1: Düğmeleri Oluşturma ve Gönderme
const { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } = require('discord.js');
// Düğmeleri oluştur
const acceptButton = new ButtonBuilder()
.setCustomId('accept_action')
.setLabel('Kabul Et')
.setStyle(ButtonStyle.Success);
const declineButton = new ButtonBuilder()
.setCustomId('decline_action')
.setLabel('Reddet')
.setStyle(ButtonStyle.Danger);
// Eylem satırını birleştir
const row = new ActionRowBuilder()
.addComponents(acceptButton, declineButton);
// Mesajı gönder
await channel.send({
content: 'Eyleminizi onaylayın:',
components: [row]
});
Adım 2: Tıklamaları İşleme (InteractionCreate)
client.on('InteractionCreate', async interaction => {
if (!interaction.isButton()) return;
if (interaction.customId === 'accept_action') {
await interaction.reply({ content: 'Eylem kabul edildi!', ephemeral: true });
} else if (interaction.customId === 'decline_action') {
await interaction.update({ content: 'Eylem iptal edildi.', components: [] });
}
});
Düğme Stillerinin Karşılaştırılması
Doğru renk seçimi, kullanıcının düğmenin amacını sezgisel olarak anlamasına yardımcı olur.
| Stil (Enum) | Renk | Amaç |
|---|---|---|
Primary | Mavi | Ana eylem (örneğin, "Daha Fazla", "İleri"). |
Secondary | Gri | Nötr eylemler (örneğin, "Geri", "İptal"). |
Success | Yeşil | Olumlu onaylar ("Kabul Et", "Satın Al"). |
Danger | Kırmızı | Tehlikeli veya geri alınamaz eylemler ("Sil", "Banla"). |
Link | Zincirli Gri | Harici bağlantı (etkileşim olayı tetiklemez). |
Link türündeki düğmeler botunuza interaction olayı göndermez. Bir kullanıcının bağlantıya tıklayıp tıklamadığını takip edemezsiniz ve gönderildikten sonra böyle bir düğmenin durumunu değiştiremezsiniz.
Geliştiricilerin Sık Yaptığı Hatalar
-
ephemeralyanıtları görmezden gelmek. Bot bir düğme tıklamasına normal bir mesajla yanıt verirse, bu kanalın tüm katılımcıları için sohbeti kirletir. Yanıt yalnızca tıklayana yönelikseephemeral=True(Python) veyaephemeral: true(JS) kullanın. -
Erişim haklarının kontrol edilmemesi. Herhangi bir kullanıcı bir düğmeye tıklayabilir. Düğme yönetimsel bir eylem gerçekleştiriyorsa, mantığı yürütmeden önce
interactionişleyicisi içinde kullanıcının rollerini mutlaka kontrol edin. -
Bot yeniden başlatıldıktan sonra düğmelerin "takılıp kalması". Bot yeniden başlatılırsa, daha önce gönderilen
Viewvarlığını "unutur".- discord.py için çözüm: Açık
custom_idkaydı ile kalıcı görünümler (Persistent Views) kullanın. - discord.js için çözüm: Bekleyen etkileşimlerin durumunu bir veritabanında saklayın veya
interactionCreateişleyicisinin mantığının kendi kendine yeterli olduğundan emin olun.
- discord.py için çözüm: Açık
-
Custom ID'de karakter sınırının aşılması. Tüm durum bilgilerini
custom_idiçine gömmeye çalışmayın. Veri çok fazlaysa, veritabanı veya önbellek kullanın vecustom_idiçinde yalnızca kısa bir anahtar saklayın (örneğin,ticket_open_123).
SSS
Zaten gönderilmiş bir mesaja düğme eklenebilir mi?
Evet, mesaj düzenleme yöntemini (edit_message veya interaction.update) kullanarak. Bileşen dizisini yeniden tam olarak iletmeniz gerekir. Mevcut bir satıra sadece tek bir düğme "ekleyemezsiniz"; tüm bileşen setini yeniden tanımlamanız gerekir.
Düğmeler neden gri ve pasif hale geliyor?
Bu, View oluşturulurken belirtilen timeout süresi dolduğunda veya bot kalıcı bileşenler kullanılmadan yeniden başlatıldığında gerçekleşir. Ayrıca, mesajı güncellerken açıkça disabled=True geçirirseniz düğmeler devre dışı bırakılır.
Düğmeler spam'e karşı güvenli mi? Discord, etkileşimler için yerleşik hız sınırlamalarına (rate-limit) sahiptir. Ancak kendi kontrolünüzü eklemeniz önerilir: Önceki işlem henüz tamamlanmamışsa aynı düğmeye yapılan tekrarlanan tıklamaları yoksayın (örneğin, veritabanı isteği yürütülürken düğmeyi bloke edin).