Integraciones
Queria esta disenada para ser integrada dentro de aplicaciones propietarias. Esta guia ilustra los modos de integracion disponibles, desde el widget incrustable a la comunicacion server-to-server.
Widget incrustable
El modo mas rapido para anadir Queria a un sitio web o portal empresarial.
Instalacion basica
Anade el siguiente codigo HTML antes del cierre de </body>:
<script src="https://cdn.queria.pro/widget.js"></script>
<script>
Queria.init({
apiKey: 'qk_live_abc123def456ghi789jkl012',
theme: 'light',
position: 'bottom-right',
language: 'es'
});
</script>Opciones de configuracion
| Opcion | Tipo | Default | Descripcion |
|---|---|---|---|
apiKey | string | - | API Key con restriccion de dominio (obligatorio) |
theme | string | light | Tema: light, dark, auto |
position | string | bottom-right | Posicion: bottom-right, bottom-left |
language | string | it | Idioma interfaz: it, en |
primaryColor | string | #2563eb | Color primario (hex) |
title | string | Asistente IA | Titulo mostrado en el header |
placeholder | string | Escribe una pregunta... | Placeholder del campo de entrada |
topicId | string | - | Limita la busqueda a una categoria especifica |
width | number | 400 | Ancho del widget en pixeles |
height | number | 600 | Alto del widget en pixeles |
Personalizacion avanzada
<script>
Queria.init({
apiKey: 'qk_live_abc123def456ghi789jkl012',
theme: 'dark',
position: 'bottom-right',
primaryColor: '#059669',
title: 'Soporte Documental',
placeholder: 'Busca en los documentos empresariales...',
topicId: 'topic_contratos',
onReady: function() {
console.log('Widget Queria cargado');
},
onMessage: function(message) {
// Callback por cada mensaje recibido
analytics.track('queria_response', { query: message.query });
}
});
</script>Control programatico
// Abrir el widget
Queria.open();
// Cerrar el widget
Queria.close();
// Enviar un mensaje programaticamente
Queria.send('Cual es la politica de devolucion?');
// Destruir la instancia
Queria.destroy();Integracion REST API
Para integraciones mas profundas, usa directamente la REST API con autenticacion server-to-server.
Arquitectura recomendada
+-----------------+ +------------------+ +-----------------+
| Tu App |---->| Tu Backend |---->| Queria API |
| (Frontend) | | (Server) | | |
+-----------------+ +------------------+ +-----------------+La API Key debe residir exclusivamente en tu backend. El frontend de tu aplicacion comunica con tu servidor, que a su vez reenvia las peticiones a Queria.
Ejemplo Node.js
const express = require('express');
const app = express();
const QUERIA_API_KEY = process.env.QUERIA_API_KEY; // qk_live_abc123...
const QUERIA_BASE_URL = 'https://api.queria.pro';
app.post('/api/ask', async (req, res) => {
const { question, sessionId } = req.body;
const response = await fetch(`${QUERIA_BASE_URL}/api/public/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': QUERIA_API_KEY
},
body: JSON.stringify({
message: question,
sessionId: sessionId
})
});
const data = await response.json();
res.json({
answer: data.data.response,
sources: data.data.sources
});
});Ejemplo Python
import requests
import os
QUERIA_API_KEY = os.environ['QUERIA_API_KEY']
QUERIA_BASE_URL = 'https://api.queria.pro'
def ask_queria(question: str, session_id: str = None) -> dict:
response = requests.post(
f'{QUERIA_BASE_URL}/api/public/chat',
headers={
'Content-Type': 'application/json',
'X-API-Key': QUERIA_API_KEY
},
json={
'message': question,
'sessionId': session_id
}
)
response.raise_for_status()
result = response.json()
return {
'answer': result['data']['response'],
'sources': result['data']['sources']
}Casos de uso
Integracion CRM
Incrusta la busqueda documental en tu CRM para permitir que los operadores encuentren contratos, ofertas y documentacion de cliente directamente desde la interfaz de gestion.
// Busca documentos relativos a un cliente especifico
const results = await fetch(`${QUERIA_BASE_URL}/api/public/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': QUERIA_API_KEY
},
body: JSON.stringify({
message: `Encuentra los contratos activos para el cliente ${customerName}`,
sessionId: `crm_${customerId}`
})
});Integracion ERP
Conecta los documentos financieros (facturas, pedidos, albaranes) para permitir busquedas inteligentes sobre los datos contables y de almacen.
Portal empresarial
Anade un asistente IA a la intranet empresarial para la consulta del knowledge base interno: manuales, procedimientos operativos, politicas HR.
Soporte al cliente
Automatiza las respuestas a las preguntas frecuentes con citas precisas de los documentos oficiales, reduciendo los tiempos de respuesta y mejorando la calidad del soporte.
Autenticacion para integraciones
| Escenario | Metodo | Notas |
|---|---|---|
| Widget en sitio publico | API Key + restriccion de dominio | El dominio debe coincidir |
| Backend-to-backend | API Key | Conserva la key en el servidor |
| App con login de usuario | JWT | Cada usuario tiene su propio token |
| App movil | JWT + refresh token | Gestiona el refresh automatico |
Best practice
Gestion de errores
Implementa una estrategia de retry con backoff exponencial para gestionar errores transitorios:
async function queriaRequest(payload, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(`${QUERIA_BASE_URL}/api/public/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': QUERIA_API_KEY
},
body: JSON.stringify(payload)
});
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 5;
await sleep(retryAfter * 1000);
continue;
}
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
if (attempt === maxRetries - 1) throw error;
await sleep(Math.pow(2, attempt) * 1000);
}
}
}Gestion del rate limit
Monitoriza las cabeceras X-RateLimit-Remaining y reduce la velocidad de las peticiones cuando el presupuesto se acerca a cero. Para cargas elevadas, contacta al soporte para limites personalizados.
Streaming para respuestas en tiempo real
Para las interfaces de usuario interactivas, usa siempre el endpoint streaming (/api/public/chat/stream) para mostrar la respuesta progresivamente, mejorando la percepcion de reactividad.
Caching
Implementa una cache del lado de la aplicacion para las queries repetidas. Queria aplica ya un caching interno, pero una cache local reduce la latencia y el consumo de quota:
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutos
async function cachedQuery(question) {
const key = question.toLowerCase().trim();
const cached = cache.get(key);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const result = await queriaRequest({ message: question });
cache.set(key, { data: result, timestamp: Date.now() });
return result;
}