- Node.js 25.9.0+
- Variables de entorno de Twitch configuradas
- Base de datos SQLite inicializable en
data/io-bot.db
npm install
npm run dev!funa <usuario>
Ejemplo:
Usuario: !funa juanperez
Bot: juanperez ha sido funado 5 veces 😅
El sistema de funa permite que usuarios ejecuten el comando !funa <usuario> en Twitch para "funar" (mencionar de forma jocosa) a otros usuarios. El bot mantiene un contador de cuántas veces cada usuario ha sido funado.
- El bot mantiene un modelo canónico de usuario (
users) vinculado a identidades en diferentes plataformas (identities). - Matching automático: Cuando se detecta por primera vez un usuario, el sistema intenta hacer auto-match con usuarios similares en base a:
- Normalización de nombre (minúsculas, sin caracteres especiales, sin números al final).
- Similitud Levenshtein con umbral configurablemente (default 0.85).
- Match seguro: Solo se auto-merge si hay exactamente un candidato por encima del umbral.
- Duplicados permitidos: Si hay ambigüedad, se crea un nuevo usuario. Luego se pueden unificar manualmente.
- Cada comando tiene un cooldown configurable (ej:
funatiene 8 segundos). - El cooldown es por usuario y por canal (además de por comando).
- Si se intenta usar un comando en cooldown, el bot responde:
"Espera Xs antes de volver a usar !<comando>." - Configuración centralizada en
config/cooldowns.json.
- Base de datos robusta y ligera sin requerimientos de servidor externo.
- Schema con migraciones automáticas al iniciar.
- Preparada para escalar a niveles, dashboard y otras features.
!funa <usuario>
Ejemplo:
!funa juanperez
Respuesta:
juanperez ha sido funado 5 veces 😅
- ID canónico de usuario en el sistema.
- Se crea automáticamente para cada usuario único encontrado.
- Mapeo entre plataforma + platform_user_id → user_id canónico.
- Ejemplo:
(platform='twitch', platform_user_id='123456', user_id=1). - Almacena nombre de usuario y display name para trazabilidad.
- Registro histórico de cada evento de funa.
- Campos: actor (identidad), target (usuario), plataforma, timestamp.
- Control de cooldowns por comando y scope (ej:
command=funa, scope=channel#twitch:user:12345). - Almacena
last_used_aten milisegundos desde epoch.
// Obtener o crear identidad automáticamente
const identity = identityService.getOrCreateIdentity(
'twitch',
platformUserId,
username,
displayName
);
// Buscar usuarios similares
const matches = identityService.findSimilarUsers('juanperez');
// Unificar usuarios (merge manual)
identityService.mergeUsers(sourceUserId, targetUserId, mergedBy, reason);const check = cooldownService.evaluateCooldown({
commandName: 'funa',
platform: 'twitch',
context: {
channel: '#canal',
user: { id: '12345' },
},
});
if (check.onCooldown) {
console.log(`Espera ${check.remainingSeconds}s`);
}// Registrar un evento de funa
funaService.recordFunaEvent(actorIdentityId, targetUserId, 'twitch');
// Obtener conteo de funas de un usuario
const count = funaService.getFunaCount(userId);
// Obtener historial
const history = funaService.getFunaHistory(userId, limit=10);
// Estadísticas globales
const stats = funaService.getFunaStats(); // { mostFunedUsers, topFuners }new FunaCommand({
identityService,
funaService,
logger
})Flujo:
- Usuario ejecuta
!funa <target>. - Middleware de comandos valida cooldown segun
config/cooldowns.json. - Se obtiene/crea identidad del actor.
- Se busca usuario target por nombre (similar o exacto).
- Se registra evento en DB.
- Middleware registra uso del comando y se retorna mensaje con conteo actualizado.
DB_PATH: Ruta de la base de datos (default:data/io-bot.db).COOLDOWN_CONFIG_FILE: Ruta del archivo JSON de cooldowns (default:config/cooldowns.json).
El umbral de matching automático es configurable por defecto a 0.85 (escala 0-1):
0.90+: muy estricto, casi solo nombres iguales.0.85: recomendado para capturar typos y variantes (juan vs juan_).0.75+: más permisivo, captura más matches pero con riesgo de falsos positivos.
El diseño está pensado para reutilizar los mismos servicios en Discord:
// En DiscordBot, igual que en TwitchBot:
const discordFunaCommand = new FunaCommand({
identityService, // compartido
funaService, // compartido
logger
});
// Al recibir mensajes en Discord:
identityService.getOrCreateIdentity('discord', userId, username, displayName);
// La identidad se unificará automáticamente si hay match con Twitch.- Modificadores de experiencia para VIP/suscriptores.
- Dashboard de ranking con gráficos.
- Sistema de niveles basado en contadores.
- Integración con IA para respuestas dinámicas.
- Match manual vía comando de admin.
Ejecutar tests del sistema de funa:
npm test -- test/funa-system.test.jsEjecutar suite dedicada de cooldowns:
npm test -- test/cooldown-system.test.jsTests cubiertos:
- Creación y matching automático de identidades.
- Búsqueda de usuarios similares.
- Gestión de cooldowns.
- Registro y conteo de eventos de funa.
- Estadísticas globales.
Error: no such column
- Revisa que las migraciones hayan corrido al iniciar.
- Si trabajas local y el esquema cambió, recrea
data/io-bot.db.
Error: UNIQUE constraint failed
- Verifica colisiones de identidad en
identities (platform, platform_user_id). - Revisa casos de merge manual incompleto.
Cooldown no se aplica como esperas
- Revisa
config/cooldowns.json. - Verifica
scopeyenabledpara plataforma/comando.