Web Scraping / Discord Bot

Bot Discord Alcampo

Un bot de Discord que automatiza la obtención de QRs y saldos de Alcampo. Slash commands, web scraping con Puppeteer, y gestión de servidor todo en uno.

El problema (otra vez)

Después del bot de Telegram, quería lo mismo pero para Discord. El servidor necesitaba funciones útiles de Alcampo + herramientas de administración. Porque, ¿por qué no?

Objetivo: Slash commands que saquen QR y saldo de Alcampo + funciones de admin del servidor

Esta vez tenía más claro el web scraping, pero Discord.js era territorio nuevo.

El camino de sufrimiento

6 hrs Tiempo total
5 Slash commands
~500 Líneas de código

Paso 1: La ilusión de la API oficial

Pensé: "Alcampo tendrá una API normal, ¿no?". Error garrafal.

// Lo que intenté primero (spoiler: no funcionó) const response = await fetch('https://api.alcampo.es/loyalty', { headers: { Authorization: 'Bearer ???' } }); // → HTTP 400 eternos 🤡

Paso 2: Investigación de endpoints

Me puse a inspeccionar la web de Alcampo con DevTools. URLs random, headers raros, tokens que no podía extraer... una pesadilla.

Realidad: No hay documentación pública. Los endpoints internos requieren autenticación compleja que no puedes replicar fácil.

Paso 3: Puppeteer al rescate

Como ya sabía que funcionaba del bot de Telegram, directamente implementé web scraping:

// Plan B (y el bueno) const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); // Login automático → navegar → extraer datos

Los problemas técnicos reales

1. Funciones fantasma

Definía `getSaldoAlcampo()` pero se me olvidaba exportarla. Errores de "función no definida" por todos lados.

2. Módulos ES vs CommonJS

Discord.js usa imports modernos, pero Puppeteer a veces no. Tuve que configurar `type: "module"` en package.json y ajustar toda la sintaxis.

// Antes (no funcionaba) const puppeteer = require('puppeteer'); // Después (funcional) import puppeteer from 'puppeteer';

3. Fetch dentro de Puppeteer

Intenté usar fetch() desde dentro del contexto del navegador para llamar a APIs. Fatal mistake. Headers raros, CORS, autenticación... un lío.

4. Comandos que no aparecían

Tenía el código para manejar `/purge` y `/nuke` pero no los registraba en el array `commands`. Discord no reconoce comandos que no registres primero.

// El problema: solo registraba 3 de 5 comandos const commands = [rename, qr, saldo]; // ❌ Faltan purge y nuke // La solución: registrar todos const commands = [rename, qr, saldo, purge, nuke]; // ✅

Stack final

Node.js + Discord.js
Para el bot. v14 porque es la más estable para slash commands.
Puppeteer
Web scraping de la página de Alcampo. Más confiable que APIs no documentadas.
Canvas extraction
El QR está en canvas. JavaScript injection para extraer los datos.
Role-based permissions
Solo usuarios con rol "All Perms" pueden usar comandos de admin.

Comandos finales

/qr email password

Devuelve el QR como imagen adjunta

/saldo email:password

Muestra puntos y euros de la cuenta

/rename nombre

Cambia el nombre del servidor

/purge cantidad [usuario]

Elimina mensajes del canal (hasta 100)

/nuke Nuke

Borra TODO el canal recreándolo

Resultado: Bot funcional que combina funciones de Alcampo con gestión de servidor.

Cómo funciona el flujo completo

Cuando mandas /saldo email:password:

1. Discord.js intercepta el slash command 2. Valida que tengas permisos necesarios 3. Puppeteer abre Chrome headless 4. Navega a ar-customerdiamond-es.my.site.com 5. Rellena credenciales automáticamente 6. Hace login y navega a /settings/loyalty 7. Extrae puntos y euros con querySelector 8. Responde en Discord con los datos 9. Cierra el navegador y limpia memoria

Para el QR es parecido, pero extrae del canvas y devuelve como AttachmentBuilder.

Lecciones aprendidas

  • APIs no documentadas = dolor: Si no hay docs oficiales, directo a web scraping.
  • Discord.js != Telegram bots: Slash commands requieren registro previo, no es dinámico.
  • Puppeteer > requests: Para SPAs complejas, simular navegador real es más confiable.
  • Gestión de permisos: En servidores públicos, controlar quién puede usar qué comandos es crucial.
  • Debugging modular: Separar web scraping de lógica del bot hace más fácil debuggear.

Al final terminé con un bot que uso regularmente en mi servidor. No es perfecto, pero cumple: automatiza las tareas aburridas de Alcampo y añade herramientas útiles de admin. Plus: aprendí Discord.js y reforcé mis skills de web scraping. 🫡