# Migration depuis la v1

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

Ce guide mappe chaque champ hérité de `/create*Message` sur son équivalent dans l'API de Messagerie v2. Utilisez-le comme référence lors de la migration de vos intégrations existantes.

<Aside type="note">
Les méthodes héritées de la v1 sont obsolètes mais entièrement opérationnelles. Il n'y a pas de date de fin de support stricte, vous pouvez donc migrer à votre propre rythme. Pour les nouvelles intégrations, utilisez l'API de Messagerie v2.
</Aside>

## Différences de haut niveau

| Aspect | v1 | v2 |
|---|---|---|
| Point de terminaison par canal | méthode distincte par canal (`/createMessage`, `/createEmailMessage`, `/createSMSMessage`, `/createKakaoMessage`, …) | point de terminaison unique — `POST /messaging/v2/notify` |
| Authentification | champ `auth` dans le corps de la requête | en-tête `Authorization: Token <API_TOKEN>` |
| Ciblage | mixte : `filter` + `conditions` + `devices` + `users` dans la même requête | séparation explicite : `NotifySegment` vs `NotifyTransactional` |
| Contenu | `contenu` plat + blocs de plateforme frères | `payload.content.localized_content.{locale}.{platform}` imbriqué |
| Réponse | `MessageCode[]` | `message_code` + `unknown_identifiers` optionnel |

## Depuis `/createMessage`

Les entrées `notifications[*]` de la v1 deviennent des requêtes `Notify` individuelles (un message chacune). Si un appel v1 a plusieurs entrées, émettez une requête `Notify` par entrée.

**Décision de ciblage.** Si l'entrée v1 utilise `devices` ou `users` (listes explicites), mappez-la sur `transactional`. Sinon, mappez-la sur `segment`.

### Champs au niveau de la requête

- `application` → `segment.application` ou `transactional.application` (même format de code d'application).
- `applications_group` : non pris en charge dans la v2. Utilisez plusieurs requêtes par application.
- `auth` : déplacé vers l'en-tête `Authorization`, n'est plus dans le corps.

### Planification

- `send_date` (`"AAAA-MM-JJ HH:mm"` ou `"now"`) → `schedule.at` (horodatage UTC RFC 3339). Pour reproduire `"now"` de la v1, définissez `schedule.at` sur l'heure actuelle. Tout horodatage dans le passé est envoyé immédiatement.
- `ignore_user_timezone` → `schedule.follow_user_timezone`. **Inversé :** `ignore_user_timezone: true` devient `follow_user_timezone: false`.
- `timezone` : non pris en charge. La v2 utilise toujours UTC pour `at`. Convertissez côté client.

### Ciblage

- `filter` (nom du segment) → `segment.code`.
- `conditions` (`[[tag, op, value], ...]`) → `segment.expression`. Réécrivez en une expression [seglang](/fr/developer/api-reference/segmentation-filters-api/segmentation-language/). En seglang, `*` est un ET logique et les tags spécifiques à l'application sont référencés comme `Tag("<application-code>", "<tag>", <op>, <value>)`. Exemple : `[["Country","EQ","BR"],["Language","EQ","pt"]]` avec `conditions_operator: AND` → `Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt")`.
- `conditions_operator` (`AND` / `OR`) : intégré dans `segment.expression`.
- `devices` (hwids ou push tokens) → `transactional.hwids.list` ou `transactional.push_tokens.list`. La v2 sépare les deux : les hwids vont dans `hwids`, les push tokens bruts dans `push_tokens`.
- `users` → `transactional.users.list`.
- `platforms` (codes numériques `[1, 3, …]`) → `segment.platforms` ou `transactional.platforms` (énumérations de chaînes `["IOS", "ANDROID", …]`). Voir [l'énumération Platform](/fr/developer/api-reference/messaging-api-v2/notify/#platform-enum).

### Contenu

- `content` (chaîne) → `payload.content.localized_content.default.{platform}.body`. Dans la v2, le contenu est toujours par locale et par plateforme. Placez une chaîne v1 simple sous la clé spéciale `"default"` (traduction fourre-tout, voir [Sélection de la locale](/fr/developer/api-reference/messaging-api-v2/payload-reference/#locale-selection-for-a-device)).
- `content` (`{locale: text}`) → `payload.content.localized_content.{locale}.{platform}.body`. Dupliquez le corps dans chaque bloc de plateforme ciblé.
- `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` (chaque bloc de plateforme a son propre `inbox`).
- `inbox_date` → `payload.content.localized_content.{locale}.{platform}.inbox.expiration_date`.
- `inbox_days` : non pris en charge. Convertissez en une `expiration_date` absolue côté client.

### Contrôles de livraison

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

### Non pris en charge dans la v2

- `transactionId` : pas d'équivalent direct. Suivez la corrélation de votre côté.
- `template_bindings` : les liaisons de modèles Liquid ne sont pas disponibles dans la v2. Continuez à utiliser la v1 si vous en dépendez.

### Blocs spécifiques à la plateforme

La v1 accepte les paramètres spécifiques à la plateforme au niveau supérieur de chaque entrée `notifications[*]` (`ios`, `android`, `safari`, `chrome`, …). Dans la v2, ils se déplacent à l'intérieur de la locale :

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

Les noms de champs dans les blocs de plateforme diffèrent par endroits. Consultez la [Référence du payload](/fr/developer/api-reference/messaging-api-v2/payload-reference/) pour les noms exacts de la v2.

### Exemple : Avant et après

**v1 `/createMessage`** (push vers un segment) :

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

## Depuis `/createTargetedMessage`

`/createTargetedMessage` se mappe sur `transactional` dans la plupart des cas ou sur `segment` si vous l'utilisiez uniquement comme un `devices_filter` inter-applications sans identifiants explicites.

- `devices_filter` → `segment.expression` (seglang) ou `segment.filter_expression` (structuré).
- `content` → `payload.content.localized_content.{locale}.{platform}.body`.
- Tous les autres champs, comme pour `/createMessage` ci-dessus.

## Depuis `/createEmailMessage`

Passez à `Notify` avec `platforms: ["EMAIL"]` et un bloc `email_payload`. Référence complète : [Référence du payload d'e-mail](/fr/developer/api-reference/messaging-api-v2/email-payload-reference/).

- `subject` → `email_payload.subject` (mappe indexée par locale. Encadrez les valeurs à locale unique dans `{"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>" }]`).
- Ciblage, planification, campagne, etc., comme pour `/createMessage`.

## Depuis `/createSMSMessage`

Passez à `Notify` avec `platforms: ["SMS"]`. Le corps du SMS est livré via le fournisseur SMS configuré de l'application. Placez le contenu dans `payload.content.localized_content.{locale}.{platform}.body` sur n'importe quel bloc de plateforme rempli.

Les options spécifiques au fournisseur SMS (ID de l'expéditeur, etc.) continuent de provenir de la configuration SMS de l'application plutôt que du corps de la requête.

## Depuis `/createKakaoMessage`

Passez à `Notify` avec `platforms: ["KAKAO"]`, en utilisant `payload.content.localized_content.{locale}.kakao` :

- `template_id` → `kakao.template`.
- `content` → `kakao.content`.
- `variables` → `kakao.content_variables` (chaîne JSON).

## Depuis `/createWhatsAppMessage`

Passez à `Notify` avec `platforms: ["WHATS_APP"]`, en utilisant `payload.content.localized_content.{locale}.whatsapp` :

- `content` (texte libre) → `whatsapp.content`. Livré par Meta uniquement dans la fenêtre de service client de 24 heures.
- `content_id` → `whatsapp.content_id`. Nom d'un modèle Meta pré-approuvé.
- `language` → `whatsapp.language`. Locale du modèle Meta (par ex. `"en_US"`). Indépendant de la clé de locale `LocalizedContent` externe.
- `content_variables` (objet en v1) → `whatsapp.content_variables` (objet sous forme de chaîne JSON). Exemple v1 `{"1": "John"}` devient v2 `"{\"1\":\"John\"}"`.
- `button_url_variables` (objet) → `whatsapp.button_url_variables` (chaîne JSON).
- `header_variables` (objet) → `whatsapp.header_variables` (chaîne JSON).
- `preset` → `payload.preset` (preset générique au niveau du payload).
- Ciblage : le numéro de téléphone WhatsApp qui, dans la v1, allait dans `devices` (par ex. `"whatsapp:+1234567890"`) doit être enregistré via [`/registerDevice`](/fr/developer/api-reference/device-api#registerdevice) pour un utilisateur. Dans la v2, ciblez l'utilisateur résultant avec `transactional.users.list` (ou le hwid via `transactional.hwids.list`).
- `use_auto_registration` : non pris en charge. Enregistrez le numéro WhatsApp avant l'envoi.

## Depuis `/createLineMessage`

Passez à `Notify` avec `platforms: ["LINE"]`, en utilisant `payload.content.localized_content.{locale}.line` :

- `content` (texte brut) → `line.content`.
- `preset` (code de preset LINE) → `line.template`. Le champ v2 stocke un code qui référence un modèle LINE configuré dans le Panneau de Contrôle Pushwoosh.
- Modèle en ligne (structures de message image, carrousel ou flex de la v1) : non pris en charge directement dans la v2. Pré-configurez le message riche comme un preset LINE dans le Panneau de Contrôle et référencez-le via `line.template`.
- Ciblage : la liste `devices` de la v1 (ID utilisateur LINE enregistrés via le SDK / `/registerDevice`) devient `transactional.users.list` (ou le hwid via `transactional.hwids.list`) dans la v2.

## Différences de réponse

La v1 `/createMessage` retourne :

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

La v2 `Notify` retourne :

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

Les réponses non-200 suivent l'enveloppe d'erreur standard gRPC-Gateway (`{ "code": ..., "message": ..., "details": [...] }`) au lieu de la paire `status_code` / `status_message` de la v1.