vsyncDOCUMENTAÇÃO

Desenvolvimento

Voz

Como bots entram em canais de voz e enviam áudio com WebRTC: operações, eventos e fluxo de sinalização.

Bots podem entrar em canais de voz como participantes que enviam áudio (por exemplo, um bot de música). O áudio é WebRTC direto entre o bot e cada pessoa no canal; o gateway só faz a sinalização. O bot precisa ser membro do servidor e ter VIEW_CHANNEL e CONNECT no canal. Ele aparece na lista de voz com a etiqueta APP e sempre com muted: false.

Operações (bot para servidor)#

  • {"op":"voice_join","guildId":"...","channelId":"..."}: entra no canal. Um bot tem no máximo uma sessão de voz por servidor; entrar em outro canal do mesmo servidor move o bot (antes chega VOICE_LEFT com reason: "moved"). Limite: 5 por minuto por bot.
  • {"op":"voice_leave","guildId":"..."}: sai do canal e recebe VOICE_LEFT com reason: "leave".
  • {"op":"voice_signal","to":"<connId>","data":{...}}: envia um sinal WebRTC para um participante do mesmo canal. data tem até 64 KiB e kind só pode ser description ({kind, sdp}) ou ice ({kind, candidate}). Limite: 600 por minuto por sessão (fora do limite geral de 120 mensagens por minuto).

Qualquer falha responde {"op":"error","code":"...","message":"..."} e a sessão continua aberta. Códigos: unknown_guild, unknown_channel, invalid_channel (não é canal de voz), missing_permissions, rate_limited, not_in_voice, invalid_signal, unknown_peer.

Eventos (servidor para bot)#

  • VOICE_JOINED: { guildId, channelId, selfConnId, peers: [{ connId, accountId }] }, com as pessoas que já estão no canal.
  • VOICE_PEER_JOINED: { guildId, channelId, connId, accountId }.
  • VOICE_PEER_LEFT: { guildId, channelId, connId }.
  • VOICE_SIGNAL: { guildId, from, fromAccountId, data }, sinal enviado por um navegador ao connId do bot.
  • VOICE_STATE: { guildId, voice: { [channelId]: participantes[] } } sempre que alguém entra, sai ou muda de estado no servidor em que o bot está em um canal de voz (o bot só recebe esse evento depois de entrar em um canal do servidor; fora disso, leia o campo voice de GET /guilds/:id). Útil para sair quando o canal ficar vazio.
  • VOICE_LEFT: { guildId, reason }. reason é leave, moved ou disconnected (desconectado por um moderador, expulso ou banido, canal ou servidor excluído, ou perdeu a permissão CONNECT).

Fluxo de sinalização#

  1. Peça os servidores ICE em GET /ice com Authorization: Bot SEU_TOKEN (credenciais TURN temporárias por bot).
  2. Envie voice_join e espere VOICE_JOINED.
  3. Quem entra é quem oferece: o bot cria uma RTCPeerConnection para cada item de peers, adiciona a faixa de áudio e envia o offer com voice_signal (kind: "description"). Pessoas que entram depois enviam a oferta ao bot por VOICE_SIGNAL; responda com um answer.
  4. Troque candidatos ICE com kind: "ice" nos dois sentidos. A negociação é educada (perfect negotiation): em colisão de ofertas, o bot cede.
  5. Feche a conexão de quem enviar VOICE_PEER_LEFT.

Limites#

  • Quando a sessão do gateway que entrou fecha, o bot sai da voz sozinho e todos recebem a saída dele.
  • As sessões de voz de bots vivem no processo que recebeu a conexão do gateway, como as sessões do gateway. Com várias instâncias, a entrada é replicada aos navegadores, mas o bot continua preso à instância onde está conectado.