> ## 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.

# Примеры Webhook для обновления статуса сообщений WhatsApp

> Узнайте о статусах сообщений WhatsApp: отправлено, доставлено, прочитано и ошибка доставки.

<Note>Полный каталог, составленный на основе схемы, доступен в разделе [все примеры](/ru/api-reference/guides/examples/webhook-examples/webhook-payload-examples).</Note>

## Что это такое

Узнайте о статусах сообщений WhatsApp: отправлено, доставлено, прочитано и ошибка доставки.

## Перед началом работы

* Создайте публичный эндпоинт HTTPS в своем приложении.
* Настройте эндпоинт webhook в YCloud для необходимых типов событий.
* Надежно сохраните секрет подписи эндпоинта (signing secret).
* Обеспечьте идемпотентность обработки событий.

## Как это работает

YCloud отправляет HTTP-запрос `POST` при возникновении события. Проверьте подпись, надежно сохраните событие, верните ответ `2xx` и обработайте длительные задачи асинхронно.

## Запрос

Ниже приведены сценарии запросов, отправляемых на ваш Webhook URL. Используйте `id` события как идентификатор доставки, а `type` — для маршрутизации полезной нагрузки (payload).

## Ответ

Возвращайте статус `2xx` после успешного приема события.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
HTTP/1.1 200 OK
```

<Note>Информацию о настройке эндпоинта, проверке подписи и логике повторных попыток см. в разделе [Настройка webhook](/ru/api-reference/guides/api-fundamentals/configure-webhooks).</Note>

После успешного запроса к API на отправку сообщений они получают статус `accepted`. Обновления статуса сообщения инициируют отправку события webhook `whatsapp.message.updated`.

Обычно статус сообщения:

* Меняется на `failed`, если нам не удалось доставить это сообщение.
* Меняется на `sent`, если сообщение возможно доставить, и позже может измениться на `failed`, `delivered` или `read`.
* Меняется на `delivered` или `read`, если сообщение было доставлено на устройство получателя.

Однако реальные сценарии могут быть сложнее. Во-первых, мы не гарантируем порядок уведомлений webhook, особенно если события происходят практически одновременно. Во-вторых, события `delivered` могут поступать позже событий `failed` и наоборот, особенно если конечный пользователь использует несколько устройств.

## Сообщение отправлено

В этом случае ваш эндпоинт webhook получил событие сообщения `sent`:

* Параметр сообщения `status` имеет значение `sent`, что означает, что сообщение находится в процессе передачи внутри систем WhatsApp.
* Содержит информацию о диалоге, включая время истечения срока действия диалога и тип инициатора (origin type).
* Содержит **предварительную** сумму `pricingCategory` и валюту `totalPrice`, которые могут быть списаны с вашего счета.
* Содержит поле `wamid` — исходный идентификатор сообщения на платформе WhatsApp, начинающийся с `wamid.`.

### Запрос

```shell theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl 'https://YOUR-WEBHOOK-ENDPOINT-URL' \
-H 'Content-Type: application/json' \
-d '{
  "id": "evt_eEVCy8eNqD9EvcFI",
  "type": "whatsapp.message.updated",
  "apiVersion": "v2",
  "createTime": "2023-02-22T12:00:00.000Z",
  "whatsappMessage": {
    "id": "63f5d602367ea403f8175a6c",
    "wamid": "wamid.BgNODYxN...",
    "recipientUserId" : "US.13491208655302741918",
    "parentRecipientUserId": "US.ENT.11815799212886844830",
    "customerProfile": {
      "name": "Pablo M."
    },
    "status": "sent",
    "pricingCategory": "marketing",
    "totalPrice": 0.0,
    "currency": "USD",
    "createTime": "2022-03-01T12:00:00.000Z",
    "sendTime": "2022-03-01T12:00:01.000Z",
    "bizType": "whatsapp",
    "type": "text",
    "text": {
      "body": "Hi there! How can we help?"
    },
    "externalId": "EXTERNAL-ID"
  }
}'
```

### Ответ

Подтвердите доставку после надежного сохранения и обработки события.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
HTTP/1.1 200 OK
```

### Пояснение

* **`totalPrice` — это только ориентировочная цена до момента доставки первого сообщения; она становится окончательной ценой, когда `status` принимает значение `delivered` или `read`. Баланс, заблокированный под отправленные, но еще не доставленные сообщения, станет доступен только после их аннулирования (отправленные сообщения, которые не были доставлены в течение 30 дней, аннулируются).**

* Как правило, статус сообщения со значением `sent` вскоре меняется на `delivered` или `read`, за исключением следующих случаев:
  * Аккаунт WhatsApp получателя находится офлайн; отправленные вами сообщения WhatsApp не будут доставлены до тех пор, пока у получателя не появится стабильное интернет-соединение.
  * Любое сообщение, отправленное контакту, который вас заблокировал, всегда будет отображать статус `sent` и никогда не перейдет в статус `delivered`.
  * Получатель отключил отчеты о прочтении, поэтому вы не получите отчеты со статусом `read`.
  * Позже статус сообщения меняется на `failed` с кодом ошибки `131026`, что означает «Message Undeliverable» (Сообщение не может быть доставлено) или «Receiver is incapable of receiving this message» (Получатель не может принять это сообщение). Чаще всего это связано с тем, что получатель не зарегистрирован или использует устаревшую версию WhatsApp.
  * Сообщение не было доставлено для поддержания высокого качества обслуживания пользователей. См. раздел [Ограничения на отправку маркетинговых шаблонных сообщений на одного пользователя](https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-message-templates#per-user-marketing-template-message-limits).

## Сообщение доставлено

В этом случае ваш эндпоинт webhook получил событие сообщения `delivered`:

* Параметр сообщения `status` имеет значение `delivered`, что означает, что сообщение было доставлено на устройство получателя.

### Запрос

```shell theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl 'https://YOUR-WEBHOOK-ENDPOINT-URL' \
-H 'Content-Type: application/json' \
-d '{
  "id": "evt_eEVCy8eNqD9EvcFI",
  "type": "whatsapp.message.updated",
  "apiVersion": "v2",
  "createTime": "2023-02-22T12:00:00.000Z",
  "whatsappMessage": {
    "id": "63f5d602367ea403f8175a6c",
    "wamid": "wamid.BgNODYxN...",
    "recipientUserId" : "US.13491208655302741918",
    "parentRecipientUserId": "US.ENT.11815799212886844830",
    "customerProfile": {
      "name": "Pablo M.",
      "username": "@pablomorales"
    },
    "status": "delivered",
    "pricingModel": "PMP",
    "pricingType": "regular",
    "pricingCategory": "marketing",
    "totalPrice": 0.0,
    "currency": "USD",
    "createTime": "2022-03-01T12:00:00.000Z",
    "sendTime": "2022-03-01T12:00:01.000Z",
    "deliverTime": "2022-03-01T12:00:02.000Z",
    "bizType": "whatsapp",
    "type": "text",
    "text": {
      "body": "Hi there! How can we help?"
    },
    "externalId": "EXTERNAL-ID"
  }
}'
```

### Ответ

Подтвердите доставку после надежного сохранения и обработки события.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
HTTP/1.1 200 OK
```

### Пояснение

* Это событие указывает на то, что сообщение, отправленное вашей компанией, было доставлено на устройство пользователя.
* **Чтобы статус стал `read`, сообщение сначала должно быть со статусом `delivered`. В некоторых случаях, например, когда пользователь находится на экране чата в момент поступления сообщения, оно становится `delivered` и `read` практически одновременно. В таком или похожих сценариях уведомление `delivered` не будет отправлено повторно, поскольку факт прочтения сообщения подразумевает, что оно уже доставлено. Такое поведение обусловлено внутренней оптимизацией.**
* Мы можем сгенерировать более 1 события webhook `delivered` для одного и того же сообщения, особенно если конечный пользователь использует несколько устройств.
* **pricingModel**: «PMP» — указывает, что применяется модель тарификации за каждое сообщение (per-message pricing). См. также [whatsapp-message-pricing-updates](https://docs.ycloud.com/reference/whatsapp-message-pricing-updates)
* **pricingType**
  * **regular** — указывает, что сообщение подлежит оплате.
  * **free\_customer\_service** — указывает, что сообщение бесплатно, так как оно было либо шаблонным сервисным сообщением (utility), либо нешаблонным сообщением, отправленным в рамках окна клиентского обслуживания.
  * **free\_entry\_point** — указывает, что сообщение бесплатно, так как оно является частью переписки с бесплатной точки входа.

## Сообщение прочитано

В этом случае ваша конечная точка Webhook получила событие сообщения `read`:

* Поле `status` сообщения имеет значение `read`, что означает, что сообщение было прочитано получателем.

### Запрос

```shell theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl 'https://YOUR-WEBHOOK-ENDPOINT-URL' \
-H 'Content-Type: application/json' \
-d '{
  "id": "evt_eEVCy8eNqD9EvcFI",
  "type": "whatsapp.message.updated",
  "apiVersion": "v2",
  "createTime": "2023-02-22T12:00:00.000Z",
  "whatsappMessage": {
    "id": "63f5d602367ea403f8175a6c",
    "wamid": "wamid.BgNODYxN...",
    "recipientUserId" : "US.13491208655302741918",
    "parentRecipientUserId": "US.ENT.11815799212886844830",
    "customerProfile": {
      "name": "Pablo M.",
      "username": "@pablomorales"
    },
    "status": "read",
    "pricingModel": "PMP",
    "pricingType": "regular",
    "pricingCategory": "marketing",
    "totalPrice": 0.0,
    "currency": "USD",
    "createTime": "2022-03-01T12:00:00.000Z",
    "sendTime": "2022-03-01T12:00:01.000Z",
    "deliverTime": "2022-03-01T12:00:02.000Z",
    "readTime": "2022-03-01T12:00:02.000Z",
    "bizType": "whatsapp",
    "type": "text",
    "text": {
      "body": "Hi there! How can we help?"
    },
    "externalId": "EXTERNAL-ID"
  }
}'
```

### Ответ

Подтвердите доставку после надежного сохранения/принятия события.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
HTTP/1.1 200 OK
```

### Пояснение

* Если получатель отключил отчеты о прочтении, вы не получите уведомления `read` о прочтении сообщения.

## Ошибка отправки сообщения

В этом случае ваша конечная точка Webhook получила событие сообщения `failed`:

* Поле `status` сообщения имеет значение `failed`.
* Содержит `errroCode`, `errorMessage` и `whatsappApiError`.

### Запрос

```shell theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl 'https://YOUR-WEBHOOK-ENDPOINT-URL' \
-H 'Content-Type: application/json' \
-d '{
  "id": "evt_eEVCy8eNqD9EvcFI",
  "type": "whatsapp.message.updated",
  "apiVersion": "v2",
  "createTime": "2023-02-22T12:00:00.000Z",
  "whatsappMessage": {
    "id": "63f5d602367ea403f8175a6c",
    "wamid": "wamid.BgNODYxN...",
    "recipientUserId" : "US.13491208655302741918",
    "parentRecipientUserId": "US.ENT.11815799212886844830",
    "status": "failed",
    "errorCode": "100",
    "errorMessage": "Parameter Invalid",
    "whatsappApiError": {
      "message": "(#100) Invalid parameter",
      "type": "OAuthException",
      "code": "100",
      "fbtrace_id": "AwmiSOCojlAkqvjCTjGt37r",
      "error_data": {
        "messaging_product": "whatsapp",
        "details": "Parameter Invalid"
      }
    },
    "pricingCategory": "marketing",
    "totalPrice": 0.0,
    "currency": "USD",
    "bizType": "whatsapp",
    "type": "text",
    "text": {
      "body": "Hi there! How can we help?"
    },
    "externalId": "EXTERNAL-ID"
  }
}'
```

### Ответ

Подтвердите доставку после надежного сохранения/принятия события.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
HTTP/1.1 200 OK
```

### Пояснение

* Эти события предназначены для уведомления об изменении статуса исходящих сообщений, которые вы ранее отправили клиентам.
* Причиной сбоя отправки сообщений обычно являются недействительные параметры запроса, незарегистрированный номер телефона клиента и т. д. См. также раздел [Ошибки WhatsApp](https://docs.ycloud.com/reference/whatsapp-errors) для информации об обработке ошибок.
* Поле `whatsappApiError` передается, если мы пытались отправить это сообщение на платформу WhatsApp от Meta, чтобы помочь вам разобраться в деталях ошибки. См. также [Коды ошибок Cloud API](https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes).
* Плата за несостоявшиеся сообщения не взимается.


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