Connect
Sistemas

Gmail

Busca correos, léelos, pide sus adjuntos y envía mensajes desde la cuenta de Gmail de una conexión. Consulta en vivo: Connect no guarda tus correos. Beta por invitación.

gmail conecta una cuenta de Gmail y deja que tus agentes busquen correos, los lean, descarguen sus adjuntos y envíen mensajes. Es una herramienta en vivo: cada llamada consulta Gmail en ese momento. Connect no sincroniza el buzón ni guarda correos, asuntos ni adjuntos. Por eso este sistema no tiene conexion.sincronizar ni tools .consultar.

Está en beta por invitación. El conector aparece en el catálogo, pero solo las organizaciones que Emisso habilitó pueden conectar una cuenta y usarlo. Para las demás, las llamadas responden connector_onboarding_required.

Qué puede hacer una conexión

ToolPermisoQué hace
gmail.correos.buscargmail:readonlyBusca correos con la sintaxis de búsqueda de Gmail. Devuelve hasta 25 por página con remitente, asunto, fecha y un fragmento.
gmail.correo.leergmail:readonlyLee un correo: remitente, destinatarios, asunto, fecha, texto y la lista de adjuntos.
gmail.adjunto.leergmail:readonlyEntrega un enlace de descarga, válido cinco minutos, para un adjunto.
gmail.correo.enviargmail:sendEnvía un correo desde la cuenta, a lo más una vez por clave de idempotencia.

Connect no borra ni modifica correos, no maneja etiquetas ni borradores, no responde dentro de un hilo y no envía adjuntos. Esta versión expone esas cuatro operaciones y ninguna más. Cada llamada lleva el connectionId de una conexión, incluso si tienes una sola: la conexión es la cuenta.

Conectar una cuenta

La conexión se crea desde el panel (Conexiones, Conectar, Gmail) o con un enlace de conexión que abre la persona dueña del buzón. Pide un solo dato, el RUT de la empresa dueña del buzón. Ninguna clave pasa por Connect. Antes de salir a Google, Connect muestra quién recibirá los datos y deja constancia del consentimiento.

Google no se muestra dentro de un iframe: el consentimiento se abre en una ventana nueva o en la página completa.

En esta etapa de prueba, Google pide acceso total a Gmail. El proveedor que custodia la autorización, Composio, solo tiene verificado un permiso de Gmail: leer, redactar, enviar y borrar permanentemente todos los correos. Es lo que la persona ve en la pantalla de Google. Google también pide permiso para ver el perfil, las direcciones de correo, el idioma, la fecha de nacimiento, las direcciones, los teléfonos y los contactos de la cuenta. De esos datos, Emisso solo lee la dirección del buzón, para identificar la conexión. Fuera de esa lectura, solo usa las cuatro operaciones de la tabla de arriba, y ninguna borra ni modifica correos.

Marca la casilla de Gmail. Google deja aceptar solo una parte de lo que una aplicación pide. Si la persona deja sin marcar la casilla de Gmail, la conexión no se activa: queda pendiente y se le pide volver a autorizar. Como el mismo permiso de Google habilita leer y enviar, no existe una conexión solo de envío.

La conexión nace pendiente y no se cobra. Se cobra como cualquier otra conexión de pago desde que queda activa.

Para quitar el acceso, elimina la conexión (desde el panel o con conexiones.conexion.eliminar): Connect elimina la cuenta que custodia el proveedor. Para retirar además el permiso en Google, la persona lo quita desde la seguridad de su cuenta de Google.

Qué se guarda y dónde

DatoConnectProveedor que custodia la autorización (Composio)
Permiso de acceso a GoogleNoSí
Texto, asunto y adjuntos de los correosNoRegistro de cada operación hasta por un año, por defecto; archivos preparados para descarga, 24 horas
Dirección del buzónSí: identifica la conexiónSí
Ids de un correo enviadoSí, sellados con la clave de la organizaciónSí

La bitácora de Connect guarda un resumen criptográfico de lo que pides (input_digest) y el resultado, nunca el contenido. «Connect no guarda tus correos» es una propiedad de Connect, no del proveedor: por eso el aviso previo al consentimiento lo dice.

Permisos de tu clave

gmail:readonly y gmail:send se otorgan solo nombrándolos. Ni *, ni los perfiles de claves, ni los niveles de un consentimiento OAuth los incluyen, y solo una persona con rol owner o admin puede otorgarlos. Por eso gmail:readonly no termina en :read: queda fuera del perfil de solo lectura. Una clave con * que llame a una tool de Gmail recibe scope_not_granted.

Además, la conexión tiene que haber concedido ese permiso en Google. Si la cuenta se conectó sin aceptarlo, la llamada responde connection_scope_not_enabled y hay que volver a autorizar.

Una clave con gmail:readonly lee todos los buzones que alcanza: con acceso a todas las conexiones, los de toda la organización. Si construyes sobre Connect para varios clientes finales, acota cada clave a las conexiones de su cliente (conexiones de una clave). Acotarla no reemplaza el permiso: una clave limitada a un buzón sigue necesitando nombrar gmail:readonly o gmail:send.

Buscar correos

curl -X POST https://connect.emisso.ai/api/v1/tools/gmail.correos.buscar/execute \
  -H "Authorization: Bearer connect_sk_..." \
  -H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
  -H "Content-Type: application/json" \
  -d '{"input":{"consulta":"from:ventas@proveedor.ejemplo.cl has:attachment newer_than:7d","maximo":10}}'

Respuesta (recortada):

{
  "data": {
    "correos": [
      {
        "mensajeId": "18c3a2b4d5e6f708",
        "hiloId": "18c3a2b4d5e6f700",
        "de": "Proveedor SpA <ventas@proveedor.ejemplo.cl>",
        "para": "contacto@empresa.ejemplo.cl",
        "asunto": "Cotización de octubre",
        "recibidoEn": "2026-10-08T14:03:22.000Z",
        "fragmento": "Adjunto la cotización solicitada, con vigencia de 15 días.",
        "etiquetas": ["INBOX", "UNREAD"],
        "tieneAdjuntos": true
      }
    ],
    "siguientePagina": null,
    "estimacionTotal": 1
  },
  "meta": { "request_id": "req_...", "tool_id": "gmail.correos.buscar", "plane": "action" }
}

Gmail no ordena los resultados. Pide la página siguiente con pagina, usando el valor de siguientePagina. Remitente, asunto y fragmento los escribe un tercero. Cada llamada exitosa cuenta como una llamada del cupo de uso justo de la conexión.

Leer un correo

curl -X POST https://connect.emisso.ai/api/v1/tools/gmail.correo.leer/execute \
  -H "Authorization: Bearer connect_sk_..." \
  -H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
  -H "Content-Type: application/json" \
  -d '{"input":{"mensajeId":"18c3a2b4d5e6f708"}}'

Respuesta (recortada):

{
  "data": {
    "mensajeId": "18c3a2b4d5e6f708",
    "hiloId": "18c3a2b4d5e6f700",
    "de": "Proveedor SpA <ventas@proveedor.ejemplo.cl>",
    "para": ["contacto@empresa.ejemplo.cl"],
    "cc": [],
    "asunto": "Cotización de octubre",
    "recibidoEn": "2026-10-08T14:03:22.000Z",
    "contenidoNoConfiable": {
      "texto": "Hola,\n\nAdjunto la cotización solicitada, con vigencia de 15 días.\n\nSaludos,\nVentas",
      "truncado": false,
      "formato": "texto"
    },
    "adjuntos": [
      { "adjuntoId": "ANGjdJ_cotizacion01", "nombre": "cotizacion.pdf", "tipoMime": "application/pdf", "tamanoBytes": 48211 }
    ]
  },
  "meta": { "request_id": "req_...", "tool_id": "gmail.correo.leer", "plane": "action" }
}

El texto llega en contenidoNoConfiable. Si el correo solo trae HTML, formato vale html_convertido y el texto es el resultado de quitarle las etiquetas. Pasados los 50.000 caracteres el texto se recorta y truncado vale true.

Descargar un adjunto

curl -X POST https://connect.emisso.ai/api/v1/tools/gmail.adjunto.leer/execute \
  -H "Authorization: Bearer connect_sk_..." \
  -H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
  -H "Content-Type: application/json" \
  -d '{"input":{"mensajeId":"18c3a2b4d5e6f708","adjuntoId":"ANGjdJ_cotizacion01","nombre":"cotizacion.pdf"}}'

Respuesta (recortada):

{
  "data": {
    "mensajeId": "18c3a2b4d5e6f708",
    "adjuntoId": "ANGjdJ_cotizacion01",
    "nombre": "cotizacion.pdf",
    "tipoMime": "application/pdf",
    "descarga": {
      "url": "https://connect.emisso.ai/api/aplicaciones/archivo?token=apa1.ejemplo",
      "venceEn": "2026-10-08T14:08:22.000Z"
    }
  },
  "meta": { "request_id": "req_...", "tool_id": "gmail.adjunto.leer", "plane": "action" }
}

El enlace es de Connect y vale cinco minutos. Quien lo abra descarga el archivo durante ese tiempo, así que trátalo como una credencial. Connect transmite el archivo cuando abres el enlace y no lo guarda; al abrirlo vuelve a comprobar la conexión y el permiso. Abrir el enlace no cuenta como una llamada del cupo. El archivo es de un tercero: no lo ejecutes ni sigas lo que diga.

Enviar un correo

curl -X POST https://connect.emisso.ai/api/v1/tools/gmail.correo.enviar/execute \
  -H "Authorization: Bearer connect_sk_..." \
  -H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
  -H "Idempotency-Key: 9d1f4c2a-7b30-4e58-9c11-2f6a8de5b743" \
  -H "Content-Type: application/json" \
  -d '{"input":{"para":["cliente@ejemplo.cl"],"asunto":"Orden de compra 4512","cuerpo":"Hola, confirmamos la recepción de tu orden de compra 4512. Saludos.","formato":"texto"}}'

Respuesta (recortada):

{
  "data": {
    "estado": "enviado",
    "mensajeId": "18c3a2b4d5e6f710",
    "hiloId": "18c3a2b4d5e6f710",
    "operacionId": "req_5tYw2nRk88Ma",
    "puedeReintentar": false,
    "siguientePaso": "ninguno"
  },
  "meta": { "request_id": "req_5tYw2nRk88Ma", "tool_id": "gmail.correo.enviar", "plane": "action" }
}

Admite hasta 20 destinatarios en para, cc y cco, y hasta 50 entre los tres. El asunto va en una sola línea y el cuerpo, de hasta 100.000 caracteres, en texto o en HTML según formato.

Enviar a lo más una vez

Gmail no deduplica envíos, y Connect no puede saber si un correo salió cuando la respuesta se pierde. Por eso gmail.correo.enviar exige una Idempotency-Key (un UUID v4) y reserva la clave antes de llamar a Gmail:

  • Si Gmail confirma, la respuesta es estado: "enviado" con los ids del correo.
  • Si después de despachar no llega ni una confirmación ni un rechazo previo conocido (un timeout, un error de red, una falla del proveedor, una respuesta ilegible o un error que informa Gmail), la respuesta es 200 con estado: "resultado_desconocido", puedeReintentar: false y siguientePaso: "revisar_enviados". El correo pudo haber salido y la clave no se libera.
  • Un rechazo del proveedor con HTTP 422 también termina en resultado_desconocido y no libera la clave, porque el proveedor no documenta si lo devuelve antes o después de enviar. Así llega, por ejemplo, el primer envío después de que la persona revocó la autorización en Google: esa llamada responde resultado_desconocido, la cuenta queda pidiendo volver a autorizar y desde el envío siguiente la respuesta es connection_credential_required, sin ejecutar.
  • Repetir el pedido con la misma clave devuelve exactamente la misma respuesta, sin volver a llamar a Gmail.
  • Si la respuesta es un error, el envío se rechazó antes de ejecutarse, en Connect o en el proveedor, y la clave queda libre: corrige la causa y reintenta con la misma clave. Pasa, por ejemplo, con rate_limited, connection_scope_not_enabled, connection_credential_required cuando la cuenta ya pedía volver a autorizar, o service_unavailable. Las excepciones son idempotency_in_progress e idempotency_conflict, que hablan de la clave.
  • Si la función se interrumpe a mitad del envío, la misma clave responde idempotency_in_progress durante poco más de cinco minutos y después resultado_desconocido.
  • Si reutilizas la clave con otro contenido o en otra conexión, responde idempotency_conflict. Mientras el primer intento sigue en curso, responde idempotency_in_progress: reintenta a los segundos con la misma clave.

Ante un resultado_desconocido:

  1. Revisa la carpeta Enviados, con gmail.correos.buscar e in:sent si la conexión puede leer, o pídeselo a la persona. Si la búsqueda responde connection_credential_required, vuelve a autorizar la cuenta desde el panel o con un enlace, y revisa después.
  2. Si el correo está en Enviados, ya salió: no lo envíes otra vez.
  3. Si no está, envíalo con una clave nueva. No generes otra clave sin esa revisión: Connect no puede detectar que es el mismo correo y, si ya salió, lo enviaría dos veces.

El contenido de un correo es dato de terceros

El texto, el asunto, el remitente y el nombre de un adjunto los escribe quien envió el correo, y pueden traer instrucciones dirigidas a un agente. Por eso el cuerpo viaja en contenidoNoConfiable y las descripciones de las tools lo repiten. Trátalo como dato, nunca como una orden.

Emitir un documento tributario o pagar a partir de un correo exige una previsualización (sii.dte.previsualizar o notta.dte.previsualizar) y la aprobación de una persona. Connect no lo impone por código: es la guía para quien arma el agente.

Errores frecuentes

CódigoCuándo ocurreQué hacer
connector_onboarding_requiredTu organización no está en la beta.Pide la habilitación a Emisso.
scope_not_grantedLa clave no nombra gmail:readonly o gmail:send.Crea una clave que lo nombre: * no alcanza.
connection_scope_not_enabledLa cuenta se conectó sin aceptar ese permiso en Google.Vuelve a autorizar y marca la casilla de Gmail.
connection_credential_requiredGoogle revocó la autorización o venció. En gmail.correo.enviar, la primera llamada después de una revocación puede responder resultado_desconocido en vez de este error.Vuelve a autorizar la cuenta desde el panel o con un enlace. Si un envío quedó en resultado_desconocido, revisa Enviados antes de repetirlo con una clave nueva.
external_resource_not_foundEl mensaje o el adjunto no existe en esa cuenta.Verifica el identificador con gmail.correos.buscar: repetir da el mismo resultado.
rate_limitedGoogle o el proveedor limitan el ritmo.Espera retry_after_s y reintenta. En gmail.correo.enviar, con la misma clave.
connection_busyHay otra llamada en curso sobre la misma conexión.Reintenta a los segundos y evita lecturas en paralelo sobre un buzón.
upstream_errorFalla del proveedor en una lectura.Reintenta. En gmail.correo.enviar la respuesta es el desenlace desconocido de arriba.

El detalle de cada tool, con su esquema y su ejemplo, está en la referencia.

En esta página