Zrzur Entwickler

Interaktionen über HTTP

Empfange Befehle, Schaltflächen und Formulare an deiner eigenen HTTPS-Adresse, ohne Gateway-Verbindung.

Das brauchst du

Schritte

  1. Öffne deinen Bot im Entwicklerportal und wähle HTTP-Interaktionen. Erzeuge ein Signier-Geheimnis und kopiere es. Es erscheint einmal.
  2. Starte das Beispiel unten auf deinem Server, mit dem Geheimnis in ZRZUR_SIGNING_SECRET.
  3. Trage deine Adresse im selben Dialog ein, speichere und bestätige dein Passwort. Zrzur schickt zuerst zwei Testanfragen in beliebiger Reihenfolge: eine mit falscher Signatur, die abgelehnt werden muss, und ein signiertes Ping, das {"type":"Pong"} bekommen muss. Das SDK erledigt beides.

Ab jetzt bekommt das Gateway die Interaktionen dieses Bots nicht mehr. Entferne die Adresse, um zurückzugehen.

Vollständiges Beispiel

// A bot without a gateway connection: `/hello` answered over HTTP.
//
//   ZRZUR_BOT_TOKEN=... ZRZUR_SIGNING_SECRET=... PORT=8787 node http-interactions.mjs

import { Client } from "@zrzur/sdk/bot";

const bot = new Client({ apiUrl: process.env.ZRZUR_API_URL });

bot.command("hello", (i) => i.reply(`Hello ${i.user.username}, over HTTP!`));

await bot.loginHttp(process.env.ZRZUR_BOT_TOKEN);
await bot.syncCommands([{ name: "hello", description: "Say hello" }]);
await bot.listen({
  secret: process.env.ZRZUR_SIGNING_SECRET,
  port: Number(process.env.PORT ?? 8787),
});
console.log(`ready as ${bot.user.username}`);

Was du sehen solltest

ready as <your bot> in der Konsole, dann Hello <name>, over HTTP! im Kanal, wenn jemand /hello nutzt.

So sieht eine Anfrage aus

Jede Anfrage ist ein POST mit demselben JSON wie interaction in InteractionCreate und drei Headern:

HeaderBedeutung
X-Zrzur-TimestampSekunden seit der Epoche beim Signieren
X-Zrzur-Signaturev1= und das hexadezimale HMAC-SHA256 des signierten Texts
X-Zrzur-DeliveryID dieser Zustellung, für deine Logs. Nicht signiert

Der signierte Text ist v1:<timestamp>:<raw body>. Ohne SDK:

  1. Lehne die Anfrage mit 401 ab, wenn der Zeitstempel mehr als 300 Sekunden von deiner Uhr abweicht.
  2. Berechne das HMAC-SHA256 des signierten Texts mit deinem Geheimnis und vergleiche in konstanter Zeit (crypto.timingSafeEqual in Node, hmac.compare_digest in Python). Vergleiche nie mit ==.
  3. Lehne eine _id aus dem signierten Text ab, die du in den letzten zehn Minuten behandelt hast: Das ist eine erneut gesendete, abgefangene Anfrage. Nutze dafür nicht X-Zrzur-Delivery: Das ist nicht signiert, jeder kann es ändern.
  4. Beantworte {"type":"Ping"} mit {"type":"Pong"}.

Ein abgeschalteter Bot, oder einer mit gesperrtem Eigentümer, bekommt nichts, und seine Adresse lässt sich nicht ändern.

Prüfe an diesem Beispiel. Mit dem Geheimnis zrzur_sign_f27c5773e21ddeceaeb5e956dc45c16451f737addd5c0e4472f61060bca9b030, dem Zeitstempel 1700000000 und dem Text {"type":"Ping"} ist die Signatur v1=928e5ffdc88564103b59f5485a6bfa7e1a633dca64f397396606a314f572c4d3.

So antwortest du

Antworte innerhalb von 3 Sekunden, auf eine von zwei Arten:

Jeder andere Status, eine Zeitüberschreitung, eine Weiterleitung oder eine Antwort über 1 MiB lässt die Interaktion scheitern, und die Person sieht das. Weiterleitungen werden nicht verfolgt.

Häufige Fehler

Eine Adresse zu speichern scheitert mit SignedDeliveryRejected, und reason sagt, warum:

reasonUrsacheLösung
invalid_urlNicht https, oder enthält ein PasswortNimm eine einfache https://-Adresse
blocked_addressDie Adresse ist privat oder gesperrtNimm eine öffentliche Adresse
not_reachableNichts hat geantwortetPrüfe, ob der Server läuft und öffentlich ist
timed_outKeine Antwort in 3 SekundenAntworte schneller
accepts_bad_signaturesDie Anfrage mit falscher Signatur kam durchPrüfe Signaturen, antworte 401
bad_statusDas Ping bekam kein 200Beantworte Ping mit 200
bad_answerDas Ping bekam kein {"type":"Pong"}Sende genau dieses JSON
answer_too_largeDie Antwort ist über 1 MiBSende eine kleinere Antwort

FeatureDisabled heißt, dieser Server hat keinen Signierschlüssel oder einen unter 32 Bytes. InvalidOperation heißt, der Bot hat noch kein Signier-Geheimnis.

Weiter