# Migración desde v1

import { Badge } from '@astrojs/starlight/components';

Esta guía mapea cada campo del antiguo `/create*Message` a su equivalente en la API de Mensajería v2. Úsela como referencia mientras migra las integraciones existentes.

<Aside type="note">
Los métodos heredados de la v1 están obsoletos pero son totalmente operativos. No hay una fecha de desactivación definitiva, por lo que puede migrar a su propio ritmo. Para nuevas integraciones, utilice la API de Mensajería v2.
</Aside>

## Diferencias de alto nivel

| Aspecto | v1 | v2 |
|---|---|---|
| Endpoint por canal | método separado por canal (`/createMessage`, `/createEmailMessage`, `/createSMSMessage`, `/createKakaoMessage`, …) | único endpoint — `POST /messaging/v2/notify` |
| Autenticación | campo `auth` en el cuerpo de la solicitud | encabezado `Authorization: Token <API_TOKEN>` |
| Segmentación | mixto: `filter` + `conditions` + `devices` + `users` en la misma solicitud | división explícita: `NotifySegment` vs `NotifyTransactional` |
| Contenido | `content` plano + bloques de plataforma hermanos | `payload.content.localized_content.{locale}.{platform}` anidado |
| Respuesta | `MessageCode[]` | `message_code` + `unknown_identifiers` opcional |

## Desde `/createMessage`

Las entradas `notifications[*]` de la v1 se convierten en solicitudes `Notify` individuales (un mensaje cada una). Si una llamada v1 tiene múltiples entradas, emita una solicitud `Notify` por cada entrada.

**Decisión de segmentación.** Si la entrada v1 utiliza `devices` o `users` (listas explícitas), mapéela a `transactional`. De lo contrario, mapéela a `segment`.

### Campos a nivel de solicitud

- `application` → `segment.application` o `transactional.application` (mismo formato de app-code).
- `applications_group`: no soportado en v2. Use múltiples solicitudes por aplicación.
- `auth`: movido al encabezado `Authorization`, ya no está en el cuerpo.

### Programación

- `send_date` (`"YYYY-MM-DD HH:mm"` o `"now"`) → `schedule.at` (marca de tiempo RFC 3339 UTC). Para reproducir el `"now"` de la v1, establezca `schedule.at` a la hora actual. Cualquier marca de tiempo en el pasado se envía inmediatamente.
- `ignore_user_timezone` → `schedule.follow_user_timezone`. **Invertido:** `ignore_user_timezone: true` se convierte en `follow_user_timezone: false`.
- `timezone`: no soportado. v2 siempre usa UTC para `at`. Convierta del lado del cliente.

### Segmentación

- `filter` (nombre del segmento) → `segment.code`.
- `conditions` (`[[tag, op, value], ...]`) → `segment.expression`. Reescriba a una expresión de [seglang](/es/developer/api-reference/segmentation-filters-api/segmentation-language/). En seglang, `*` es un Y lógico y las etiquetas específicas de la aplicación se referencian como `Tag("<application-code>", "<tag>", <op>, <value>)`. Ejemplo: `[["Country","EQ","BR"],["Language","EQ","pt"]]` con `conditions_operator: AND` → `Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt")`.
- `conditions_operator` (`AND` / `OR`): integrado en `segment.expression`.
- `devices` (hwids o push tokens) → `transactional.hwids.list` o `transactional.push_tokens.list`. v2 separa los dos: los hwids van en `hwids`, los push tokens sin procesar van en `push_tokens`.
- `users` → `transactional.users.list`.
- `platforms` (códigos numéricos `[1, 3, …]`) → `segment.platforms` o `transactional.platforms` (enums de cadena `["IOS", "ANDROID", …]`). Consulte el [Platform enum](/es/developer/api-reference/messaging-api-v2/notify/#platform-enum).

### Contenido

- `content` (cadena) → `payload.content.localized_content.default.{platform}.body`. En v2, el contenido es siempre por configuración regional y por plataforma. Coloque una cadena simple de v1 bajo la clave especial `"default"` (traducción general, consulte [Selección de configuración regional](/es/developer/api-reference/messaging-api-v2/payload-reference/#locale-selection-for-a-device)).
- `content` (`{locale: text}`) → `payload.content.localized_content.{locale}.{platform}.body`. Duplique el cuerpo en cada bloque de plataforma segmentado.
- `preset` → `payload.preset`.
- `data` → `payload.custom_data`.
- `rich_media` → `payload.open_action.rich_media.code`.
- `link` → `payload.open_action.link.url`.
- `minimize_link` (`0` o `2`) → `payload.open_action.link.shortener` (`NONE` o `BITLY`).
- `inbox_image` → `payload.content.localized_content.{locale}.{platform}.inbox.image_url` (cada bloque de plataforma tiene su propio `inbox`).
- `inbox_date` → `payload.content.localized_content.{locale}.{platform}.inbox.expiration_date`.
- `inbox_days`: no soportado. Convierta a una `expiration_date` absoluta del lado del cliente.

### Controles de entrega

- `dynamic_content` / `dynamic_content_placeholders` → `dynamic_content_placeholders` en `segment` o `transactional`.
- `campaign` → `campaign` en `segment` o `transactional`.
- `capping_days` → `frequency_capping.days`.
- `capping_count` → `frequency_capping.count`.
- `send_rate` (int) → `send_rate.value` con `send_rate.bucket: "1s"`.
- `message_type` (`"marketing"` / `"transactional"`) → `message_type` (`MESSAGE_TYPE_MARKETING` / `MESSAGE_TYPE_TRANSACTIONAL`).

### No soportado en v2

- `transactionId`: sin equivalente directo. Realice el seguimiento de la correlación de su lado.
- `template_bindings`: Las vinculaciones de plantillas Liquid no están disponibles en v2. Siga usando v1 si depende de ellas.

### Bloques específicos de la plataforma

v1 acepta parámetros específicos de la plataforma en el nivel superior de cada entrada `notifications[*]` (`ios`, `android`, `safari`, `chrome`, …). En v2 se mueven dentro de la configuración regional:

```
// v1
"notifications": [{
  "content": "Hello",
  "ios":     { "title": "Hi",    "sound": "default.caf" },
  "android": { "header": "Hi",   "led": "#ff0000" }
}]

// v2
"payload": {
  "content": {
    "localized_content": {
      "en": {
        "ios":     { "title": "Hi", "body": "Hello", "sound": "default.caf" },
        "android": { "title": "Hi", "body": "Hello", "led_color": "#ff0000" }
      }
    }
  }
}
```

Los nombres de los campos dentro de los bloques de plataforma difieren en algunos lugares. Consulte la [Referencia de payload](/es/developer/api-reference/messaging-api-v2/payload-reference/) para los nombres exactos de v2.

### Ejemplo: Antes y después

**v1 `/createMessage`** (push a un segmento):

```json
{
  "request": {
    "application": "XXXXX-XXXXX",
    "auth":        "YOUR_API_TOKEN",
    "notifications": [{
      "send_date":  "2026-05-01 12:00",
      "content":    "Hello!",
      "platforms":  [1, 3],
      "filter":     "active_users",
      "campaign":   "YYYYY-YYYYY",
      "capping_days":  7,
      "capping_count": 3,
      "message_type":  "marketing"
    }]
  }
}
```

**v2 `/messaging/v2/notify`**:

```json
{
  "segment": {
    "application": "XXXXX-XXXXX",
    "platforms":   ["IOS", "ANDROID"],
    "code":        "active_users",
    "payload": {
      "content": {
        "localized_content": {
          "en": {
            "ios":     { "body": "Hello!" },
            "android": { "body": "Hello!" }
          }
        }
      }
    },
    "schedule":          { "at": "2026-05-01T12:00:00Z" },
    "frequency_capping": { "days": 7, "count": 3 },
    "campaign":          "YYYYY-YYYYY",
    "message_type":      "MESSAGE_TYPE_MARKETING"
  }
}
```

## Desde `/createTargetedMessage`

`/createTargetedMessage` se mapea a `transactional` en la mayoría de los casos o a `segment` si lo estaba usando puramente como un `devices_filter` entre aplicaciones sin identificadores explícitos.

- `devices_filter` → `segment.expression` (seglang) o `segment.filter_expression` (estructurado).
- `content` → `payload.content.localized_content.{locale}.{platform}.body`.
- Todos los demás campos, igual que en `/createMessage` arriba.

## Desde `/createEmailMessage`

Pase a `Notify` con `platforms: ["EMAIL"]` y un bloque `email_payload`. Referencia completa: [Referencia de payload de correo electrónico](/es/developer/api-reference/messaging-api-v2/email-payload-reference/).

- `subject` → `email_payload.subject` (mapa con clave por configuración regional. Envuelva los valores de una sola configuración regional en `{"en": "..."}`).
- `content` (HTML) → `email_payload.body`.
- `email_template` → `email_payload.email_template`.
- `from` / `from_name` → `email_payload.from` (`{ "name": "...", "email": "..." }`).
- `reply_to` / `reply_to_name` → `email_payload.reply_to`.
- `list_unsubscribe` → `email_payload.list_unsubscribe`.
- `attachments` → `email_payload.attachments` (`[{ "name": "...", "content": "<base64>" }]`).
- Segmentación, programación, campaña, etc., igual que en `/createMessage`.

## Desde `/createSMSMessage`

Pase a `Notify` con `platforms: ["SMS"]`. El cuerpo del SMS se entrega a través del proveedor de SMS configurado en la aplicación. Coloque el contenido en `payload.content.localized_content.{locale}.{platform}.body` en cualquier bloque de plataforma rellenado.

Las opciones específicas del proveedor de SMS (ID del remitente, etc.) continúan proviniendo de la configuración de SMS de la aplicación en lugar del cuerpo de la solicitud.

## Desde `/createKakaoMessage`

Pase a `Notify` con `platforms: ["KAKAO"]`, usando `payload.content.localized_content.{locale}.kakao`:

- `template_id` → `kakao.template`.
- `content` → `kakao.content`.
- `variables` → `kakao.content_variables` (en formato de cadena JSON).

## Desde `/createWhatsAppMessage`

Pase a `Notify` con `platforms: ["WHATS_APP"]`, usando `payload.content.localized_content.{locale}.whatsapp`:

- `content` (texto de formato libre) → `whatsapp.content`. Entregado por Meta solo dentro de la ventana de servicio al cliente de 24 horas.
- `content_id` → `whatsapp.content_id`. Nombre de una plantilla de Meta preaprobada.
- `language` → `whatsapp.language`. Configuración regional de la plantilla de Meta (p. ej., `"en_US"`). Independiente de la clave de configuración regional de `LocalizedContent` externa.
- `content_variables` (objeto en v1) → `whatsapp.content_variables` (objeto en formato de cadena JSON). Ejemplo v1 `{"1": "John"}` se convierte en v2 `"{\"1\":\"John\"}"`.
- `button_url_variables` (objeto) → `whatsapp.button_url_variables` (en formato de cadena JSON).
- `header_variables` (objeto) → `whatsapp.header_variables` (en formato de cadena JSON).
- `preset` → `payload.preset` (preset genérico a nivel de payload).
- Segmentación: el número de teléfono de WhatsApp que en v1 iba en `devices` (p. ej., `"whatsapp:+1234567890"`) debe registrarse a través de [`/registerDevice`](/es/developer/api-reference/device-api#registerdevice) contra un usuario. En v2, segmente al usuario resultante con `transactional.users.list` (o el hwid a través de `transactional.hwids.list`).
- `use_auto_registration`: no soportado. Registre el número de WhatsApp antes de enviar.

## Desde `/createLineMessage`

Pase a `Notify` con `platforms: ["LINE"]`, usando `payload.content.localized_content.{locale}.line`:

- `content` (texto plano) → `line.content`.
- `preset` (código de preset de LINE) → `line.template`. El campo v2 almacena un código que hace referencia a una plantilla de LINE configurada en el Panel de Control de Pushwoosh.
- Plantilla en línea (estructuras de mensajes de imagen, carrusel o flex de v1): no soportado directamente en v2. Preconfigure el mensaje enriquecido como un preset de LINE en el Panel de Control y haga referencia a él a través de `line.template`.
- Segmentación: la lista de `devices` de v1 (IDs de usuario de LINE registrados a través del SDK / `/registerDevice`) se convierte en `transactional.users.list` (o el hwid a través de `transactional.hwids.list`) en v2.

## Diferencias en la respuesta

v1 `/createMessage` devuelve:

```json
{
  "status_code": 200,
  "status_message": "OK",
  "response": { "Messages": ["XXXXX-XXXXX-AAAAA"] }
}
```

v2 `Notify` devuelve:

```json
{
  "result": {
    "message_code": "XXXXX-XXXXX-AAAAA",
    "unknown_identifiers": []
  }
}
```

Las respuestas que no son 200 siguen el sobre de error estándar de gRPC-Gateway (`{ "code": ..., "message": ..., "details": [...] }`) en lugar del par `status_code` / `status_message` de v1.