# Migração da v1

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

Este guia mapeia cada campo legado do `/create*Message` para seu equivalente na Messaging API v2. Use-o como referência ao portar integrações existentes.

<Aside type="note">
Os métodos legados da v1 estão obsoletos, mas totalmente operacionais. Não há uma data final definitiva, então você pode migrar no seu próprio ritmo. Para novas integrações, use a Messaging API v2.
</Aside>

## Diferenças de alto nível

| Aspecto | v1 | v2 |
|---|---|---|
| Endpoint por canal | método separado por canal (`/createMessage`, `/createEmailMessage`, `/createSMSMessage`, `/createKakaoMessage`, …) | endpoint único — `POST /messaging/v2/notify` |
| Autenticação | campo `auth` no corpo da requisição | cabeçalho `Authorization: Token <API_TOKEN>` |
| Direcionamento | misto: `filter` + `conditions` + `devices` + `users` na mesma requisição | divisão explícita: `NotifySegment` vs `NotifyTransactional` |
| Conteúdo | `content` plano + blocos de plataforma irmãos | `payload.content.localized_content.{locale}.{platform}` aninhado |
| Resposta | `MessageCode[]` | `message_code` + `unknown_identifiers` opcional |

## A partir de `/createMessage`

As entradas `notifications[*]` da v1 tornam-se requisições `Notify` individuais (uma mensagem cada). Se uma chamada v1 tiver múltiplas entradas, emita uma `Notify` por entrada.

**Decisão de direcionamento.** Se a entrada v1 usa `devices` ou `users` (listas explícitas), mapeie-a para `transactional`. Caso contrário, mapeie-a para `segment`.

### Campos a nível de requisição

- `application` → `segment.application` ou `transactional.application` (mesmo formato de app-code).
- `applications_group`: não suportado na v2. Use múltiplas requisições por aplicativo.
- `auth`: movido para o cabeçalho `Authorization`, não está mais no corpo.

### Agendamento

- `send_date` (`"YYYY-MM-DD HH:mm"` ou `"now"`) → `schedule.at` (timestamp RFC 3339 UTC). Para reproduzir o `"now"` da v1, defina `schedule.at` para o horário atual. Qualquer timestamp no passado é enviado imediatamente.
- `ignore_user_timezone` → `schedule.follow_user_timezone`. **Invertido:** `ignore_user_timezone: true` torna-se `follow_user_timezone: false`.
- `timezone`: não suportado. A v2 sempre usa UTC para `at`. Converta no lado do cliente.

### Direcionamento

- `filter` (nome do segmento) → `segment.code`.
- `conditions` (`[[tag, op, value], ...]`) → `segment.expression`. Reescreva para uma expressão [seglang](/pt/developer/api-reference/segmentation-filters-api/segmentation-language/). Em seglang, `*` é o E lógico e as tags específicas do aplicativo são referenciadas como `Tag("<application-code>", "<tag>", <op>, <value>)`. Exemplo: `[["Country","EQ","BR"],["Language","EQ","pt"]]` com `conditions_operator: AND` → `Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt")`.
- `conditions_operator` (`AND` / `OR`): incorporado em `segment.expression`.
- `devices` (hwids ou push tokens) → `transactional.hwids.list` ou `transactional.push_tokens.list`. A v2 separa os dois: hwids vão para `hwids`, push tokens brutos para `push_tokens`.
- `users` → `transactional.users.list`.
- `platforms` (códigos numéricos `[1, 3, …]`) → `segment.platforms` ou `transactional.platforms` (enums de string `["IOS", "ANDROID", …]`). Veja [Enum de Plataforma](/pt/developer/api-reference/messaging-api-v2/notify/#platform-enum).

### Conteúdo

- `content` (string) → `payload.content.localized_content.default.{platform}.body`. Na v2, o conteúdo é sempre por localidade e por plataforma. Coloque uma string simples da v1 sob a chave especial `"default"` (tradução genérica, veja [Seleção de Localidade](/pt/developer/api-reference/messaging-api-v2/payload-reference/#locale-selection-for-a-device)).
- `content` (`{locale: text}`) → `payload.content.localized_content.{locale}.{platform}.body`. Duplique o corpo em cada bloco de plataforma direcionado.
- `preset` → `payload.preset`.
- `data` → `payload.custom_data`.
- `rich_media` → `payload.open_action.rich_media.code`.
- `link` → `payload.open_action.link.url`.
- `minimize_link` (`0` ou `2`) → `payload.open_action.link.shortener` (`NONE` ou `BITLY`).
- `inbox_image` → `payload.content.localized_content.{locale}.{platform}.inbox.image_url` (cada bloco de plataforma tem seu próprio `inbox`).
- `inbox_date` → `payload.content.localized_content.{locale}.{platform}.inbox.expiration_date`.
- `inbox_days`: não suportado. Converta para uma `expiration_date` absoluta no lado do cliente.

### Controles de entrega

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

### Não suportado na v2

- `transactionId`: sem equivalente direto. Rastreie a correlação do seu lado.
- `template_bindings`: Vinculações de template Liquid não estão disponíveis na v2. Continue usando a v1 se você depende delas.

### Blocos específicos da plataforma

A v1 aceita parâmetros específicos da plataforma no nível superior de cada entrada `notifications[*]` (`ios`, `android`, `safari`, `chrome`, …). Na v2, eles se movem para dentro da localidade:

```
// 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" }
      }
    }
  }
}
```

Os nomes dos campos dentro dos blocos de plataforma diferem em alguns lugares. Consulte a [Referência de Payload](/pt/developer/api-reference/messaging-api-v2/payload-reference/) para os nomes exatos da v2.

### Exemplo: Antes e depois

**v1 `/createMessage`** (push para um 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"
  }
}
```

## A partir de `/createTargetedMessage`

`/createTargetedMessage` mapeia para `transactional` na maioria dos casos ou para `segment` se você o estivesse usando puramente como um `devices_filter` entre aplicativos sem identificadores explícitos.

- `devices_filter` → `segment.expression` (seglang) ou `segment.filter_expression` (estruturado).
- `content` → `payload.content.localized_content.{locale}.{platform}.body`.
- Todos os outros campos, o mesmo que `/createMessage` acima.

## A partir de `/createEmailMessage`

Mude para `Notify` com `platforms: ["EMAIL"]` e um bloco `email_payload`. Referência completa: [Referência de payload de e-mail](/pt/developer/api-reference/messaging-api-v2/email-payload-reference/).

- `subject` → `email_payload.subject` (mapa chaveado por localidade. Envolva valores de localidade única em `{"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>" }]`).
- Direcionamento, agendamento, campanha, etc., o mesmo que `/createMessage`.

## A partir de `/createSMSMessage`

Mude para `Notify` com `platforms: ["SMS"]`. O corpo do SMS é entregue através do provedor de SMS configurado do aplicativo. Coloque o conteúdo em `payload.content.localized_content.{locale}.{platform}.body` em qualquer bloco de plataforma preenchido.

Opções específicas do provedor de SMS (ID do remetente, etc.) continuam a vir da configuração de SMS do aplicativo em vez do corpo da requisição.

## A partir de `/createKakaoMessage`

Mude para `Notify` com `platforms: ["KAKAO"]`, usando `payload.content.localized_content.{locale}.kakao`:

- `template_id` → `kakao.template`.
- `content` → `kakao.content`.
- `variables` → `kakao.content_variables` (string JSON).

## A partir de `/createWhatsAppMessage`

Mude para `Notify` com `platforms: ["WHATS_APP"]`, usando `payload.content.localized_content.{locale}.whatsapp`:

- `content` (texto de forma livre) → `whatsapp.content`. Entregue pela Meta apenas dentro da janela de 24 horas de atendimento ao cliente.
- `content_id` → `whatsapp.content_id`. Nome de um template da Meta pré-aprovado.
- `language` → `whatsapp.language`. Localidade do template da Meta (ex: `"en_US"`). Independente da chave de localidade externa `LocalizedContent`.
- `content_variables` (objeto na v1) → `whatsapp.content_variables` (objeto em string JSON). Exemplo v1 `{"1": "John"}` torna-se v2 `"{\"1\":\"John\"}"`.
- `button_url_variables` (objeto) → `whatsapp.button_url_variables` (string JSON).
- `header_variables` (objeto) → `whatsapp.header_variables` (string JSON).
- `preset` → `payload.preset` (preset genérico no nível do payload).
- Direcionamento: o número de telefone do WhatsApp que na v1 ia em `devices` (ex: `"whatsapp:+1234567890"`) deve ser registrado via [`/registerDevice`](/pt/developer/api-reference/device-api#registerdevice) em um usuário. Na v2, direcione o usuário resultante com `transactional.users.list` (ou o hwid via `transactional.hwids.list`).
- `use_auto_registration`: não suportado. Registre o número do WhatsApp antes de enviar.

## A partir de `/createLineMessage`

Mude para `Notify` com `platforms: ["LINE"]`, usando `payload.content.localized_content.{locale}.line`:

- `content` (texto simples) → `line.content`.
- `preset` (código de preset LINE) → `line.template`. O campo v2 armazena um código que referencia um template LINE configurado no Painel de Controle da Pushwoosh.
- `template` em linha (estruturas de mensagem de imagem, carrossel ou flex da v1): não suportado diretamente na v2. Pré-configure a mensagem rica como um preset LINE no Painel de Controle e referencie-a através de `line.template`.
- Direcionamento: a lista `devices` da v1 (IDs de usuário LINE registrados através do SDK / `/registerDevice`) torna-se `transactional.users.list` (ou o hwid via `transactional.hwids.list`) na v2.

## Diferenças na resposta

v1 `/createMessage` retorna:

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

v2 `Notify` retorna:

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

Respostas diferentes de 200 seguem o envelope de erro padrão do gRPC-Gateway (`{ "code": ..., "message": ..., "details": [...] }`) em vez do par `status_code` / `status_message` da v1.