Saltar al contenido principal
External Agent está disponible en los planes YCloud Pro y superiores.
Conecta tu propio agente de IA a YCloud como un External Agent. Tu agente se ejecuta en tu infraestructura y colabora junto con tus agentes humanos en Inbox: recibe mensajes de clientes, envía respuestas, recupera el historial de conversaciones y transfiere conversaciones a tu equipo. YCloud envía eventos a tu URL de webhook. Tu servicio procesa esos eventos y llama a la API REST de Inbox para responder o gestionar la conversación. YCloud no llama a tu API de inferencia de IA, y la respuesta HTTP de tu webhook no se envía al cliente.

Antes de comenzar

Prepara:
  • Un endpoint HTTPS accesible públicamente que acepte solicitudes JSON POST.
  • Un servicio que verifique las firmas de webhook, almacene eventos, evite el procesamiento de duplicados y ejecute tu agente de IA.
  • Una clave de API estándar de tu cuenta de YCloud, almacenada en tu servidor. Las claves de API de Developer App no son compatibles con estos endpoints de Inbox.
  • Un número comercial de WhatsApp conectado a YCloud y un equipo o agente humano para recibir transferencias.
Usa https://api.ycloud.com como la URL base de la API.

Conecta tu agente

1. Crear un External Agent

  1. En la consola de YCloud, abre AI Agent > AI Agent.
  2. Selecciona Create Agent > External Agent.
  3. Introduce un Name y tu Webhook URL, como https://agent.example.com/webhooks/ycloud.
  4. Selecciona Save.
  5. Copia el Bot ID generado desde los detalles del agente. Usa este valor como botId en las solicitudes de la API; no necesitas proporcionar un ID de tu propio sistema de IA.
Formulario Create External Agent de YCloud con los controles Name, Webhook URL y Save.

Create an External Agent with a name and a webhook URL. This example shows the form before saving.

La página de detalles muestra el endpoint de webhook, su Signing secret y los cuatro tipos de eventos. Usa el signing secret para verificar los eventos entrantes. Selecciona View delivery logs para investigar la entrega de webhooks. El mismo endpoint también está disponible en la página Webhooks . Mantén el signing secret del endpoint separado de tu clave de API. El secreto verifica los webhooks entrantes; X-API-Key autentica tus solicitudes REST salientes. Un Bot ID es un identificador, no una credencial.

2. Asignar un número de WhatsApp

Abre WhatsApp Manager > WhatsApp accounts, luego abre la configuración del número comercial y selecciona Inbox > Assignment. En Priority 3 Assign to, selecciona AI Agent, y después elige tu agente en la sección External Agent del selector de agentes. Comprueba la prioridad de las reglas: la asignación al propietario del cliente o al último agente que atendió puede tener precedencia. Consulta Conversation assignment rules. Un solo External Agent puede gestionar múltiples números. Cada número está asociado con un solo bot a la vez. Administra estas asociaciones en la configuración de asignación del número.

3. Procesar una conversación

  1. Un cliente envía un mensaje de WhatsApp a tu número comercial.
  2. YCloud abre o continúa un diálogo de Inbox y aplica las reglas de asignación del número.
  3. Cuando tu External Agent gestiona el diálogo, YCloud envía los eventos de webhook correspondientes a su endpoint.
  4. Tu servicio verifica y almacena el evento, devuelve 2xx y procesa la entrada del cliente de forma asíncrona.
  5. Tu servicio llama a la API de Inbox para responder, transferir o cerrar el diálogo.
  6. Tu servicio rastrea la entrega mediante whatsapp.message.updated.

Comprender los identificadores

Los ID son cadenas. Las marcas de tiempo utilizan UTC RFC 3339. Usa dialogId, no conversationId, en las rutas de la API del diálogo.

Recibir eventos de webhook

Los cuatro tipos de eventos llegan a la misma URL de webhook. Cada entrega dedicada de External Agent incluye id, type, apiVersion, createTime e externalBotContext, además del objeto de negocio correspondiente.

Verificar, almacenar y confirmar

Verifica el encabezado YCloud-Signature usando el secreto de firma del endpoint y el cuerpo sin procesar de la solicitud HTTP, antes de analizar el JSON. El formato de la firma es:
Usa una comparación de tiempo constante y valida la marca de tiempo con una tolerancia razonable, como cinco minutos. Consulta Implementar un receptor de webhook para ver ejemplos de verificación de firma. Persiste el evento y su estado de deduplicación, y luego devuelve de inmediato cualquier respuesta 2xx exitosa. Ejecuta la inferencia de IA y otros procesos lentos de forma asíncrona. Las respuestas que no sean 2xx y los tiempos de espera pueden activar un número limitado de reintentos. Deduplica por (botId, event.id), dentro de tu cuenta de YCloud. Un cambio de asignación puede notificar tanto al agente saliente como al entrante; usar únicamente un ID de evento global puede descartar la notificación de uno de los agentes. Mantén el estado de procesamiento para que un evento repetido no envíe una segunda respuesta.

Ejemplo: mensaje del cliente

Lee el contenido del cliente desde inboxMessage.inbound. Los eventos de creación salientes usan inboxMessage.outbound en su lugar. Conserva los tipos de mensajes y campos desconocidos por motivos de compatibilidad en lugar de tratarlos como texto.

Decidir si responder

externalBotContext es una instantánea tomada cuando se genera la notificación. Su campo botId identifica al bot receptor; assignee identifica al gestor real en esa instantánea. Estos pueden diferir tras una transferencia. actionable=true significa que el bot receptor estaba gestionando un diálogo abierto en ese momento. También puede ser true en un evento de creación saliente o en un recibo de entrega.
No actives una respuesta de IA únicamente a partir de actionable. Comprueba el tipo de evento y la dirección del mensaje. Un evento retrasado no demuestra que tu agente aún gestione el diálogo. Consulta el diálogo actual cuando sea necesario y gestiona los errores de propiedad de cada solicitud de escritura.
Los eventos pueden llegar más de una vez o desordenados. No existe un campo de secuencia de eventos. Agrupa el trabajo por dialogId y evita procesar dos veces la misma entrada del cliente. Un evento de asignación inicial no debe activar de forma independiente una segunda respuesta al mensaje inicial del cliente.

¿Qué ocurre tras una transferencia o cierre?

Los nuevos mensajes de clientes y las respuestas humanas ya no se entregan al External Agent anterior una vez que el diálogo es gestionado por un humano, queda en cola, sin asignar o cerrado. El agente anterior sigue recibiendo la notificación correspondiente de asignación saliente o de cierre. Las notificaciones de creación y los recibos de entrega de los mensajes que ya envió permanecen asociados a ese agente emisor, incluso después de una transferencia o reasignación de número. Las notificaciones generadas previamente pueden llegar tarde. Cancela el trabajo pendiente cuando cambie la asignación o se cierre el diálogo, y no lo reanudes únicamente porque un evento antiguo tenga actionable=true. Los endpoints de webhook normales conservan su comportamiento de suscripción y su formato de carga útil existentes. La entrega dedicada de External Agent añade externalBotContext; no exijas ese campo en entregas ordinarias de whatsapp.message.updated.

Usar la API de Inbox

Envía X-API-Key en cada solicitud y Content-Type: application/json en solicitudes POST. Todos los ejemplos que aparecen a continuación usan identificadores de marcador de posición. Sustitúyelos por valores de tu agente y de los eventos recibidos. Las respuestas correctas devuelven directamente el objeto de negocio, sin un contenedor data. Las operaciones de escritura comprueban que el diálogo esté abierto y gestionado actualmente por el bot especificado. YCloud determina el remitente y el cliente a partir del diálogo; no envíes tenantId, from, to, recipient, operatorId ni source para anularlos.

Obtener el diálogo actual

Comprueba status, assignee y canAct. El campo bot puede hacer referencia al último bot externo asociado y no es una prueba de la propiedad actual. canAct refleja los permisos del bot consultado en el momento de la solicitud; una escritura posterior seguirá realizando sus propias comprobaciones.

Recuperar el historial de conversaciones

La respuesta contiene items y nextCursor. Cada elemento incluye un mensaje de Inbox id, direction, type, content y createTime. Para un mensaje de texto, lee content.text.body. El historial incluye los mensajes visibles para el cliente de la misma conversación, posiblemente a través de diálogos anteriores. El propio dialogId de un mensaje puede ser diferente del diálogo solicitado o no estar presente en un historial más antiguo. Las notas internas, los resúmenes privados de derivación y los mensajes internos del sistema quedan excluidos. Los mensajes se devuelven en orden ascendente por ID de mensaje, de más antiguos a más recientes. Omite after en la primera solicitud; pasa nextCursor sin modificar como after en las solicitudes posteriores hasta que sea null. El valor predeterminado de limit es 50, con un rango de 1 a 100. La lista de destinatarios de derivación utiliza el mismo patrón de paginación.

Enviar una respuesta

botId y message son obligatorios. sourceEventId y replyToMessageId son opcionales. La referencia de respuesta es un ID de mensaje de Inbox, como inboxMessage.id; no es un wamid.
Comprueba status incluso cuando HTTP devuelva 200. accepted significa que el mensaje entró en la canalización de envío, no que haya llegado al cliente. Una respuesta 200 también puede indicar failed; es posible que channelMessageId aún no esté disponible. Usa whatsapp.message.updated para rastrear los estados posteriores, incluidos sent, delivered, read, failed, expired o deleted. Correlaciona el externalBotContext.inboxMessageId del recibo con el inboxMessageId de la respuesta de envío. Revisa whatsappMessage.errorCode y errorMessage en busca de errores.

Tipos de mensaje

El objeto message utiliza el modelo estándar de mensajes de WhatsApp: type más el campo de contenido correspondiente. Entre los ejemplos se incluyen text, image, video, audio, document, sticker, location, contacts, interactive, template y reaction. Los requisitos existentes de envío y plantillas de WhatsApp siguen aplicando. Por ejemplo, sustituye el objeto message por:
Para archivos multimedia, proporciona id o bien link. Para conocer las estructuras del cuerpo del mensaje, consulta Enviar un mensaje de WhatsApp. Envía la respuesta a través del endpoint de Inbox anterior para que utilice las comprobaciones de gestión del diálogo y el contexto de Inbox. No envíes ni dependas de filterUnsubscribed o filterBlocked en esta solicitud de mensaje de Inbox. Las respuestas de los clientes pueden incluir interactive.button_reply, interactive.list_reply, interactive.nfm_reply o button. El response_json de una respuesta de Flow es una cadena JSON. El tipo entrante button no es un tipo de mensaje saliente para este endpoint.

Derivar a un agente humano

Primero, lista los equipos o agentes disponibles para el número de negocio del diálogo:
Usa type=agent para listar los miembros en su lugar. Cada destinatario devuelto proporciona el id y el type para la solicitud de derivación. El campo opcional online de un agente describe la presencia; no garantiza una asignación inmediata.
Debes especificar un target con type (team o agent) y id. No hay una alternativa humana predeterminada. El campo opcional reason admite hasta 256 caracteres; el campo opcional summary admite hasta 4000 caracteres y no forma parte del historial de mensajes visible para el cliente. La respuesta contiene outcome y el dialog actualizado. Los resultados son assigned, queued, team_unassigned o unassigned. Comprueba el resultado real en lugar de asumir que un agente humano ha aceptado la conversación. Una derivación mantiene el mismo dialogId. Una vez que tu agente pierda la asignación, deja de responder o de intentar cerrar ese diálogo.

Cerrar un diálogo resuelto

La respuesta contiene dialog con status=closed y canAct=false. Tu agente no puede continuar enviando mensajes ni derivando ese diálogo cerrado. Un mensaje válido posterior del cliente iniciará un nuevo diálogo y volverá a ejecutar las reglas de asignación del número.

Gestionar errores y reintentos

Las respuestas de error utilizan un objeto error con status, code, message y requestId. Conserva el ID de solicitud al ponerte en contacto con el soporte de YCloud.
sourceEventId y X-Request-Id admiten el rastreo; ninguno de los dos es una clave de idempotencia. La API no ofrece deduplicación entre solicitudes. Un reintento a ciegas tras un resultado incierto puede enviar un mensaje duplicado.
Monitorea View delivery logs para detectar fallos de webhook. Conserva los ID de evento, ID de diálogo, ID de mensaje, ID de solicitud y los resultados del procesamiento. Los reintentos de Webhook son limitados, así que usa consultas de diálogo e historial para recuperar el contexto cuando sea necesario.

Preguntas frecuentes

¿Puedo conectar un agente creado con mi propio framework de IA?

Sí. Tu servicio debe recibir y verificar los webhooks de YCloud y llamar a la API REST de Inbox. Tú controlas cómo genera respuestas tu servicio, cómo accede al conocimiento y cómo invoca sus propias herramientas.

¿Mi agente recibirá todas las conversaciones de Inbox?

No. Su endpoint dedicado recibe eventos dentro de su ámbito de gestión, junto con notificaciones pertinentes de asignación y cierre, y recibos de sus propios mensajes enviados. Los nuevos mensajes tras una transferencia a un agente humano no se reenvían al agente anterior. Los eventos generados previamente aún pueden llegar con retraso.

¿Puede mi agente utilizar mensajes de diálogos anteriores?

Sí. El endpoint de historial devuelve el historial visible para el cliente correspondiente a la conversación, incluidos los diálogos anteriores. Utiliza el propio dialogId de cada mensaje cuando esté disponible; no asumas que cada mensaje devuelto pertenece a la sesión de servicio actual.

¿Qué ocurre si cambio el agente asignado a un número?

Los diálogos abiertos gestionados actualmente por un bot se reasignan de forma asíncrona según el comportamiento de enrutamiento del número. El agente saliente recibe assignmentRole=outgoing y debe detener su trabajo. El agente entrante recibe reason=phone_binding_changed con assignmentRole=incoming; debe consultar el diálogo actual y el historial antes de continuar. El ID del diálogo y el historial permanecen sin cambios. Los diálogos gestionados actualmente por una persona no se transfieren al nuevo bot mediante esta reasignación de número. Después de que otro bot lo sustituya, el bot anterior ya no podrá consultar ese diálogo a través de estos endpoints.

¿La respuesta de mi webhook se convierte en la respuesta al cliente?

No. Devuelve 2xx para confirmar la recepción del evento y luego envía la respuesta al cliente a través de POST /v2/inbox/dialogs/{dialogId}/messages.

¿Por qué recibe mi agente actionable=true para su propia respuesta?

El campo describe quién gestionaba el diálogo abierto cuando se generó el evento. Por tanto, los eventos de creación de salida y los recibos de entrega pueden tener actionable=true. Activa una respuesta de IA normal únicamente para un evento inbox.message.created entrante, y ten en cuenta los cambios en la titularidad del diálogo en vivo.