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

Python kütüphanesi (noluyo-bot)

Son güncelleme:

noluyo-bot (içe aktarma adıyla noluyo_bot), N'oluyo bot platformunun Python 3.11 ve üstü için geliştirilmiş resmi asyncio kütüphanesidir. Çalışma zamanında yalnızca aiohttp kullanır, PEP 561 (py.typed) tip bildirimleriyle gelir ve MIT lisanslıdır.

Kurulum

Sanal ortam oluşturup paketi kur (HTTP imza doğrulaması veya ses yayını kullanacaksan isteğe bağlı ekleri ekle):

Bash
python3 -m venv .venv
source .venv/bin/activate   # Windows PowerShell: .venv\Scripts\Activate.ps1
pip install noluyo-bot

# İsteğe bağlı ekler:
pip install "noluyo-bot[http]"    # Ed25519 HTTP etkileşim doğrulaması (cryptography)
pip install "noluyo-bot[voice]"   # Ses kanallarında yayın (livekit)

İlk bot

Paket PyPI'da noluyo-bot adıyla kurulur, Python kodunda alt çizgiyle import noluyo_bot olarak içe aktarılır. Token'ı koda yazma; os.environ["BOT_TOKEN"] ile ortamdan oku:

bot.py
import os
import noluyo_bot

bot = noluyo_bot.Client(
    token=os.environ["BOT_TOKEN"],
    intents=noluyo_bot.Intents.GUILDS
    | noluyo_bot.Intents.GUILD_MESSAGES
    | noluyo_bot.Intents.MESSAGE_CONTENT,
)

@bot.on("READY")
async def on_ready(ready):
    print(f"{ready['user']['username']} bağlandı")

@bot.on("MESSAGE_CREATE")
async def on_message(message):
    if message["author"].get("bot"):
        return
    if message["content"] == "!merhaba":
        await bot.rest.create_message(message["channel_id"], {"content": "Merhaba!"})

@bot.interactions.on("ping")
async def on_ping(i):
    await i.reply({"content": "Pong!"}, ephemeral=True)

@bot.on("READY")
async def sync_commands(_ready):
    await bot.commands.sync([
        {"name": "ping", "description": "Botun yanıt verip vermediğini sınar"},
    ])

bot.run()

Zaten çalışan bir asyncio döngüsünün içindeysen bot.run() yerine await bot.start() ve kapatırken await bot.close() kullanabilirsin.

Gateway olayları ve TypedDict veri modeli

@bot.on("OLAY_ADI") dekoratörü Gateway üzerindeki tüm olayları dinler. Python kütüphanesi gelen JSON verisini ağır sınıf hiyerarşilerine sarmalamaz; alan adları dokümandaki JSON anahtarlarıyla (message["channel_id"], member["user"]["id"]) birebir aynı TypedDict sözlükleri olarak 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

Dinleyici fonksiyon tek argüman (data) ya da iki argüman (data, meta — meta["shard_id"] ve meta["seq"]) alabilir. İhtiyacın olan intent bitlerini Intent'ler rehberinden seç.

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

OpenAPI şemasındaki her operationId, bot.rest üzerinde snake_case adıyla async bir metottur:

py
from pathlib import Path

# Metin ve embed gönderme:
await bot.rest.create_message(
    channel_id,
    {
        "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:
await bot.rest.create_message(
    channel_id,
    {
        "embeds": [{"title": "Grafik", "image": {"url": "attachment://grafik.png"}}],
        "files": [
            {
                "name": "grafik.png",
                "data": Path("./grafik.png").read_bytes(),
                "content_type": "image/png",
            }
        ],
    },
)

# Üyeye rol verme ve 10 dakikalık zaman aşımı uygulama:
from datetime import datetime, timedelta, timezone

until = (datetime.now(timezone.utc) + timedelta(minutes=10)).isoformat()
await bot.rest.add_member_role(guild_id, user_id, role_id)
await bot.rest.update_member(guild_id, user_id, {"communication_disabled_until": until})

Gateway açmadan yalnızca HTTP istekleri atmak için async with noluyo_bot.Rest(token=os.environ["BOT_TOKEN"]) as rest: bağlam yöneticisini kullanabilirsin. Görsel ve alan sınırları Embed'ler rehberindedir.

Komut kaydı ve etkileşimler

await bot.commands.sync(liste) küresel komutlarını tek çağrıda eşitler (guild_id=... verirsen yalnızca o sunucunun komutlarını günceller).

@bot.interactions.on(ad_veya_desen) dekoratörü Komutlar, Bileşenler (custom_id) ve Formlar etkileşimlerini yönlendirir; tam metin ya da derlenmiş re.compile(r"^anket:") verebilirsin:

py
import re

@bot.interactions.on("duyuru")
async def on_announce(i):
    baslik = i.option("baslik")
    await i.defer(ephemeral=True)
    await bot.rest.create_message(
        i.channel_id,
        {"embeds": [{"title": str(baslik), "description": "Yeni duyuru yayınlandı."}]},
    )
    await i.edit_reply({"content": "Duyuru kanala gönderildi."})

@bot.interactions.on(re.compile(r"^anket:"))
async def on_poll_vote(i):
    secim = i.data["custom_id"].split(":", 1)[1]
    await i.reply({"content": f"Oyun kaydedildi: {secim}"}, ephemeral=True)

InteractionContext üzerindeki yardımcılar: i.option(ad), i.fields(), await i.reply(..., ephemeral=...), await i.defer(ephemeral=...), await i.defer_update(), await i.update(...), await i.edit_reply(...), await i.delete_reply(), await i.follow_up(...), await i.show_modal(...) ve Otomatik tamamlama için await i.autocomplete(secenekler). Ayrıntılar Etkileşimler sayfasındadır.

HTTP modu ve imza doğrulama ([http])

Etkileşimleri HTTPS sunucundan karşılıyorsan (HTTP ile teslim), noluyo-bot[http] ekini kurup Ed25519 imzasını verify_interaction ile doğrula:

py
import os
from noluyo_bot import verify_interaction

gecerli = verify_interaction(
    os.environ["NOLUYO_PUBLIC_KEY"],
    request.headers["X-Signature-Ed25519"],
    request.headers["X-Signature-Timestamp"],
    raw_body_bytes,
)
if not gecerli:
    return Response(status=401, text="invalid signature")

Ses kanallarında yayın ([voice])

noluyo-bot[voice] kurulu olduğunda await bot.voice.join(guild_id, channel_id) gateway op 4 ve VOICE_SERVER_UPDATE adımlarını yürüterek LiveKit odasına bağlanır:

py
conn = await bot.voice.join(guild_id, voice_channel_id)
await conn.play_file("./muzik.mp3")
await conn.leave()

N'oluyo'da botlar seste yalnızca yayın yapar; kütüphane hiçbir uzak ses izine abone olmaz ve kimseyi duyamaz. Ses kuralları ve hata kodları Ses sayfasındadır.

Hız sınırı kuyruğu, shard ve güvenlik kuralları

JavaScript kütüphanesiyle birebir aynı çalışma kuralları geçerlidir:

  • Kova kuyruğu ve 429: X-RateLimit-Bucket, X-RateLimit-Remaining ve X-RateLimit-Reset-After başlıklarına göre kova bazında sıra korur; 429 durumunda Retry-After kadar bekler ve X-RateLimit-Scope: shared geldiğinde tüm rotaları birlikte yavaşlatır (Hız sınırları).

  • Yalnız GET tekrarı: 5xx hatalarında yalnız GET çağrıları en çok 3 kez yeniden denenir; POST, PATCH, PUT ve DELETE tekrar edilmez.

  • Shard aralığı ve RESUME: Shard sayısını /gateway/bot ucundan alır, IDENTIFY çerçevelerini en az 5,1 saniye arayla gönderir (Shard'lar) ve kopmalarda op 6 (RESUME) ile devam eder.

  • Kalıcı kapanış koruması ve token gizleme: 4004 ve 4014 gibi reconnect: false kapanış kodlarında yeniden bağlanmaya çalışmaz; çözüm ipucu içeren GatewayCloseError fırlatır. İstisna metinlerinde (str, repr, log çıktıları) bot token'ı otomatik olarak [REDACTED] ile gizlenir.

Hata sınıfları ve örnek projeler

Yakalayabileceğin hata sınıfları noluyo_bot kökünden dışa aktarılır:

  • NoluyoError: tüm kütüphane hatalarının taban sınıfı

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

  • RateLimitedError: yeniden deneme sınırını aşan 429 yanıtı (err.retry_after, err.scope)

  • GatewayCloseError: kalıcı gateway kapanışı (err.code, err.close_name, err.hint)

  • VoiceJoinError: ses kanalına giriş reddi (err.code, err.guild_id)

Tam çalışan Python örnek projeleri depoda yer alır:

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

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

  • sdks/examples/python/muzik: yerel ses dosyası yayınlayan ses botu

  • sdks/examples/python/oauth_site: PKCE tabanlı "N'oluyo ile giriş" web uygulaması

Bu sayfayı yapay zekaya verirsen

Sırada ne var