## Čím sa hromadné doručenky líšia

V predvolenom nastavení príde na vašu adresu jedna požiadavka za každú správu.
Pri veľkých objemoch to znamená tisíce požiadaviek — hromadná varianta ich zlúči
do dávok.

| | Jednotlivo | Hromadne |
|:--|:--|:--|
| Metóda | HTTP GET | HTTP POST |
| Formát | Parametre v query stringu | JSON v tele požiadavky |
| Obsah | Jedna správa | Pole záznamov |

Obe nesú to isté — potvrdenia o doručení aj prichádzajúce správy. Popis jednotlivej
varianty nájdete na stránke
[Potvrdenie o doručení](https://www.bulkgate.com/sk/dokumentacia/api-administracia-a-tokeny/api-potvrdenie-o-doruceni-a-prichadzajucich-spravach/).

## Ako zapnem hromadné zasielanie

V nastavení webhooku zaškrtnite `Zasielať doručenky hromadne`. Adresa aj ostatné
voľby zostávajú rovnaké — mení sa len spôsob, akým vám dáta prichádzajú.

![Nastavenie potvrdení o doručení so zaškrtnutou voľbou hromadného zasielania](docs:api-bulk-delivery-confirmations-and-incoming-sms/bulk-setting_cs)

Celý postup vrátane toho, kde nastavenie nájdete, popisuje
[Webhooky](https://www.bulkgate.com/sk/dokumentacia/api-administracia-a-tokeny/webhooky/).

## Ako vyzerá požiadavka

Príde metódou POST s hlavičkou `Content-Type: application/json`. Telo je pole,
v ktorom sa miešajú doručenky aj prichádzajúce správy — rozlíšite ich podľa `status`.

```http-json
POST /hook/delivery-report HTTP/1.1
Host: example.com
Content-Type: application/json

[
   {
      "status": "1",
      "smsID": "3t2563af3ff285",
      "price": "0.71",
      "date": "1904111007;1904111011"
   },
   {
      "status": "2",
      "smsID": "2t2563af3ff285",
      "price": "0.71",
      "date": "1904111007;1904111011"
   },
   {
      "status": "10",
      "from": "420777777777",
      "message": "text odpovede"
   }
]
```

## Parametre záznamu

| Parameter | Hodnota | Kedy príde |
|:--|:--|:--|
| `status` | Kód stavu — pozri [stavy doručenia](#stavy-dorucenia) | Vždy |
| `smsID` | Jednoznačné ID správy | Pri doručenke |
| `price` | Cena správy v kreditoch | Pri doručenke |
| `date` | Čas odoslania a doručenia oddelený bodkočiarkou, časové pásmo CET | Pri doručenke |
| `from` | Telefónne číslo odosielateľa | Len pri `status` `10` |
| `message` | Text správy v kódovaní UTF-8 | Len pri `status` `10` |

Hodnota `date` má tvar `RRMMDDHHMM;RRMMDDHHMM` — `1904111007;1904111011` teda
znamená odoslané 11. 4. 2019 o 10:07 a doručené o 10:11.

## Stavy doručenia

| Kód | Význam |
|:--|:--|
| `1` | Správa bola doručená |
| `2` | Správa čaká vo fronte na strane operátora — príjemca je momentálne nedostupný a doručenie sa skúsi znova |
| `3` | Správu sa nepodarilo doručiť — príjemca je neznámy alebo trvalo nedostupný |
| `10` | Prichádzajúca správa alebo odpoveď, nie doručenka |
| `13` | Správa bola prečítaná (len Viber) |

> [!NOTE]
> Stav `2` nie je konečný — k tej istej správe vám neskôr príde ďalší záznam
> s výsledným stavom. Počítajte s tým, že `smsID` uvidíte viackrát, pokojne
> aj v tej istej dávke.

## Ukážka spracovania

Skript načíta telo požiadavky, prejde pole a každý záznam pošle podľa `status` do
príslušnej vetvy:

```php
<?php declare(strict_types=1);

const STATUS = [
    1 => 'doručené',
    2 => 'čaká u operátora',
    3 => 'nedoručené',
    13 => 'prečítané',
];

function log_line(string $file, string $message): void
{
    file_put_contents(
        __DIR__ . "/$file.log",
        '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL,
        FILE_APPEND
    );
}

function parse_date(string $value): string
{
    // tvar RRMMDDHHMM, napríklad 1904111007
    $date = DateTimeImmutable::createFromFormat('ymdHi', $value);

    return $date ? $date->format('Y-m-d H:i') : '?';
}

$body = file_get_contents('php://input');
$records = json_decode($body ?: '', true);

if (!is_array($records))
{
    http_response_code(400);
    exit;
}

foreach ($records as $record)
{
    $status = (int) ($record['status'] ?? 0);

    if ($status === 10) // prichádzajúca správa
    {
        log_line('inbox', sprintf(
            'Od: [%s] Správa: [%s]',
            $record['from'] ?? '',
            $record['message'] ?? ''
        ));
    }
    else if (isset(STATUS[$status])) // potvrdenie o doručení
    {
        [$sent, $delivered] = array_pad(explode(';', $record['date'] ?? ''), 2, '');

        log_line('delivery', sprintf(
            'Správa [%s]: %s, cena %.4f, odoslané %s, doručené %s',
            $record['smsID'] ?? '',
            STATUS[$status],
            (float) ($record['price'] ?? 0),
            parse_date($sent),
            parse_date($delivered)
        ));
    }
}

http_response_code(200);
```

> [!WARNING]
> Adresa musí odpovedať rýchlo a stavovým kódom `200`. Celá dávka čaká na jednu
> odpoveď, takže náročné spracovanie odložte do frontu a požiadavku rovno
> potvrďte.
