Documentación del Código
Descripción
WH-Tebex-MicroService es un microservicio desarrollado en Node.js que integra Tebex con Discord.
El servicio recibe webhooks de Tebex, valida el origen de las solicitudes, evita eventos duplicados y publica compras confirmadas en un canal específico de Discord mediante mensajes embebidos claros y legibles.
Además, incluye comandos administrativos para consultar usuarios y pagos de Tebex directamente desde Discord.
Vista Rápida
- Tebex webhook: recibe eventos de validación y compras.
- Express: expone el servidor HTTP y los endpoints del servicio.
- Discord bot: publica embeds en el canal configurado.
- Idempotencia: evita que una misma compra se publique varias veces.
- Observabilidad: incluye X-Request-Id, GET /healthz y GET /metrics.
Requisitos
- Node.js 18 o superior.
- Un bot de Discord con permisos para leer y enviar mensajes.
- Un canal de Discord donde se publicarán las compras.
- Un endpoint de Tebex configurado hacia este servicio.
- La Private Key de Tebex si deseas usar los comandos de consulta.
Instalación
1. Copia el archivo config.example.json y renómbralo como config.json.
2. Configura el token del bot, canal de Discord, puerto, Private Key de Tebex y opciones del embed.
3. Instala las dependencias del proyecto:
npm install
4. Inicia el servicio:
node index.js
Configuración Principal
Antes de ejecutar la aplicación, es necesario configurar el archivo config.json.
- showServer: muestra u oculta servidores asociados a cada producto.
- debug: activa logs más detallados. En modo debug se omite la deduplicación para facilitar pruebas.
- defPort: puerto HTTP donde se ejecutará el servicio.
- token: token del bot de Discord.
- shopchannelID: ID del canal de Discord donde se publicarán las compras.
- language: idioma de los textos de la aplicación.
Configuración del Embed
- embed.url: URL principal del embed.
- embed.url_infooter: añade el dominio al footer del mensaje.
- embed.gifurl: imagen o banner superior.
- embed.imageurl: imagen principal del embed.
- embed.emojititle: emoji mostrado en el título.
- embed.emojireact: reacción automática al mensaje publicado.
- embed.emojicurrency: emoji usado para representar la moneda.
- embed.color: color principal del embed.
- embed.emojiproductArrow: prefijo visual para cada producto.
- embed.useMCskin: cambia el thumbnail al avatar estilo Minecraft del comprador.
Configuración API Opcional
- api.favicon_url: permite redirigir /favicon.ico hacia una URL externa.
Configuración de Comandos Tebex
- tebexCheck.prefix: prefijo usado para los comandos de Discord.
- tebexCheck.apiKey: Private Key de Tebex para consultar la API.
- tebexCheck.requiredRole: rol necesario para usar !tbxuser y !tbxcheck. Puede dejarse vacío si no se desea restringir por rol.
Ejemplo de Configuración
showServer: false
debug: false
defPort: 25500
token: DISCORD_BOT_TOKEN
shopchannelID: 123456789012345678
language: es
embed.url:
https://tienda.ejemplo.com
embed.url_infooter: true
embed.gifurl:
https://cdn.ejemplo.com/banner.png
embed.imageurl:
https://cdn.ejemplo.com/embed.png
embed.emojititle: <:Tienda:000000000000000000>
embed.emojireact: <:CHECK:000000000000000000>
embed.emojicurrency: <:coin:000000000000000000>
embed.color: #0099ff
embed.emojiproductArrow: <:linea:000000000000000000>
embed.useMCskin: true
api.favicon_url:
https://example.com/favicon.png
tebexCheck.prefix: !
tebexCheck.apiKey: TEBEX_PRIVATE_KEY
tebexCheck.requiredRole: vacío si no deseas restringir por rol
Configuración de Tebex
1. Crea un DNS apuntando al servidor donde alojas este servicio.
2. Configura el webhook en Tebex apuntando al dominio y puerto definidos.
3. Verifica que Tebex pueda alcanzar correctamente el endpoint.
4. Comprueba que el servicio responda correctamente a los eventos de validación.
Ejemplo
us1.haliacraft.com:25500
Allowlist de IPs de Tebex
Para mayor seguridad, el servicio valida que las solicitudes provengan de IPs oficiales de Tebex.
- 18.209.80.3
- 54.87.231.232
Si una solicitud no proviene de una IP autorizada, será rechazada.
Endpoints Disponibles
GET /healthz
Devuelve el estado básico del servicio.
Respuesta esperada:
ok: true
language: es
uptime_seconds: 120
request_count: 18
GET /metrics
Devuelve contadores internos del servicio, incluyendo:
- Solicitudes totales.
- Validaciones webhook.
- Solicitudes aceptadas.
- Solicitudes rechazadas.
- Duplicados descartados.
- Errores.
- Payloads vacíos.
POST /
Recibe el webhook de Tebex y procesa:
- Validación del webhook.
- Compras válidas.
- Rechazos por IP no autorizada.
- Deduplicación por transaction_id u order_id.
Comandos de Tebex en Discord
!tbxuser nick_o_uuid
Consulta un usuario de Tebex usando su nick o UUID.
Muestra:
- Perfil del usuario.
- Pagos encontrados.
- Paginación mediante botones.
- Selector para abrir un pago concreto.
- Detalles del pago de forma privada.
Ejemplo:
!tbxuser Notch
!tbxcheck tbx-id
Consulta un pago específico de Tebex usando el ID de transacción.
Ejemplo:
!tbxcheck 1234567890
Embed Visual
El embed está diseñado para mostrar la información de compra de forma clara para administradores y usuarios.
Ejemplo visual:
Compra confirmada
────────────────────────────
Cliente: usuario
Total: $10.00 USD
Productos:
- Producto A x1 | $5.00
- Producto B x2 | $5.00
Footer: tienda.ejemplo.com
Idempotencia
El servicio guarda los eventos ya procesados en:
.data/tebex-idempotency.json
Esto evita que una misma compra se publique varias veces si Tebex reintenta enviar el mismo webhook.
- Si el evento ya fue procesado, el servicio responde 200 y no vuelve a publicar el mensaje.
- En modo debug, la deduplicación se omite para facilitar pruebas manuales.
- Para reiniciar la deduplicación local, se puede borrar la carpeta .data/.
Logs y Depuración
Cada solicitud recibe un identificador único llamado X-Request-Id.
Este ID se replica en logs y respuestas para facilitar el seguimiento de errores o eventos específicos.
Cuando debug está activado:
- Se muestran logs más detallados.
- Se omite la deduplicación.
- Se facilita la validación completa del flujo webhook hacia Discord.
Estructura del Proyecto
- index.js: arranque principal de Discord y Express.
- handlers/: middlewares y manejo de solicitudes.
- functions/: lógica de envío, comandos Tebex y traducciones.
- lib/: validación, logger, métricas e idempotencia.
- langs/: archivos de idioma.
Solución de Problemas
- Not authorized o 403: la IP no está en la allowlist de Tebex.
- Webhook sin productos: Tebex envió un payload vacío o incompleto.
- No llega a Discord: revisa shopchannelID, token y permisos del bot.
- Mensajes duplicados: el evento ya fue procesado y quedó guardado en el sistema de idempotencia.
- Falta configurar tebexCheck.apiKey: no añadiste la Private Key de Tebex en config.json.
Notas Finales
Este proyecto incluye endpoints de salud y métricas, validación de origen, deduplicación de eventos y comandos administrativos para consultar información de Tebex desde Discord.
El texto del embed puede modificarse sin tocar directamente la lógica del webhook, lo que facilita personalizar la apariencia de los mensajes publicados en Discord.
Se recomienda usar este servicio en producción con un dominio configurado correctamente, puerto protegido, token privado, Private Key segura y permisos mínimos necesarios para el bot de Discord.