Pular para o conteúdo
Decoding Chat API

Comandos do cliente

Os clientes enviam comandos através do WebSocket do Gateway, com um opcode inteiro em op e os dados do comando em d. Um comando pode produzir um Dispatch, um frame de fechamento ou nenhuma resposta.

Com exceção de Heartbeat, Identify e Resume, todos os comandos exigem uma sessão autenticada. Enviar um comando antes da autenticação encerra a conexão com o código 4003 e motivo Not authenticated. Heartbeat e Resume são aceitos em qualquer estado aberto, e Identify é aceito apenas enquanto a conexão não estiver autenticada.

OpcodeComandoResultado
1HeartbeatOpcode 11 Heartbeat ACK
2IdentifyReady, um frame de fechamento, ou nenhuma resposta caso o Decoding Chat descarte um Identify com taxa limitada ou o retenha para tentar iniciar a sessão novamente
3Presence UpdateSem resposta direta
4Voice State UpdateVoice State Update e Voice Server Update quando o estado for alterado
6ResumeDispatches reproduzidos seguidos por Resumed, Invalid Session ou um frame de fechamento
8Request Guild MembersUm ou mais eventos Guild Members Chunk
14Lazy RequestGuild Sync e Guild Member List Update
15Request Guild CountsGuild Counts Update
16Request Channel Member CountsChannel Member Counts Update

Um frame que falhar nas checagens de tamanho, descompressão ou decodificação fecha a conexão sem consumir orçamento de taxa. Um frame que decodificar em algo que não seja um objeto fecha com 4002 e motivo Decode failed, e um objeto sem op fecha com 4002 e motivo Invalid payload.

O Decoding Chat debita todo comando que passar por essas checagens nos orçamentos de payload de IP de origem, sessão e conexão antes de processar o opcode. Cada sessão possui seu próprio orçamento de sessão (duas sessões da mesma conta nunca compartilham orçamento), e essa verificação é ignorada enquanto a conexão não estiver autenticada.

Um opcode fora do registro oficial fecha com 4001 e motivo Unknown opcode após a vinculação de sessão, e com 4003 enquanto a conexão não estiver autenticada. Um payload com op mas sem d também fecha com 4001, exceto Identify, que fecha com 4005.

Um campo booleano de comando é ativado apenas por true e pela string "true" nos locais indicados. Qualquer outro valor resolve para false, exceto no objeto de assinatura de servidor do Lazy Request, que possui regra própria.

O Opcode 1 carrega a última sequência de Dispatch que o cliente processou, ou null antes do primeiro Dispatch.

CampoTipoDescrição
d?integerA última sequência de Dispatch processada pelo cliente, ou null antes do primeiro Dispatch
{
"op": 1,
"d": 42
}

Antes da autenticação, o Gateway aceita qualquer valor de d e responde com o Opcode 11. Um payload sem a chave d fecha com 4001 e motivo Unknown opcode.

Após a autenticação, um d que não seja null nem um número inteiro fecha com 4007 e motivo Invalid sequence. Qualquer número inteiro é aceito, mas confirmações de sequência nunca retrocedem. Dispatches iguais ou inferiores à maior sequência confirmada deixam de estar disponíveis para Resume.

Quando a sessão termina, o Decoding Chat envia o Opcode 9 com d: false, após o qual os heartbeats voltam a ser confirmados normalmente. Um heartbeat que chegue na janela de transição entre o encerramento da sessão e esse frame fecha com 4007.

Consulte Visão geral do Gateway para o contrato de temporização.

O Opcode 2 autentica e cria uma nova sessão.

CampoTipoDescrição
tokenstringToken da conta ou do bot, sem prefixo de autenticação HTTP
propertiesidentify properties objectInformações de software e capacidades do cliente que está conectando
presence?1?initial presence objectPresença a ser publicada no início da sessão
ignored_events?2?array[string]Nomes de eventos de Dispatch que esta sessão não deseja receber (no máximo 256 entradas)
flags?integerBitfield de flags de sessão não negativo (padrão 0)
initial_guild_id?3?snowflakeO snowflake de um servidor no qual a sessão ingressa já no estado ativo
shard?4?array[integer]O par [shard_id, shard_count]

1 null e chave omitida selecionam o status salvo e status personalizado salvo da conta

2 Nomes são convertidos para maiúsculo e desduplicados. Consulte Filtragem de eventos para a regra exata de supressão

3 A sessão torna-se ativa nesse servidor sem a necessidade de um Lazy Request, conforme descrito em Filtragem de eventos, e não recebe Guild Sync inicial. Um valor que não seja uma string Snowflake decimal canônica é ignorado sem falhar o Identify

4 shard_count é um inteiro de 1 até 16.384, e shard_id é um inteiro maior ou igual a 0 e menor que shard_count

{
"op": 2,
"d": {
"token": "...",
"properties": {
"os": "Linux",
"browser": "Decoding Client",
"device": "desktop"
},
"presence": {
"status": "online",
"afk": false,
"mobile": false
},
"ignored_events": ["TYPING_START"],
"flags": 2,
"initial_guild_id": "1189375284394692608"
}
}

token e properties são obrigatórios. O Decoding Chat ignora campos desconhecidos. Não existe campo intents nem sistema de intents.

As seguintes falhas encerram a conexão com 4002 e motivo Invalid identify payload:

  • token ou properties ausente.
  • properties que não seja um objeto.
  • properties cujo os, browser ou device esteja ausente ou não seja uma string.
  • Valor de ignored_events que não seja um array de strings ou que contenha mais de 256 itens.
  • Valor de flags que não seja um número inteiro não negativo.

Um par de shard malformado fecha com 4010 e motivo Invalid shard.

O Decoding Chat recusa sessões de bot que alcancem mais de 2.500 servidores após o filtro de shard. A conexão fecha com 4011 e motivo Sharding required. Sessões de usuário nunca são recusadas pela contagem de servidores.

Um token rejeitado pelo backend fecha com 4004 e motivo Invalid token. Uma conta comum (não-bot) que já possua 100 sessões ativas fecha com 4008 e motivo Too many sessions (credenciais de bot não sofrem esse limite). Um Identify enviado em um socket que já possua sessão vinculada fecha com 4005 e motivo Already authenticated, com ou sem d.

ValorNomeDescrição
1 << 1DEBOUNCE_MESSAGE_REACTIONSAgrupa sequências de adições de reações em Message Reaction Add Many

O bit 0 e todos os bits acima de 1 são indefinidos. Bits indefinidos são aceitos e ignorados sem fechar a conexão.

DEBOUNCE_MESSAGE_REACTIONS se aplica a reações em mensagens diretas (DM) ou mensagens diretas em grupo (GDM). Reações em canais de servidores nunca são agrupadas e chegam individualmente como Message Reaction Add.

CampoTipoDescrição
osstringSistema operacional onde o cliente está sendo executado
browserstringIdentificador da biblioteca ou cliente
devicestringIdentificador do dispositivo ou aplicação
e2ee_capable?1booleanIndica se o cliente suporta voz criptografada ponta a ponta
mobile?2booleanIndica se a sessão é móvel (padrão: false)
latitude?3stringLatitude do cliente como string decimal de 1 até 32 caracteres
longitude?3stringLongitude do cliente como string decimal de 1 até 32 caracteres

1 Sessões sem esse suporte são recusadas em canais de voz com criptografia de ponta a ponta com VOICE_E2EE_REQUIRED

2 Lido apenas quando presence estiver ausente ou for null, decidindo a flag mobile da sessão. Caso contrário, o objeto de presença inicial tem preferência

3 Usado para ordenar o array rtc_regions do Ready por proximidade geográfica

os, browser e device são strings obrigatórias. Os demais campos são sugestões opcionais. Propriedades desconhecidas são ignoradas.

latitude e longitude são aceitos aqui exclusivamente como strings (ex.: " -23.55"). Números puros falham na validação e invalidam o início da sessão. Ambos devem ser enviados juntos para ter efeito; strings não numéricas são consideradas ausentes. Clientes sem localização omitem ambos, e o Ready ordena rtc_regions pelo ID da região.

CampoTipoDescrição
status?1stringStatus inicial: online, idle, dnd, invisible ou offline
afk?booleanIndica se a sessão está ausente (padrão: false)
mobile?booleanIndica se a presença é móvel (padrão: false)
custom_status?2?custom status objectStatus personalizado que esta sessão publica

1 O status salvo da conta é usado quando status estiver ausente, for null/não-string, for a string unknown ou quando for online enquanto o status salvo não for online. String vazia resolve para online, e os demais valores válidos são usados como enviados

2 Lido apenas quando a conta não possuir status personalizado salvo, sendo armazenado como enviado sem validação

O Identify aceita offline como status inicial distinto, e o Presence Update normaliza offline para invisible. Uma sessão cujo status resolvido seja offline ou invisible publica status: "offline" e custom_status: null para os outros usuários.

CampoTipoDescrição
text??stringTexto do status personalizado (1 a 128 caracteres)
expires_at?1?ISO8601 timestampMomento em que o status personalizado expira
emoji_id?2?snowflakeO snowflake do emoji personalizado
emoji_name?3?stringO emoji Unicode (1 a 32 caracteres)

1 Timestamp deve estar no futuro

2 O Snowflake deve corresponder a um emoji existente. O Decoding Chat remove o campo do objeto publicado caso a conta não tenha direito a expressões globais

3 Um único emoji Unicode. O campo é descartado antes da validação se emoji_id for fornecido

Apenas esses campos são lidos. Presence Update valida o objeto contra a conta antes de publicá-lo.

A presença publicada adiciona o campo emoji_animated a esse objeto.

O Opcode 6 restaura uma sessão retida.

CampoTipoDescrição
tokenstringToken proprietário da sessão retida
session_idstringO ID da sessão recebido no Ready
seqintegerÚltima sequência de Dispatch que o cliente processou

Todos os campos são obrigatórios. Campo ausente, token ou session_id que não sejam strings, ou seq que não seja número inteiro encerram a conexão com 4002 e motivo Invalid resume payload.

Sessão desconhecida ou expirada envia o Opcode 9 com d: false e mantém o socket não autenticado. Um seq abaixo do piso de replay gera o mesmo frame. Token inválido fecha com 4004 e motivo Invalid token. Um seq maior que a sequência atual ou menor que a já confirmada fecha com 4007 e motivo Invalid sequence. Um seq negativo fecha com 4000 e motivo Session unavailable, o mesmo ocorrendo para sessões inalcançáveis. Nenhuma dessas falhas destrói a sessão retida associada a session_id.

Um Resume bem-sucedido reproduz em ordem todos os Dispatches retidos estritamente acima de seq e finaliza com Resumed. Ele substitui o socket da sessão, e o socket antigo recebe o Opcode 7 seguido por desconexão.

Envie Resume preferencialmente em um socket novo.

O Opcode 3 altera a presença da sessão atual.

CampoTipoDescrição
statusstringStatus a publicar: online, idle, dnd, invisible ou offline
afk?booleanIndica se a sessão está ausente (padrão: false)
mobile?booleanIndica se a sessão é móvel (padrão: false)
custom_status?1?custom status objectStatus personalizado que substitui o atual

1 Objeto idêntico ao atual em text, expires_at, emoji_id e emoji_name é reaproveitado sem revalidação

{
"op": 3,
"d": {
"status": "idle",
"afk": true,
"mobile": false,
"custom_status": {
"text": "ausente no momento"
}
}
}

status é obrigatório. Payloads que não sejam objetos, objetos sem a chave status ou strings fora das opções válidas fecham com 4002 e motivo Invalid presence payload. String vazia resolve para online.

Valores de status não-string são tratados: null e booleano publicam a sessão como offline, e qualquer outro valor resolve para online.

offline é normalizado para invisible, de modo que o Presence Update não publica uma sessão como offline enquanto ela estiver conectada.

custom_status é substituído apenas quando a chave estiver presente. Omitir a chave mantém o status personalizado atual, null o remove, e valores inválidos são ignorados. Se o backend rejeitar o objeto (como um emoji_id inexistente), o status atual é mantido e a conexão segue aberta.

O Presence Update possui limite de 5 comandos aceitos a cada 20 segundos por WebSocket. Atualizações além do limite são descartadas sem encerrar a conexão, após consumirem os orçamentos compartilhados de payload.

O Opcode 4 conecta, move, atualiza ou desconecta a participação de voz da sessão atual do Gateway.

CampoTipoDescrição
guild_id??snowflakeO servidor que contém o canal de voz (null seleciona contexto de chamada em DM/GDM)
channel_id??snowflakeO canal para conectar ou mover (null desconecta da chamada/canal atual)
connection_id?1?stringA conexão de voz existente à qual esta atualização se aplica
self_mute?2booleanSe o cliente mutou o próprio microfone (padrão: false)
self_deaf?2booleanSe o cliente ensurdeceu o próprio áudio (padrão: false)
self_video?2booleanSe o cliente está transmitindo vídeo de câmera (padrão: false)
self_stream?4booleanSe esta conexão anuncia compartilhamento de tela (padrão: false)
is_mobile?2booleanSe este é um cliente de voz móvel (padrão: false)
viewer_stream_keys?3?array[string]Stream keys que esta conexão está assistindo (omitir mantém a lista, null a limpa)
latitude?number or stringLatitude do cliente para seleção de região de voz
longitude?number or stringLongitude do cliente para seleção de região de voz

1 channel_id sem connection_id abre uma nova conexão; com connection_id, move ou atualiza a conexão. Desconectar de um servidor (guild_id não nulo com channel_id: null) exige connection_id e a omissão resulta em VOICE_MISSING_CONNECTION_ID

2 Apenas true e a string "true" ativam a flag. Qualquer outro valor resolve para false

3 Cada entrada é uma stream key cujo escopo, servidor e canal correspondem a esta atualização. Entradas inválidas rejeitam a atualização com VOICE_INVALID_STATE, e conexões inexistentes com VOICE_CONNECTION_NOT_FOUND

4 Apenas true e "true" ativam a flag. O Decoding Chat publica false se o membro não possuir permissão STREAM no canal. A transmissão de tela utiliza a mesma conexão de áudio

{
"op": 4,
"d": {
"guild_id": "1189375284394692608",
"channel_id": "1189375284394692610",
"self_mute": false,
"self_deaf": false,
"self_video": false,
"self_stream": false
}
}

Todos os campos são opcionais. guild_id ou channel_id não nulos devem ser strings decimais canônicas de snowflake ou inteiros positivos. Outros formatos falham na validação e a atualização é descartada sem código de fechamento.

guild_id: null com channel_id: null e um connection_id desconecta da chamada em DM ou GDM específica. A mesma estrutura sem connection_id desconecta a sessão de todas as salas de voz em que estiver conectada.

latitude e longitude aceitam número ou string, sendo convertidos internamente para string.

Conectar ou obter uma nova permissão emite o evento Voice Server Update com o token e endpoint para a conexão de mídia, além de Voice State Update para todas as sessões que podem visualizar o canal.

As duas primeiras atualizações em uma janela de um segundo são aplicadas imediatamente. Atualizações subsequentes podem ser agrupadas ou substituídas por atualizações mais novas para o mesmo guild_id e connection_id.

O Opcode 8 solicita lotes (chunks) delimitados de membros de servidores.

CampoTipoDescrição
guild_id?1snowflakeID de um único servidor a ser consultado
guild_ids?1array[snowflake]Array não vazio de IDs de servidores a consultar
query?2stringPrefixo do nome de exibição para correspondência (padrão: string vazia)
limit?3integerLimite de resultados (0 a 100, padrão: 0)
user_ids?4array[snowflake]IDs explícitos de usuários para buscar, no máximo 100 (padrão: vazio)
presences?5booleanSe os resultados incluem presenças dos membros (padrão: false)
nonce?stringValor de até 32 bytes ecoado em cada chunk retornado

1 O array guild_ids tem prioridade; guild_id só é lido se guild_ids estiver ausente ou vazio

2 Comparação insensível a maiúsculas/minúsculas no apelido do servidor, depois nome global e por fim nome de usuário

3 limit: 0 com query preenchida retorna até 25 resultados; limit: 0 com query vazia solicita a lista completa de membros (até 100.000)

4 user_ids não vazio seleciona diretamente esses membros e ignora query e limit

5 Presenças com status offline ou invisible não são incluídas no retorno

{
"op": 8,
"d": {
"guild_id": "1189375284394692608",
"query": "ann",
"limit": 50,
"presences": true,
"nonce": "a1b2c3"
}
}

O comando nunca encerra a conexão. Entradas inválidas são ajustadas ou descartadas:

  • ID de servidor inválido descarta a requisição por completo.
  • IDs de servidores duplicados são agrupados.
  • user_ids com mais de 100 entradas anula a requisição.
  • limit não numérico vira 0, e valores acima de 100 são limitados a 100.
  • query não-string vira string vazia.
  • nonce com mais de 32 bytes vira null.

O nonce só é ecoado quando a requisição especificar exatamente um único servidor.

Para solicitar a lista completa de membros (query vazia, limit: 0 e user_ids vazio), contas de usuários precisam possuir as permissões MANAGE_ROLES, KICK_MEMBERS e BAN_MEMBERS cumulativamente no servidor (ou ser dono/possuir ADMINISTRATOR).

Bots que solicitem a listagem completa sofrem taxa limite de uma requisição a cada 30 segundos por servidor. Requisições excedentes produzem o evento Rate Limited sem retornar membros.

Os resultados chegam como Guild Members Chunk em páginas de até 1.000 membros, cada uma com chunk_index e chunk_count. Esses chunks são entregues em tempo real e nunca são retidos no buffer de replay de retomada.

O Opcode 14 define as assinaturas por servidor que determinam a lista de membros, digitação e sincronização de tráfego para a sessão.

CampoTipoDescrição
subscriptions1map[snowflake, guild subscription object]Opções de assinatura para cada servidor, indexadas pelo ID do servidor

1 O Decoding Chat preserva as opções da sessão para cada servidor e as reaplica caso a sessão se reconecte a ele posteriormente

{
"op": 14,
"d": {
"subscriptions": {
"1189375284394692608": {
"active": true,
"typing": true,
"member_list_channels": {
"1189375284394692610": [[0, 99]]
}
}
}
}
}
CampoTipoDescrição
active?1booleanSe o servidor está no estado ativo para esta sessão
sync?1booleanSe a sessão solicita um Guild Sync para o servidor
typing?booleanSe o servidor envia eventos Typing Start, sobrepondo a flag active
member_list_channels?2map[snowflake, array[array[integer]]]Intervalos visíveis da lista de membros a assinar, indexados pelo ID do canal
members?array[snowflake]IDs explícitos de membros a assinar (máximo: 1.000)

1 Devem ser booleanos quando presentes. Valores inválidos impedem o processamento das demais opções para o servidor

2 Intervalos enviados em uma janela de 100 ms para o mesmo canal são mesclados

As permissões VIEW_CHANNEL e VIEW_CHANNEL_MEMBERS controlam o recebimento da lista de membros em cada canal separadamente. Canais sem ambas as permissões não enviam Guild Member List Update.

member_list_channels mapeia o ID do canal para listas de intervalos [start, end], onde start >= 0, end >= start, end <= 100000 e end - start <= 99. Cada canal retém até 10 intervalos válidos.

O Opcode 15 solicita as contagens de membros totais e online para servidores.

CampoTipoDescrição
guild_idsarray[snowflake]IDs dos servidores a consultar (desduplicados e truncados em até 100)
nonce?stringValor de 1 a 64 bytes ecoado no resultado
{
"op": 15,
"d": {
"guild_ids": ["1189375284394692608"],
"nonce": "counts-1"
}
}

Os resultados chegam no evento Guild Counts Update.

O Opcode 16 solicita a contagem de membros totais e online para canais de um servidor.

CampoTipoDescrição
guild_idsnowflakeID do servidor que contém os canais consultados
channel_idsarray[snowflake]IDs dos canais a consultar (truncados em até 25)
channel_id?snowflakeID de canal único quando channel_ids estiver ausente
nonce?stringValor de 1 a 64 bytes ecoado no resultado
{
"op": 16,
"d": {
"guild_id": "1189375284394692610",
"channel_ids": ["1189375284394692612"],
"nonce": "channel-counts-1"
}
}

Os resultados chegam no evento Channel Member Counts Update.

Um WebSocket processa no máximo quatro comandos delimitados simultaneamente entre Request Guild Members, Lazy Request, Request Guild Counts e Request Channel Member Counts. Comandos excedentes são descartados silenciosamente. Cada requisição tem um prazo limite de 10.000 ms.