Añadir Kaleidr Chat a un mapa de Google
Al terminar esta guía tendrás una página con un mapa de Google y un panel de chat integrado. El visitante hace una pregunta, la respuesta se transmite al panel y los lugares citados aparecen como marcadores en el mapa, mientras la cámara se mueve para mostrarlos. Funciona en todos los planes, incluso Free, con una clave publicable. Las preguntas gastan créditos de IA de tu organización.
Tu clave de Google Maps y tu clave de Kaleidr son distintas. Google cobra el mapa y Kaleidr cobra las preguntas. Kaleidr nunca recibe tu clave de Google.
Antes de empezar
- Una clave publicable de Kaleidr (
kld_pk_live_…) de kaleidr.com/api-keys. Las claves nuevas incluyenai, el permiso necesario para Chat. Consulta Obtener una clave API. - El origen de tu página entre los orígenes permitidos de la clave, si hay restricciones; en local, por ejemplo
http://localhost:8080. - Una clave de Google Maps JavaScript API de tu proyecto de Google Cloud, con la API habilitada y el origen autorizado por las restricciones de referentes de Google.
- Un servidor HTTP como
npx serveopython -m http.server 8080. Un archivo abierto desde el disco no funciona. - Si el sitio aplica una Política de seguridad de contenido, autoriza los hosts de Política de seguridad de contenido, además de los que requiere Google Maps.
Google Maps JavaScript API siempre define el objeto global google.maps, por lo que no necesitas ningún paso adicional para exponer la biblioteca al bundle de chat.
Paso 1: Disponer el mapa y la capa de chat
Coloca el mapa y el destino de montaje del chat dentro de un mismo contenedor posicionado. La capa de chat se superpone al mapa y deja pasar los eventos de puntero.
<div id="mapHost" style="position:relative; height:520px">
<div id="map" style="position:relative; height:100%; z-index:0"></div>
<div id="chat" style="position:absolute; inset:0; z-index:1; pointer-events:none"></div>
</div>
El elemento del mapa ocupa el contenedor con height:100%. position:relative junto con z-index:0 mantiene las capas de Google dentro del elemento del mapa, por debajo del chat.
Resultado esperado: todavía nada; solo un bloque vacío de 520 px de alto.
Paso 3: Cargar kaleidr.js
Carga el loader de Kaleidr mediante una etiqueta script normal, para que Kaleidr esté disponible cuando se ejecute el callback del mapa.
<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
Resultado esperado: la página no cambia. En la consola, Kaleidr.version devuelve una cadena de versión.
Paso 3: Definir la función callback que crea el mapa y monta el panel
El script de Google Maps llama a la función que indiques una vez cargado. Crea el mapa y monta el panel dentro de esa función, porque google.maps no existe antes de su ejecución.
<script>
function initMap() {
const map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 51.5, lng: -0.12 },
zoom: 11,
});
Kaleidr.mount('#chat', {
product: 'chat',
publishableKey: 'kld_pk_live_…',
map,
contained: true,
});
}
</script>
Resultado esperado: todavía nada. La función está definida, pero no se ha llamado.
Paso 4: Cargar el script de Google Maps después de definir el callback
Coloca la etiqueta script de Google debajo del script que define initMap.
<script async
src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_KEY&callback=initMap&loading=async&v=weekly"></script>
El orden importa. El script de Google es async, por lo que el navegador lo ejecuta al terminar de descargarlo y llama enseguida a initMap. Si la etiqueta aparece primero, puede acabar antes de que el navegador haya definido initMap, provocando el error de Google initMap no es una función («initMap is not a function»). Definir primero el callback elimina esa condición de carrera.
Resultado esperado: un mapa de Google del centro de Londres con una barra «Ask Kaleidr» en la esquina superior izquierda.
La página completa
Guarda el archivo como index.html, sustituye las dos claves y sirve la carpeta por HTTP.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Kaleidr Chat on Google Maps</title>
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
#mapHost { position: relative; height: 100vh; }
#map { position: relative; height: 100%; z-index: 0; }
#chat { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
</style>
</head>
<body>
<div id="mapHost">
<div id="map"></div>
<div id="chat"></div>
</div>
<!-- 1. The Kaleidr loader. -->
<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<!-- 2. The callback, defined before the Google script can call it. -->
<script>
function initMap() {
const map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 51.5, lng: -0.12 },
zoom: 11,
});
Kaleidr.mount('#chat', {
product: 'chat',
publishableKey: 'kld_pk_live_…',
map,
contained: true,
});
}
</script>
<!-- 3. The Google Maps script, last. -->
<script async
src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_KEY&callback=initMap&loading=async&v=weekly"></script>
</body>
</html>
Cómo funciona
| Visitante | Panel | Tu mapa de Google |
|---|---|---|
| Envía una pregunta | Abre una ventana de chat y transmite la respuesta como texto. | Aún no ocurre nada. |
| Espera | Muestra una tarjeta por cada lugar de la respuesta. | Aparecen marcadores conforme se localizan. Un lugar: el mapa se desplaza hasta él y cambia el zoom. Varios: el mapa los encuadra con 56 px de margen. |
| Hace clic en un marcador o resultado | Abre una ficha de lugar con descripción, fotos y herramienta de indicaciones. | Hacer clic en un resultado lleva el mapa al lugar. |
| Solicita indicaciones | Muestra la distancia y la duración del trayecto. | Se dibuja y encuadra la ruta. |
| Hace otra pregunta | Continúa la misma conversación. | Se añaden marcadores nuevos y se conservan los anteriores. |
| Cierra el chat | Vuelve a la barra de entrada y termina la conversación. | Se eliminan marcadores y ruta. |
Detalles propios de Google Maps:
- Los marcadores son elementos HTML dibujados mediante un overlay personalizado. No requieren Map ID. Si cargas la biblioteca
markerde Google, el bundle de chat usa marcadores avanzados y Google exige configurar unmapId. - El movimiento a un lugar consiste en desplazar el mapa y luego cambiar el zoom, no en un único vuelo animado.
- El ajuste usa 56 px de margen por cada lado. No tiene en cuenta el panel de chat, por lo que un resultado puede quedar oculto detrás de él. El visitante puede mover el mapa o minimizar el panel.
- La ruta consta de dos polilíneas: una base blanca bajo una línea de color.
- El mapa se trata como plano y orientado al norte; el asistente no cambia rumbo ni inclinación.
- La sesión se renueva en segundo plano mientras el panel esté montado. No gestionas tokens.
Comprobar que funciona
En la página
- La barra Ask Kaleidr aparece sobre la esquina superior izquierda del mapa.
- Escribe
Show me three museums in Londony pulsa Enter. Aparece texto progresivamente, se añaden tres marcadores y el mapa se ajusta para mostrarlos.
En la consola
- Ningún error o advertencia contiene
[kaleidr, ni hay errores de Google Maps API.
En la pestaña Network
| Solicitud | Resultado esperado |
|---|---|
GET https://cdn.kaleidr.com/embed/v1/kaleidr.js | 200 |
GET https://cdn.kaleidr.com/embed/v1/chat.js | 200 |
POST https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions | 200, con cuerpo JSON como el ejemplo siguiente |
POST https://api.kaleidr.com/inference-api/b2b/v1/chat/control/stream (después de preguntar) | 200, content-type: text/event-stream |
{ "session_token": "kld_sess_live_ …", "expires_in": 900, "product": "chat" }
Si no funciona
El SDK escribe un mensaje breve y no repite el motivo del servidor. Si falla una solicitud, ábrela en Network y lee su respuesta JSON. En un 403 o 404 el código aparece en detail; en un 429, en error, acompañado de una frase en detail.
| Síntoma | Causa | Solución |
|---|---|---|
No hay mapa; Google dice initMap is not a function | El script de Google se ejecutó antes de definir initMap. | Coloca el script de Google debajo del callback, como en el paso 4. |
| No hay mapa o aparece gris con un mensaje de Google | Problema con la clave de Google: API desactivada, facturación no configurada u origen no autorizado. | Corrígelo en Google Cloud. No depende de Kaleidr. |
Kaleidr is not defined dentro de initMap | kaleidr.js tiene async o defer, o está después del script de Google. | Carga kaleidr.js primero, con una etiqueta script normal. |
El mapa aparece, pero no el panel; error CORS en …/sdk/sessions y error [kaleidr:chat] | Clave de Kaleidr desconocida o revocada, u origen no autorizado; el navegador oculta la respuesta sin cabeceras CORS. | Comprueba la clave y añade el origen exacto (protocolo y puerto) en kaleidr.com/api-keys. |
[kaleidr:chat] kaleidr session exchange failed (403) | Clave válida, pero el campo detail puede ser insufficient_scope (sin ai), product_not_allowed u tier_capability_not_allowed. | Usa una clave con ai que permita el producto chat. |
[kaleidr:chat] Kaleidr: a server key (kld_sk_…) must never be used in the browser … | Se pasó una clave de servidor y no se efectuó ninguna solicitud. | Usa una clave publicable (kld_pk_live_…) y revoca la del servidor si se expuso. |
[kaleidr:chat] [kaleidr] failed to load https://cdn.kaleidr.com/embed/v1/chat.js | El bundle fue bloqueado, generalmente por la Política de seguridad de contenido o un bloqueador de anuncios. | Autoriza https://cdn.kaleidr.com en script-src. |
| El panel aparece en la esquina de la ventana y no sobre el mapa | Falta contained o #chat no tiene posición. | Añade contained: true y los estilos del paso 1. |
| El panel queda detrás del mapa | El elemento de mapa carece de su propio contexto de apilamiento. | Conserva z-index:0 en #map y z-index:1 en #chat. |
| El panel responde, pero no aparecen marcadores ni se mueve el mapa | El objeto indicado en map no es la instancia google.maps.Map, sino un elemento o wrapper. | Pasa la instancia devuelta por new google.maps.Map(…). Consulta Mapas compatibles. |
| El panel responde y se mueve el mapa, pero no hay marcadores | Se cargó la biblioteca marker sin mapId. | Añade mapId a las opciones o no cargues la biblioteca marker. |
| El panel siempre muestra "Sorry — that didn't go through. Please try again." | Sesión inválida tras revocar la clave o cambiar los orígenes permitidos. | Comprueba la clave y recarga la página. |
| El panel muestra "You've reached your usage limit for now." | 429: créditos de IA agotados o límite de frecuencia de la clave alcanzado; todos los visitantes comparten el límite. | Consulta Cuotas y límites de frecuencia. |
Encontrarás más síntomas en Solución de problemas.
Limitaciones
- Tu página no recibe callbacks ni eventos del panel; no puedes reaccionar desde código a preguntas, respuestas o clics en marcadores.
- El asistente no ve tus overlays, tus marcadores ni la zona visible; solo envía el nivel de zoom con cada pregunta.
- No puedes proporcionar instrucciones ni datos propios al asistente mediante el panel.
- Idioma de respuesta, título y texto de entrada son opciones de montaje (
lang,title,placeholder): consulta Referencia de Chat. Las demás etiquetas están en inglés. - En Google Maps, el ajuste de vista no evita el panel de chat.
handle.setCamera()no tiene efecto en un Chat montado y genera una advertencia. Mueve la cámara mediante la API de Google.- En una aplicación de una sola página, llama a
handle.destroy()al quitar la vista y vuelve a montar cuando regrese.
La lista completa está en Capacidades y límites.
Próximos pasos
- Temas y disposición: adapta el panel al sitio.
- Mapas compatibles: acciones disponibles en Google Maps.
- Referencia de Chat: opciones, objeto de control y errores.
- Lista de verificación de producción: qué comprobar antes de publicar.