Eventos
O catálogo inteiro, com a família de intent que entrega cada um. A tabela é derivada do vocabulário do Trivo: evento novo aparece aqui sozinho.
Como você os recebe
app.on("message_create", (evento) => { /* … */ });
app.on("reaction_add", (evento) => { /* … */ }); // derivado, exige a intent reactions
app.on("ready", () => {}); // a cada abertura de conexãoO nome que você escreve é o nome que viaja no fio — não há tabela de tradução. No protocolo existe só reaction_update, com o agregado novo e um booleano reacted; o SDK deriva reaction_add e reaction_remove a partir dele, sem esconder o original, que continua chegando inteiro.
A forma de um nome
<substantivo>_<verbo>, minúsculas com sublinhado, verbo no radical — message_create, e nunca message_was_created. delete é para o que deixa de existir; remove é para o vínculo que se desfaz enquanto os dois lados continuam de pé (por isso member_remove e channel_delete). Episódio com começo e fim usa start e end.
Campo é camelCase, com sufixo Id quando carrega identificador em vez do objeto: channelId contra channel.
O que chega a um App
| Evento | Intent | O que é |
|---|---|---|
profile_update | profiles | O perfil de alguém mudou. Sem o que mudou: carrega uma revisão, e quem precisa relê. |
feature_update | platform | Uma flag de recurso da instância mudou de estado, com o motivo público junto. |
server_update | server | A forma do servidor mudou, e a `revision` nova está aqui. Sai junto de toda mutação administrativa. |
server_delete | server | O servidor deixou de existir. |
member_add | members | Alguém entrou no servidor. |
member_remove | members | Alguém deixou de ser membro. `reason` diz se saiu, foi expulso ou banido. |
member_update | members | O vínculo de um membro mudou. `roles` é o conjunto DEPOIS da mudança, nunca o delta. |
channel_create | channels | Canal criado. Vai o retrato inteiro. |
channel_update | channels | Canal editado ou movido de categoria. |
channel_delete | channels | Canal arquivado. Só o id. |
role_create | roles | Cargo criado, com as permissões dele. |
role_update | roles | Cargo editado. |
role_delete | roles | Cargo apagado. Só o id. |
connection_open | protocolo | A conexão abriu e o estado anterior não vale mais. Recomece. |
connection_resume | protocolo | A conexão voltou pela janela de retomada; os eventos do intervalo vêm logo atrás. |
message_create | messages | Mensagem nova num canal de texto. |
message_update | messages | Mensagem editada. |
message_delete | messages | Mensagem apagada. Só o id: o que sumiu não tem retrato a mandar. |
reaction_update | reactions | O agregado de um emoji naquela mensagem mudou. Carrega o total, quem alternou e se o gesto pôs ou tirou. |
typing_start | typing | Alguém começou a escrever. Efêmero, e sem par: não existe 'parei de digitar'. |
announcement_publish | platform | O Trivo publicou um comunicado oficial. Difusão global, sem corpo. |
interaction_create | interactions | Alguém acionou algo deste App. É o caminho de entrega pelo gateway. |
Os dois quadros de protocolo não pertencem a família nenhuma, e nenhuma declaração de intent os desliga: sem eles você não saberia que está conectado, nem se recomeçou ou retomou.
O que NUNCA chega a um App
Não é filtro que se possa ligar. Os primeiros são endereçados por to, que carrega id público de conta — e um App não tem conta, então o corte acontece no funil, antes de qualquer outra pergunta. Os dois últimos dependem de ver ocupação de voz, que um App não vê.
| Evento | O que é |
|---|---|
notification_settings_update | As preferências de aviso de uma conta mudaram. |
capabilities_update | As capacidades de uma conta mudaram (sanção, ou volta ao normal). |
channel_occupancy_update | Quem está em qual sala de voz. |
presence_update | Presença pública de uma conta. |
relationship_update | Amizade ou bloqueio mudou para estes destinatários. |
dm_message_create | Mensagem nova numa conversa privada. |
dm_message_delete | Mensagem de conversa privada apagada. |
call_ring_start | Alguém está ligando no privado. |
call_ring_end | O toque acabou, com o motivo. |
announcement_read_update | A leitura da caixa oficial de uma conta mudou. |
interaction_response | A resposta privada de uma interação, endereçada a quem acionou. |
interaction_modal | O formulário que o App abriu em resposta, endereçado a quem acionou. O envio dele é uma interação nova, do tipo `form`. |
interaction_accepted | O App aceitou a interação e está processando (`defer`), endereçado a quem acionou. Ele traz o prazo NOVO — a tela sai de "esperando" para "em curso" na hora. |
interaction_suggestions | As sugestões do autocompletar, endereçadas a quem está digitando. Elas vão para o compositor, e não para o canal: não viram mensagem e somem na tecla seguinte. |
Três formas que se repetem no catálogo
O agregado, e não o delta
reaction_update carrega o total novo daquele emoji, e member_update carrega o conjunto de cargos depois da mudança. Nenhum dos dois manda "somou um" ou "tirou este": somar deltas dessincroniza no primeiro evento perdido, e evento se perde.
O cutucão sem carga
profile_update não diz o que mudou: carrega uma revisão, e quem precisa do dado novo o relê. Assim o mesmo aviso serve a todas as telas sem inventar um formato de perfil para manter em dois lugares.
A duração, e não o instante
expiresInMs e remainingMs são durações porque o relógio é o do servidor. Mandar um instante absoluto obrigaria a sua máquina a concordar com o relógio da nossa.
Um evento inteiro, campo a campo
Dentro de uma versão nada some, nada é renomeado e nada troca de tipo — o que acontece é acréscimo. Por isso o exemplo abaixo é um piso e não um contorno: campo que você não conhece pode aparecer ao lado dos que estão aqui, e Versão da API e compatibilidade diz o que fazer com ele.
Um evento de reação, inteiro
{
"type": "reaction_update",
"serverId": "1234567890123456789",
"channelId": "1111111111111111111",
"messageId": "9876543210987654321",
"emoji": "👍",
"count": 3,
"actor": { "type": "user", "id": "2222222222222222222" },
"reacted": true
}actor.type discrimina user de app: um bot que dá cargo a quem reage precisa saber que o gesto pode ter vindo de outro robô.