> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ycloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Implementar un endpoint de WhatsApp Flow

> Gestiona health checks de Flow, notificaciones de errores, intercambio de datos, navegación y finalización a través de YCloud.

Usa un endpoint de Flow cuando necesites cargar pantallas de forma dinámica o procesar datos
enviados por un usuario de WhatsApp. Configura tu URL HTTPS pública como `endpointUri`
al crear un Flow o actualizar sus metadatos.

Esta guía describe las solicitudes JSON sin formato que YCloud reenvía a tu endpoint.
No describe una conexión directa al endpoint de datos cifrados de Meta.
Consulta [Gestionar WhatsApp Flows](/es/api-reference/guides/whatsapp-platform/manage-whatsapp-flows)
para la creación, vista previa, publicación y gestión del ciclo de vida de Flow.

## Antes de comenzar

* Expón un endpoint HTTPS público que acepte solicitudes `POST`.
* Devuelve JSON en menos de 15 segundos.
* Define las pantallas y sus campos de datos en tu Flow JSON.
* Genera un `flow_token` al enviar el mensaje de Flow para poder correlacionar
  la interacción con la sesión de tu aplicación.
* Usa validación del lado del servidor antes de aceptar los datos enviados.

## Flujo de solicitudes

1. El usuario abre o interactúa con un Flow en WhatsApp.
2. YCloud reenvía una solicitud JSON a tu endpoint configurado.
3. Tu endpoint lee `action` y procesa la solicitud.
4. Tu respuesta JSON selecciona una pantalla y proporciona sus datos, o completa el Flow.

## Gestionar un health check

Un health check contiene `action: ping`:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "action": "ping"
}
```

Devuelve:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "status": "active"
  }
}
```

Mantén esta ruta ligera. No realices una transacción comercial durante un health check.

## Gestionar una notificación de error

Las notificaciones de error incluyen `data.error` y `data.error_message`. Pueden usar
`INIT` o `data_exchange` como acción. Comprueba si existen estos datos de error antes de enrutar
solicitudes ordinarias por acción.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "version": "3.0",
  "flow_token": "FLOW_SESSION_TOKEN",
  "action": "data_exchange",
  "data": {
    "error": "ERROR_KEY",
    "error_message": "Error details"
  }
}
```

Registra el error para su investigación y devuelve una confirmación:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "acknowledged": true
  }
}
```

## Gestionar el intercambio de datos

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "version": "3.0",
  "screen": "DETAILS",
  "action": "data_exchange",
  "data": {
    "email": "customer@example.com"
  },
  "flow_token": "FLOW_SESSION_TOKEN"
}
```

| Campo | Significado |
| - | - |
| `version` | Versión de la API de datos, `3.0` en estas solicitudes. |
| `action` | `INIT` al abrir el Flow, `data_exchange` al enviar una pantalla o `BACK` al retroceder. |
| `screen` | ID de pantalla actual. Puede estar ausente en `INIT` o `BACK`. No nombres una pantalla de Flow `SUCCESS`; ese valor está reservado para la finalización. |
| `data` | Campos de pantalla o entrada enviada. Puede estar ausente en `INIT` o `BACK`. |
| `flow_token` | Token de sesión que suministraste en el mensaje de Flow. |

Gestiona cada acción según las pantallas que hayas definido:

| Acción | Comportamiento de respuesta |
| - | - |
| `INIT` | Devuelve la pantalla inicial y sus datos de partida. |
| `data_exchange` | Valida los datos enviados y luego devuelve la siguiente pantalla o un error de validación en la misma pantalla. |
| `BACK` | Devuelve la pantalla anterior con los datos que necesita. |

### Navegar a una pantalla

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "screen": "CONFIRMATION",
  "data": {
    "user_email": "customer@example.com"
  }
}
```

El `screen` debe existir en tu Flow JSON. Su esquema de datos declarado debe aceptar
los campos en `data`.

### Devolver un error de validación

Permanece en la pantalla actual y devuelve un campo de error que tu pantalla muestre:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "screen": "DETAILS",
  "data": {
    "error_message": "Please enter a valid email address."
  }
}
```

### Completar el Flow

Devuelve `screen: SUCCESS` con `extension_message_response.params`. Incluye el
`flow_token` original y cualquier campo de resultado adicional que desees en el mensaje de
respuesta del Flow.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "screen": "SUCCESS",
  "data": {
    "extension_message_response": {
      "params": {
        "flow_token": "FLOW_SESSION_TOKEN",
        "appointment_id": "APPOINTMENT_ID"
      }
    }
  }
}
```

Esto cierra el Flow y envía un mensaje de respuesta del Flow al chat. Analiza el
resultado desde el [webhook de respuesta entrante del Flow](/es/api-reference/guides/examples/webhook-examples/whatsapp-inbound-message-webhook-examples#inbound-interactive-flow-response-message).

## Ejemplo de implementación

Este ejemplo con Express gestiona las tres categorías de solicitudes. Haz coincidir los
IDs de pantalla y los campos de respuesta con tu propio Flow JSON. Monta cualquier control
de acceso al endpoint utilizado por tu despliegue antes de este manejador.

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import express from "express";

const app = express();
app.use(express.json({ limit: "256kb" }));

app.post("/flow-endpoint", (req, res) => {
  if (!req.body || typeof req.body !== "object" || Array.isArray(req.body)) {
    return res.status(400).json({ error: "Expected a JSON object" });
  }
  const { action, screen, flow_token: flowToken } = req.body;
  const data = req.body.data ?? {};

  if (action === "ping") {
    return res.json({ data: { status: "active" } });
  }
  if (data.error) {
    // Record the error without logging sensitive form data or session tokens.
    return res.json({ data: { acknowledged: true } });
  }
  if (!flowToken) {
    return res.status(400).json({ error: "Missing flow_token" });
  }
  if (action === "INIT" || action === "BACK") {
    return res.json({ screen: "DETAILS", data: {} });
  }
  if (action === "data_exchange" && screen === "DETAILS") {
    if (typeof data.email !== "string" || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
      return res.json({
        screen: "DETAILS",
        data: { error_message: "Please enter a valid email address." }
      });
    }
    return res.json({ screen: "CONFIRMATION", data: { user_email: data.email } });
  }
  if (action === "data_exchange" && screen === "CONFIRMATION") {
    return res.json({
      screen: "SUCCESS",
      data: { extension_message_response: { params: { flow_token: flowToken } } }
    });
  }
  return res.status(400).json({ error: "Unsupported action or screen" });
});

app.listen(3000);
```

## Verificar el endpoint

Prueba `ping`, la confirmación de errores, `INIT` sin `screen` ni `data`, envíos válidos
e inválidos, `BACK` y la finalización con `SUCCESS`. Comprueba el límite de respuesta
de 15 segundos y confirma que el webhook de finalización incluya tu
`flow_token` original. Previsualiza el Flow antes de publicarlo.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.