İçeriğe geç
N'oluyo
Kütüphaneler

JavaScript kütüphanesi (noluyo-bot)

Son güncelleme:

noluyo-bot, N'oluyo bot platformu için geliştirilmiş resmi JavaScript ve TypeScript kütüphanesidir. Node.js 22 veya üstü üzerinde sıfır çalışma zamanı bağımlılığıyla çalışır (yerleşik fetch, WebSocket, FormData ve node:crypto kullanır), tam .d.ts tip tanımlarıyla gelir ve MIT lisanslıdır.

Kurulum

Proje klasöründe package.json dosyanın "type": "module" kullandığından emin ol ve paketi kur:

Bash
npm install noluyo-bot
# Yalnızca ses kanallarında yayın yapacaksan isteğe bağlı ek paket:
npm install @livekit/rtc-node@^1.2.1

İlk bot

Token'ı kaynak koda yazma; .env dosyasındaki BOT_TOKEN değişkeninden oku ve node --env-file=.env bot.mjs ile çalıştır:

bot.mjs
import { Client, Intents } from "noluyo-bot";

const bot = new Client({
  token: process.env.BOT_TOKEN,
  intents: Intents.GUILDS | Intents.GUILD_MESSAGES | Intents.MESSAGE_CONTENT,
});

bot.on("READY", (ready, meta) => {
  console.log(`${ready.user.username} bağlandı (shard ${meta.shardId})`);
});

bot.on("MESSAGE_CREATE", async (message) => {
  if (message.author.bot) return;
  if (message.content === "!merhaba") {
    await bot.rest.createMessage(message.channel_id, { content: "Merhaba!" });
  }
});

bot.interactions.on("ping", async (i) => {
  await i.reply({ content: "Pong!", ephemeral: true });
});

await bot.login();
await bot.commands.sync([
  { name: "ping", description: "Botun yanıt verip vermediğini sınar" },
]);

Kapatırken açık WebSocket ve ses bağlantılarını temizlemek için await bot.close() çağrılır. new Client({ token, intents, applicationId, baseUrl, presence }) yapılandırıcısı isteğe bağlı olarak applicationId (bot.login() öncesinde komut eşitlemek istersen), baseUrl ve başlangıç presence nesnesini kabul eder. İzin bitleri için Permissions nesnesi hem Permissions.ModerateMembers hem Permissions.MODERATE_MEMBERS biçiminde BigInt sabitleri sunar (String(Permissions.ModerateMembers) ile ondalık dizgeye çevrilir).

Gateway olayları ve durum yönetimi

bot.on(olayAdi, dinleyici) ile Gateway üzerindeki tüm dağıtım olaylarını dinlersin. İkinci parametre (data, meta) içinde meta.shardId ve meta.seq gelir:

  • Bağlantı ve sunucular: READY, RESUMED, GUILD_CREATE, GUILD_UPDATE, GUILD_DELETE

  • Mesajlar ve tepkiler: MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, MESSAGE_REACTION_ADD, MESSAGE_REACTION_REMOVE

  • Üyeler, roller ve kanallar: GUILD_MEMBER_ADD, GUILD_MEMBER_UPDATE, GUILD_MEMBER_REMOVE, CHANNEL_CREATE, CHANNEL_UPDATE, CHANNEL_DELETE, GUILD_ROLE_CREATE, GUILD_ROLE_UPDATE, GUILD_ROLE_DELETE

  • Etkileşim ve ses: INTERACTION_CREATE, VOICE_STATE_UPDATE, VOICE_SERVER_UPDATE, VOICE_JOIN_ERROR

Durum güncellemek için bot.setPresence("online", [{ name: "/yardim", type: 0 }]), büyük sunucuda üye aramak için bot.requestGuildMembers(guildId, { query: "ada", limit: 25 }) yardımcılarını kullanabilirsin. İhtiyacın olan bitleri Intent'ler tablosundan seçip Intents bayraklarıyla birleştir.

REST çağrıları (bot.rest)

OpenAPI şemasındaki her operationId, bot.rest üzerinde camelCase adıyla hazır bir metottur. Yol parametreleri sırayla ilk argümanlar olarak, JSON gövdesi veya sorgu parametreleri son nesne olarak verilir:

JavaScript
// Basit mesaj ve embed gönderme:
await bot.rest.createMessage(channelId, {
  content: "Haftalık özet hazır.",
  embeds: [{ title: "Özet", description: "12 yeni üye katıldı.", color: 0x3366ff }],
});

// Dosya ekiyle birlikte attachment:// görselli embed gönderme:
import { readFile } from "node:fs/promises";
await bot.rest.createMessage(channelId, {
  embeds: [{ title: "Grafik", image: { url: "attachment://grafik.png" } }],
  files: [{ name: "grafik.png", data: await readFile("./grafik.png"), contentType: "image/png" }],
});

// Üyeye rol verme ve 10 dakikalık zaman aşımı uygulama:
await bot.rest.addMemberRole(guildId, userId, roleId);
await bot.rest.updateMember(guildId, userId, {
  communication_disabled_until: new Date(Date.now() + 10 * 60_000).toISOString(),
});

Gateway bağlantısı açmadan yalnızca HTTP çağrısı yapmak istediğinde import { Rest } from "noluyo-bot" ile doğrudan new Rest({ token: process.env.BOT_TOKEN }) oluşturabilirsin. Zengin mesaj sınırları Embed'ler rehberindedir.

Komut kaydı ve etkileşimler

bot.commands.sync(liste) metodu PUT /applications/{id}/commands rotasını çağırarak tüm küresel komutlarını tek adımda eşitler ({ guildId } verirsen yalnızca o sunucunun komutlarını günceller). bot.login() sonrasında bot.applicationId otomatik dolduğu için ayrıca kimlik yazman gerekmez.

bot.interactions.on(adVeyaKalip, isleyici) hem eğik çizgi komutlarını (name), hem Bileşenler üzerindeki custom_id değerlerini, hem de Formlar gönderimlerini yakalar; dize yerine RegExp (/ ^rol:/ ) de verebilirsin:

JavaScript
bot.interactions.on("duyuru", async (i) => {
  const baslik = i.option("baslik");
  await i.defer({ ephemeral: true });
  await bot.rest.createMessage(i.channel_id, {
    embeds: [{ title: String(baslik), description: "Yeni duyuru yayınlandı." }],
  });
  await i.editReply({ content: "Duyuru kanala gönderildi." });
});

bot.interactions.on(/^anket:/, async (i) => {
  const secim = i.data.custom_id.split(":")[1];
  await i.reply({ content: `Oyun kaydedildi: ${secim}`, ephemeral: true });
});

InteractionContext üzerindeki veri alanları (i.id, i.guild_id, i.channel_id, i.member, i.user, sunucu veya DM fark etmeksizin tetikleyen kullanıcıyı veren i.person, i.data) ve yardımcılar: i.option(ad), i.fields(), i.reply(), i.defer({ ephemeral }), i.deferUpdate(), i.update(), i.editReply(), i.deleteReply(), i.followUp(), i.showModal() ve Otomatik tamamlama için i.autocomplete(secenekler). Tüm etkileşim türlerinin kuralları Komutlar ve Etkileşimler sayfalarında yer alır.

HTTP modu ve imza doğrulama

Etkileşimleri WebSocket yerine kendi HTTPS sunucundan alıyorsan (HTTP ile teslim), gelen her isteğin Ed25519 imzasını ek paket kurmadan verifyInteraction ile doğrula:

JavaScript
import { verifyInteraction } from "noluyo-bot";

const gecerli = verifyInteraction(
  process.env.NOLUYO_PUBLIC_KEY,
  req.headers["x-signature-ed25519"],
  req.headers["x-signature-timestamp"],
  rawBodyBuffer,
);
if (!gecerli) {
  res.writeHead(401).end("invalid signature");
  return;
}

Ses kanallarında yayın (bot.voice)

@livekit/rtc-node@^1.2.1 kurulu olduğunda bot.voice.join(guildId, channelId) senin yerine gateway op 4 gönderir, VOICE_SERVER_UPDATE yanıtını bekler ve yayın odasına bağlanır:

JavaScript
const conn = await bot.voice.join(guildId, voiceChannelId);
await conn.playFile("./muzik.mp3"); // Yerel ses dosyasını 48 kHz PCM olarak yayınlar
await conn.leave();

N'oluyo'da botlar seste yalnızca yayın yapar (canSubscribe: false); kütüphane hiçbir zaman ses aboneliği açmaz ve konuşulanları duyamaz. Ses sınırları ve VOICE_JOIN_ERROR kodları Ses rehberindedir.

Hız sınırı kuyruğu, yeniden deneme ve shard davranışı

Kütüphane platform kurallarını varsayılan olarak uygular:

  • Kova kuyruğu: X-RateLimit-Bucket, X-RateLimit-Remaining ve X-RateLimit-Reset-After başlıklarını izler; aynı kovaya giden istekleri sırayı bozmadan bekletir (Hız sınırları).

  • 429 ve ortak tavan: 429 yanıtında Retry-After süresince bekleyip isteği tekrarlar; X-RateLimit-Scope: shared geldiğinde tüm rotaları birlikte yavaşlatır.

  • Güvenli yeniden deneme: 5xx sunucu hatalarında yalnızca GET isteklerini en çok 3 kez yeniden dener; POST, PATCH, PUT ve DELETE yazma isteklerini çift mesaj oluşmaması için tekrarlamaz.

  • Shard ve sürdürme (RESUME): bot.login() önerilen shard sayısını GET /gateway/bot ucundan alır ve IDENTIFY çerçevelerini en az 5,1 saniye arayla gönderir (Shard'lar). Bağlantı koptuğunda op 6 (RESUME) ile kaçan olayları tamamlar.

  • Kalıcı kapanış koruması ve token gizleme: 4004 (geçersiz token) veya 4014 (onaysız ayrıcalıklı intent) gibi reconnect: false kapanış kodlarında sonsuz döngüye girmez; portal yönlendirmesi içeren GatewayCloseError fırlatır. Hata mesajlarında, JSON.stringify ve util.inspect çıktılarında bot token'ı otomatik olarak [REDACTED] ile maskelenir.

Hata sınıfları, test ve sürüm politikası

Yakalamak için dışa aktarılan hata sınıfları:

  • ApiError: 4xx/5xx yanıtları (err.status, err.code, err.errors, err.path)

  • RateLimitedError: yeniden deneme tavanı aşıldığında dönen 429 hatası (err.retryAfter, err.scope)

  • GatewayCloseError: yeniden bağlanılmaması gereken gateway kapanışı (err.code, err.closeName, err.hint)

  • VoiceJoinError: ses kanalına katılma reddi (err.code, err.guildId)

Birim testlerinde new Rest({ token: "test", fetch: sahteFetch }) ile gerçek ağa çıkmadan REST çağrılarını sınayabilirsin. Kütüphane anlamsal sürümleme (SemVer) izler; OpenAPI veya olay şemasına yeni alan eklendiğinde geriye dönük uyumlu küçük sürüm (0.x) çıkar.

Tam çalışan örnek projeler depoda hazır bulunur:

  • sdks/examples/js/moderasyon: sözcük süzgeci, /sustur zaman aşımı komutu ve denetim embed'i

  • sdks/examples/js/anket: süreli buton oylaması

  • sdks/examples/js/muzik: yerel ses dosyası çalan ses botu

  • sdks/examples/js/oauth-site: PKCE tabanlı "N'oluyo ile giriş" web sunucusu

Bu sayfayı yapay zekaya verirsen

Sırada ne var