Zrzur المطوّرون

بلا مكتبة

كل ما يفعله البوت هو 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 داخل الرسالة.

الحلقة كاملة

  1. PUT /applications/{application_id}/commands مع أوامرك.
  2. افتح wss://events.zrzur.com/?version=1&format=json.
  3. أرسل { "type": "Authenticate", "token": "YOUR_BOT_TOKEN", "intents": 33 }.
  4. كل 20 ثانية أرسل { "type": "Ping", "data": 1 }.
  5. لكل حزمة: إذا كان type يساوي Bulk فعالج كل عنصر في v.
  6. عند InteractionCreate، خلال 3 ثوانٍ، POST /interactions/{interaction_id}/{token}/callback.
  7. عند إغلاق المقبس انتظر وابدأ مجددًا من الخطوة 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 /عناوين هذا السيرفر وحدوده

ولّد منها عميلًا بلغتك.

التالي