Python kütüphanesi (noluyo-bot)
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):
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:
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:
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:
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:
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:
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-RemainingveX-RateLimit-Reset-Afterbaşlıklarına göre kova bazında sıra korur;429durumundaRetry-Afterkadar bekler veX-RateLimit-Scope: sharedgeldiğinde tüm rotaları birlikte yavaşlatır (Hız sınırları). - Yalnız
GETtekrarı:5xxhatalarında yalnızGETçağrıları en çok 3 kez yeniden denenir;POST,PATCH,PUTveDELETEtekrar edilmez. - Shard aralığı ve
RESUME: Shard sayısını/gateway/botucundan alır,IDENTIFYçerçevelerini en az 5,1 saniye arayla gönderir (Shard'lar) ve kopmalardaop 6(RESUME) ile devam eder. - Kalıcı kapanış koruması ve token gizleme:
4004ve4014gibireconnect: falsekapanış kodlarında yeniden bağlanmaya çalışmaz; çözüm ipucu içerenGatewayCloseErrorfı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/5xxyanıtları (err.status,err.code,err.errors,err.path)RateLimitedError: yeniden deneme sınırını aşan429yanı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,/susturzaman aşımı komutu ve denetim embed'isdks/examples/python/anket: süreli buton oylamasısdks/examples/python/muzik: yerel ses dosyası yayınlayan ses botusdks/examples/python/oauth_site: PKCE tabanlı "N'oluyo ile giriş" web uygulaması
Bu sayfayı yapay zekaya verirsen
Sırada ne var
- Hazır tarifler: hem Python hem JavaScript sekmeli 9 çalışan bot örneği
- JavaScript kütüphanesi: Node.js 22+ için sıfır bağımlılıklı kütüphane rehberi
- Botu açık tut: Python botunu Linux sunucuda sanal ortam ve
systemdile çalıştırma