Kendi Discord botunuzu yazmak sandığınızdan kısa sürer: Developer Portal'da bir uygulama açar, bot kullanıcısının token'ını alır, botu test sunucunuza ekler ve birkaç satır JavaScript ile ilk slash komutunuzu çalıştırırsınız. Bu rehber, hiç bot yazmamış birinin sıfırdan çalışan bir /ping komutuna ulaşması için gereken her adımı sırayla anlatıyor.

Örneklerde Node.js ve en yaygın kütüphane olan discord.js (v14 sözdizimi) kullanılıyor. Python tercih ediyorsanız aynı adımların discord.py karşılığını discord.py ile bot yapımı yazısında bulabilirsiniz. Yazının sonundaki "Sonraki adımlar" bölümü, botunuzu büyütürken ihtiyaç duyacağınız tüm konulara (butonlar, intent'ler, izinler, 7/24 barındırma, hata kodları) bağlantı veriyor.

Başlamadan önce: bot mu, webhook mu?

Başlamadan önce: bot mu, webhook mu? Bir Discord hesabı ve yönetebildiğiniz, başkalarının aktif kullanmadığı bir..., Node.js, Bir kod editörü (ör. Visual Studio Code) ve temel...

Discord'un belgelerine göre botlar, sunucularda APP etiketiyle görünen ve olayları dinleyebilen, slash komutlarına yanıt verebilen, mesaj gönderebilen uygulama kullanıcılarıdır. Yalnızca bir kanala bildirim göndermek istiyorsanız (ör. sitenize yeni sipariş geldiğinde mesaj atmak) tam bir bot yerine webhook daha basit olabilir; webhook'lar olay dinleyemez ve etkileşimlere yanıt veremez. Bu ayrımı Discord webhook ve bot entegrasyonu rehberi yazısında ayrıntılı ele aldık.

Botlar Discord'a iki yolla bağlanabilir: sürekli açık bir Gateway WebSocket bağlantısı ya da yalnızca slash komut ve bileşen etkileşimlerini alan bir HTTP interactions endpoint. Bu rehber, discord.js'in varsayılanı olan Gateway yaklaşımını kullanıyor. Sunucusuz (serverless) bir mimari düşünüyorsanız HTTP interactions ve Cloudflare Workers yazısına bakın.

Gerekenler

  • Bir Discord hesabı ve yönetebildiğiniz, başkalarının aktif kullanmadığı bir test sunucusu
  • Node.js: discord.js rehberi en güncel LTS sürümünü öneriyor; terminalde node -v ile kontrol edebilirsiniz (Node.js nedir)
  • Bir kod editörü (ör. Visual Studio Code) ve temel JavaScript bilgisi

Adım 1: Developer Portal'da uygulama oluşturun

Discord Developer Portal (discord.com/developers/applications) adresine girip hesabınızla oturum açın ve "New Application" düğmesine tıklayın. Bir ad girip "Create" ile onayladığınızda uygulamanın "General Information" sayfasına düşersiniz. Burada açıklama ve simge düzenleyebilir, ayrıca iki önemli değeri görürsünüz:

  • Application ID: uygulamanızın kimliği. Davet linklerinde client_id olarak, komut kaydında da clientId olarak kullanılır.
  • Public Key: yalnızca HTTP interactions kullanan botlarda, gelen isteğin gerçekten Discord'dan geldiğini doğrulamak için gerekir.

Bu değerlerin hangisinin gizli olduğunu, client secret ile token arasındaki farkı Discord bot token nedir yazısında tablo hâlinde anlattık.

Adım 2: Bot kullanıcısı ve token

Discord'un başlangıç rehberine göre yeni oluşturulan uygulamalarda bot kullanıcısı varsayılan olarak etkindir. Sol menüdeki "Bot" sayfasında botun kullanıcı adını ve avatarını ayarlayabilir, "Reset Token" düğmesiyle token üretebilirsiniz. Token yalnızca üretildiği anda gösterilir; kaybederseniz yeniden sıfırlamanız gerekir ve sıfırlama eski token'ları geçersiz kılar.

Aynı sayfada "Public Bot" seçeneği de bulunur. Bu seçenek kapalıysa botu yalnızca siz sunuculara ekleyebilirsiniz; açıksa davet linkine sahip herkes, yetkisi olan sunuculara ekleyebilir.

Adım 3: Intent'leri anlayın

Adım 3: Intent'leri anlayın: GUILD_MEMBERS, GUILD_PRESENCES, MESSAGE_CONTENT

Intent, Gateway bağlantısı kurarken botunuzun hangi olayları almak istediğini Discord'a bildirdiğiniz bayraklardır. discord.js rehberi, istemcinin beklendiği gibi çalışması için en azından GatewayIntentBits.Guilds intent'ini öneriyor; bu intent sunucu, kanal ve rol önbelleklerinin dolmasını sağlar. Slash komutlarıyla çalışan basit bir bot için çoğu zaman bu kadarı yeterlidir.

Bazı intent'ler privileged (ayrıcalıklı) olarak işaretlidir ve kullanmadan önce "Bot" sayfasındaki "Privileged Gateway Intents" bölümünden açılmaları gerekir:

Privileged intentdiscord.js adıNe için gerekir
GUILD_MEMBERSGuildMembersÜye katılma/ayrılma ve üye güncelleme olayları, üye listesini çekme
GUILD_PRESENCESGuildPresencesÜyelerin çevrimiçi durumu ve etkinlikleri
MESSAGE_CONTENTMessageContentMesajların içerik, ek, embed ve bileşen alanlarını okumak

Portalda açmadığınız bir privileged intent'i kodda isterseniz Gateway bağlantısı 4014 (Disallowed intents) kapanış koduyla kesilir. Discord'un güncel kuralına göre, sunucularında 10.000'den fazla benzersiz kullanıcının görebildiği uygulamalar privileged intent erişimi için başvuru yapmak zorundadır. Hangi intent'e gerçekten ihtiyacınız olduğunu Discord intent nedir, başvuru sürecini bot doğrulama ve privileged intent yazısında anlattık.

Adım 4: Botu test sunucunuza ekleyin

Sol menüden "Installation" sayfasını açın. "Installation Contexts" bölümünde "Guild Install" seçili olsun. "Install Link" bölümünde "Discord Provided Link" seçiliyken altında "Default Install Settings" görünür. "Guild Install" için applications.commands ve bot scope'larını ekleyin; bot seçildiğinde bot izinleri listesi açılır. Başlangıç için yalnızca "Send Messages" yeterlidir.

Sayfadaki install link'i kopyalayıp tarayıcıya yapıştırın, "Add to server" seçeneğiyle test sunucunuzu seçin ve onaylayın. Bir sunucuya bot ekleyebilmek için o sunucuda "Manage Server" (MANAGE_GUILD) iznine sahip olmanız gerekir. Bot üye listesinde görünüyorsa bu adım tamamdır. Davet linkinin yapısı, izin tamsayısı ve kullanıcıya kurulum (user install) seçeneği için Discord bot sunucuya ekleme yazısına bakın.

Adım 5: Node.js projesini kurun

Bilgisayarınızda discord-bot adında bir klasör açın, terminalde bu klasöre geçin ve projeyi başlatıp discord.js'i kurun:

bash
mkdir discord-bot
cd discord-bot
npm init -y
npm install discord.js

Ardından proje kökünde iki dosya oluşturun. .env dosyası gizli değerleri tutar; .gitignore ise bu dosyanın ve node_modules klasörünün Git'e girmesini engeller. Sunucu kimliğini (GUILD_ID) almak için Discord'da geliştirici modunu açıp sunucu adına sağ tıklayın ve "Copy ID" seçin.

bash
# .env
DISCORD_TOKEN=buraya-bot-tokeniniz
CLIENT_ID=buraya-application-id
GUILD_ID=buraya-test-sunucusu-id
bash
# .gitignore
node_modules
.env

discord.js rehberi, ortam değişkenlerini okumak için Node.js'in --env-file bayrağını öneriyor; böylece ek bir paket kurmanız gerekmez. Bu dosyaların mantığı için .env dosyası nedir ve .gitignore nedir yazılarına göz atabilirsiniz.

Adım 6: İlk slash komutunu tanımlayın

Slash komutu tanımı en az bir ad ve bir açıklama içermelidir. discord.js rehberine göre komut adı 1 ile 32 karakter arasında olmalı; büyük harf, boşluk ve - ile _ dışındaki semboller kullanılamaz. Tanımları ayrı bir dosyada tutmak, kayıt betiğiyle botun ana dosyasının aynı listeyi kullanmasını sağlar:

javascript
// commands.js
const { SlashCommandBuilder } = require('discord.js');

module.exports = [
  new SlashCommandBuilder().setName('ping').setDescription('Pong ile yanıt verir'),
  new SlashCommandBuilder().setName('sunucu').setDescription('Sunucu bilgisini gösterir'),
];

Adım 7: Komutları Discord'a kaydedin (guild ve global)

Adım 7: Komutları Discord'a kaydedin (guild ve global): Route, Nerede görünür, Güncelleme, Ne zaman

Komutların Discord istemcisinde görünmesi için tanımlarını bir kez Discord API'sine kaydetmeniz gerekir. discord.js rehberi bunun her açılışta değil, yalnızca komut tanımı (ad, açıklama, seçenekler) değiştiğinde çalıştırılan ayrı bir betikle yapılmasını öneriyor; çünkü günlük komut oluşturma sınırı vardır. Komutun ne yaptığını (execute kısmını) değiştirmek yeniden kayıt gerektirmez.

javascript
// deploy-commands.js
const { REST, Routes } = require('discord.js');
const commands = require('./commands.js').map((c) => c.toJSON());

const rest = new REST().setToken(process.env.DISCORD_TOKEN);

(async () => {
  try {
    const data = await rest.put(
      Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.GUILD_ID),
      { body: commands },
    );
    console.log(`${data.length} komut kaydedildi.`);
  } catch (error) {
    console.error(error);
  }
})();

put çağrısı, o kapsamdaki komut listesini gönderdiğiniz listeyle tamamen değiştirir. Komutlar iki kapsamda kaydedilebilir:

Guild (sunucu) komutuGlobal komut
RouteRoutes.applicationGuildCommands(clientId, guildId)Routes.applicationCommands(clientId)
Nerede görünürYalnızca belirtilen sunucuda, DM'de görünmezUygulamanın eklendiği tüm sunucularda, varsayılan olarak DM'lerde de
GüncellemeDiscord belgesine göre anındaTüm sunuculara yayılır
Ne zamanGeliştirme ve testKomut hazır olduğunda yayın

Discord'un belgelerine göre bir uygulama en fazla 100 global CHAT_INPUT (slash) komutuna sahip olabilir ve sunucu başına günde 200 komut oluşturma sınırı vardır. Seçenekli komutlar, alt komutlar ve otomatik tamamlama için Discord slash komut oluşturma yazısına geçebilirsiniz.

Adım 8: Botun ana dosyasını yazın ve çalıştırın

Ana dosya istemciyi oluşturur, Discord'a giriş yapar ve gelen her etkileşimde komut adına göre yanıt verir. isChatInputCommand() kontrolü, buton veya menü gibi başka etkileşim türlerini bu işleyiciden ayırır:

javascript
// index.js
const { Client, Events, GatewayIntentBits, MessageFlags } = require('discord.js');

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.once(Events.ClientReady, (readyClient) => {
  console.log(`Hazır: ${readyClient.user.tag} olarak giriş yapıldı`);
});

client.on(Events.InteractionCreate, async (interaction) => {
  if (!interaction.isChatInputCommand()) return;

  if (interaction.commandName === 'ping') {
    await interaction.reply('Pong!');
  } else if (interaction.commandName === 'sunucu') {
    await interaction.reply({
      content: `Sunucu: ${interaction.guild.name}, üye sayısı: ${interaction.guild.memberCount}`,
      flags: MessageFlags.Ephemeral,
    });
  }
});

client.login(process.env.DISCORD_TOKEN);

MessageFlags.Ephemeral bayrağı, yanıtı yalnızca komutu kullanan kişinin görmesini sağlar. Şimdi önce komutları kaydedin, sonra botu başlatın:

bash
node --env-file=.env deploy-commands.js
node --env-file=.env index.js

Terminalde "Hazır" yazısını gördükten sonra test sunucunuzda / yazın; /ping komutu listede çıkmalı ve bot "Pong!" diye yanıt vermelidir. Ctrl+C ile süreci durdurduğunuzda bot çevrimdışı olur.

Bot büyüdükçe tüm komutları tek dosyada if zinciriyle yönetmek zorlaşır. discord.js rehberi her komutu commands klasöründe ayrı bir dosyada (data ve execute dışa aktararak) tutmayı ve bunları bir Collection içine yükleyen bir komut işleyicisi yazmayı öneriyor.

Sık karşılaşılan ilk sorunlar

BelirtiMuhtemel nedenÇözüm
Gateway 4004 Authentication failedToken yanlış, eksik kopyalanmış ya da sıfırlanmışToken'ı "Bot" sayfasında sıfırlayıp .env dosyasını güncelleyin
Gateway 4014 Disallowed intent(s)Kodda istenen privileged intent portalda kapalıIntent'i portalda açın ya da koddan çıkarın
Komut / listesinde yokKayıt betiği çalıştırılmadı veya uygulama o sunucuda applications.commands ile yetkilendirilmedideploy-commands.js betiğini çalıştırın, botu doğru scope'larla yeniden ekleyin
"Bot requires a code grant"Portalda "Require OAuth2 Code Grant" açıkNeden gerektiğini bilmiyorsanız bu seçeneği kapatın
"Bu etkileşim başarısız oldu"3 saniye içinde yanıt verilmedi veya kod hata verdiTerminal loglarına bakın, gerekirse deferReply() kullanın

Discord API'sinin döndürdüğü sayısal hata kodlarının (ör. 50001 Missing access, 50013 izin eksikliği) Türkçe açıklamaları Discord API hata kodları yazısında.

Sonraki adımlar

Çalışan bir botunuz var. Buradan sonra ihtiyacınıza göre şu yazılara geçebilirsiniz:

Sık Sorulan Sorular

Discord botu yapmak için JavaScript bilmek şart mı?

Hayır. Discord API'si dilden bağımsızdır; Python, Java, C#, Rust ve Go için de olgun kütüphaneler var. Python biliyorsanız discord.py rehberi ile başlayabilirsiniz. Kütüphaneleri yan yana görmek için kütüphane karşılaştırması yazısına bakın.

Bilgisayarımı kapatınca bot neden çevrimdışı oluyor?

Gateway botu, kodunuz çalıştığı sürece Discord'a bağlı kalır. Süreç durduğunda bağlantı kapanır ve bot çevrimdışı görünür. Botun sürekli açık kalması için kodu bir sunucuda çalıştırıp bir süreç yöneticisine (systemd, PM2, Docker) bağlamanız gerekir. Adımlar: Discord botu 7/24 aktif tutma.

Prefix komutları (!komut) yerine neden slash komut?

Mesaj içeriğini okuyarak çalışan prefix komutları MESSAGE_CONTENT privileged intent'ini gerektirir. Slash komutları ise Discord arayüzüne entegre olur; seçenekler türlü ve doğrulanmış gelir, yanıtlar yalnızca kullanıcıya görünecek şekilde (ephemeral) gönderilebilir ve bu intent'e ihtiyaç duymaz.

Komutlarım test sunucusunda var ama başka sunucuda yok, neden?

Komutları guild route'u ile kaydettiyseniz yalnızca o sunucuda görünürler. Diğer sunucular için Routes.applicationCommands(clientId) ile global kayıt yapmanız gerekir. discord.js rehberi, geliştirme için ayrı bir uygulama ve token kullanmayı da öneriyor; böylece test komutlarınız yayındaki komutlarla karışmaz.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Botu sunucuya ekleme · Bot token güvenliği · Slash komut oluşturma · Botu 7/24 aktif tutma · Node.js nedir · .env dosyası nedir