Integra agentes de Gemini Enterprise con Google Workspace

1. Antes de comenzar

83e1c1629d14fb31.png

¿Qué es Gemini Enterprise?

Gemini Enterprise es una plataforma agente avanzada que lleva lo mejor de la IA de Google a cada empleado y a cada flujo de trabajo. Permite a los equipos descubrir, crear, compartir y ejecutar agentes de IA en un entorno seguro.

  • Acceso a modelos avanzados: Los usuarios obtienen acceso inmediato a la IA multimodal más potente de Google, incluido Gemini, para abordar desafíos comerciales complejos.
  • Utiliza agentes especializados: El paquete incluye agentes de Google listos para usar para la investigación, la programación y la toma de notas, lo que proporciona valor inmediato.
  • Capacita a todos los empleados: Las opciones con código y sin código permiten que el personal de todos los departamentos cree y administre sus propios agentes personalizados para la automatización del flujo de trabajo.
  • Fundamenta los agentes en los datos: Los agentes se pueden conectar de forma segura a los datos internos de la empresa y a las aplicaciones de terceros para garantizar que sus respuestas sean precisas en el contexto.
  • Administración centralizada: Los administradores pueden visualizar y auditar toda la actividad de los agentes para garantizar que la organización cumpla con los estrictos estándares de seguridad y cumplimiento.
  • Expansión con ecosistemas: La plataforma se integra con una amplia red de aplicaciones de socios y proveedores de servicios para extender la automatización a diferentes sistemas.

127f2ed7d484722c.png

¿Qué es Google Workspace?

Google Workspace es una colección de soluciones de productividad y colaboración basadas en la nube diseñadas para personas, escuelas y empresas:

  • Comunicación: Servicios de correo electrónico profesional (Gmail), videoconferencias (Meet) y mensajería para equipos (Chat).
  • Creación de contenido: Herramientas para escribir documentos (Documentos), crear hojas de cálculo (Hojas de cálculo) y diseñar presentaciones (Presentaciones).
  • Organización: Calendarios compartidos (Calendario) y toma de notas digitales (Keep).
  • Almacenamiento: Espacio centralizado en la nube para guardar y compartir archivos de forma segura (Drive).
  • Administración: Controles administrativos para administrar usuarios y la configuración de seguridad (Consola del administrador de Workspace).

¿Qué tipo de integraciones personalizadas?

Google Workspace y Gemini Enterprise crean un potente circuito de retroalimentación en el que Workspace proporciona datos en tiempo real y contexto de colaboración, mientras que Gemini Enterprise ofrece los modelos, el razonamiento de agentes y la organización necesarios para automatizar flujos de trabajo inteligentes.

  • Conectividad inteligente: Los almacenes de datos, las APIs y los servidores de MCP administrados por Google (personalizados y administrados por Google) permiten que los agentes accedan de forma segura y sin problemas a los datos de Workspace y realicen acciones en nombre de los usuarios.
  • Agentes personalizados: Con diseñadores sin código o frameworks de código profesional, los equipos pueden crear agentes especializados basados en datos y acciones de Workspace controlados por el administrador.
  • Integración nativa: Los complementos de Workspace cierran la brecha entre los sistemas de IA y las aplicaciones como Chat y Gmail, ya sea a través de componentes de IU dedicados o procesos en segundo plano. Esto permite que los agentes se comuniquen con los usuarios exactamente donde se encuentran para brindar asistencia instantánea y contextual.

Al combinar el sólido ecosistema de productividad de Google Workspace con la potencia avanzada de Gemini Enterprise, las organizaciones pueden transformar sus operaciones a través de agentes de IA personalizados y basados en datos que automatizan flujos de trabajo complejos directamente en las herramientas que sus equipos ya usan todos los días.

Requisitos previos

Si quieres seguir todos los pasos en tu propio entorno, necesitarás lo siguiente:

Qué compilarás

En este codelab, compilaremos tres soluciones con agentes de IA de Gemini Enterprise que están estrechamente integrados con Google Workspace. Demostrarán patrones arquitectónicos que se pueden usar para interactuar con datos, acciones y UIs.

Agente personalizado sin código

Este agente permite a los usuarios buscar datos y realizar acciones en Workspace en su lenguaje natural. Se basa en los siguientes elementos:

  • Modelo: Gemini.
  • Datos y acciones: Almacenes de datos de Gemini Enterprise para Google Workspace (Calendario, Gmail, Drive, NotebookLM) y Búsqueda de Google.
  • Herramientas de creación de agentes: Agent Designer de Gemini Enterprise
  • Host del agente: Gemini Enterprise.
  • IU: App web de Gemini Enterprise

90e42539e5959634.png

60e62437ce29a818.png

Agente personalizado con código

Este agente permite a los usuarios buscar datos y realizar acciones en Workspace en su lenguaje natural con herramientas y reglas personalizadas. Se basa en los siguientes elementos:

  • Modelo: Gemini.
  • Datos y acciones: Almacenes de datos de Gemini Enterprise para Google Workspace (Calendario, Gmail, Drive, NotebookLM), Búsqueda de Google, servidor del Protocolo de contexto del modelo (MCP) de Vertex AI Search administrado por Google, función de herramienta personalizada para enviar mensajes de Google Chat (a través de la API de Google Chat).
  • Herramientas de creación de agentes: Kit de desarrollo de agentes (ADK)
  • Host del agente: Vertex AI Agent Engine.
  • IU: App web de Gemini Enterprise

1647ebff031c42e7.png

a8087d2351e77fb4.png

Agente predeterminado como complemento de Google Workspace

Este agente permite a los usuarios buscar datos de Workspace en lenguaje natural dentro del contexto de las IU de las apps de Workspace. Se basa en los siguientes elementos:

  • Modelo: Gemini.
  • Datos: Almacenes de datos de Gemini Enterprise para Google Workspace (Calendario, Gmail, Drive, NotebookLM) y la Búsqueda de Google.
  • Host del agente: Gemini Enterprise.
  • IU: Complemento de Google Workspace para Chat y Gmail (se puede extender fácilmente a Calendario, Drive, Documentos, Hojas de cálculo y Presentaciones).
  • Complemento de Google Workspace: Apps Script, APIs de Gemini Enterprise y Vertex AI, contextual (metadatos del usuario, mensaje de Gmail seleccionado).

c8c63fb3f324fecf.png

d33b8cb50ee251b7.png

Qué aprenderás

  • Son los puntos de integración entre Gemini Enterprise y Google Workspace que habilitan los datos y las acciones.
  • Las opciones sin código y con código profesional para crear agentes personalizados alojados en Gemini Enterprise
  • Las formas en que los usuarios pueden acceder a los agentes desde la app web de Gemini Enterprise y las aplicaciones de Google Workspace

2. Prepárate

Repasa conceptos

App de Gemini Enterprise

Una app de Gemini Enterprise proporciona resultados de búsqueda, acciones y agentes a los usuarios finales. El término app se puede usar indistintamente con el término motor en el contexto de las APIs. Una app debe estar conectada a un almacén de datos para usar sus datos y mostrar resultados de búsqueda, respuestas o acciones.

App web de Gemini Enterprise

Una app web de Gemini Enterprise está asociada a una app de Gemini Enterprise. Funciona como una base de operaciones centralizada de IA en la que los empleados usan una sola interfaz de chat para buscar en los datos aislados de la empresa, ejecutar agentes de IA especializados para flujos de trabajo complejos y generar contenido de nivel profesional con privacidad de nivel empresarial.

Inicializa recursos y accede a ellos

En esta sección, accederás a los siguientes recursos y los configurarás desde tu navegador web preferido.

App de Gemini Enterprise

Abre la consola de Google Cloud en una pestaña nueva y, luego, sigue estos pasos:

  1. Elige tu proyecto.
  2. En el campo de búsqueda de Google Cloud, busca y selecciona Gemini Enterprise y, luego, haz clic en + Crear app. Si no tienes una licencia de Gemini Enterprise, se te pedirá que actives una licencia de prueba gratuita de 30 días.

  1. Establece el Nombre de la app como codelab.
  2. Se genera un ID en función del nombre y se muestra debajo del campo. Cópialo.
  3. Establece Multi-region en global (Global).
  4. Haz clic en Crear.

8712ada39377205e.png

  1. Se creará la app y se te redireccionará automáticamente a Gemini Enterprise > Overview.
  2. En Obtén acceso completo, haz clic en Configurar identidad.
  3. En la nueva pantalla, selecciona Usar Google Identity y haz clic en Confirmar la identidad del personal.

3209c156eff4ba43.png

  1. Se guardará la configuración y se te redireccionará automáticamente a Gemini Enterprise > Descripción general.
  2. Navega a Configuraciones.
  3. En la pestaña Administrador de funciones, activa Habilitar el diseñador de agentes y haz clic en Guardar.

f0cd9da419b41cb6.png

App web de Gemini Enterprise

Abre Gemini Enterprise desde la consola de Cloud en una pestaña nueva y, luego, sigue estos pasos:

  1. Haz clic en la app llamada codelab.
  2. Copia la URL que aparece, ya que la usaremos para navegar a la app web de Gemini Enterprise en los próximos pasos.

b46ee6176744565d.png

3. Agente personalizado sin código

Este agente permite a los usuarios buscar datos y realizar acciones en Workspace en su lenguaje natural. Se basa en los siguientes elementos:

  • Modelo: Gemini.
  • Datos y acciones: Almacenes de datos de Gemini Enterprise para Google Workspace (Calendario, Gmail, Drive, NotebookLM) y Búsqueda de Google.
  • Herramientas de creación de agentes: Agent Designer de Gemini Enterprise
  • Host del agente: Gemini Enterprise.
  • IU: App web de Gemini Enterprise

Repasa conceptos

Gemini

Gemini es un LLM multimodal de Google. Ayuda a las personas a desbloquear su potencial humano para aumentar su imaginación, expandir su curiosidad y mejorar su productividad.

Almacén de datos de Gemini Enterprise

Un almacén de datos de Gemini Enterprise es una entidad que contiene los datos que se transfirieron desde una fuente de datos propia, como Google Workspace, o desde aplicaciones de terceros, como Jira o Salesforce. Los almacenes de datos que contienen datos de aplicaciones de terceros también se denominan conectores de datos.

Diseñador de agentes de Gemini Enterprise

Gemini Enterprise Agent Designer es una plataforma interactiva sin código y con poco código para crear, administrar y lanzar agentes de un solo paso y de varios pasos en Gemini Enterprise.

Revisa la arquitectura de la solución

e77aafb772502aaf.png

Habilita las APIs

Los almacenes de datos de Gemini Enterprise Workspace requieren la habilitación de las siguientes APIs:

  1. En la consola de Google Cloud, habilita las APIs de Calendar, Gmail y People:

573322606b715a69.png

  1. Haz clic en Menú ☰ > APIs y servicios > APIs y servicios habilitados y, luego, confirma que Google Calendar API, Gmail API y People API estén en la lista.

Las acciones de Gemini Enterprise en Calendario de Workspace y Gmail requieren la configuración de una pantalla de consentimiento:

  1. En la consola de Google Cloud, haz clic en Menú ☰ > Plataforma de autenticación de Google > Desarrollo de la marca.

  1. Haz clic en Comenzar.
  2. En Información de la aplicación, establece el Nombre de la aplicación como Codelab .
  3. En Correo electrónico de asistencia al usuario, elige una dirección de correo electrónico de asistencia a la que los usuarios puedan comunicarse contigo si tienen preguntas sobre su consentimiento.
  4. Haz clic en Siguiente.
  5. En Público, selecciona Interno.
  6. Haz clic en Siguiente.
  7. En Información de contacto, ingresa una dirección de correo electrónico en la que puedas recibir notificaciones sobre cualquier cambio en tu proyecto.
  8. Haz clic en Siguiente.
  9. En Finalizar, revisa la Política de Datos del Usuario de los Servicios de las APIs de Google y, si la aceptas, selecciona Acepto la Política de Datos del Usuario de los Servicios de las APIs de Google.
  10. Haz clic en Continuar y, luego, en Crear.

578c2b38219b2f7b.png

  1. Se guardará la configuración y se te redireccionará automáticamente a Google Auth Platform > Overview.
  2. Navega a Acceso a los datos.
  3. Haz clic en Agregar o quitar permisos.
  4. Copia los siguientes permisos y pégalos en el campo Manually add scopes.
https://www.googleapis.com/auth/calendar.readonly
https://www.googleapis.com/auth/calendar.events
https://www.googleapis.com/auth/calendar.calendars
https://www.googleapis.com/auth/gmail.send
https://www.googleapis.com/auth/gmail.readonly
  1. Haz clic en Agregar a la tabla, luego en Actualizar y, por último, en Guardar.

874b1dda14e8f379.png

Para obtener más información, consulta la guía completa Configura el consentimiento de OAuth.

Crea credenciales de cliente de OAuth

Crea un cliente de OAuth nuevo para que Gemini Enterprise autentique a los usuarios:

  1. En la consola de Google Cloud, haz clic en Menú ☰ > Plataforma de Google Auth > Clientes.

  1. Haz clic en + Crear cliente.
  2. En Tipo de aplicación, selecciona Aplicación web.
  3. Configura el campo Nombre como codelab.
  4. Omite Orígenes autorizados de JavaScript.
  5. En la sección URI de redireccionamiento autorizados, haz clic en Agregar URI y, luego, ingresa https://vertexaisearch.cloud.google.com/oauth-redirect.
  6. Haz clic en Crear.
  7. Aparecerá un diálogo con el ID y el secreto del cliente de OAuth que acabas de crear. Guarda esta información en un lugar seguro.

a46e5ebfb851aea5.png

Crea almacenes de datos

Abre Gemini Enterprise desde la consola de Cloud en una pestaña nueva y, luego, sigue estos pasos:

  1. Haz clic en la app llamada codelab.
  2. En el menú de navegación, haz clic en Almacenes de datos conectados.
  3. Haz clic en + Crear almacén de datos nuevo.
  4. En Fuente, busca Calendario de Google y haz clic en Seleccionar.
  5. En la sección Acciones, ingresa el ID de cliente y el secreto del cliente que guardaste en los pasos anteriores. Luego, haz clic en Verificar autenticación y sigue los pasos para autenticar y autorizar el cliente de OAuth.
  6. Habilita las acciones Crear evento de calendario y Actualizar evento de calendario.
  7. Haz clic en Continuar.

a1d76e70edec0cf.png

  1. En la sección Configuración, establece el Nombre del conector de datos como calendar.
  2. Haz clic en Crear.
  3. Se te redireccionará automáticamente a Almacenes de datos conectados, donde podrás ver el almacén de datos que se agregó recientemente.

Crea el almacén de datos de Google Gmail:

  1. Haz clic en + Crear almacén de datos nuevo.
  2. En Fuente, busca Google Gmail y haz clic en Seleccionar.
  3. En la sección Actions, ingresa el ID de cliente y el secreto del cliente que guardaste en los pasos anteriores y, luego, haz clic en Verify Auth.
  4. Habilita la acción Enviar correo electrónico.
  5. Haz clic en Continuar.
  6. En la sección Configuración, establece el Nombre del conector de datos como gmail.
  7. Haz clic en Crear.
  8. Se te redireccionará automáticamente a Almacenes de datos conectados, donde podrás ver el almacén de datos que se agregó recientemente.

Crea el almacén de datos de Google Drive:

  1. Haz clic en + Crear almacén de datos nuevo.
  2. En Fuente, busca Google Drive y haz clic en Seleccionar.
  3. En la sección Datos, selecciona Todos y, luego, haz clic en Continuar.
  4. En la sección Configuración, establece el Nombre del conector de datos como drive.
  5. Haz clic en Crear.
  6. Se te redireccionará automáticamente a Almacenes de datos conectados, donde podrás ver el almacén de datos que se agregó recientemente.

Crea el almacén de datos de NotebookLM:

  1. Haz clic en + Crear almacén de datos nuevo.
  2. En Fuente, busca NotebookLM y haz clic en Seleccionar.
  3. En la sección Configuración, establece el Nombre del conector de datos como notebooklm.
  4. Haz clic en Crear.
  5. Se te redireccionará automáticamente a Almacenes de datos conectados, donde podrás ver el almacén de datos que se agregó recientemente.

Después de unos minutos, el estado de todos los almacenes de datos conectados (excepto NotebookLM) será Activo. Si ves algún error, puedes hacer clic en la fuente de datos para ver los detalles.

ceba9eb2480a2696.png

Almacenes de datos de prueba

Abre la URL de la app web de Gemini Enterprise que copiamos antes:

  1. Haz clic en Menú ☰ > Nuevo chat.
  2. En el pie de página del nuevo campo de mensaje de chat, haz clic en el ícono de conectores y habilita todos los conectores.
  3. Ahora puedes experimentar con instrucciones relacionadas con los conectores. Por ejemplo, en el chat, escribe Do I have any meetings today? y presiona enter.
  4. A continuación, intenta escribir How many emails did I receive today? y presiona enter.
  5. Por último, escribe Give me the title of the last Drive file I created y presiona enter.

90e42539e5959634.png

Crear un agente personalizado

En la app web de Gemini Enterprise, crea un agente nuevo con el Diseñador de agentes:

  1. Haz clic en Menú ☰ > + Agente nuevo.
  2. En el chat, escribe An agent that always sends pirate-themed emails but use normal English otherwise y presiona enter.

2803c1dedd20433e.png

  1. Agent Designer crea un borrador del agente según la instrucción y lo abre en el editor.
  2. Haz clic en Create.

Probar agente personalizado

  1. En la app web de Gemini Enterprise, chatea con el agente recién creado:
  2. Haz clic en Menú ☰ > Agents.
  3. Selecciona el agente en Tus agentes.
  4. En el pie de página del nuevo campo de mensaje de chat, haz clic en el ícono de conectores y, luego, en Habilitar acciones para Correo y sigue las instrucciones para autorizar al agente.
  5. En el chat, escribe Send an email to someone@example.com saying I'll see them at Cloud Next, generate some subject and body yourself y presiona enter. Puedes reemplazar el correo electrónico de ejemplo por tu dirección de correo electrónico.
  6. Haz clic en ✔️ para enviar el correo electrónico.

60e62437ce29a818.png

d4fb65d14fdf27da.png

4. Agente personalizado con código avanzado

Este agente permite a los usuarios buscar datos y realizar acciones en Workspace en su lenguaje natural con herramientas y reglas personalizadas. Se basa en los siguientes elementos:

  • Modelo: Gemini.
  • Datos y acciones: Almacenes de datos de Gemini Enterprise para Google Workspace (Calendario, Gmail, Drive, NotebookLM), Búsqueda de Google, servidor del Protocolo de contexto del modelo (MCP) de Vertex AI Search administrado por Google, función de herramienta personalizada para enviar mensajes de Google Chat (a través de la API de Google Chat).
  • Herramientas de creación de agentes: Kit de desarrollo de agentes (ADK)
  • Host del agente: Vertex AI Agent Engine.
  • IU: App web de Gemini Enterprise

Se integrará en Gemini Enterprise con la función de integración de tu propio modelo, por lo que debemos seguir los pasos de implementación, registro y configuración.

Repasa conceptos

Vertex AI

Vertex AI ofrece todo lo que necesitas para compilar y usar IA generativa, como soluciones de IA, búsqueda y conversación, más de 130 modelos de base y una plataforma de IA unificada.

4670fcf7a826af4d.png

Kit de desarrollo de agentes (ADK)

El Kit de desarrollo de agentes (ADK) es un conjunto especializado de herramientas y frameworks diseñados para simplificar la creación de agentes autónomos de IA, ya que proporciona módulos prediseñados para el razonamiento, la administración de la memoria y la integración de herramientas.

Model Context Protocol (MCP)

El Protocolo de contexto del modelo (MCP) es un estándar abierto diseñado para permitir una integración segura y fluida entre las aplicaciones de IA y varias fuentes de datos o herramientas a través de una interfaz universal de "conectar y usar".

Herramienta de funciones

Una herramienta de función es una rutina ejecutable predefinida que un modelo de IA puede activar para realizar acciones específicas o recuperar datos en tiempo real de sistemas externos, lo que extiende sus capacidades más allá de la simple generación de texto.

Revisa la arquitectura de la solución

43df337e0f3d64e8.png

Revisa el código fuente

agent.py

...
MODEL = "gemini-2.5-flash"

# Gemini Enterprise authentication injects a bearer token into the ToolContext state.
# The key pattern is "GE_AUTH_NAME_<random_digits>".
# We dynamically parse this token to authenticate our MCP and API calls.
GE_AUTH_NAME = "enterprise-ai"

VERTEXAI_SEARCH_TIMEOUT = 15.0

def get_project_id():
    """Fetches the consumer project ID from the environment natively."""
    _, project = google.auth.default()
    if project:
        return project
    raise Exception(f"Failed to resolve GCP Project ID from environment.")

def find_serving_config_path():
    """Dynamically finds the default serving config in the engine."""
    project_id = get_project_id()
    engines = discoveryengine_v1.EngineServiceClient().list_engines(
        parent=f"projects/{project_id}/locations/global/collections/default_collection"
    )
    for engine in engines:
        # engine.name natively contains the numeric Project Number
        return f"{engine.name}/servingConfigs/default_serving_config"
    raise Exception(f"No Discovery Engines found in project {project_id}")

def _get_access_token_from_context(tool_context: ToolContext) -> str:
    """Helper method to dynamically parse the intercepted bearer token from the context state."""
    escaped_name = re.escape(GE_AUTH_NAME)
    pattern = re.compile(fr"^{escaped_name}_\d+$")
    # Handle ADK varying state object types (Raw Dict vs ADK State)
    state_dict = tool_context.state.to_dict() if hasattr(tool_context.state, 'to_dict') else tool_context.state
    matching_keys = [k for k in state_dict.keys() if pattern.match(k)]
    if matching_keys:
        return state_dict.get(matching_keys[0])
    raise Exception(f"No bearer token found in ToolContext state matching pattern {pattern.pattern}")

def auth_header_provider(tool_context: ToolContext) -> dict[str, str]:
    token = _get_access_token_from_context(tool_context)
    return {"Authorization": f"Bearer {token}"}

def send_direct_message(email: str, message: str, tool_context: ToolContext) -> dict:
    """Sends a Google Chat Direct Message (DM) to a specific user by email address."""
    chat_client = chat_v1.ChatServiceClient(
        credentials=Credentials(token=_get_access_token_from_context(tool_context))
    )

    # 1. Setup the DM space or find existing one
    person = chat_v1.User(
        name=f"users/{email}",
        type_=chat_v1.User.Type.HUMAN
    )
    membership = chat_v1.Membership(member=person)
    space_req = chat_v1.Space(space_type=chat_v1.Space.SpaceType.DIRECT_MESSAGE)
    setup_request = chat_v1.SetUpSpaceRequest(
        space=space_req,
        memberships=[membership]
    )
    space_response = chat_client.set_up_space(request=setup_request)
    space_name = space_response.name
    
    # 2. Send the message
    msg = chat_v1.Message(text=message)
    message_request = chat_v1.CreateMessageRequest(
        parent=space_name,
        message=msg
    )
    message_response = chat_client.create_message(request=message_request)
    
    return {"status": "success", "message_id": message_response.name, "space": space_name}

vertexai_mcp = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://discoveryengine.googleapis.com/mcp",
        timeout=VERTEXAI_SEARCH_TIMEOUT,
        sse_read_timeout=VERTEXAI_SEARCH_TIMEOUT
    ),
    tool_filter=['search'],
    # The auth_header_provider dynamically injects the bearer token from the ToolContext
    # into the MCP call for authentication.
    header_provider=auth_header_provider
)

# Answer nicely the following user queries:
#  - Please find my meetings for today, I need their titles and links
#  - What is the latest Drive file I created?
#  - What is the latest Gmail message I received?
#  - Please send the following message to someone@example.com: Hello, this is a test message.

root_agent = LlmAgent(
    model=MODEL,
    name='enterprise_ai',
    instruction=f"""
        You are a helpful assistant that always uses the Vertex AI MCP search tool to answer the user's message, unless the user asks you to send a message to someone.
        If the user asks you to send a message to someone, use the send_direct_message tool to send the message.
        You MUST unconditionally use the Vertex AI MCP search tool to find answer, even if you believe you already know the answer or believe the Vertex AI MCP search tool does not contain the data.
        The Vertex AI MCP search tool accesses the user's data through datastores including Google Drive, Google Calendar, and Gmail.
        Only use the Vertex AI MCP search tool with servingConfig and query parameters, do not use any other parameters.
        Always use the servingConfig {find_serving_config_path()} while using the Vertex AI MCP search tool.
    """,
    tools=[vertexai_mcp, FunctionTool(send_direct_message)]
)

Habilita las APIs

La solución requiere la habilitación de APIs adicionales:

  1. En la consola de Google Cloud, habilita las APIs de Vertex AI, Cloud Resource Manager y Google Chat:

4f02a36b050bab00.png

  1. Haz clic en Menú ☰ > APIs y servicios > APIs y servicios habilitados y, luego, confirma que API de Vertex AI, API de Cloud Resource Manager y API de Google Chat estén en la lista.

La solución requiere acceso a datos adicionales:

  1. En la consola de Google Cloud, haz clic en Menú ☰ > Plataforma de autenticación de Google > Acceso a los datos.

  1. Haz clic en Agregar o quitar permisos.
  2. Copia los siguientes permisos y pégalos en el campo Manually add scopes.
  3. Haz clic en Agregar a la tabla, luego en Actualizar y, por último, en Guardar.
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/chat.messages.create
https://www.googleapis.com/auth/chat.spaces.create
  1. Haz clic en Agregar a la tabla, luego en Actualizar y, por último, en Guardar.

56fbba733139acfe.png

Actualiza las credenciales de cliente de OAuth

La solución requiere un URI de redireccionamiento autorizado adicional:

  1. En la consola de Google Cloud, haz clic en Menú ☰ > Plataforma de Google Auth > Clientes.

  1. Haz clic en el nombre del cliente codelab.
  2. En la sección URI de redireccionamiento autorizados, haz clic en Agregar URI y, luego, ingresa https://vertexaisearch.cloud.google.com/static/oauth/oauth.html.
  3. Haz clic en Guardar.

deed597aa54fec91.png

Habilita el MCP de Vertex AI Search

  1. En una terminal, ejecuta lo siguiente:
gcloud beta services mcp enable discoveryengine.googleapis.com \
     --project=$(gcloud config get-value project)

Configura la app de Chat

  1. En la consola de Google Cloud, busca Google Chat API en el campo de búsqueda de Google Cloud, haz clic en API de Google Chat, luego en Administrar y, por último, en Configuración.

  1. Configura el Nombre de la app y la Descripción como Gemini Enterprise.
  2. Establece la URL del avatar en https://developers.google.com/workspace/add-ons/images/quickstart-app-avatar.png.
  3. Anula la selección de Habilitar funciones interactivas y, luego, haz clic en Inhabilitar en el diálogo modal que aparece.
  4. Selecciona Registrar errores en Logging.
  5. Haz clic en Guardar.

90cb612e51bce4e6.png

Implementa el agente en Vertex AI Agent Engine

  1. Descarga este repositorio de GitHub.

Descargar ZIP

  1. En una terminal, abre el directorio solutions/enterprise-ai-agent y, luego, ejecuta el siguiente comando:
# 1. Create and activate a new virtual environment
python3 -m venv .venv
source .venv/bin/activate

# 2. Install poetry and project dependencies
pip install poetry
poetry install

# 3. Deploy the agent
adk deploy agent_engine \
  --project=$(gcloud config get-value project) \
  --region=us-central1 \
  --display_name="Enterprise AI" \
  enterprise_ai

eafd2f9c4fbf305.png

  1. Cuando veas la línea Deploying to agent engine… en los registros, abre una nueva terminal y ejecuta el siguiente comando para agregar los permisos necesarios a Vertex AI Reasoning Engine Service Agent:
# 1. Get the current Project ID
PROJECT_ID=$(gcloud config get-value project)

# 2. Extract the Project Number for that ID
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

# 3. Construct the Service Account name
SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"

# 4. Apply the IAM policy binding
gcloud projects add-iam-policy-binding $PROJECT_ID \
     --member="serviceAccount:$SERVICE_ACCOUNT" \
     --role="roles/discoveryengine.viewer"
  1. Espera a que se complete el comando adk deploy y, luego, copia el nombre del recurso del agente recién implementado del resultado del comando en verde.

d098fe1347d6581b.png

Cómo registrar un agente en Gemini Enterprise

Abre Gemini Enterprise desde la consola de Cloud en una pestaña nueva y, luego, sigue estos pasos:

  1. Haz clic en la app llamada codelab.
  2. En el menú de navegación, haz clic en Agentes.
  3. Haz clic en + Agregar agente.
  4. Haz clic en Agregar para Agente personalizado a través de Agent Engine. Se muestra la sección Autorizaciones.
  5. Haz clic en Agregar autorización.
  6. Establece el Nombre de autorización en enterprise-ai. Se genera un ID en función del nombre y se muestra debajo del campo. Cópialo.
  7. Establece el ID de cliente con el mismo valor que el cliente de OAuth creado y actualizado en los pasos anteriores.
  8. Establece el secreto del cliente con el mismo valor que el cliente de OAuth que se creó y actualizó en los pasos anteriores.
  9. Establece el URI del token en https://oauth2.googleapis.com/token.
  10. Establece el URI de autorización en el siguiente valor después de reemplazar <CLIENT_ID> por el ID de cliente de OAuth creado y actualizado en los pasos anteriores.
https://accounts.google.com/o/oauth2/v2/auth?client_id=<CLIENT_ID>&redirect_uri=https%3A%2F%2Fvertexaisearch.cloud.google.com%2Fstatic%2Foauth%2Foauth.html&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.calendars%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.events%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.send%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fchat.messages.create%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fchat.spaces.create&include_granted_scopes=true&response_type=code&access_type=offline&prompt=consent
  1. Haz clic en Listo y, luego, en Siguiente. Aparecerá la sección Configuración.
  2. Establece el Nombre del agente y la Descripción del agente como Enterprise AI.
  3. Establece el motor de razonamiento de Agent Engine en el nombre del recurso del motor de razonamiento que copiaste en los pasos anteriores. Tiene el siguiente formato:
projects/<PROJECT_ID>/locations/<LOCATION>/reasoningEngines/<REASONING_ENGINE_ID>
  1. Haz clic en Crear. El agente recién agregado ahora aparece en Agentes.

Probar agente

  1. En la app web de Gemini Enterprise, chatea con el agente recién registrado:
  2. Haz clic en Menú ☰ > Agents.
  3. Selecciona el agente en De tu organización.
  4. En el chat, escribe Please find my meetings for today, I need their titles and links y presiona enter.
  5. Haz clic en Autorizar y, luego, sigue el flujo de autorización.

ed61cf654cbcd76c.png

  1. El agente responde con una lista de eventos del Calendario (según la cuenta del usuario).
  2. En el chat, escribe Please send a Chat message to someone@example.com with the following text: Hello! y presiona enter.
  3. El agente responde con un mensaje de confirmación.

1647ebff031c42e7.png

a8087d2351e77fb4.png

5. Agente predeterminado como complemento de Google Workspace

Este agente permite que los usuarios busquen datos de Workspace en lenguaje natural en el contexto de las IU de las apps de Workspace. Se basa en los siguientes elementos:

  • Modelo: Gemini.
  • Datos: Almacenes de datos de Gemini Enterprise para Google Workspace (Calendario, Gmail, Drive, NotebookLM) y la Búsqueda de Google.
  • Host del agente: Gemini Enterprise.
  • IU: Complemento de Google Workspace para Chat y Gmail (se puede extender fácilmente a Calendario, Drive, Documentos, Hojas de cálculo y Presentaciones).
  • Complemento de Google Workspace: Apps Script, APIs de Gemini Enterprise y Vertex AI, contextual (metadatos del usuario, mensaje de Gmail seleccionado).

El complemento de Google Workspace se conectará a Gemini Enterprise a través de la API de StreamAssist.

Repasa conceptos

Complemento de Google Workspace

Un complemento de Google Workspace es una aplicación personalizada que extiende una o varias aplicaciones de Google Workspace (Gmail, Chat, Calendario, Documentos, Drive, Meet, Hojas de cálculo y Presentaciones).

Apps Script

Apps Script es una plataforma de JavaScript basada en la nube y potenciada por Google Drive que te permite integrar y automatizar tareas en los productos de Google.

Marco de tarjetas de Google Workspace

El framework de tarjetas en Google Workspace permite que los desarrolladores creen interfaces de usuario interactivas y enriquecidas. Permite crear tarjetas organizadas y visualmente atractivas que pueden incluir texto, imágenes, botones y otros widgets. Estas tarjetas mejoran la experiencia del usuario, ya que proporcionan información estructurada y permiten realizar acciones rápidas directamente en las aplicaciones de Workspace.

Revisa la arquitectura de la solución

1798c39f7aaed8fc.png

Revisa el código fuente

appsscript.json

...
"addOns": {
    "common": {
      "name": "Enterprise AI",
      "logoUrl": "https://developers.google.com/workspace/add-ons/images/quickstart-app-avatar.png"
    },
    "chat": {},
    "gmail": {
      "contextualTriggers": [
        {
          "unconditional": {},
          "onTriggerFunction": "onAddonEvent"
        }
      ]
    }
  },
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/discoveryengine.assist.readwrite",
    "https://www.googleapis.com/auth/gmail.addons.execute",
    "https://www.googleapis.com/auth/gmail.addons.current.message.readonly"
  ]
...

Chat.gs

...
// Service that handles Google Chat operations.

// Handle incoming Google Chat message events, actions will be taken via Google Chat API calls
function onMessage(event) {
  if (isInDebugMode()) {
    console.log(`MESSAGE event received (Chat): ${JSON.stringify(event)}`);
  }
  // Extract data from the event.
  const chatEvent = event.chat;
  setChatConfig(chatEvent.messagePayload.space.name);

  // Request AI agent to answer the message
  requestAgent(chatEvent.messagePayload.message);
  // Respond with an empty response to the Google Chat platform to acknowledge execution
  return null; 
}

// --- Utility functions ---

// The Chat direct message (DM) space associated with the user
const SPACE_NAME_PROPERTY = "DM_SPACE_NAME"

// Sets the Chat DM space name for subsequent operations.
function setChatConfig(spaceName) {
  const userProperties = PropertiesService.getUserProperties();
  userProperties.setProperty(SPACE_NAME_PROPERTY, spaceName);
  console.log(`Space is set to ${spaceName}`);
}

// Retrieved the Chat DM space name to sent messages to.
function getConfiguredChat() {
  const userProperties = PropertiesService.getUserProperties();
  return userProperties.getProperty(SPACE_NAME_PROPERTY);
}

// Finds the Chat DM space name between the Chat app and the given user.
function findChatAppDm(userName) {
  return Chat.Spaces.findDirectMessage(
    { 'name': userName },
    {'Authorization': `Bearer ${getAddonCredentials().getAccessToken()}`}
  ).name;
}

// Creates a Chat message in the configured space.
function createMessage(message) {
  const spaceName = getConfiguredChat();
  console.log(`Creating message in space ${spaceName}...`);
  return Chat.Spaces.Messages.create(
    message,
    spaceName,
    {},
    {'Authorization': `Bearer ${getAddonCredentials().getAccessToken()}`}
  ).name;
}

Sidebar.gs

...
// Service that handles Gmail operations.

// Triggered when the user opens the Gmail Add-on or selects an email.
function onAddonEvent(event) {
  // If this was triggered by a button click, handle it
  if (event.parameters && event.parameters.action === 'send') {
    return handleSendMessage(event);
  }

  // Otherwise, just render the default initial sidebar
  return createSidebarCard();
}

// Creates the standard Gmail sidebar card consisting of a text input and send button.
// Optionally includes an answer section if a response was generated.
function createSidebarCard(optionalAnswerSection) {
  const card = CardService.newCardBuilder();
  const actionSection = CardService.newCardSection();

  // Create text input for the user's message
  const messageInput = CardService.newTextInput()
    .setFieldName("message")
    .setTitle("Message")
    .setMultiline(true);

  // Create action for sending the message
  const sendAction = CardService.newAction()
    .setFunctionName('onAddonEvent')
    .setParameters({ 'action': 'send' });

  const sendButton = CardService.newTextButton()
    .setText("Send message")
    .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
    .setOnClickAction(sendAction);

  actionSection.addWidget(messageInput);
  actionSection.addWidget(CardService.newButtonSet().addButton(sendButton));

  card.addSection(actionSection);

  // Attach the response at the bottom if we have one
  if (optionalAnswerSection) {
    card.addSection(optionalAnswerSection);
  }

  return card.build();
}

// Handles clicks from the Send message button.
function handleSendMessage(event) {
  const commonEventObject = event.commonEventObject || {};
  const formInputs = commonEventObject.formInputs || {};
  const messageInput = formInputs.message;

  let userMessage = "";
  if (messageInput && messageInput.stringInputs && messageInput.stringInputs.value.length > 0) {
    userMessage = messageInput.stringInputs.value[0];
  }

  if (!userMessage || userMessage.trim().length === 0) {
    return CardService.newActionResponseBuilder()
      .setNotification(CardService.newNotification().setText("Please enter a message."))
      .build();
  }

  let finalQueryText = `USER MESSAGE TO ANSWER: ${userMessage}`;

  // If we have an email selected in Gmail, append its content as context
  if (event.gmail && event.gmail.messageId) {
    try {
      GmailApp.setCurrentMessageAccessToken(event.gmail.accessToken);
      const message = GmailApp.getMessageById(event.gmail.messageId);

      const subject = message.getSubject();
      const bodyText = message.getPlainBody() || message.getBody();

      finalQueryText += `\n\nEMAIL THE USER HAS OPENED ON SCREEN:\nSubject: ${subject}\nBody:\n---\n${bodyText}\n---`;
    } catch (e) {
      console.error("Could not fetch Gmail context: " + e);
      // Invalidate the token explicitly so the next prompt requests the missing scopes
      ScriptApp.invalidateAuth();

      CardService.newAuthorizationException()
        .setResourceDisplayName("Enterprise AI")
        .setAuthorizationUrl(ScriptApp.getAuthorizationUrl())
        .throwException();
    }
  }

  try {
    const responseText = queryAgent({ text: finalQueryText, forceNewSession: true });

    // We leverage the 'showdown' library to parse the LLM's Markdown output into HTML
    // We also substitute markdown listings with arrows and adjust newlines for clearer rendering in the sidebar
    let displayedText = substituteListingsFromMarkdown(responseText);
    displayedText = new showdown.Converter().makeHtml(displayedText).replace(/\n/g, '\n\n');

    const textParagraph = CardService.newTextParagraph();
    textParagraph.setText(displayedText);

    const answerSection = CardService.newCardSection()
      .addWidget(textParagraph);

    const updatedCard = createSidebarCard(answerSection);

    return CardService.newActionResponseBuilder()
      .setNavigation(CardService.newNavigation().updateCard(updatedCard))
      .build();

  } catch (err) {
    return CardService.newActionResponseBuilder()
      .setNotification(CardService.newNotification().setText("Error fetching response: " + err.message))
      .build();
  }
}
...

AgentHandler.gs

...
// Service that handles Gemini Enterprise AI Agent operations.

// Submits a query to the AI agent and returns the response string synchronously
function queryAgent(input) {
  const isNewSession = input.forceNewSession || !PropertiesService.getUserProperties().getProperty(AGENT_SESSION_NAME);
  const sessionName = input.forceNewSession ? createAgentSession() : getOrCreateAgentSession();

  let systemPrompt = "SYSTEM PROMPT START Do not respond with tables but use bullet points instead.";
  if (input.forceNewSession) {
    systemPrompt += " Do not ask the user follow-up questions or converse with them as history is not kept in this interface.";
  }
  systemPrompt += " SYSTEM PROMPT END\n\n";

  const queryText = isNewSession ? systemPrompt + input.text : input.text;

  const requestPayload = {
    "session": sessionName,
    "userMetadata": { "timeZone": Session.getScriptTimeZone() },
    "query": { "text": queryText },
    "toolsSpec": { "vertexAiSearchSpec": { "dataStoreSpecs": getAgentDataStores().map(ds => { dataStore: ds }) } },
    "agentsSpec": { "agentSpecs": [{ "agentId": getAgentId() }] }
  };

  const responseContentText = UrlFetchApp.fetch(
    `https://${getLocation()}-discoveryengine.googleapis.com/v1alpha/${getReasoningEngine()}/assistants/default_assistant:streamAssist?alt=sse`,
    {
      method: 'post',
      headers: { 'Authorization': `Bearer ${ScriptApp.getOAuthToken()}` },
      contentType: 'application/json',
      payload: JSON.stringify(requestPayload),
      muteHttpExceptions: true
    }
  ).getContentText();

  if (isInDebugMode()) {
    console.log(`Response: ${responseContentText}`);
  }

  const events = responseContentText.split('\n').map(s => s.replace(/^data:\s*/, '')).filter(s => s.trim().length > 0);
  console.log(`Received ${events.length} agent events.`);

  let answerText = "";
  for (const eventJson of events) {
    if (isInDebugMode()) {
      console.log("Event: " + eventJson);
    }
    const event = JSON.parse(eventJson);

    // Ignore internal events
    if (!event.answer) {
      console.log(`Ignored: internal event`);
      continue;
    }

    // Handle text replies
    const replies = event.answer.replies || [];
    for (const reply of replies) {
      const content = reply.groundedContent.content;
      if (content) {
        if (isInDebugMode()) {
          console.log(`Processing content: ${JSON.stringify(content)}`);
        }
        if (content.thought) {
          console.log(`Ignored: thought event`);
          continue;
        }
        answerText += content.text;
      }
    }

    if (event.answer.state === "SUCCEEDED") {
      console.log(`Answer text: ${answerText}`);
      return answerText;
    } else if (event.answer.state !== "IN_PROGRESS") {
      throw new Error("Something went wrong, check the Apps Script logs for more info.");
    }
  }
  return answerText;
}

// Gets the list of data stores configured for the agent to include in the request.
function getAgentDataStores() {
  const responseContentText = UrlFetchApp.fetch(
    `https://${getLocation()}-discoveryengine.googleapis.com/v1/${getReasoningEngine().split('/').slice(0, 6).join('/')}/dataStores`,
    {
      method: 'get',
      // Use the add on service account credentials for data store listing access
      headers: { 'Authorization': `Bearer ${getAddonCredentials().getAccessToken()}` },
      contentType: 'application/json',
      muteHttpExceptions: true
    }
  ).getContentText();
  if (isInDebugMode()) {
    console.log(`Response: ${responseContentText}`);
  }
  const dataStores = JSON.parse(responseContentText).dataStores.map(ds => ds.name);
  if (isInDebugMode()) {
    console.log(`Data stores: ${dataStores}`);
  }
  return dataStores;
}
...

Inicia la cuenta de servicio

En la consola de Google Cloud, sigue estos pasos:

  1. Haz clic en Menú ☰ > > IAM y administración > Cuentas de servicio > + Crear cuenta de servicio.

  1. Establece el Nombre de la cuenta de servicio como ge-add-on.

d44d6aae29e2464c.png

  1. Haz clic en Crear y continuar.
  2. Agrega el rol Visualizador de Discovery Engine en los permisos.

f1374efa4f326ef5.png

  1. Haz clic en Continuar y, luego, en Listo. Se te redireccionará a la página Cuentas de servicio, donde podrás ver la cuenta de servicio que creaste.

b9496085f1404c5c.png

  1. Selecciona la cuenta de servicio recién creada y, luego, la pestaña Claves.
  2. Haz clic en Agregar clave y, luego, en Crear clave nueva.
  3. Selecciona JSON y, luego, haz clic en Crear.

f4280f5533a08821.png

  1. Se cerrará el cuadro de diálogo, y el nuevo par de clave pública/privada se descargará automáticamente en tu entorno local como un archivo JSON.

Crea y configura un proyecto de Apps Script

  1. Haz clic en el siguiente botón para abrir el proyecto de Apps Script del complemento de IA empresarial:

  1. Haz clic en Descripción general > Crear una copia.
  2. En tu proyecto de Apps Script, haz clic en Configuración del proyecto > Editar propiedades de la secuencia de comandos > Agregar propiedad de la secuencia de comandos para agregar propiedades de la secuencia de comandos.
  3. Establece REASONING_ENGINE_RESOURCE_NAME en el nombre del recurso de la aplicación de Gemini Enterprise. Tiene el siguiente formato:
# 1. Replace PROJECT_ID with the Google Cloud project ID.
# 2. Replace GE_APP_ID with the codelab app ID found in Google Cloud console > Gemini Enterprise > Apps.

projects/<PROJECT_ID>/locations/global/collections/default_collection/engines/<GE_APP_ID>
  1. Establece APP_SERVICE_ACCOUNT_KEY en la clave JSON del archivo de la cuenta de servicio que descargaste en los pasos anteriores.
  2. Haz clic en Guardar las propiedades de las secuencias de comandos.

Implementación en Gmail y Chat

En tu proyecto de Apps Script, sigue estos pasos:

  1. Haz clic en Implementar > Implementaciones de prueba y, luego, en Instalar. Ahora está disponible en Gmail.
  2. Haz clic en Copiar en ID de implementación principal.

2ed2df972ad92715.png

En la consola de Google Cloud, sigue estos pasos:

  1. Busca Google Chat API en el campo de búsqueda de Google Cloud, haz clic en API de Google Chat, luego en Administrar y, por último, en Configuración.

  1. Selecciona Habilitar funciones interactivas.
  2. Anula la selección de Unirse a espacios y conversaciones grupales.
  3. En Configuración de conexión, selecciona Apps Script.
  4. Establece el ID de implementación en el ID de implementación principal que copiaste en los pasos anteriores.
  5. En Visibilidad, selecciona Hacer que esta app de Chat esté disponible para personas y grupos específicos de Tu dominio de Workspace y escribe tu dirección de correo electrónico.
  6. Haz clic en Guardar.

3b7d461c423f7c51.png

Probar el complemento

Abre Google Chat en una pestaña nueva y, luego, sigue estos pasos:

  1. Abre un espacio de mensajes directos con la app de Chat Gemini Enterprise.

3da8690d19baf2d0.png

  1. Haz clic en Configurar y completa el flujo de autenticación.
  2. Escribe What are my meetings for today? y presiona enter. La app de chat de Gemini Enterprise debería responder con los resultados.

c8c63fb3f324fecf.png

Abre Gmail en una pestaña nueva y, luego, sigue estos pasos:

  1. Envía un correo electrónico con el Asunto establecido en We need to talk y el Cuerpo establecido en Are you available today between 8 and 9 AM?.
  2. Abre el correo electrónico que acabas de recibir.
  3. Abre la barra lateral del complemento de IA empresarial.
  4. Establece el Mensaje en Am I?.
  5. Haz clic en Enviar mensaje.
  6. La respuesta se muestra después del botón.

d33b8cb50ee251b7.png

6. Limpia

Borra el proyecto de Google Cloud

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en este codelab, te recomendamos que borres el proyecto de Google Cloud.

En la consola de Google Cloud, sigue estos pasos:

  1. Haz clic en Menú ☰ > IAM y administración > Configuración.

  1. Haz clic en Cerrar.
  2. Ingresa el ID del proyecto.
  3. Haz clic en Apagar de todos modos.

3b9492d97f771b2c.png

7. Felicitaciones

¡Felicitaciones! Creaste soluciones que aprovechan el poder de acercar Gemini Enterprise y Google Workspace a los trabajadores.

Próximos pasos

En este codelab, solo mostramos los casos de uso más típicos, pero hay muchas áreas de expansión que podrías considerar en tus soluciones, como las siguientes:

  • Usar herramientas para desarrolladores potenciadas por IA, como Gemini CLI y Antigravity
  • Integración con otros frameworks y herramientas de agentes, como MCP personalizados, llamadas a funciones personalizadas y UIs generativas
  • Integrar otros modelos de IA, incluidos los personalizados, alojados en plataformas dedicadas, como Vertex AI
  • Integrarse con otros agentes alojados en plataformas dedicadas, como Dialogflow, o por terceros a través de Cloud Marketplace
  • Publica agentes en Cloud Marketplace para potenciar a los equipos, las organizaciones o los usuarios públicos.

Más información

Existen muchos recursos disponibles para los desarrolladores, como videos de YouTube, sitios web de documentación, muestras de código e instructivos: