Saltar a contenido

Convoca Assistant

Guía para administradores del ecosistema Convoca. Todo lo documentado aquí refleja el comportamiento de la versión 0.2.2 del plugin.

1. Introducción

Convoca Assistant convierte el contenido de tu WordPress en un asistente conversacional que responde preguntas de tus visitantes. Sin IA, sin APIs externas, sin cloud: 100 % local. Tus datos nunca salen de tu servidor — compatible GDPR.

Cómo funciona

  1. Indexa tu contenido (entradas, páginas, FAQs, base de conocimiento y productos WooCommerce) en un archivo index.json servido desde wp-content/uploads/convoca-assistant/.
  2. Busca en el navegador con Fuse.js (búsqueda difusa con tolerancia a errores tipográficos y acentos) y, como respaldo, en el servidor con distancia de Levenshtein.
  3. Responde desde el widget flotante. Si el mejor resultado es una fuente prioritaria (FAQ o Wiki) con suficiente confianza, muestra la respuesta directa en el chat; si no, lista los resultados como fuentes clicables.

Capacidades

  • ✅ Búsqueda difusa con Fuse.js (tolerancia a errores y acentos en español)
  • ✅ Expansión semántica: sinónimos, n-gramas (unigramas/bigramas/trigramas) y lematización ligera en español
  • Exact-title priority: un match exacto de título siempre gana (no lo tapa la conectividad del grafo)
  • Prioridad de respuesta configurable: FAQ y Wiki responden primero; el resto solo cuando no hay match claro
  • ✅ Grafo de conocimiento: contenido relacionado como chips clicables
  • ✅ Memoria de sesión en el navegador (últimas consultas)
  • ✅ 5 proveedores de contenido: Entradas, Páginas, FAQ, Base de Conocimiento y WooCommerce
  • ✅ Widget flotante personalizable + shortcode para incrustar el chat
  • ✅ Analíticas de uso y preguntas sin respuesta
  • ✅ API REST con 7 endpoints
  • ✅ Exportar/importar conocimiento y configuración

2. Instalación

  1. Sube la carpeta convoca-assistant a /wp-content/plugins/.
  2. Activa el plugin desde el menú Plugins.
  3. Ve a Convoca Assistant → Ajustes para configurar fuentes y apariencia.
  4. El índice se regenera automáticamente al activar (y de nuevo cuando cambia el contenido). El widget flotante aparece solo en la esquina inferior derecha.

Requisitos

Requisito Valor
PHP 8.1 o superior
WordPress 6.4 o superior (probado hasta 7.1)
Dependencias externas Ninguna (Fuse.js v7.1.0 incluido)
Convoca Core Opcional (solo para logging centralizado)

3. Panel de administración

El menú Convoca Assistant (icono de chat) tiene 7 subpáginas:

Subpágina Descripción
Dashboard Estadísticas (consultas 30 días, tasa de resolución, sin respuesta, tiempo medio), gráfico por día, top consultas y estado del índice
Conocimiento Gestión de FAQs y artículos de la base de conocimiento
Sinónimos Grupos de sinónimos y lista de stop words
Analytics Estadísticas detalladas de uso
Sin respuesta Consultas que no obtuvieron respuesta
Ajustes Widget, búsqueda, fuentes y prioridad, privacidad y mantenimiento
Herramientas Exportar/importar JSON, regenerar índice, limpiar logs y debug

Dashboard

Muestra tarjetas de resumen, un gráfico de consultas por día, las consultas más frecuentes y el estado del índice (generado / no generado, entradas, tamaño, última generación y hash). Incluye el botón Regenerar índice ahora.

Dashboard de Convoca Assistant

4. Widget flotante y shortcode

Widget flotante

Aparece automáticamente en todas las páginas. Su DOM se construye desde JavaScript (buildWidgetDOM()), por lo que funciona incluso en temas que no ejecutan wp_footer.

Elemento Descripción
💬 Botón flotante Abre/cierra el chat (posición configurable: abajo derecha o izquierda)
Campo de texto Escribe la pregunta y pulsa Enter o el botón ►
Respuesta directa Si el mejor resultado es prioritario y supera el umbral de confianza, se muestra como respuesta en el chat
Chips de contenido relacionado Sugerencias clicables basadas en el grafo de conocimiento
👍/👎 Feedback por respuesta
📋 Historial de la sesión actual

Shortcode

Además del widget flotante, puedes incrustar el chat dentro de cualquier página o entrada:

[convoca_assistant]

El shortcode renderiza un contenedor convoca-assistant-inline en el lugar donde lo coloques. En modo mantenimiento, tanto el widget como el shortcode muestran el mensaje de mantenimiento configurado.

Personalización CSS

Clases CSS disponibles para personalizar el aspecto:

  • .convoca-assistant-widget — contenedor del widget
  • .convoca-assistant-toggle — botón flotante
  • .convoca-chat-container — ventana de chat
  • .convoca-message — mensaje individual
  • .convoca-chat-suggestions — chips de contenido relacionado

El widget respeta el modo oscuro del sistema y el color primario configurado (variable CSS --convoca-primary).

5. Fuentes de contenido (proveedores)

El plugin incluye 5 proveedores built-in. Cada uno puede activarse/desactivarse desde Ajustes → Fuentes y prioridad de respuesta.

Proveedor CPT / origen Peso por defecto Activo por defecto
Entradas post 1.0
Páginas page 1.0
FAQ convoca_faq 2.0
Base de Conocimiento convoca_kb 1.5
Productos WooCommerce product 0.8 ❌ (requiere WooCommerce activo)

Los proveedores son clases PHP que implementan Knowledge_Provider_Interface (véase la sección 14). WooCommerce añade precio y SKU a las entradas indexadas cuando está disponible.

6. Motor de búsqueda y prioridad de respuesta

La búsqueda se ejecuta por defecto en el cliente (Fuse.js), con fallback en el servidor (Levenshtein) para navegadores sin JavaScript, crawlers y llamadas REST. El modo es configurable: cliente, servidor o ambos.

Normalización

Tanto la consulta como los campos de cada entrada se normalizan antes de puntuar: minúsculas, sin acentos ni signos (remove_accents + limpieza de puntuación). Esto hace que «Cómo hacerse socio», «como hacerse socio» y «¿cómo hacerse socio?» puntúen igual.

Score compuesto

La puntuación (0–1) es idéntica en cliente y servidor y combina 8 componentes:

Componente Peso Descripción
Fuzzy (Fuse.js / Levenshtein) 0.45 Coincidencia difusa sobre el título
Grafo (conectividad) 0.10 Cuánto de conectada está la entrada en el grafo
Exact match 0.15 Bonus si el título/keywords/contenido contiene la consulta
Sinónimos 0.10 Bonus si aparecen sinónimos expandidos
Stemming español 0.05 Bonus por raíces coincidentes
Cobertura 0.05 Fracción de palabras de la consulta presentes
Recencia 0.05 Bonus por contenido reciente (< 30/90/365 días)
Peso 0.05 Peso individual o por tipo de contenido

El resultado se escala con (0.5 + peso/20) y se limita a 1.0. La conectividad del grafo ya no domina el ranking: el contenido (fuzzy + exact) pesa mucho más que el grafo.

Exact-title priority

Si el título normalizado de una entrada coincide exactamente con la consulta (o una contiene a la otra, cuando la consulta tiene ≥ 6 caracteres), el score de esa entrada se fuerza a mínimo 0.90. Es la respuesta directa, independientemente de su conectividad en el grafo.

Prioridad de respuesta (FAQ / Wiki primero)

Los tipos prioritarios (por defecto convoca_faq y convoca_kb) reciben un boost multiplicando su score por priority_boost (por defecto 1.35).

En el widget, si el mejor resultado es de un tipo prioritario y su score es ≥ 0.55 (umbral directThreshold del cliente), el chat muestra la respuesta directa (extracto o contenido truncado) en lugar de una lista de fuentes. Si no se alcanza ese umbral, se listan los resultados como fuentes clicables.

Longitud de respuesta

La respuesta directa se trunca a answer_max_length caracteres (por defecto 600), usando el extracto si existe y, si no, el contenido.

7. Índice, grafo y clustering

Índice (index.json)

Se genera en wp-content/uploads/convoca-assistant/ (sin compresión gzip, protegido con .htaccess). Contiene version, schema, generated, locale, site_name, total, hash, entries, synonyms, stop_words y config.

Cada entrada incluye: id, type, title, content (truncado a index_max_content, por defecto 5000), excerpt, url, thumbnail, categories, tags, keywords, weight, date y modified (más price y sku en productos).

Regeneración automática

  • Al activar el plugin.
  • Vía cron (every_5_minutes) si el índice está marcado como «sucio».
  • Al guardar/eliminar/papelera de contenido, cambiar metadatos relevantes (_convoca_assistant_keywords, _convoca_assistant_weight, _convoca_assistant_exclude) o cambiar taxonomías, con debounce de 30 s.
  • Manualmente desde Dashboard o Herramientas.

Grafo de conocimiento (graph.json)

Relaciona entradas por categoría/tag compartidos y por tipo. Tipos de arista: same_category (0.3), same_tag (0.4), same_faq_category (0.3), same_kb_category (0.3), same_product_category (0.3), same_product_tag (0.4) y same_type_* (0.15, fallback). El grafo alimenta los chips de contenido relacionado y el componente de grafo del score.

Clustering

Los resultados se agrupan por tema en el cliente para evitar duplicados en la respuesta.

8. FAQs y Base de Conocimiento

El plugin registra dos tipos de contenido y dos taxonomías:

Tipo Slug Descripción
CPT convoca_faq faq Preguntas frecuentes
CPT convoca_kb knowledge-base Artículos de la base de conocimiento
Taxonomía convoca_faq_cat faq-category Categorías de FAQ
Taxonomía convoca_kb_cat kb-category Categorías de KB

Ambos CPTs son públicos y visibles en REST. Se gestionan desde Convoca Assistant → Conocimiento o desde el menú de entradas.

Categorías de FAQ en el índice

El proveedor de FAQ usa convoca_faq_cat como categorías de la entrada al construir el índice y las relaciones del grafo. Esto es necesario porque el proveedor base lee la taxonomía estándar category, que en las FAQs está vacía: sin este override, el clustering y el grafo de FAQs quedarían vacíos.

Metadatos por entrada

En las pantallas de edición de FAQ, KB, entradas y páginas hay un metabox Convoca Assistant con tres campos:

Campo Meta key Descripción
Palabras clave extra _convoca_assistant_keywords Separadas por coma; mejoran la búsqueda
Peso (0–10) _convoca_assistant_weight Peso individual; 0 = usar el peso del tipo
Excluir del índice _convoca_assistant_exclude Marca la entrada para no indexarla

9. Sinónimos y stop words

Los sinónimos permiten que el asistente entienda distintas formas de preguntar lo mismo. Se gestionan desde Convoca Assistant → Sinónimos.

  • Los sinónimos se guardan en la opción convoca_assistant_synonyms (diccionario término → [sinónimos]). La instalación no incluye grupos por defecto: se empieza vacío y el administrador añade los suyos.
  • Las stop words (palabras ignoradas al tokenizar) se guardan en convoca_assistant_stop_words y tienen una lista por defecto en español (artículos, pronombres, preposiciones, etc.).
  • Al cambiar sinónimos o stop words, el índice se marca como «sucio» y se regenera en el siguiente ciclo de cron.

10. Analíticas y preguntas sin respuesta

Las interacciones se registran en la tabla {prefijo}convoca_assistant_log (si el logging está activado). Cada registro guarda consulta, id de respuesta, si hubo respuesta, score, si se hizo clic en la fuente, tiempo de respuesta y URL de la página.

  • Dashboard / Analytics: total de consultas, encontradas, no encontradas, tasa de resolución, score medio, tiempo medio, top consultas y serie diaria (ventana configurable por días).
  • Sin respuesta: consultas sin respuesta agrupadas por frecuencia y última aparición. Útiles para decidir qué FAQs crear.
  • Retención: los logs antiguos se eliminan según log_retention_days (por defecto 90 días).

11. API REST

Todos los endpoints viven bajo el namespace convoca/v1 y el prefijo /assistant/. Son 7 endpoints:

Método Endpoint Acceso Descripción
GET /assistant/index Público (CORS) Sirve el índice completo (caché 5 min)
POST /assistant/search Público (rate-limit) Búsqueda en servidor
POST /assistant/log Público (rate-limit) Registrar una interacción
GET /assistant/stats Admin (manage_options) Estadísticas (?days=30)
GET /assistant/unanswered Admin Preguntas sin respuesta (?limit=50)
POST /assistant/rebuild-index Admin Regenerar el índice
POST /assistant/clear-logs Admin Vaciar la tabla de logs

Ejemplo de búsqueda

curl -X POST https://tusitio.com/wp-json/convoca/v1/assistant/search \
  -H "Content-Type: application/json" \
  -d '{"query": "cómo hacerse socio"}'

Respuesta:

{
  "query": "cómo hacerse socio",
  "results": [
    { "entry": { "id": 42, "title": "…", "url": "…" }, "score": 0.91 }
  ],
  "total": 1,
  "time_ms": 12.45
}

Ejemplo de registro de interacción

{
  "query": "cómo hacerse socio",
  "response_id": 42,
  "response_found": true,
  "score": 0.91,
  "clicked": false,
  "time_ms": 5,
  "page_url": "https://tusitio.com/"
}

12. Exportar / importar

Desde Convoca Assistant → Herramientas:

  • Exportar conocimiento — JSON con FAQs, artículos KB, sinónimos y stop words.
  • Exportar configuración — JSON con todos los ajustes del plugin.

La importación valida el archivo (máx. 5 MB, solo .json, con metadato _meta.type) antes de aplicar los datos y marca el índice como «sucio» para regenerarlo.

13. Privacidad y seguridad

Privacidad

  • Logging opcional (log_enabled), desactivable por completo.
  • Anonimización (log_anonymous): el User-Agent se guarda como hash SHA-256, no en claro.
  • Sin cookies de terceros: la memoria de sesión vive en el navegador (localStorage) y no llega al servidor.
  • Retención configurable de logs (por defecto 90 días).

Seguridad

  • No indexa contenido protegido por contraseña: todos los proveedores consultan con has_password => false.
  • Rate-limit por IP real (REMOTE_ADDR): 60 peticiones/minuto por IP en los endpoints públicos. No se confía en cabeceras forjables (X-Forwarded-For, etc.) salvo que definas explícitamente CONVOCA_ASSISTANT_TRUSTED_PROXY (para entornos tras proxy de confianza).
  • Guards ABSPATH en todos los archivos y uso de la Settings API de WordPress con saneado de cada campo.
  • PCP (Plugin Check) con 0 errores.

14. Hooks y filtros (desarrolladores)

La API pública para extender el plugin son los siguientes hooks/filtros:

Hook Tipo Archivo Uso
convoca_assistant/providers filter Provider_Registry.php Registrar proveedores personalizados
convoca_assistant/index_data filter Indexer.php Modificar entradas antes de indexar
convoca_assistant/index_url filter Indexer.php, Cache.php Modificar la URL del índice
convoca_assistant/graph_data filter Graph_Builder.php Añadir aristas al grafo
convoca_assistant/before_index action Indexer.php Antes de regenerar el índice
convoca_assistant/after_index action Indexer.php Tras regenerar el índice
convoca_assistant/before_graph action Graph_Builder.php Antes de construir el grafo
convoca_assistant/after_graph action Graph_Builder.php Tras escribir el grafo
convoca_assistant/before_search action Searcher.php Antes de cada búsqueda en servidor

Añadir un proveedor personalizado

Cualquier plugin puede registrar una fuente de contenido implementando Knowledge_Provider_Interface (métodos get_id, get_name, get_description, is_available, get_default_weight, get_setting_key, get_entries, get_entry_count y get_relations):

<?php
use Convoca\Assistant\Knowledge_Provider_Interface;

add_filter( 'convoca_assistant/providers', function ( $providers ) {
    $providers['mi_fuente'] = new Mi_Proveedor();
    return $providers;
} );

El proveedor aparece automáticamente como fuente activable, participa en la indexación y aporta relaciones al grafo mediante get_relations().

15. Compatibilidad

  • ✅ Temas clásicos y temas FSE (Full Site Editing)
  • ✅ Page builders (Elementor, Divi, Beaver Builder)
  • ✅ Plugins de caché (el índice se sirve por REST, fuera de la caché de página)
  • ✅ WooCommerce (fuente opcional de productos)
  • ✅ GDPR: búsqueda en cliente, logging anónimo y opcional, sin datos a terceros

16. Changelog

Consulta CHANGELOG.md en el repositorio para el historial completo. Destacados:

  • 0.2.2 — Seguridad: no indexa contenido con contraseña; rate-limit por IP real (REMOTE_ADDR); PCP 0 errores.
  • 0.2.1 — Widget DOM desde JavaScript (compatibilidad con temas sin wp_footer); fix de orden de carga JS.
  • 0.2.0 — Saludos automáticos, chips de contenido relacionado, sinónimos expandidos, fix XSS en enlaces markdown, eliminación de compresión gzip.
  • 0.1.0 — Lanzamiento inicial.