vsyncDOCUMENTAÇÃO

Passo a passo

Receber interações por HTTP

Use uma URL de interações em vez do gateway: entrega, resposta no corpo e verificação da assinatura HMAC.

Em vez do gateway, o aplicativo pode receber as interações por HTTP: na aba Bot, preencha URL de interações (obrigatoriamente https:// e com endereço público; endereços locais e de redes privadas são recusados, e a API valida isso também ao enviar). Regras:

  • O gateway tem prioridade: a entrega por HTTP só acontece se o bot não tiver conexão aberta.
  • A API faz POST com o mesmo JSON do INTERACTION_CREATE (campo d do gateway), Content-Type: application/json e timeout de 3 segundos. Respostas acima de 64 KiB, redirecionamentos e status fora de 2xx contam como falha.
  • Você pode responder no corpo: { "type": "message", "data": { ... } } ou { "type": "defer" }. Sem corpo, responda depois pelo callback usando id e token do payload.
  • Cada requisição vem assinada. Cabeçalhos: X-vsync-Timestamp (segundos Unix) e X-vsync-Signature (HMAC-SHA256 em hexadecimal de timestamp + "." + corpo bruto, usando a chave de assinatura da aba Bot como segredo). Confira sempre a assinatura antes de confiar na requisição.

Verificação em Node (use o corpo bruto, antes de qualquer JSON.parse):

JavaScript
import { createServer } from "node:http";
import { createHmac, timingSafeEqual } from "node:crypto";

const SECRET = process.env.VSYNC_SIGNING_SECRET; // aba Bot > Chave de assinatura

function verify(rawBody, headers) {
  const timestamp = headers["x-vsync-timestamp"];
  const signature = headers["x-vsync-signature"];
  if (!timestamp || !signature) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false; // rejeita requisições antigas
  const expected = createHmac("sha256", SECRET).update(`${timestamp}.${rawBody}`).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(signature);
  return a.length === b.length && timingSafeEqual(a, b);
}

createServer(async (req, res) => {
  let raw = "";
  for await (const chunk of req) raw += chunk;
  if (req.method !== "POST" || !verify(raw, req.headers)) {
    res.writeHead(401).end();
    return;
  }
  const interaction = JSON.parse(raw);
  res.writeHead(200, { "content-type": "application/json" });
  res.end(JSON.stringify({ type: "message", data: { body: `Você usou /${interaction.data.name}` } }));
}).listen(8080);

Em Python: hmac.new(secret.encode(), f"{timestamp}.{raw_body}".encode(), "sha256").hexdigest() e compare com hmac.compare_digest. Para redefinir a chave, use Bot → Chave de assinatura → Redefinir.