İçeriğe geç
N'oluyo
Rehberler

Etkileşimler

Son güncelleme:

Biri botunun butonuna bastığında ya da komutunu çalıştırdığında bot INTERACTION_CREATE alır ve ona yanıt verir. Bu sayfa yanıtın dört türünü, süreleri ve sonradan gelen mesajları anlatır. Basmanın kendisi ve bileşenlerin nasıl yazıldığı Bileşenler sayfasında.

Zaman çizelgesi

Ne zamanNe olur
0 snKişi basar, bot INTERACTION_CREATE alır. Olayda id ve token vardır.
3 snİlk yanıtın son anı. Sonrası 400 interaction_timeout döner, kişi "Bot yanıt vermedi" görür.
15 dkToken'ın ömrü. @original düzenlemesi ve takip mesajları buraya kadar çalışır, sonrası 400 interaction_expired döner.

Her etkileşim tek bir ilk yanıt alır. İkincisi 400 interaction_already_acknowledged döner. Reddedilen bir yanıt hakkını harcamaz: hatayı düzeltip süre içinde yeniden gönderebilirsin.

Gateway mı HTTP mi

Etkileşim botuna iki yoldan gelebilir. Uygulamanın etkileşim adresi yoksa gateway'den, varsa yalnızca o adrese. İçerik ikisinde aynıdır; değişen, yanıtı nasıl verdiğindir:

GatewayHTTP adresi
Etkileşim nasıl gelirINTERACTION_CREATE olayıAdresine imzalı POST
İlk yanıtcallback rotası, bot token'ıylaAynı isteğin 200 gövdesi; ya da 202 dönüp callback rotası
3 saniyeEtkileşimin kimliğinden sayılırAdresine bağlanma ve yanıtın tamamı dahil
Reddedilen yanıtHata kodunu sen alırsın, süre içinde düzeltip yeniden gönderebilirsinKişi "Bot zamanında yanıt vermedi." görür, kod teslim günlüğüne yazılır
Bot kapalıysaEtkileşim kaybolur, kişi 3 saniye sonra hatayı görürKişi hatayı hemen görür
Takip, @originalAynı rotalarAynı rotalar, bot token'ıyla
Sınırlarinteraction sınıfı ve ortak tavanlarAynısı

Kişi hangi yolu kullandığını görmez.

Sunucuda mı DM'de mi

Her etkileşim context alanını taşır: 0 sunucu kanalı, 1 kişinin botunla açtığı DM. Basma, komut, otomatik tamamlama ve form DM'de de aynı çalışır; fark yalnızca kimin nerede olduğundadır:

AlanSunucudaDM'de
context01
guild_idSunucunun kimliğiYok
memberKişi, permissions doluYok
userYokKişi
app_permissionsBotun bu kanaldaki izinleriDM'nin sabit izinleri
JavaScript
// Aynı kod sunucuda ve DM'de çalışır.
const guildId = interaction.guild_id ?? null; // DM'de null
const person = interaction.member?.user ?? interaction.user;
const inDM = interaction.context === 1;
if (inDM) {
  // Rol yok, izin yok: yetki isteyen işi burada yapma.
}

Yanıt rotaları DM'de de aynıdır. Kişi DM'yi kapatır ya da botu engellerse yanıt 403 dm_closed alır (Özel mesajlar).

Hangi yanıtı seçmeliyim?

İşin 3 saniyeden uzun sürer mi?Neyi değiştiriyorsun?Seç
HayırKanala yeni bir mesaj yazıyorsuntype: 4
HayırButonun durduğu mesajı değiştiriyorsuntype: 7
EvetSonuç yeni bir mesaj olacaktype: 5, sonra PATCH @original
EvetButonun durduğu mesajı değiştireceksintype: 6, sonra kanal mesajını düzenle
Evet ya da hayırGörünen hiçbir şey değişmiyortype: 6
HayırBir komuta yanıt veriyorsuntype: 4
EvetBir komuta yanıt veriyorsuntype: 5, sonra PATCH @original

Her yanıt her etkileşime uymaz. Uymayanı göndermek 400 interaction_response_invalid döner:

Etkileşimtype: 4type: 5type: 6type: 7type: 8type: 9
Butona basma, menüden seçme (type: 3)EvetEvetEvetEvetHayırEvet
Komut çalıştırma (type: 2)EvetEvetHayırHayırHayırEvet
Otomatik tamamlama (type: 4)HayırHayırHayırHayırEvetHayır
Gönderilen form (type: 5)EvetEvetButondan açıldıysaButondan açıldıysaHayırHayır

Komut çalıştırmanın üzerinde durduğu bir mesaj yoktur; değiştirilecek bir şey olmadığı için 6 ve 7 almaz. type: 8 kişi yazarken önerdiğin seçeneklerdir (data.choices) ve yalnızca otomatik tamamlamaya uyar. type: 9 kişiye bir form açar; ilk yanıt olmalıdır ve gönderilen form sana yeni bir etkileşim olarak gelir.

Yanıtı yalnızca basan kişi görsün istiyorsan data içine flags: 64 ekle: Yalnızca basan kişi görsün.

Yanıt rotası

Dört tür de aynı rotaya gider:

Bash
curl -X POST "https://noluyo.net/api/v1/interactions/$INTERACTION_ID/$INTERACTION_TOKEN/callback" \
  -H "Authorization: Bot $BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":4,"data":{"content":"Kaydın alındı."}}'

type 4: yeni mesajla yanıt

Kanala yeni bir mesaj yazar. data bir mesaj gibidir: content, embeds, components, allowed_mentions. Metin ya da embed zorunludur.

JSON
{ "type": 4, "data": { "content": "Kaydın alındı." } }

Yanıt 200 ve mesajdır. Mesajın interaction alanı kimin bastığını söyler:

JSON
{
  "message": {
    "id": "111600000000000500",
    "type": 0,
    "channel_id": "111500000000000100",
    "content": "Kaydın alındı.",
    "application_id": "111540000000000000",
    "interaction": {
      "id": "111600000000000400",
      "type": 3,
      "user": { "id": "111540000000000009", "username": "ayse" }
    }
  }
}

type 5: önce "düşünüyor", sonra sonuç

İşin uzun sürecekse hemen bunu gönder. Kanala boş bir mesaj düşer ve flags: 128 taşır; kişi onu "düşünüyor" olarak görür. data içinden yalnızca flags okunur: content, embeds ve components gönderirsen yok sayılır, onları PATCH @original ile gönder.

JSON
{ "type": 5 }

Yanıt 200 ve mesajdır:

JSON
{
  "message": {
    "id": "111600000000000500",
    "type": 0,
    "content": "",
    "flags": 128,
    "interaction": {
      "id": "111600000000000400",
      "type": 3,
      "user": { "id": "111540000000000009", "username": "ayse" }
    }
  }
}

İş bitince mesajı doldur. flags'teki 128 kendiliğinden silinir, mesaj "(düzenlendi)" olarak işaretlenmez:

Bash
curl -X PATCH "https://noluyo.net/api/v1/interactions/$INTERACTION_ID/$INTERACTION_TOKEN/messages/@original" \
  -H "Authorization: Bot $BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content":"Rapor hazır."}'

type 6: sessiz onay

Bastığını aldığını söyler, ekranda hiçbir şey değişmez. Mesaj oluşmaz, SendMessages da gerekmez. data gönderirsen yok sayılır.

JSON
{ "type": 6 }

Yanıt 204, gövdesizdir. Sonra kanala bir şey yazmak istersen takip mesajı kullan. Butonun durduğu mesajı değiştirmek istersen mesaj düzenleme rotası çalışır; @original burada işe yaramaz, çünkü bu yanıtın mesajı yoktur: istek 200 döner ama ekranda bir şey değişmez.

type 7: basılan mesajı güncelle

Butonun durduğu mesajı değiştirir. Göndermediğin alan olduğu gibi kalır, boş components listesi butonları kaldırır. Yalnızca components değişirse mesaj "(düzenlendi)" olarak işaretlenmez.

JSON
{ "type": 7, "data": { "content": "Oylama bitti.", "components": [] } }

Yanıt 200 ve güncellenen mesajdır:

JSON
{
  "message": {
    "id": "111600000000000000",
    "content": "Oylama bitti.",
    "edited_timestamp": "2026-11-07T20:00:00.000Z"
  }
}

Bu rotalarda yeni dosya gönderilemez. Görsel göndermek istiyorsan takip mesajı kullan.

@original ve takip mesajları

İlk yanıtı verdikten sonra token 15 dakika boyunca çalışır:

İstekNe yaparYanıt
POST /interactions/{id}/{token}/messagesYeni takip mesajı yazar, dosya da alır200 ve mesaj
PATCH /interactions/{id}/{token}/messages/@originaltype: 4 ya da type: 5 mesajını düzenler200 ve mesaj
PATCH /interactions/{id}/{token}/messages/{message_id}Bu etkileşimin bir mesajını düzenler200 ve mesaj
DELETE /interactions/{id}/{token}/messages/{message_id}Bu etkileşimin bir mesajını siler, @original da olur204

Token yalnızca kendi etkileşiminin mesajlarına ulaşır. Aynı kanaldaki başka bir mesaj 404 unknown_message döner. Bir etkileşim en çok 5 takip mesajı atabilir, altıncısı 429 döner. Takip mesajı dosya almak için multipart/form-data kullanır; biçimi mesaj gönderme ile aynıdır.

Bash
curl -X POST "https://noluyo.net/api/v1/interactions/$INTERACTION_ID/$INTERACTION_TOKEN/messages" \
  -H "Authorization: Bot $BOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content":"Bir şey daha: rapor e-postana da gitti."}'

Ephemeral takip mesajı dosya almaz ama beşe aynı sayılır. Bir etkileşimin ephemeral mesajları 5 saniyede en çok 5 kez düzenlenebilir, fazlası 429 döner. Ayrıca tüm botlar birlikte bir kişiye 5 saniyede en çok 262144 bayt ephemeral mesaj gönderebilir (metin, embed'ler ve bileşenlerin üç katı sayılır); fazlası 429 rate_limited döner ve kişiye bir şey gitmez. Yanıtlara yavaş mod ve mesaj sınırı işlemez, çünkü onları bir kişinin basması tetikler. SendMessages izni, otomatik moderasyon ve interaction sınıfı ile ortak tavanlar yine geçerlidir.

Yalnızca basan kişi görsün

data içine flags: 64 eklersen yanıtı yalnızca basan kişi görür. Buna ephemeral mesaj denir. type: 4, type: 5 ve takip mesajında çalışır:

JSON
{ "type": 4, "data": { "content": "Kaydın alındı. Bunu yalnızca sen görüyorsun.", "flags": 64 } }

Yanıt 200 ve {"message": ...}, takip mesajında yalnızca mesajdır. flags 64 gelir, mentions her zaman boştur. İlk yanıtın kimliği etkileşimin kimliğidir, takip mesajı yeni kimlik alır.

type: 5 ile flags: 64 gönderirsen kişi "düşünüyor" görür ve flags 192 gelir. PATCH @original ile doldurduğunda 64 olur. Bu PATCH ve diğerleri yalnızca basan kişiye gider. Kişi artık kanalı görmüyorsa 404 unknown_channel döner, ona bir şey gitmez.

Ne zaman kaybolur

N'oluyo bu mesajı saklamaz. Kişi sayfayı yenilerse ya da uygulamayı yeniden açarsa mesaj gider. O anda açık olan başka cihazında da görünür, sonradan açtığı cihazda görünmez. Kişi mesajdaki "Kapat" düğmesiyle onu kendi ekranından kaldırabilir, bu sana haber vermez. Mesaj geçmişte çıkmaz, okunmadı sayacını ve last_message_id'yi oynatmaz, bildirim göndermez. Diğer üyeler ve botlar, senin botun da, MESSAGE_CREATE almaz.

Kalıcı olması gereken bir şeyi burada söyleme. Kişi mesajı kaybetse de sonucu bulabilmeli.

Ne yapamaz

YapılamayanOlanYerine
Görsel ya da dosya400 ephemeral_files, hem attachment:// hem multipart/form-dataDosya bir mesaj satırına bağlıdır, burada satır yok. Görseli herkese açık mesajla gönder.
Tepki, sabitlemeSatırı olmayan mesajda çalışmazBileşen kullan.
Kanala doğrudan atmaPOST /channels/{id}/messages 400 ephemeral_forbidden dönerBir etkileşime yanıt ver: kime gösterileceğini basma söyler.
Kanal mesajı rotalarıyla okuma, düzenleme404 unknown_messageEtkileşim rotalarını kullan.
15 dakika sonra basmaKişi 400 interaction_expired alır, sana bir şey gelmezMesajı değiştirirsen süre yeniden başlar.

Butonlu ephemeral

Bileşen eklersen kişi basabilir. Mesaj saklanmadığı için botuna gelen message kısadır: id, channel_id, flags, author ve components. Metni gelmez, gerekiyorsa bilgiyi custom_id'ye koy ya da kendi veritabanında tut.

JSON
{
  "type": 4,
  "data": {
    "content": "Silinsin mi?",
    "flags": 64,
    "components": [{ "type": 1, "components": [
      { "type": 2, "style": 4, "label": "Sil", "custom_id": "sil:42" }
    ] }]
  }
}

Kişi bastığında:

JSON
{
  "id": "111600000000000700",
  "type": 3,
  "token": "...",
  "channel_id": "111500000000000100",
  "data": { "custom_id": "sil:42", "component_type": 2 },
  "message": {
    "id": "111600000000000400",
    "channel_id": "111500000000000100",
    "flags": 64,
    "author": { "id": "111540000000000001", "username": "botun" },
    "components": [{ "type": 1, "components": [
      { "type": 2, "style": 4, "label": "Sil", "custom_id": "sil:42" }
    ] }]
  }
}

type: 7 basılan mesajı değiştirir. type: 4 ile flags: 64 yeni bir ephemeral açar, flags olmadan herkese açık yanıt verir. type: 7 sonrası düzenleme için @original değil, message.id kullan: PATCH /interactions/{id}/{token}/messages/{message.id}.

JSON
{ "type": 7, "data": { "content": "Silindi.", "components": [] } }

Satırı olmayan kimlik ephemeral sayıldığı için type: 6 ya da type: 7 sonrası @original 200 döner ama ekranda bir şey değişmez: o kimlikte mesaj yoktur. İstemci ephemeral MESSAGE_UPDATE ve MESSAGE_DELETE olayını yalnızca elinde flags: 64 ile tuttuğu ve application_id'si aynı olan mesaja uygular. Böylece bir bot başka botun mesajını değiştiremez.

Kişi ne görür

Etkileşime yanıt olan mesajın üstünde, yanıt satırı gibi, "ad kullandı" yazar. Herkese açık yanıtta bunu kanaldaki herkes görür. Böyle bir mesaj botunun bir önceki mesajıyla tek blokta birleşmez, adı ve avatarıyla ayrı başlar.

type: 5 sonrası mesajda üç nokta oynar ve "Botun adı düşünüyor…" yazar. PATCH @original gelince yerini yanıt alır. Bot 15 dakika içinde doldurmazsa yazı "Bot yanıt vermedi." olur; kişi sonsuza dek bekleyen bir mesaj görmez.

Ephemeral mesaj hafif renkli bir zeminde, solunda temanın renginde bir çizgiyle durur, altında "Yalnızca sen görüyorsun · Kapat" yazar. Üzerinde mesaj araç çubuğu ve sağ tık menüsü yoktur: yanıtlanamaz, iletilemez, sabitlenemez, tepki eklenemez ve bildirilemez. "Kapat" mesajı yalnızca o ekrandan kaldırır. Sayfa yenilenince ephemeral mesajlar gider; okunmadı sayacı ve kanalın son mesajı yerinde kalır.

Ephemeral mesajın butonları ve menüleri herkese açık mesajdakiler gibi çizilir ve basılır. Basınca uygulama mesajla gelen ephemeral_state'i geri gönderir, sunucu bileşenleri onunla doğrular. type: 7 ile yanıt verirsen ephemeral mesaj yerinde değişir. Mesaj gelişinden ya da son güncellenişinden 15 dakika sonra basan kişi "Bu etkileşimin süresi doldu." görür.

Token'ı koru

Token tek başına yetmez: dört rota da Authorization: Bot başlığı ister ve token'ı yalnızca etkileşimin gittiği bot kullanabilir. Başka bir botun göndermesi 400 interaction_token_invalid döner. Sunucu bu rotaların adresindeki token'ı kendi log'larına yazmaz.

Hatalar

KodNe olduNe yap
interaction_timeoutİlk yanıt 3 saniyeyi geçtiİşi yanıttan önce yapma. Önce type: 5 ya da type: 6 gönder, sonra işe başla.
interaction_already_acknowledgedBu etkileşime zaten yanıt verdinSonrası için takip mesajı ya da @original kullan.
interaction_not_acknowledgedTakip ya da düzenleme ilk yanıttan önce geldiÖnce callback gönder ve yanıtını bekle.
interaction_response_invalidBu etkileşime uymayan bir type gönderdin, type: 7'de data yok, choices type: 8 dışında geldi, ya da type: 9 otomatik tamamlamaya veya gönderilen forma gittiBasmaya 4, 5, 6, 7 ya da 9, komuta 4, 5 ya da 9, otomatik tamamlamaya 8 gönder.
interaction_token_invalidToken bozuk, adresteki kimlikle uyuşmuyor ya da başka bir botunid ve token'ı aynı olaydan al, kendi bot token'ınla gönder.
interaction_expiredToken'ın 15 dakikası dolduKanala normal mesaj gönder.
ephemeral_filesEphemeral mesajda dosya ya da attachment:// varGörseli herkese açık mesajla gönder.
validation_faileddata bir mesaj olarak geçersiz, örneğin metin yokerrors alanına bak. Hakkın gitmedi, düzeltip yeniden gönder.
missing_permissionsBotun bu kanalda SendMessages izni yoktype: 6 izin istemez. Diğerleri için izni ver.
rate_limitedSınır doldu; X-RateLimit-Scope: shared ise tüm botların ortak tavanıretry_after kadar bekle. 3 saniye geçtiyse ilk yanıt artık kabul edilmez.

Her tür için hangisi gelebilir:

Kodtype: 4type: 5type: 6type: 7
interaction_timeoutEvetEvetEvetEvet
interaction_already_acknowledgedEvetEvetEvetEvet
validation_failedEvetYalnızca flagsHayırEvet
missing_permissionsEvetEvetHayırEvet
automod_blockedEvetHayırHayırEvet

Tam örnek: sayaç botu

Node.js 22 veya üstü yeter. Gateway sayfasındaki gateway.mjs ile Örnekler sayfasındaki api.mjs aynı klasörde olmalı. Bot açılınca kanala bir buton atar. Her basmada sayıyı bir artırıp aynı mesajı type: 7 ile günceller. Sayı custom_id'nin içinde durur, bot yeniden başlasa da kaybolmaz:

sayac-botu.mjs
import { connect } from "./gateway.mjs";
import { call } from "./api.mjs";

const { CHANNEL_ID } = process.env;
if (!CHANNEL_ID) throw new Error("CHANNEL_ID tanımlı olmalı");

// Mesajın gövdesi: hem ilk gönderimde hem güncellemede aynı biçim.
const view = (count) => ({
  content: `Sayaç: ${count}`,
  components: [{ type: 1, components: [
    { type: 2, style: 1, label: "Artır", custom_id: `sayac:${count}` },
  ] }],
});

async function onPress(d) {
  const [kind, count] = d.data.custom_id.split(":");
  if (kind !== "sayac") return;
  await call("POST", `/interactions/${d.id}/${d.token}/callback`, {
    type: 7,
    data: view(Number(count) + 1),
  });
}

let posted = false;

await connect({
  intents: 0,
  onEvent(t, d) {
    if (t === "READY" && !posted) {
      posted = true;
      call("POST", `/channels/${CHANNEL_ID}/messages`, view(0)).catch(console.error);
    }
    if (t === "INTERACTION_CREATE") onPress(d).catch(console.error);
  },
});

Çalıştırmak için:

Bash
BOT_TOKEN='kopyaladigin_token' CHANNEL_ID='kanal id degeri' node sayac-botu.mjs

İki kişi aynı anda basarsa ikisi de aynı sayıyı görüp aynı sonucu yazar. Sayım önemliyse sayıyı kendi veritabanında tut.

Bu sayfayı yapay zekaya verirsen

Sırada ne var

  • Komutlar: / menüsü, kullanıcı ve mesaj komutlarının tanımı

  • Formlar: type: 9 ile çok satırlı form penceresi açmak

  • HTTP ile teslim: etkileşimleri gateway yerine kendi HTTPS adresine almak