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¶
- Indexa tu contenido (entradas, páginas, FAQs, base de conocimiento y productos WooCommerce) en un archivo
index.jsonservido desdewp-content/uploads/convoca-assistant/. - 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.
- 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¶
- Sube la carpeta
convoca-assistanta/wp-content/plugins/. - Activa el plugin desde el menú Plugins.
- Ve a Convoca Assistant → Ajustes para configurar fuentes y apariencia.
- 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.

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:
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(diccionarioté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_wordsy 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ícitamenteCONVOCA_ASSISTANT_TRUSTED_PROXY(para entornos tras proxy de confianza). - Guards
ABSPATHen 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.