# Миграция с v1

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

Это руководство сопоставляет каждое поле устаревших методов `/create*Message` с его эквивалентом в Messaging API v2. Используйте его как справочник при переносе существующих интеграций.

<Aside type="note">
Устаревшие методы v1 считаются нерекомендуемыми, но полностью работоспособны. Точная дата прекращения поддержки не установлена, поэтому вы можете выполнять миграцию в удобном для вас темпе. Для новых интеграций используйте Messaging API v2.
</Aside>

## Ключевые различия

| Аспект | v1 | v2 |
|---|---|---|
| Конечная точка для каждого канала | отдельный метод для каждого канала (`/createMessage`, `/createEmailMessage`, `/createSMSMessage`, `/createKakaoMessage`, …) | единая конечная точка — `POST /messaging/v2/notify` |
| Аутентификация | поле `auth` в теле запроса | заголовок `Authorization: Token <API_TOKEN>` |
| Таргетинг | смешанный: `filter` + `conditions` + `devices` + `users` в одном запросе | явное разделение: `NotifySegment` и `NotifyTransactional` |
| Контент | плоский `content` + соседние блоки платформ | вложенный `payload.content.localized_content.{locale}.{platform}` |
| Ответ | `MessageCode[]` | `message_code` + опциональный `unknown_identifiers` |

## Из `/createMessage`

Записи v1 `notifications[*]` становятся отдельными запросами `Notify` (по одному сообщению в каждом). Если вызов v1 содержит несколько записей, выполните по одному `Notify` для каждой записи.

**Решение по таргетингу.** Если запись v1 использует `devices` или `users` (явные списки), сопоставьте ее с `transactional`. В противном случае сопоставьте ее с `segment`.

### Поля на уровне запроса

- `application` → `segment.application` или `transactional.application` (тот же формат app-code).
- `applications_group`: не поддерживается в v2. Используйте несколько запросов для каждого приложения.
- `auth`: перенесено в заголовок `Authorization`, больше не находится в теле запроса.

### Планирование

- `send_date` (`"YYYY-MM-DD HH:mm"` или `"now"`) → `schedule.at` (метка времени в формате RFC 3339 UTC). Чтобы воспроизвести `"now"` из v1, установите `schedule.at` на текущее время. Любая метка времени в прошлом отправляется немедленно.
- `ignore_user_timezone` → `schedule.follow_user_timezone`. **Инвертировано:** `ignore_user_timezone: true` становится `follow_user_timezone: false`.
- `timezone`: не поддерживается. v2 всегда использует UTC для `at`. Выполняйте преобразование на стороне клиента.

### Таргетинг

- `filter` (название сегмента) → `segment.code`.
- `conditions` (`[[tag, op, value], ...]`) → `segment.expression`. Перепишите в выражение [seglang](/ru/developer/api-reference/segmentation-filters-api/segmentation-language/). В seglang `*` — это логическое И, а теги, специфичные для приложения, указываются как `Tag("<application-code>", "<tag>", <op>, <value>)`. Пример: `[["Country","EQ","BR"],["Language","EQ","pt"]]` с `conditions_operator: AND` → `Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt")`.
- `conditions_operator` (`AND` / `OR`): включен в `segment.expression`.
- `devices` (hwids или push-токены) → `transactional.hwids.list` или `transactional.push_tokens.list`. v2 разделяет их: hwids идут в `hwids`, а необработанные push-токены — в `push_tokens`.
- `users` → `transactional.users.list`.
- `platforms` (числовые коды `[1, 3, …]`) → `segment.platforms` или `transactional.platforms` (строковые перечисления `["IOS", "ANDROID", …]`). См. [Platform enum](/ru/developer/api-reference/messaging-api-v2/notify/#platform-enum).

### Контент

- `content` (строка) → `payload.content.localized_content.default.{platform}.body`. В v2 контент всегда указывается для каждой локали и платформы. Поместите простую строку из v1 под специальный ключ `"default"` (общий перевод, см. [Выбор локали](/ru/developer/api-reference/messaging-api-v2/payload-reference/#locale-selection-for-a-device)).
- `content` (`{locale: text}`) → `payload.content.localized_content.{locale}.{platform}.body`. Дублируйте тело в каждый блок целевой платформы.
- `preset` → `payload.preset`.
- `data` → `payload.custom_data`.
- `rich_media` → `payload.open_action.rich_media.code`.
- `link` → `payload.open_action.link.url`.
- `minimize_link` (`0` или `2`) → `payload.open_action.link.shortener` (`NONE` или `BITLY`).
- `inbox_image` → `payload.content.localized_content.{locale}.{platform}.inbox.image_url` (у каждого блока платформы есть свой `inbox`).
- `inbox_date` → `payload.content.localized_content.{locale}.{platform}.inbox.expiration_date`.
- `inbox_days`: не поддерживается. Преобразуйте в абсолютную `expiration_date` на стороне клиента.

### Управление доставкой

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

### Не поддерживается в v2

- `transactionId`: нет прямого эквивалента. Отслеживайте корреляцию на своей стороне.
- `template_bindings`: Привязки шаблонов Liquid недоступны в v2. Продолжайте использовать v1, если вы на них полагаетесь.

### Блоки для конкретных платформ

v1 принимает параметры для конкретных платформ на верхнем уровне каждой записи `notifications[*]` (`ios`, `android`, `safari`, `chrome`, …). В v2 они перемещаются внутрь локали:

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

Названия полей в блоках платформ могут отличаться. Точные названия для v2 см. в [Справочнике по payload](/ru/developer/api-reference/messaging-api-v2/payload-reference/).

### Пример: До и после

**v1 `/createMessage`** (пуш в сегмент):

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

## Из `/createTargetedMessage`

`/createTargetedMessage` в большинстве случаев сопоставляется с `transactional` или с `segment`, если вы использовали его исключительно как межприложенческий `devices_filter` без явных идентификаторов.

- `devices_filter` → `segment.expression` (seglang) или `segment.filter_expression` (структурированный).
- `content` → `payload.content.localized_content.{locale}.{platform}.body`.
- Все остальные поля — так же, как и для `/createMessage` выше.

## Из `/createEmailMessage`

Перейдите на `Notify` с `platforms: ["EMAIL"]` и блоком `email_payload`. Полный справочник: [Справочник по email payload](/ru/developer/api-reference/messaging-api-v2/email-payload-reference/).

- `subject` → `email_payload.subject` (карта с ключом по локали. Оберните значения для одной локали в `{"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>" }]`).
- Таргетинг, планирование, кампания и т.д. — так же, как и для `/createMessage`.

## Из `/createSMSMessage`

Перейдите на `Notify` с `platforms: ["SMS"]`. Тело SMS доставляется через настроенного в приложении SMS-провайдера. Поместите контент в `payload.content.localized_content.{locale}.{platform}.body` в любом заполненном блоке платформы.

Специфичные для SMS опции провайдера (ID отправителя и т.д.) по-прежнему берутся из конфигурации SMS приложения, а не из тела запроса.

## Из `/createKakaoMessage`

Перейдите на `Notify` с `platforms: ["KAKAO"]`, используя `payload.content.localized_content.{locale}.kakao`:

- `template_id` → `kakao.template`.
- `content` → `kakao.content`.
- `variables` → `kakao.content_variables` (преобразованный в строку JSON).

## Из `/createWhatsAppMessage`

Перейдите на `Notify` с `platforms: ["WHATS_APP"]`, используя `payload.content.localized_content.{locale}.whatsapp`:

- `content` (свободный текст) → `whatsapp.content`. Доставляется Meta только в течение 24-часового окна обслуживания клиентов.
- `content_id` → `whatsapp.content_id`. Название предварительно одобренного шаблона Meta.
- `language` → `whatsapp.language`. Локаль шаблона Meta (например, `"en_US"`). Независимо от ключа локали внешнего `LocalizedContent`.
- `content_variables` (объект в v1) → `whatsapp.content_variables` (объект, преобразованный в строку JSON). Пример: v1 `{"1": "John"}` становится v2 `"{\"1\":\"John\"}"`.
- `button_url_variables` (объект) → `whatsapp.button_url_variables` (преобразованный в строку JSON).
- `header_variables` (объект) → `whatsapp.header_variables` (преобразованный в строку JSON).
- `preset` → `payload.preset` (общий пресет на уровне payload).
- Таргетинг: номер телефона WhatsApp, который в v1 передавался в `devices` (например, `"whatsapp:+1234567890"`), должен быть зарегистрирован через [`/registerDevice`](/ru/developer/api-reference/device-api#registerdevice) для пользователя. В v2 нацеливайтесь на полученного пользователя с помощью `transactional.users.list` (или на hwid через `transactional.hwids.list`).
- `use_auto_registration`: не поддерживается. Зарегистрируйте номер WhatsApp перед отправкой.

## Из `/createLineMessage`

Перейдите на `Notify` с `platforms: ["LINE"]`, используя `payload.content.localized_content.{locale}.line`:

- `content` (простой текст) → `line.content`.
- `preset` (код пресета LINE) → `line.template`. Поле v2 хранит код, который ссылается на шаблон LINE, настроенный в Панели управления Pushwoosh.
- Встроенный `template` (структуры сообщений v1: изображение, карусель или flex): не поддерживается напрямую в v2. Предварительно настройте rich-сообщение как пресет LINE в Панели управления и ссылайтесь на него через `line.template`.
- Таргетинг: список `devices` из v1 (ID пользователей LINE, зарегистрированные через SDK / `/registerDevice`) становится `transactional.users.list` (или hwid через `transactional.hwids.list`) в v2.

## Различия в ответах

v1 `/createMessage` возвращает:

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

v2 `Notify` возвращает:

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

Ответы, отличные от 200, следуют стандартной структуре ошибок gRPC-Gateway (`{ "code": ..., "message": ..., "details": [...] }`) вместо пары `status_code` / `status_message` из v1.