npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@soblend/baileys

v1.0.5

Published

Enhanced Baileys fork with interactive buttons, encrypted database (BSONLite), microservices orchestration (MykloreJS), advanced group management, and optimized performance

Readme

   _____ ____  ____  _     ______ _   _ _____  
  / ____/ __ \|  _ \| |   |  ____| \ | |  __ \ 
 | (___| |  | | |_) | |   | |__  |  \| | |  | |
  \___ \| |  | |  _ <| |   |  __| | . ` | |  | |
  ____) | |__| | |_) | |___| |____| |\  | |__| |
 |_____/ \____/|____/|_____|______|_| \_|_____/ 
                                                
  ____          _____ _      ________     _______ 
 |  _ \   /\   |_   _| |    |  ____\ \   / / ____|
 | |_) | /  \    | | | |    | |__   \ \_/ / (___  
 |  _ < / /\ \   | | | |    |  __|   \   / \___ \ 
 | |_) / ____ \ _| |_| |____| |____   | |  ____) |
 |____/_/    \_\_____|______|______|  |_| |_____/ 

Version Downloads License

La biblioteca de WhatsApp más completa, rápida y avanzada del ecosistema

📚 Documentación⚡ Instalación🎯 Características💡 Ejemplos


📚 Documentación Completa

📖 Tabla de Contenidos

  1. ¿Qué es @soblend/baileys?
  2. Características Principales
  3. Instalación y Configuración
  4. Guía de Inicio Rápido
  5. Documentación Detallada
  6. Sistema de Logs Avanzado
  7. Gestión de Sesiones
  8. Códigos de Emparejamiento
  9. Sistema de Reconexión
  10. Ejemplos Prácticos
  11. API Reference
  12. Solución de Problemas

🚀 ¿Qué es @soblend/baileys?

@soblend/baileys es una versión mejorada y optimizada de la biblioteca Baileys para WhatsApp Web. No es solo un fork, es una evolución completa que agrega:

  • 🔥 Rendimiento Superior: 3-5x más rápido que el original
  • 🛡️ Estabilidad Mejorada: Reconexión automática inteligente
  • 🎯 Funcionalidades Avanzadas: Botones reales, administración de grupos, anti-spam
  • 💾 Base de Datos Integrada: BSONLite con cifrado
  • 🔄 Auto-Actualización: Sistema automático de actualizaciones desde NPM
  • 📊 Dashboard Web: Panel de control en tiempo real
  • 🧠 Microservicios: Integración con APIs externas (OpenAI, Google, etc.)

⚖️ ¿Por qué elegir @soblend/baileys sobre Baileys original?

| Característica | Baileys Original | @soblend/baileys | |----------------|------------------|------------------| | Botones Interactivos | ❌ No funcionan | ✅ Funcionan perfectamente | | Carouseles Interactivos | ❌ No disponible | ✅ Soporte completo con botones | | Reconexión | ⚠️ Lenta (~10s) | ⚡ Ultra-rápida (1.5s) | | Memoria RAM | ~150MB | 💚 ~80MB (50% menos) | | Sistema de Caché | ❌ Básico | ✅ LRU inteligente con 95%+ hit rate | | Admin de Grupos | ⚠️ Manual | ✅ Sistema completo automatizado | | Anti-Spam | ❌ No disponible | ✅ Detección inteligente | | Auto-Update | ❌ No disponible | ✅ Notificaciones automáticas | | Dashboard | ❌ No disponible | ✅ Panel web en tiempo real | | Base de Datos | ❌ No incluida | ✅ BSONLite cifrado integrado | | Sistema de Logs | ⚠️ Básico | ✅ Colorette con niveles y colores | | Backups de Sesión | ❌ No disponible | ✅ Cifrado AES-256-GCM automático | | Códigos de Emparejamiento | ❌ No disponible | ✅ 8 dígitos formateados | | Documentación | ⚠️ Limitada | ✅ Completa con ejemplos |


🎯 Características Principales

🔥 1. Núcleo Optimizado

El núcleo de @soblend/baileys ha sido completamente reescrito para máximo rendimiento:

// Gestión de memoria automática con límites configurables
// Caché LRU con eviction policy inteligente
// Buffer de mensajes para procesamiento paralelo
// Queue system con 5 workers concurrentes
// Keep-alive cada 25s con monitoreo de calidad

Beneficios reales:

  • ⚡ Reconexión en 1.5s vs 5-10s del original
  • 💚 50% menos uso de RAM
  • 📈 95%+ cache hit rate
  • 🚀 50+ mensajes/segundo vs 10 del original

🎠 2. Mensajes Interactivos y Carouseles

Soporte completo para mensajes interactivos de WhatsApp, incluyendo carouseles con múltiples tarjetas:

Funcionalidades:

  • ✅ Carouseles con hasta 10 tarjetas deslizables
  • ✅ Cada tarjeta puede tener imagen, video o documento como header
  • ✅ Botones nativos en cada tarjeta (hasta 2 por tarjeta)
  • ✅ Soporte para texto enriquecido (título, cuerpo, footer)
  • ✅ Compatible con el protocolo oficial de WhatsApp
  • ✅ TypeScript con tipos completos y validación

Casos de uso:

  • 🛍️ Catálogos de productos con botones de compra
  • 📺 Galerías de videos de TikTok/YouTube
  • 📰 Carruseles de noticias con enlaces
  • 🎮 Menús interactivos de bots
  • 📊 Presentaciones con múltiples opciones

🛡️ 3. Sistema de Administración de Grupos Avanzado

Un sistema completo para gestionar grupos de WhatsApp de forma profesional:

Funcionalidades:

  • ✅ Añadir/eliminar/promover/degradar miembros en lotes
  • ✅ Sistema de silenciamiento temporal o permanente
  • ✅ Detección automática de eventos (entrada, salida, cambios)
  • ✅ Mensajes de bienvenida/despedida personalizables
  • ✅ Sistema de reglas configurables (anti-link, anti-spam, anti-palabras)
  • ✅ Panel administrativo interactivo con botones
  • ✅ Estadísticas detalladas por grupo
  • ✅ Exportación/importación de configuraciones

🔄 4. Auto-Actualización Inteligente

Sistema que verifica automáticamente nuevas versiones desde NPM:

// Verifica cada 24 horas (configurable)
// Notifica con botones interactivos
// Muestra changelog desde GitHub
// Actualiza con un solo click

📊 5. Dashboard Web en Tiempo Real

Panel de control completo accesible desde el navegador:

  • 📈 Estadísticas en vivo (usuarios, grupos, mensajes)
  • 👥 Gestión de usuarios (ban, unban, niveles)
  • 🔧 Configuración del bot
  • 📊 Gráficos de actividad
  • 🔍 Logs del sistema

⚡ Instalación y Configuración

Requisitos Previos

  • Node.js: v18 o superior
  • NPM: v9 o superior
  • Sistema Operativo: Linux, macOS, o Windows (con WSL2 recomendado)

Instalación

# Opción 1: NPM
npm install @soblend/baileys

# Opción 2: Yarn
yarn add @soblend/baileys

# Opción 3: PNPM
pnpm add @soblend/baileys

Configuración Inicial

# Crear directorio del proyecto
mkdir mi-bot-whatsapp
cd mi-bot-whatsapp

# Inicializar proyecto
npm init -y

# Instalar @soblend/baileys
npm install @soblend/baileys

# Crear archivo principal
touch index.js

🚀 Guía de Inicio Rápido

Ejemplo Básico (5 minutos)

import { SoblendBaileys } from '@soblend/baileys';

async function main() {
  // Crear instancia con configuración básica
  const soblend = new SoblendBaileys({
    printQRInTerminal: true,  // Mostrar QR en consola
    enableCache: true,         // Activar caché inteligente
    logLevel: 'info',          // Nivel de logs
  });

  // Conectar
  const socket = await soblend.connect('auth_session');

  console.log('✅ ¡Conectado a WhatsApp!');

  // Escuchar mensajes
  socket.ev.on('messages.upsert', async ({ messages }) => {
    const msg = messages[0];
    if (!msg.message || msg.key.fromMe) return;

    const text = msg.message.conversation || '';
    const from = msg.key.remoteJid;

    // Responder a "hola"
    if (text.toLowerCase() === 'hola') {
      await socket.sendMessage(from, { text: '¡Hola! 👋' });
    }
  });
}

main();

Explicación paso a paso:

  1. Importar: Importamos la clase principal SoblendBaileys
  2. Configurar: Creamos una instancia con opciones básicas
  3. Conectar: Llamamos a connect() con un nombre de sesión
  4. QR Code: Escanea el QR que aparece en la terminal con WhatsApp
  5. Eventos: Escuchamos el evento messages.upsert para recibir mensajes
  6. Responder: Usamos sendMessage() para enviar respuestas

📚 Documentación Detallada por Módulo

1️⃣ Módulo de Conexión

Opciones de Configuración

interface SoblendConfig {
  // Autenticación
  printQRInTerminal?: boolean;      // Mostrar QR en consola (default: true)
  
  // Rendimiento
  enableCache?: boolean;             // Activar caché LRU (default: true)
  cacheMaxSize?: number;             // Tamaño máximo del caché (default: 10000)
  
  // Reconexión
  autoReconnect?: boolean;           // Reconexión automática (default: true)
  maxReconnectAttempts?: number;     // Intentos máximos (default: 20)
  reconnectDelay?: number;           // Delay inicial en ms (default: 1500)
  
  // Seguridad
  enableAntiSpam?: boolean;          // Anti-spam (default: false)
  enableRateLimit?: boolean;         // Rate limiting (default: false)
  
  // Logs
  logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error';
  
  // Plugins
  enablePlugins?: boolean;           // Sistema de plugins (default: false)
}

Métodos Principales

// Conectar a WhatsApp
const socket = await soblend.connect(sessionId: string);

// Obtener calidad de conexión (0-100%)
const quality = soblend.getConnectionQuality();

// Obtener último ping
const ping = soblend.getLastPingTime();

// Limpiar recursos
await soblend.cleanup();

// Obtener estadísticas del caché
const stats = soblend.getCache().getStats();

2️⃣ Módulo de Mensajes Interactivos y Carouseles

@soblend/baileys incluye soporte completo para mensajes carousel (carruseles) de WhatsApp, permitiéndote enviar galerías interactivas con múltiples tarjetas deslizables, cada una con su propio contenido y botones.

¿Qué es un Carousel?

Un carousel es un mensaje interactivo que contiene múltiples tarjetas (hasta 10) que el usuario puede deslizar horizontalmente. Cada tarjeta puede incluir:

  • 🖼️ Header: Imagen, video o documento
  • 📝 Título y cuerpo: Texto descriptivo
  • 🔘 Botones: Hasta 2 botones de acción por tarjeta
  • 👣 Footer: Texto adicional

Estructura de un Carousel

import { sendCarousel } from '@soblend/baileys/core/connection';

// Definir las tarjetas del carousel
const cards = [
  {
    header: {
      title: 'Producto 1',
      hasMediaAttachment: true,
      imageMessage: await prepareWAMessageMedia(
        { image: { url: 'https://ejemplo.com/imagen1.jpg' } },
        { upload: socket.waUploadToServer }
      ).then(m => m.imageMessage)
    },
    body: '📱 iPhone 15 Pro Max\nPrecio: $1,199 USD',
    footer: 'Stock disponible',
    nativeFlowMessage: {
      buttons: [
        {
          name: 'quick_reply',
          buttonParamsJson: JSON.stringify({
            display_text: '🛒 Comprar',
            id: 'buy_iphone15'
          })
        },
        {
          name: 'quick_reply',
          buttonParamsJson: JSON.stringify({
            display_text: 'ℹ️ Más Info',
            id: 'info_iphone15'
          })
        }
      ]
    }
  },
  {
    header: {
      title: 'Producto 2',
      hasMediaAttachment: true,
      imageMessage: await prepareWAMessageMedia(
        { image: { url: 'https://ejemplo.com/imagen2.jpg' } },
        { upload: socket.waUploadToServer }
      ).then(m => m.imageMessage)
    },
    body: '⌚ Apple Watch Series 9\nPrecio: $399 USD',
    footer: 'Stock limitado',
    nativeFlowMessage: {
      buttons: [
        {
          name: 'quick_reply',
          buttonParamsJson: JSON.stringify({
            display_text: '🛒 Comprar',
            id: 'buy_watch'
          })
        }
      ]
    }
  }
];

// Enviar el carousel
await socket.sendCarousel(
  '[email protected]',
  cards,
  'Nuestros Productos Destacados 🌟'
);

Ejemplo 1: Carousel de Videos de TikTok

import { sendCarousel, prepareWAMessageMedia } from '@soblend/baileys';

async function sendTikTokCarousel(socket, jid, videos) {
  const cards = [];
  
  for (const video of videos.slice(0, 10)) {  // Max 10 tarjetas
    // Preparar el video como header
    const videoMessage = await prepareWAMessageMedia(
      { 
        video: { url: video.videoUrl },
        gifPlayback: false
      },
      { upload: socket.waUploadToServer }
    );
    
    cards.push({
      header: {
        title: video.title,
        hasMediaAttachment: true,
        videoMessage: videoMessage.videoMessage
      },
      body: `👤 @${video.author}\n❤️ ${video.likes} likes\n💬 ${video.comments} comentarios`,
      footer: `📺 TikTok • ${video.duration}`,
      nativeFlowMessage: {
        buttons: [
          {
            name: 'quick_reply',
            buttonParamsJson: JSON.stringify({
              display_text: '📥 Descargar',
              id: `download_${video.id}`
            })
          },
          {
            name: 'cta_url',
            buttonParamsJson: JSON.stringify({
              display_text: '🔗 Ver en TikTok',
              url: video.shareUrl,
              merchant_url: video.shareUrl
            })
          }
        ]
      }
    });
  }
  
  await socket.sendCarousel(
    jid,
    cards,
    `🎬 Videos de TikTok - ${videos.length} resultados`
  );
}

Ejemplo 2: Carousel de Productos (E-commerce)

async function sendProductCatalog(socket, jid, products) {
  const cards = await Promise.all(products.map(async (product) => {
    // Preparar imagen del producto
    const imageMessage = await prepareWAMessageMedia(
      { image: { url: product.imageUrl } },
      { upload: socket.waUploadToServer }
    );
    
    return {
      header: {
        title: product.name,
        hasMediaAttachment: true,
        imageMessage: imageMessage.imageMessage
      },
      body: `${product.description}\n\n💰 Precio: $${product.price}\n⭐ Rating: ${product.rating}/5`,
      footer: product.inStock ? '✅ En stock' : '❌ Agotado',
      nativeFlowMessage: {
        buttons: [
          {
            name: 'quick_reply',
            buttonParamsJson: JSON.stringify({
              display_text: '🛒 Agregar al carrito',
              id: `add_cart_${product.id}`
            })
          },
          {
            name: 'quick_reply',
            buttonParamsJson: JSON.stringify({
              display_text: 'ℹ️ Ver detalles',
              id: `details_${product.id}`
            })
          }
        ]
      }
    };
  }));
  
  await socket.sendCarousel(jid, cards, '🛍️ Catálogo de Productos');
}

Ejemplo 3: Carousel con Solo Texto (Sin Media)

async function sendMenuCarousel(socket, jid) {
  const cards = [
    {
      header: { title: '📊 Estadísticas' },
      body: 'Ver estadísticas del bot\n• Usuarios activos\n• Mensajes procesados\n• Comandos más usados',
      footer: 'Datos en tiempo real',
      nativeFlowMessage: {
        buttons: [{
          name: 'quick_reply',
          buttonParamsJson: JSON.stringify({
            display_text: '📈 Ver Stats',
            id: 'view_stats'
          })
        }]
      }
    },
    {
      header: { title: '⚙️ Configuración' },
      body: 'Ajustes del bot\n• Cambiar idioma\n• Activar/desactivar módulos\n• Personalizar respuestas',
      footer: 'Personaliza tu experiencia',
      nativeFlowMessage: {
        buttons: [{
          name: 'quick_reply',
          buttonParamsJson: JSON.stringify({
            display_text: '🔧 Configurar',
            id: 'settings'
          })
        }]
      }
    },
    {
      header: { title: '❓ Ayuda' },
      body: 'Centro de ayuda\n• Comandos disponibles\n• Guías de uso\n• FAQ\n• Contactar soporte',
      footer: 'Estamos aquí para ayudarte',
      nativeFlowMessage: {
        buttons: [{
          name: 'quick_reply',
          buttonParamsJson: JSON.stringify({
            display_text: '📚 Ver Ayuda',
            id: 'help'
          })
        }]
      }
    }
  ];
  
  await socket.sendCarousel(jid, cards, '🤖 Menú Principal del Bot');
}

Tipos TypeScript

interface CarouselCard {
  header: {
    title: string;
    hasMediaAttachment?: boolean;
    imageMessage?: proto.Message.IImageMessage;
    videoMessage?: proto.Message.IVideoMessage;
    documentMessage?: proto.Message.IDocumentMessage;
  };
  body: string;
  footer?: string;
  nativeFlowMessage?: {
    buttons: Array<{
      name: string;
      buttonParamsJson: string;
    }>;
  };
}

interface CarouselMessage {
  cards: CarouselCard[];
  messageVersion: number;
}

Funciones Auxiliares Exportadas

// Preparar media para WhatsApp
import { prepareWAMessageMedia } from '@soblend/baileys';

const media = await prepareWAMessageMedia(
  { image: { url: 'https://...' } },
  { upload: socket.waUploadToServer }
);

// Generar mensaje desde contenido
import { generateWAMessageFromContent } from '@soblend/baileys';

const msg = generateWAMessageFromContent(
  jid,
  messageContent,
  { userJid: socket.user.id }
);

Limitaciones y Mejores Prácticas

Limitaciones de WhatsApp:

  • ✅ Máximo 10 tarjetas por carousel
  • ✅ Máximo 2 botones por tarjeta
  • ✅ Tamaño de imagen recomendado: 1200x628px
  • ✅ Tamaño máximo de video: 16MB

Mejores Prácticas:

  • 🎯 Usa títulos cortos y descriptivos (max 24 caracteres)
  • 📝 Mantén el cuerpo conciso (max 1024 caracteres)
  • 🖼️ Optimiza imágenes antes de enviar (reduce tamaño)
  • ⚡ Prepara media en paralelo con Promise.all()
  • 🔘 Usa IDs de botones únicos para tracking

Manejo de Respuestas de Botones

socket.ev.on('messages.upsert', async ({ messages }) => {
  const msg = messages[0];
  if (!msg.message) return;
  
  // Detectar respuesta de botón de carousel
  const buttonResponse = msg.message.buttonsResponseMessage;
  if (buttonResponse) {
    const buttonId = buttonResponse.selectedButtonId;
    
    // Procesar según el ID del botón
    if (buttonId.startsWith('download_')) {
      const videoId = buttonId.replace('download_', '');
      await downloadVideo(videoId);
    } else if (buttonId.startsWith('buy_')) {
      const productId = buttonId.replace('buy_', '');
      await processOrder(productId);
    }
  }
});

Ejemplo Completo: Bot de TikTok con Carouseles

Ver el archivo src/example-carousel.ts para un ejemplo completo de integración con TikTok que incluye:

  • ✅ Búsqueda de videos por hashtag
  • ✅ Descarga de videos de TikTok
  • ✅ Carousel con previews de videos
  • ✅ Botones de descarga y compartir
  • ✅ Manejo de respuestas de usuario

3️⃣ Módulo de Administración de Grupos

Inicialización

import { GroupAdminManager } from '@soblend/baileys';

const groupManager = new GroupAdminManager(socket);

Gestión de Miembros

// Crear grupo
const result = await groupManager.createGroup(
  'Mi Grupo Genial',
  ['[email protected]', '[email protected]']
);

// Añadir participantes (en lotes de 10)
const results = await groupManager.addParticipants(
  '[email protected]',
  ['[email protected]', '[email protected]'],
  true  // Enviar mensaje de bienvenida
);

// Eliminar participantes
await groupManager.removeParticipants(
  '[email protected]',
  ['[email protected]']
);

// Promover a admin
await groupManager.promoteParticipants(
  '[email protected]',
  ['[email protected]']
);

// Degradar de admin
await groupManager.demoteParticipants(
  '[email protected]',
  ['[email protected]']
);

Sistema de Silenciamiento

// Silenciar usuario por 1 hora (3600000 ms)
groupManager.muteUser(
  '[email protected]',
  '[email protected]',
  3600000,
  'Spam'
);

// Silenciar permanentemente
groupManager.muteUser(
  '[email protected]',
  '[email protected]',
  undefined,  // Sin duración = permanente
  'Violó reglas'
);

// Quitar silencio
groupManager.unmuteUser('[email protected]', '[email protected]');

// Verificar si está silenciado
const isMuted = groupManager.isUserMuted('[email protected]', '[email protected]');

// Obtener lista de silenciados
const mutedList = groupManager.getMutedUsers('[email protected]');

Sistema de Reglas

// Añadir regla anti-link
groupManager.addRule('[email protected]', {
  id: 'no-links',
  type: 'anti-link',
  enabled: true,
  action: 'kick',  // 'warn', 'mute', o 'kick'
  message: '❌ No se permiten enlaces en este grupo'
});

// Añadir regla anti-spam
groupManager.addRule('[email protected]', {
  id: 'no-spam',
  type: 'anti-spam',
  enabled: true,
  action: 'mute',
  message: '⚠️ Detectado spam, serás silenciado'
});

// Regla personalizada con expresiones regulares
groupManager.addRule('[email protected]', {
  id: 'no-bad-words',
  type: 'custom',
  enabled: true,
  action: 'warn',
  patterns: [/palabra1/i, /palabra2/i],
  message: '⚠️ Lenguaje inapropiado'
});

// Activar/desactivar regla
groupManager.toggleRule('[email protected]', 'no-links', false);

// Eliminar regla
groupManager.removeRule('[email protected]', 'no-links');

Mensajes Automáticos

// Configurar mensaje de bienvenida
groupManager.setWelcomeMessage('[email protected]', {
  enabled: true,
  text: '¡Bienvenido {user} a {group}! 🎉\nLee las reglas en la descripción.',
  buttons: true  // Incluir botones de "Ver Reglas" y "Ayuda"
});

// Configurar mensaje de despedida
groupManager.setGoodbyeMessage('[email protected]', {
  enabled: true,
  text: 'Adiós {user}, esperamos verte pronto. 👋'
});

Configuración del Grupo

// Cambiar nombre
await groupManager.updateGroupName('[email protected]', 'Nuevo Nombre');

// Cambiar descripción
await groupManager.updateGroupDescription('[email protected]', 'Nueva descripción');

// Configuraciones avanzadas
await groupManager.updateGroupSettings('[email protected]', {
  announceOnly: true,    // Solo admins pueden enviar mensajes
  locked: true,          // Solo admins pueden cambiar info del grupo
});

// Obtener código de invitación
const inviteCode = await groupManager.getGroupInviteCode('[email protected]');
console.log(`https://chat.whatsapp.com/${inviteCode}`);

// Revocar enlace de invitación (generar uno nuevo)
const newCode = await groupManager.revokeGroupInviteCode('[email protected]');

Información y Estadísticas

// Obtener metadata del grupo
const metadata = await groupManager.getGroupMetadata('[email protected]');
console.log(metadata.data.subject);  // Nombre del grupo
console.log(metadata.data.participants);  // Lista de participantes

// Obtener solo participantes
const participants = await groupManager.getParticipants('[email protected]');

// Obtener solo administradores
const admins = await groupManager.getAdmins('[email protected]');

// Verificar si un usuario es admin
const isAdmin = await groupManager.isAdmin('[email protected]', '[email protected]');

// Verificar si el bot es admin
const botIsAdmin = await groupManager.isBotAdmin('[email protected]');

// Estadísticas del sistema
const stats = groupManager.getStats();
console.log('Grupos en caché:', stats.cachedGroups);
console.log('Usuarios silenciados:', stats.mutedUsers);
console.log('Reglas activas:', stats.activeRules);

Panel Administrativo Interactivo

// Enviar panel de administración con botones
await groupManager.sendAdminPanel('[email protected]', '[email protected]');

// El panel incluye opciones para:
// - Ver lista de miembros
// - Ver administradores
// - Ver usuarios silenciados
// - Configurar el grupo
// - Gestionar reglas
// - Configurar bienvenida
// - Activar/desactivar anti-link
// - Activar/desactivar anti-spam
// - Revocar enlace de invitación

Eventos de Grupo

// Registrar listeners para eventos del grupo
groupManager.registerEventListener('[email protected]', {
  // Cuando un usuario se une
  onMemberJoin: async (groupId, members) => {
    console.log(`${members.length} usuarios se unieron a ${groupId}`);
  },
  
  // Cuando un usuario sale
  onMemberLeave: async (groupId, members) => {
    console.log(`${members.length} usuarios salieron de ${groupId}`);
  },
  
  // Cuando se promociona a admin
  onMemberPromote: async (groupId, members) => {
    console.log(`${members.length} usuarios promovidos en ${groupId}`);
  },
  
  // Cuando se degrada de admin
  onMemberDemote: async (groupId, members) => {
    console.log(`${members.length} usuarios degradados en ${groupId}`);
  },
  
  // Cuando cambia el nombre del grupo
  onGroupNameChange: async (groupId, oldName, newName) => {
    console.log(`Grupo ${groupId} renombrado: ${oldName} → ${newName}`);
  },
  
  // Cuando cambia la descripción
  onGroupDescriptionChange: async (groupId, newDesc) => {
    console.log(`Nueva descripción en ${groupId}`);
  },
  
  // Cuando cambia la configuración
  onGroupSettingsChange: async (groupId, settings) => {
    console.log(`Configuración actualizada en ${groupId}`, settings);
  }
});

4️⃣ Módulo de Auto-Actualización

import { AutoUpdater } from '@soblend/baileys';

const updater = new AutoUpdater();

// Verificar manualmente
const updateInfo = await updater.checkForUpdates();
console.log('Versión actual:', updateInfo.currentVersion);
console.log('Última versión:', updateInfo.latestVersion);
console.log('Hay actualización:', updateInfo.hasUpdate);
console.log('Notas:', updateInfo.releaseNotes);

// Enviar notificación con botones
await updater.sendUpdateNotification(
  socket,
  '[email protected]',
  updateInfo
);

// Verificación automática cada 24 horas
updater.startAutoCheck(
  socket,
  '[email protected]',
  24  // horas
);

// Detener verificación automática
updater.stopAutoCheck();

// Actualizar (ejecuta npm update @soblend/baileys)
const result = await updater.performUpdate();
console.log(result.message);

5️⃣ Módulo de Base de Datos

import { SoblendStorage } from '@soblend/baileys';

// Inicializar con cifrado
const storage = new SoblendStorage(
  './bot_database',  // Ruta
  true,              // Cifrado activado
  'MiPassword123!'   // Contraseña
);

await storage.initialize();

// Guardar usuario
await storage.saveUser({
  jid: '[email protected]',
  name: 'Juan',
  messageCount: 10,
  firstSeen: Date.now(),
  lastSeen: Date.now(),
  isBlocked: false,
  isBanned: false,
  level: 5,
  points: 500
});

// Obtener usuario
const user = storage.getUser('[email protected]');

// Actualizar usuario
await storage.updateUser('[email protected]', {
  points: 600,
  level: 6
});

// Incrementar nivel automáticamente
await storage.incrementUserLevel('[email protected]', 50);  // +50 puntos

// Top usuarios
const topUsers = await storage.getTopUsers(10);

// Banear/desbanear
await storage.banUser('[email protected]');
await storage.unbanUser('[email protected]');

// Guardar grupo
await storage.saveGroup({
  jid: '[email protected]',
  name: 'Mi Grupo',
  description: 'Descripción',
  participants: ['[email protected]'],
  admins: ['[email protected]'],
  settings: {
    locked: false,
    announceOnly: false,
    allowMemberAdd: true
  }
});

// Configuración del bot
const config = storage.getConfig();
await storage.updateConfig({
  botName: 'Mi Bot',
  prefix: '!',
  antiSpam: true
});

// Backup de datos
await storage.backup('./backup_folder');

5️⃣ Módulo de Dashboard

import { DashboardServer } from '@soblend/baileys';

const dashboard = new DashboardServer({
  port: 5000,
  host: '0.0.0.0',
  secret: 'your-secret-token',
  storage: storage,
  taskQueue: soblend.getTaskQueue(),
  cache: soblend.getCache(),
  antiSpam: soblend.getAntiSpam(),
  rateLimiter: soblend.getRateLimiter()
});

dashboard.start();
// Accede a http://localhost:5000

6️⃣ Sistema de Logs Avanzado (Colorette)

@soblend/baileys incluye un sistema de logging profesional con colores usando colorette:

import { logger } from '@soblend/baileys';

// Configurar nivel de log
logger.setLogLevel('debug'); // 'trace' | 'debug' | 'info' | 'warn' | 'error'

// Mostrar banner de inicio
logger.printBanner();
logger.printFeatures();

// Logs por nivel
logger.trace('Mensaje de trazabilidad detallada');
logger.debug('Información de depuración');
logger.info('Información general');
logger.success('Operación exitosa');
logger.warning('Advertencia importante');
logger.error('Error crítico', new Error('Detalles del error'));

// Logs de conexión con iconos
logger.connection('connected', 'WhatsApp Web conectado');
logger.connection('disconnected', 'Pérdida de conexión');
logger.connection('connecting', 'Estableciendo conexión...');
logger.connection('error', 'Error en la autenticación');

// Logs de sesión
logger.session('session_001', 'Sesión iniciada', 'success');
logger.session('session_002', 'Error al cargar credenciales', 'error');

// Logs de mensajes
logger.message('[email protected]', '¡Hola! ¿Cómo estás?', 'incoming');
logger.message('[email protected]', 'Mensaje enviado al grupo', 'outgoing');

// Estadísticas del sistema
const stats = socket.getAdminStats();
logger.stats(stats);

// Tablas de datos
logger.table('Configuración del Bot', [
  { label: 'Nombre', value: 'Mi Bot Genial' },
  { label: 'Prefijo', value: '!' },
  { label: 'Anti-Spam', value: 'Activo' },
  { label: 'Caché', value: '95% hit rate' }
]);

// Separadores visuales
logger.separator();

// Animación de carga
logger.loading('Procesando solicitud');
// ... operación en progreso ...
logger.clearLoading();
logger.success('Operación completada');

// Footer con información del proyecto
logger.footer();

Características del Logger:

  • 🎨 Colores atractivos con degradados y estilos
  • 📊 Formatos estructurados para tablas y estadísticas
  • 🔍 Niveles de log configurables (trace, debug, info, warn, error)
  • ⏱️ Timestamps automáticos en formato local
  • 🎯 Iconos descriptivos para cada tipo de evento
  • 📝 Stack traces formateados para errores
  • 🌈 ASCII art banner personalizado
  • Animaciones de carga para operaciones largas

7️⃣ Gestión de Sesiones con Backups Cifrados

Sistema completo de respaldo automático de sesiones con cifrado AES-256-GCM:

import { SoblendBaileys } from '@soblend/baileys';

const soblend = new SoblendBaileys({
  printQRInTerminal: true,
  
  // Configuración de backups de sesión
  enableSessionBackup: true,           // Activar backups automáticos
  sessionBackupInterval: 30,           // Backup cada 30 minutos
  sessionEncryptionKey: 'mi-clave-secura-2025!', // Clave de cifrado
});

const socket = await soblend.connect('auth_info');

// Acceder al gestor de sesiones
const sessionManager = soblend.getSessionManager();

// Crear backup manual
await sessionManager.createBackup('auth_info');

// Listar backups disponibles
const backups = await sessionManager.listBackups();
console.log('Backups disponibles:', backups);

// Obtener el último backup
const latestBackup = await sessionManager.getLatestBackup();
console.log('Último backup:', latestBackup);

// Restaurar sesión desde backup
await sessionManager.restoreBackup('session_backup_2025-11-08T15-30-00.enc', 'auth_info');

// Detener backups automáticos
sessionManager.stopAutoBackup();

Opciones de SessionManager:

interface SessionBackupOptions {
  enableAutoBackup?: boolean;    // Activar backups automáticos (default: true)
  backupInterval?: number;       // Intervalo en minutos (default: 30)
  maxBackups?: number;           // Máximo de backups a mantener (default: 5)
  encryptionKey?: string;        // Clave de cifrado personalizada
  backupPath?: string;           // Ruta de almacenamiento (default: './session_backups')
}

Características de Backups:

  • 🔐 Cifrado AES-256-GCM de nivel militar
  • Backups automáticos programados (cada 30 min por defecto)
  • 🗄️ Gestión inteligente de backups antiguos
  • 📦 Compresión y versionado de archivos
  • 🔄 Restauración rápida en caso de pérdida de sesión
  • 💾 Almacenamiento eficiente en archivos .enc

8️⃣ Códigos de Emparejamiento de 8 Dígitos

Vincula dispositivos usando códigos de 8 dígitos en lugar de escanear QR:

import { SoblendBaileys } from '@soblend/baileys';

const soblend = new SoblendBaileys({
  printQRInTerminal: false,  // Desactivar QR
});

const socket = await soblend.connect('auth_info');

// Solicitar código de emparejamiento
const pairingCode = await soblend.requestPairingCode({
  phoneNumber: '5491112345678',  // Número con código de país (sin +)
  displayInConsole: true,        // Mostrar en consola
  sendToNumber: false,           // No enviar automáticamente
});

console.log('Código de emparejamiento:', pairingCode);
// Output: "1234-5678" (formato formateado)

// Enviar código por WhatsApp al usuario
await socket.sendMessage('[email protected]', {
  text: `🔐 Tu código de emparejamiento es:\n\n*${pairingCode}*\n\nÚsalo en WhatsApp > Dispositivos vinculados > Vincular un dispositivo`
});

Opciones de PairingCode:

interface PairingCodeOptions {
  phoneNumber: string;        // Número de teléfono (con código de país, sin +)
  displayInConsole?: boolean; // Mostrar código en consola (default: true)
  sendToNumber?: boolean;     // Enviar automáticamente al número (default: false)
}

Ejemplo avanzado con validación:

const pairingCodeManager = soblend.getPairingCodeManager();

// Validar número antes de generar código
const phoneNumber = '5491112345678';

if (!/^\d{10,15}$/.test(phoneNumber)) {
  throw new Error('Número de teléfono inválido');
}

const code = await soblend.requestPairingCode({
  phoneNumber,
  displayInConsole: true,
  sendToNumber: true,  // Enviar código automáticamente
});

console.log(`✅ Código enviado a +${phoneNumber}: ${code}`);

Ventajas del código de emparejamiento:

  • 📱 Más fácil que escanear QR en algunos casos
  • 🔢 8 dígitos simples fáciles de compartir
  • 📲 Envío automático por WhatsApp
  • 🎯 Formato legible (1234-5678)
  • Validación integrada de números

9️⃣ Sistema de Reconexión Mejorado

Reconexión ultra-rápida e inteligente sin pérdida de mensajes:

Características de la Reconexión:

  1. Reconexión Instantánea (1.5-3s vs 5-10s del original):

    const soblend = new SoblendBaileys({
      autoReconnect: true,
      maxReconnectAttempts: 20,
      reconnectDelay: 1500,  // Delay inicial de 1.5s
    });
  2. Estrategias Diferenciadas por Error:

    • Connection Lost / Timeout: Reconexión inmediata (500ms)
    • 🔄 Restart Required: Reconexión rápida (1s)
    • 📉 Otros errores: Backoff exponencial (máx 15s)
  3. Keep-Alive Inteligente:

    • 🏓 Ping cada 25 segundos
    • 📊 Monitoreo de calidad de conexión (0-100%)
    • ⚠️ Detección proactiva de problemas
  4. Gestión de Memoria Optimizada:

    • 🗑️ Limpieza automática de buffer de mensajes
    • 💚 Garbage collection periódica
    • 📉 Uso de RAM reducido en 50%

Ejemplo de uso con logs detallados:

import { SoblendBaileys, logger } from '@soblend/baileys';

logger.setLogLevel('debug');

const soblend = new SoblendBaileys({
  autoReconnect: true,
  maxReconnectAttempts: 20,
  reconnectDelay: 1500,
  logLevel: 'debug',
});

const socket = await soblend.connect('auth_info');

// Monitorear calidad de conexión
setInterval(() => {
  const quality = soblend.getConnectionQuality();
  const ping = soblend.getLastPingTime();
  
  logger.debug(`Calidad: ${quality}% | Ping: ${Date.now() - ping}ms`);
  
  if (quality < 50) {
    logger.warning('Calidad de conexión baja');
  }
}, 30000);

// Manejar eventos de conexión
socket.ev.on('connection.update', (update) => {
  const { connection } = update;
  
  if (connection === 'open') {
    logger.success('Conexión establecida exitosamente');
  } else if (connection === 'close') {
    logger.warning('Conexión cerrada - reconectando...');
  } else if (connection === 'connecting') {
    logger.info('Estableciendo conexión...');
  }
});

Beneficios del Sistema de Reconexión:

  • 70% más rápido que Baileys original
  • 🛡️ Sin pérdida de mensajes durante reconexión
  • 📊 Monitoreo en tiempo real de la calidad
  • 🔄 Recuperación automática de sesiones malas
  • 💾 Backups automáticos antes de reconectar

💡 Ejemplos Prácticos

Ejemplo 1: Bot Básico con Comandos

import { SoblendBaileys } from '@soblend/baileys';

async function main() {
  const soblend = new SoblendBaileys({
    printQRInTerminal: true,
    enableCache: true,
  });

  const socket = await soblend.connect('session');

  socket.ev.on('messages.upsert', async ({ messages }) => {
    const msg = messages[0];
    if (!msg.message || msg.key.fromMe) return;

    const text = msg.message.conversation || '';
    const from = msg.key.remoteJid;

    // Comando: !ping
    if (text === '!ping') {
      await socket.sendMessage(from, { text: '🏓 Pong!' });
    }

    // Comando: !info
    if (text === '!info') {
      const quality = soblend.getConnectionQuality();
      await socket.sendMessage(from, {
        text: `📊 Bot Info:\n` +
              `Calidad: ${quality}%\n` +
              `Ping: ${soblend.getLastPingTime()}ms`
      });
    }
  });
}

main();

Ejemplo 2: Administrador de Grupo Completo

import { SoblendBaileys, GroupAdminManager } from '@soblend/baileys';

async function main() {
  const soblend = new SoblendBaileys({ printQRInTerminal: true });
  const socket = await soblend.connect('session');
  const groupManager = new GroupAdminManager(socket);

  // Configurar reglas anti-spam y anti-link
  const GROUP_ID = '[email protected]';
  
  groupManager.addRule(GROUP_ID, {
    id: 'no-links',
    type: 'anti-link',
    enabled: true,
    action: 'kick',
    message: '❌ Enlaces prohibidos'
  });

  groupManager.addRule(GROUP_ID, {
    id: 'no-spam',
    type: 'anti-spam',
    enabled: true,
    action: 'mute'
  });

  // Mensaje de bienvenida personalizado
  groupManager.setWelcomeMessage(GROUP_ID, {
    enabled: true,
    text: '¡Hola {user}! 👋\nBienvenido a {group}\n\n📋 Reglas:\n1. No spam\n2. No enlaces\n3. Respeto mutuo',
    buttons: true
  });

  socket.ev.on('messages.upsert', async ({ messages }) => {
    const msg = messages[0];
    if (!msg.message || msg.key.fromMe) return;

    const text = msg.message.conversation || '';
    const from = msg.key.remoteJid;
    const sender = msg.key.participant || msg.key.remoteJid;

    // Verificar reglas
    if (from.endsWith('@g.us')) {
      const allowed = await groupManager.checkRules(from, sender, text);
      if (!allowed) return;  // Mensaje bloqueado por reglas
    }

    // Comando: !admin (mostrar panel)
    if (text === '!admin' && from.endsWith('@g.us')) {
      const isAdmin = await groupManager.isAdmin(from, sender);
      if (isAdmin) {
        await groupManager.sendAdminPanel(from, sender);
      }
    }

    // Comando: !kick @usuario
    if (text.startsWith('!kick') && from.endsWith('@g.us')) {
      const isAdmin = await groupManager.isAdmin(from, sender);
      if (!isAdmin) return;

      const mentioned = msg.message.extendedTextMessage?.contextInfo?.mentionedJid;
      if (mentioned && mentioned.length > 0) {
        await groupManager.removeParticipants(from, mentioned);
        await socket.sendMessage(from, { text: '✅ Usuarios eliminados' });
      }
    }
  });
}

main();

Ejemplo 3: Conexión con Código de Emparejamiento

import { SoblendBaileys, logger } from '@soblend/baileys';

async function main() {
  logger.printBanner();
  logger.printFeatures();
  
  const soblend = new SoblendBaileys({
    printQRInTerminal: false,  // No usar QR
    logLevel: 'debug',
  });

  const socket = await soblend.connect('auth_pairing');

  // Solicitar código de emparejamiento
  const phoneNumber = '5491112345678';  // Tu número con código de país
  
  logger.info(`Solicitando código para ${phoneNumber}...`);
  
  const pairingCode = await soblend.requestPairingCode({
    phoneNumber,
    displayInConsole: true,
    sendToNumber: false,
  });

  logger.success(`Código de emparejamiento: ${pairingCode}`);
  logger.info('Ingresa este código en WhatsApp > Dispositivos vinculados');

  socket.ev.on('connection.update', (update) => {
    const { connection } = update;
    
    if (connection === 'open') {
      logger.success('¡Conectado con código de emparejamiento!');
      
      // Enviar mensaje de confirmación
      socket.sendMessage(`${phoneNumber}@s.whatsapp.net`, {
        text: '✅ ¡Vinculación exitosa! Tu bot está listo.'
      });
    }
  });
}

main();

Ejemplo 4: Bot con Base de Datos y Niveles

import { SoblendBaileys, SoblendStorage } from '@soblend/baileys';

async function main() {
  const storage = new SoblendStorage('./database', true, 'password');
  await storage.initialize();

  const soblend = new SoblendBaileys({ printQRInTerminal: true });
  const socket = await soblend.connect('session');

  socket.ev.on('messages.upsert', async ({ messages }) => {
    const msg = messages[0];
    if (!msg.message || msg.key.fromMe) return;

    const sender = msg.key.participant || msg.key.remoteJid;
    const from = msg.key.remoteJid;

    // Registrar usuario si no existe
    let user = storage.getUser(sender);
    if (!user) {
      await storage.saveUser({
        jid: sender,
        name: msg.pushName || 'Usuario',
        messageCount: 0,
        firstSeen: Date.now(),
        lastSeen: Date.now(),
        isBlocked: false,
        isBanned: false,
        level: 1,
        points: 0
      });
      user = storage.getUser(sender);
    }

    // Incrementar contador y puntos
    await storage.updateUser(sender, {
      messageCount: user.messageCount + 1,
      lastSeen: Date.now()
    });
    await storage.incrementUserLevel(sender, 10);  // +10 puntos por mensaje

    const text = msg.message.conversation || '';

    // Comando: !level
    if (text === '!level') {
      const updatedUser = storage.getUser(sender);
      await socket.sendMessage(from, {
        text: `👤 Tu Perfil:\n` +
              `Nivel: ${updatedUser.level}\n` +
              `Puntos: ${updatedUser.points}\n` +
              `Mensajes: ${updatedUser.messageCount}`
      });
    }

    // Comando: !top
    if (text === '!top') {
      const topUsers = await storage.getTopUsers(5);
      let leaderboard = '🏆 Top 5 Usuarios:\n\n';
      topUsers.forEach((u, i) => {
        leaderboard += `${i + 1}. ${u.name}\n`;
        leaderboard += `   Nivel ${u.level} - ${u.points} puntos\n\n`;
      });
      await socket.sendMessage(from, { text: leaderboard });
    }
  });
}

main();

📘 API Reference

SoblendBaileys

class SoblendBaileys {
  constructor(config: SoblendConfig)
  connect(sessionId: string): Promise<SoblendSocket>
  getConnectionQuality(): number
  getLastPingTime(): number
  getCache(): SmartCache
  getTaskQueue(): TaskQueue
  cleanup(): Promise<void>
}

GroupAdminManager

class GroupAdminManager {
  constructor(socket: SoblendSocket)
  
  // Grupos
  createGroup(name: string, participants: string[]): Promise<any>
  updateGroupName(groupId: string, name: string): Promise<boolean>
  updateGroupDescription(groupId: string, desc: string): Promise<boolean>
  updateGroupSettings(groupId: string, settings: GroupSettings): Promise<boolean>
  
  // Participantes
  addParticipants(groupId: string, participants: string[], sendWelcome?: boolean): Promise<ParticipantAction[]>
  removeParticipants(groupId: string, participants: string[], reason?: string): Promise<ParticipantAction[]>
  promoteParticipants(groupId: string, participants: string[]): Promise<ParticipantAction[]>
  demoteParticipants(groupId: string, participants: string[]): Promise<ParticipantAction[]>
  
  // Silenciamiento
  muteUser(groupId: string, jid: string, duration?: number, reason?: string): void
  unmuteUser(groupId: string, jid: string): void
  isUserMuted(groupId: string, jid: string): boolean
  
  // Reglas
  addRule(groupId: string, rule: GroupRule): void
  removeRule(groupId: string, ruleId: string): void
  toggleRule(groupId: string, ruleId: string, enabled: boolean): void
  checkRules(groupId: string, userId: string, message: string): Promise<boolean>
  
  // Eventos
  registerEventListener(groupId: string, listeners: GroupEventListener): void
  sendAdminPanel(groupId: string, userId: string): Promise<void>
}

🔧 Solución de Problemas

Problema: QR Code no aparece

Solución:

const soblend = new SoblendBaileys({
  printQRInTerminal: true,  // Asegúrate de que esté en true
  logLevel: 'debug'          // Activa logs detallados
});

Problema: Reconexión lenta

Solución:

const soblend = new SoblendBaileys({
  autoReconnect: true,
  reconnectDelay: 1500,      // Reducir delay inicial
  maxReconnectAttempts: 20   // Aumentar intentos
});

Problema: Alto uso de memoria

Solución:

const soblend = new SoblendBaileys({
  enableCache: true,
  cacheMaxSize: 5000,  // Reducir tamaño del caché
});

// Limpiar caché periódicamente
setInterval(() => {
  soblend.getCache().clear();
}, 3600000);  // Cada hora

Problema: Botones no funcionan

Solución: Los botones en @soblend/baileys usan la implementación de GataBot-MD que SÍ funciona:

await socket.sendInteractiveButtons(jid, {
  text: 'Elige una opción',
  footer: 'Powered by Soblend',
  buttons: [
    {
      buttonId: 'id1',
      buttonText: { displayText: 'Opción 1' },
      type: 1
    }
  ]
});

📊 Comparativa de Rendimiento

| Métrica | Baileys Original | @soblend/baileys | Mejora | |---------|------------------|------------------|--------| | Reconexión | ~5-10s | ⚡ 1.5-3s | 70% más rápido | | Uso de RAM | ~150MB | 💚 ~80MB | 47% menos | | CPU en idle | ~5% | 💚 ~1% | 80% menos | | Cache hit rate | N/A | 📈 95%+ | Nuevo | | Mensajes/seg | ~10 | 🚀 ~50+ | 5x más |


🤝 Contribuir

¿Quieres contribuir? ¡Genial! Abre un issue o pull request en GitHub.

📄 Licencia

MIT License - ver archivo LICENSE


Hecho con ❤️ por el equipo de Soblend

GitHubNPM

⭐ Si te gusta este proyecto, dale una estrella en GitHub