Cómo conectar Angular con la API de Gemini

Resumen

Conectar una aplicación Angular con la API de Gemini de Google requiere preparar un service que maneje peticiones, respuestas, contexto e historial. Aprenderás a estructurar el GeminiService, mapear interfaces, configurar seguridad y reemplazar el mock por una integración real con HttpClient.

Cómo se estructura el service de Gemini en Angular

Dentro de la carpeta src/app/services se crea el archivo correspondiente a Gemini, donde lo primero que aparece son las interfaces que reflejan exactamente lo que la API espera y devuelve. Esto es clave: si la estructura no coincide, la petición falla.

La interfaz de petición incluye un array de ContentGemini con dos roles posibles: user o model. Cada contenido es texto, y se acompaña de parámetros como el máximo de tokens, la temperatura y la configuración de seguridad por categoría con su umbral de bloqueo.

La interfaz de respuesta entrega el texto generado por el modelo más metadatos como la cantidad de tokens consumidos. Tener este contrato bien definido evita errores silenciosos al mapear la respuesta hacia la UI.

¿Qué es la temperatura en la API de Gemini? Es el parámetro que regula la creatividad de la respuesta. Con 0 el modelo es más conservador, con 0.7 equilibra precisión y creatividad, y con 1 genera respuestas mucho más libres.

Por qué enviar el historial junto al mensaje a Gemini

Cuando construyes el método para enviar mensajes, no basta con mandar el texto actual. Tienes que enviar también el historial previo, porque sin ese contexto el modelo no tiene memoria y responde solo con base en la última frase recibida.

El flujo del método sendMessage sigue estos pasos:

  • Verifica que la API key exista y no sea el placeholder tu API key de Gemini que trae el template.
  • Construye los headers necesarios para la petición HTTP.
  • Genera un mensaje de sistema que define el comportamiento del asistente.
  • Adjunta el historial previo y el nuevo mensaje en el campo contents.
  • Aplica la configuración de seguridad y los parámetros de generación.

El mensaje de sistema usado en el ejemplo le indica al modelo que actúe como asistente útil y amigable, que responda en español de forma clara, especializado en preguntas generales, programación y tecnología, manteniendo un tono profesional pero cercano. Cambiar este prompt transforma por completo la personalidad del bot, así que vale la pena experimentar.

Cómo configurar la seguridad y manejar errores en la petición

La configuración de seguridad se arma con las categorías recomendadas en la documentación oficial de AI Google Dev. Cada categoría tiene un umbral que va desde no bloquear nada hasta bloquear la mayoría de contenido sensible. Los valores por defecto suelen ser un buen punto de partida si vas a publicar la aplicación.

La petición se realiza con HttpClient.post, esperando un observable de tipo RespuestaGemini. Se envía la URL completa, el cuerpo armado y los headers, y luego se mapea la respuesta para extraer solo el texto que se mostrará en el chat.

El manejo de errores responde según el código HTTP recibido:

  • 400: petición inválida, normalmente por un cuerpo mal formado.
  • 403: la API key no tiene permisos o ha caducado.
  • Otros estados se traducen a mensajes claros en español para el usuario.

¿Cómo sé si mi configuración de Gemini es válida? Implementa un método verificarConfiguracion que devuelva true solo si existen la API key y la URL, y si la API key no coincide con el valor mock del template.

Cómo convertir el historial del chat al formato de Gemini

La aplicación maneja sus mensajes en un modelo propio, en español y con campos pensados para los componentes Angular. Gemini, en cambio, espera un formato distinto con roles user o model y un array parts con el texto.

Para salvar esa diferencia se usa un método helper llamado convertirHistorialAGemini. Recorre los mensajes locales y, si el emisor es el usuario, asigna el rol user; en caso contrario, asigna model. El campo parts recibe el contenido del mensaje. El método retorna el historial completo ya convertido, listo para enviarse.

Esta separación entre el modelo interno y el modelo que espera la API es una buena práctica: protege tu front-end de cambios futuros en la estructura de Gemini.

Cómo reemplazar el mock en el ChatService por la integración real

Una vez que el GeminiService está completo, toca modificar el ChatService, que era quien manipulaba los mensajes con datos simulados. El proceso es similar al que se hizo con Firestore: borrar el mock, descomentar la importación del service real y dejar que los errores del compilador guíen los cambios.

Los puntos donde se sustituye el mock son:

  1. La conversión del historial: se toman los últimos seis mensajes actuales y se pasan por el helper convertirHistorialAGemini.
  2. La respuesta del asistente: se elimina la respuesta simulada y se invoca sendMessage con el contenido y el historial reales.
  3. La verificación de chatListo: combina verificarConfiguracion con el estado de autenticación del usuario.

Solo cuando el usuario está autenticado y Gemini está correctamente configurado, el flag chatListo se vuelve true y se habilita el envío de mensajes.

Cómo probar la integración y verificar la persistencia en Firestore

Para probar la app abres la terminal, ejecutas npm start y entras a localhost:4200. Tras loguearte, envías un mensaje como Estoy hablando con Gemini y el modelo responde identificándose como un modelo de lenguaje grande entrenado por Google, ofreciendo ayuda en conocimiento general, programación y tecnología, justo como lo definiste en el prompt de sistema.

Si cierras sesión y vuelves a entrar, los mensajes siguen ahí porque se guardaron en Firestore. Al revisar la base de datos verás cada mensaje con asteriscos y saltos de línea que el HTML del front-end interpreta correctamente. Como el orden en Firestore no siempre llega ordenado, el sorting se aplica en el cliente.

Con esto quedan operativos los cuatro services del proyecto: autenticación, chat, Firestore y Gemini. ¿Qué prompt de sistema probarías tú para darle una personalidad distinta al asistente?