Portal de Desarrolladores
Experimental La plataforma de bots y apps está en desarrollo activo. Los servidores autoalojados ejecutan bots, comandos de barra y componentes de mensaje, con algunas diferencias respecto a la nube. Consulta qué se admite.
← Documentación

Registros del bot

La pestaña Bot de tu aplicación puede pedir al bot en ejecución sus líneas de registro recientes, para que veas qué pasó sin iniciar sesión en la máquina donde se ejecuta. Esta página describe el protocolo que implementa un bot para responder.

Cómo funciona

  1. Alguien con acceso de desarrollo (la persona propietaria, o un miembro del equipo con rol de desarrollador o superior) pulsa Solicitar registros en la pestaña Bot y elige un intervalo de tiempo y un número de líneas.
  2. GameVox envía a tu bot un despacho de gateway llamado GAMEVOX_LOG_REQUEST. Solo va a las sesiones de gateway activas de esa misma aplicación.
  3. Tu bot reúne las líneas de ese intervalo y las sube con una sola llamada REST. El portal las muestra en cuanto llegan.
  4. Si no llega nada en dos minutos, el portal indica que el bot no respondió. Un bot que no conoce el evento lo ignora, así que no se rompe nada en las bibliotecas que nunca han oído hablar de él.

El evento de gateway

Un despacho corriente (opcode 0) con t igual a GAMEVOX_LOG_REQUEST. Lleva un número de secuencia como cualquier otro despacho y se vuelve a enviar al reanudar la sesión.

{
  "op": 0,
  "s": 4821,
  "t": "GAMEVOX_LOG_REQUEST",
  "d": {
    "request_id": "6f0c2d1e-8a54-4b7e-9c3d-2a1f5e7b9d40",
    "since": "2026-10-30T11:45:00Z",
    "max_lines": 2000,
    "nonce": "3f9a0c...e1b7",
    "expires_at": "2026-10-30T12:02:00Z"
  }
}
  • request_id: identifica la petición; forma parte de la URL de subida.
  • since: hora RFC 3339. Envía las líneas de ese momento en adelante.
  • max_lines: el máximo de líneas que se quieren (de 50 a 20.000). Si tienes más, envía las más recientes.
  • nonce: un secreto de un solo uso para esta petición. Devuélvelo con la subida; demuestra que la subida viene del bot que recibió la petición.
  • expires_at: hora RFC 3339 a partir de la cual se rechaza la subida (dos minutos después de la petición).

Subir las líneas

Responde con una sola petición, autenticada como cualquier otra llamada de bot (Authorization: Bot <token>). JSON es la forma normal:

POST /api/v10/applications/@me/log-requests/6f0c2d1e-8a54-4b7e-9c3d-2a1f5e7b9d40
Authorization: Bot <token>
Content-Type: application/json

{
  "nonce": "3f9a0c...e1b7",
  "lines": [
    { "ts": "2026-10-30T11:58:02.114Z", "level": "info",  "msg": "synced 12 guilds" },
    { "ts": "2026-10-30T11:58:09.870Z", "level": "error", "msg": "poll failed: timeout" }
  ]
}

HTTP/1.1 204 No Content

Cada línea es {ts, level, msg}: ts, una hora RFC 3339; level, uno de debug, info, warn, error; y msg, el texto. También se acepta una cadena sin más en lugar de un objeto.

También vale texto plano: envía Content-Type: text/plain con una línea por fila y el nonce en una cabecera X-GameVox-Log-Nonce. Las líneas enviadas así no llevan marca de tiempo ni nivel (GameVox deduce un nivel a partir de las palabras de la línea). La cabecera también funciona con JSON; el campo del cuerpo es solo una comodidad.

Límites y reglas

  • El cuerpo puede ocupar como mucho 2 MiB y una petición conserva como mucho 20.000 líneas. Por encima del límite de líneas se conservan las más recientes; un cuerpo mayor se rechaza con 413.
  • Una petición se puede responder una vez. Una segunda subida recibe 409.
  • Solo la aplicación para la que se hizo la petición puede responderla. El id de petición de otra aplicación parece un id desconocido (404).
  • La subida debe llegar antes de expires_at (410 después).
  • El nonce debe coincidir (403 si no).
  • Las peticiones están limitadas a una cada 30 segundos y 30 al día por aplicación. Los paquetes se guardan 7 días y luego se eliminan.
  • El texto de los registros se muestra solo como texto plano. Se quitan los caracteres de control y cada línea se corta a los 4.000 caracteres.

Errores

  • 400: el cuerpo no es JSON válido, o falta el nonce.
  • 403: el nonce no coincide.
  • 404: no existe esa petición para tu aplicación.
  • 409: la petición ya se respondió.
  • 410: la petición caducó.
  • 413: el cuerpo ocupa más de 2 MiB.
  • 429: tu bot ha alcanzado el límite de solicitudes, como en cualquier otra ruta.

Quita los secretos antes de enviar

Los registros salen de tu máquina, así que quita lo que no deba salir: el token de tu bot y cualquier otra credencial, las cabeceras Authorization, las contraseñas en URL, las direcciones de correo y las direcciones IP de tus usuarios. Los bots propios de GameVox hacen todo esto antes de subir.

GameVox también oculta datos al recibirlos (tokens, valores de Authorization, pares key=value cuya clave nombra un secreto, contraseñas en URL, cadenas hexadecimales largas y direcciones de correo) e indica a quien los mira cuántos valores ocultó. Es una red de seguridad, no un motivo para saltarte tu propia ocultación: no puede saber qué es privado en tus mensajes.

Ejemplo

La mayoría de las bibliotecas te pasan los eventos que no modelan mediante un hook en bruto: on_socket_raw_receive en discord.py, el evento raw en discord.js. Guarda los últimos miles de líneas en un búfer circular y, cuando llegue el evento, envía la parte que se pidió.

# discord.py: keep recent lines, answer GAMEVOX_LOG_REQUEST
import collections, json, logging
from datetime import datetime, timezone

RING = collections.deque(maxlen=5000)

class Ring(logging.Handler):
    def emit(self, record):
        RING.append({"ts": datetime.fromtimestamp(record.created, timezone.utc).isoformat(),
                     "level": record.levelname.lower(),
                     "msg": redact(self.format(record))})

logging.getLogger().addHandler(Ring())

@client.event
async def on_socket_raw_receive(msg):
    packet = json.loads(msg)
    if packet.get("t") != "GAMEVOX_LOG_REQUEST":
        return
    d = packet["d"]
    lines = [l for l in RING if l["ts"] >= d["since"]][-d["max_lines"]:]
    await session.post(
        f"https://app-api.gamevox.com/api/v10/applications/@me/log-requests/{d['request_id']}",
        headers={"Authorization": f"Bot {TOKEN}"},
        json={"nonce": d["nonce"], "lines": lines})

Compatibilidad

El evento es nuevo y opcional. Los bots escritos con bibliotecas de Discord siguen funcionando sin cambios, porque una biblioteca ignora los despachos que no conoce. Los bots propios de GameVox (League of Legends, VALORANT, Deadlock, Valheim, WARDOGS, gremio de WoW, Tickets y Tibia) lo admiten mediante la biblioteca de bots compartida.

← Documentación