falafy
PT
Baixar grátis

API pública v1 · @falafy/bot

Interações: comandos, componentes e modais

Quando alguém usa um comando, clica num botão ou envia um modal, o app recebe uma interação e tem 3 segundos para responder.

Registrar comandos

Comandos globais valem em todo servidor onde o bot está; comandos de servidor valem só ali e na hora (ótimos para testar). PUT substitui a lista inteira do escopo. Tipos: 1 chat (/nome), 2 menu de usuário, 3 menu de mensagem. Opções: 3 texto, 4 inteiro, 5 booleano, 6 usuário, 7 canal, 8 cargo, 10 número; com choices (até 25), minValue/maxValue, minLength/maxLength ou autocomplete. Limites: 100 comandos de chat, 15 de usuário e 15 de mensagem por escopo.

PUT /api/v1/applications/APP_ID/commands
[
  { "name": "dado", "description": "Rola um dado",
    "options": [{ "type": 4, "name": "lados", "description": "Quantos lados", "minValue": 2, "maxValue": 100 }] },
  { "name": "jogo", "description": "Escolhe um jogo",
    "options": [{ "type": 3, "name": "nome", "description": "Nome", "autocomplete": true }] },
  { "name": "kick", "description": "Só admins", "defaultMemberPermissions": "0" },
  { "type": 2, "name": "Ver perfil" }
]

defaultMemberPermissions esconde o comando de quem não tem aquelas permissões ("0" = só administradores).

A interação

Pelo gateway chega INTERACTION_CREATE com id, token, type (2 comando, 3 componente, 4 autocomplete, 5 modal), user, member (cargos e permissões), channelId, serverId e data com as opções já tipadas.

Responder

POST /api/v1/interactions/{id}/{token}/callback, sem Authorization (o token é a credencial), uma única vez e em até 3 segundos:

  • 4 mensagem (com flags: 64 fica efêmera: só quem usou vê, e ela nunca entra no histórico do canal).
  • 5 adiada: aparece “pensando…”; depois edite com PATCH /webhooks/{appId}/{token}/messages/@original.
  • 6 confirma um clique sem mudar nada · 7 edita a mensagem do componente.
  • 8 escolhas do autocomplete (até 25) · 9 abre um modal.

Depois da resposta inicial, o token vale 15 minutos para follow-ups (POST /webhooks/{appId}/{token}) e para editar ou apagar essas mensagens. Se o app não responder a tempo, a pessoa vê “A interação falhou”.

Botões, menus e modais

Linhas (type 1) com até 5 botões ou 1 menu de seleção. Botões: 1 primário, 2 secundário, 3 sucesso, 4 perigo (todos com customId) e 5 link (com url, não gera interação). Menus de texto: até 25 opções, minValues/maxValues. Modais: título e até 5 campos de texto (curto ou parágrafo), cada um em uma linha.

Receber por HTTP

Salve uma URL de interações no portal e as interações passam a chegar por POST no seu servidor, assinadas com Ed25519: valide X-Signature-Ed25519 sobre X-Signature-Timestamp + corpo com a chave pública do app e responda 401 se não bater. Ao salvar, o Falafy manda um PING (responda {"type":1}) e um pedido com assinatura errada (precisa dar 401). A resposta pode vir no próprio corpo da resposta HTTP.

import crypto from 'node:crypto';
import http from 'node:http';

const PUBLIC_KEY = process.env.FALAFY_PUBLIC_KEY; // hex, no portal
const spki = Buffer.concat([Buffer.from('302a300506032b6570032100', 'hex'), Buffer.from(PUBLIC_KEY, 'hex')]);
const key = crypto.createPublicKey({ key: spki, format: 'der', type: 'spki' });

http.createServer((req, res) => {
  let raw = '';
  req.on('data', (c) => (raw += c));
  req.on('end', () => {
    const sig = req.headers['x-signature-ed25519'];
    const ts = req.headers['x-signature-timestamp'];
    const ok = sig && ts && crypto.verify(null, Buffer.from(ts + raw), key, Buffer.from(sig, 'hex'));
    if (!ok) return res.writeHead(401).end();
    const i = JSON.parse(raw);
    res.writeHead(200, { 'content-type': 'application/json' });
    if (i.type === 1) return res.end(JSON.stringify({ type: 1 })); // PING -> PONG
    res.end(JSON.stringify({ type: 4, data: { content: 'Olá!', flags: 64 } }));
  });
}).listen(8080);