بلا مكتبة
كل ما يفعله البوت هو HTTPS وWebSocket عاديان. تعرض هذه الصفحة الطلبات، لتكتب بوتًا بأي لغة.
ما تحتاج إليه
عميل HTTP وعميل WebSocket. يكفي curl للخطوات الأولى. يمثل YOUR_BOT_TOKEN رمزك.
أرسل طلبًا
curl "https://api.zrzur.com/users/@me" -H "x-bot-token: YOUR_BOT_TOKEN"_id في الجواب هو معرّف بوتك، وهو أيضًا معرّف تطبيقه.
الأجسام JSON مع content-type: application/json. والأجوبة JSON، أو فارغة مع 204.
أرسل رسالة
curl -X POST "https://api.zrzur.com/channels/CHANNEL_ID/messages" \
-H "x-bot-token: YOUR_BOT_TOKEN" \
-H "content-type: application/json" \
-d '{ "content": "Hello!" }'ارفع ملفًا
curl -X POST "https://cdn.zrzur.com/attachments" \
-H "x-bot-token: YOUR_BOT_TOKEN" \
-F "[email protected];type=text/csv"الجواب هو { "id": "FILE_ID" }. أرسله في attachments داخل الرسالة.
الحلقة كاملة
PUT /applications/{application_id}/commandsمع أوامرك.- افتح
wss://events.zrzur.com/?version=1&format=json. - أرسل
{ "type": "Authenticate", "token": "YOUR_BOT_TOKEN", "intents": 33 }. - كل 20 ثانية أرسل
{ "type": "Ping", "data": 1 }. - لكل حزمة: إذا كان
typeيساويBulkفعالج كل عنصر فيv. - عند
InteractionCreate، خلال 3 ثوانٍ،POST /interactions/{interaction_id}/{token}/callback. - عند إغلاق المقبس انتظر وابدأ مجددًا من الخطوة 2.
Node
يتضمن Node 22 fetch وWebSocket جاهزين. هذا بوت كامل في ملف واحد:
// Hello World without any library: Node 22+, fetch and WebSocket only.
//
// ZRZUR_BOT_TOKEN=YOUR_BOT_TOKEN node hello-raw.mjs
const token = process.env.ZRZUR_BOT_TOKEN;
const api = process.env.ZRZUR_API_URL ?? "https://api.zrzur.com";
const ws = process.env.ZRZUR_WS_URL ?? "wss://events.zrzur.com";
if (!token) {
console.error("Set ZRZUR_BOT_TOKEN first.");
process.exit(2);
}
/** An interaction's token is in its path: it must never reach a log */
const masked = (path) =>
path.replace(/(\/interactions\/[^/]+\/)[^/]+/, "$1***");
async function rest(method, path, body) {
const response = await fetch(api + path, {
method,
headers: {
"x-bot-token": token,
...(body ? { "content-type": "application/json" } : {}),
},
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok)
throw new Error(
`${method} ${masked(path)}: ${response.status} ${await response.text()}`,
);
return response.status === 204 ? null : response.json();
}
// 1. Who am I? A bot's application id is its user id.
const me = await rest("GET", "/users/@me");
// 2. Register the global /hello command (PUT replaces the whole list).
await rest("PUT", `/applications/${me._id}/commands`, [
{ name: "hello", description: "Say hello" },
]);
// 3. Connect to the gateway and answer interactions.
const socket = new WebSocket(`${ws}/?version=1&format=json`);
// intents 33 = SERVERS (1) + INTERACTIONS (32): commands, nothing else
socket.addEventListener("open", () =>
socket.send(JSON.stringify({ type: "Authenticate", token, intents: 33 })),
);
async function handle(event) {
if (event.type === "Ready") console.log(`ready as ${me.username}`);
if (
event.type === "InteractionCreate" &&
event.interaction.command?.name === "hello"
) {
const { _id, token: interactionToken } = event.interaction;
// answer within 3 seconds
await rest("POST", `/interactions/${_id}/${interactionToken}/callback`, {
type: "Message",
data: { content: "Hello from Zrzur!" },
});
}
}
socket.addEventListener("message", ({ data }) => {
const event = JSON.parse(data);
// several events can arrive together in one Bulk packet
for (const item of event.type === "Bulk" ? event.v : [event])
handle(item).catch(console.error);
});
// keep the connection alive
setInterval(
() => socket.send(JSON.stringify({ type: "Ping", data: Date.now() })),
20_000,
);
يضيف البوت الكامل حدود المعدل وإعادة المحاولة وإعادة الاتصال والبيانات المحفوظة.
Python
تحتاج Python إلى حزمة websockets (pip install websockets). وتكفي المكتبة القياسية لـHTTP.
import asyncio, json, os, urllib.request
import websockets
TOKEN = os.environ["ZRZUR_BOT_TOKEN"]
API = "https://api.zrzur.com"
def rest(method, path, body=None):
request = urllib.request.Request(
API + path,
method=method,
data=json.dumps(body).encode() if body is not None else None,
headers={"x-bot-token": TOKEN, "content-type": "application/json"},
)
with urllib.request.urlopen(request) as response:
data = response.read()
return json.loads(data) if data else None
async def main():
me = rest("GET", "/users/@me")
rest("PUT", f"/applications/{me['_id']}/commands",
[{"name": "hello", "description": "Say hello"}])
async with websockets.connect("wss://events.zrzur.com/?version=1&format=json") as socket:
await socket.send(json.dumps({"type": "Authenticate", "token": TOKEN, "intents": 33}))
async def ping():
while True:
await asyncio.sleep(20)
await socket.send(json.dumps({"type": "Ping", "data": 1}))
asyncio.create_task(ping())
async for raw in socket:
packet = json.loads(raw)
for event in packet["v"] if packet["type"] == "Bulk" else [packet]:
if event["type"] == "Ready":
print("ready")
if event["type"] == "InteractionCreate":
i = event["interaction"]
rest("POST", f"/interactions/{i['_id']}/{i['token']}/callback",
{"type": "Message", "data": {"content": "Hello from Python!"}})
asyncio.run(main())لا تعيد هذه النسخة القصيرة الاتصال. أضف الحلقة من صفحة البوابة.
أوصاف قابلة للقراءة آليًا
| العنوان | ما هو |
|---|---|
GET /openapi.json | كل مسارات REST بصيغة OpenAPI 3 |
GET /gateway/schema | كل أحداث البوابة بصيغة JSON Schema |
GET / | عناوين هذا السيرفر وحدوده |
ولّد منها عميلًا بلغتك.