## Hvordan masserapporter skiller seg ut

Som standard kommer én forespørsel per melding til adressen din. Ved store volumer
betyr det tusenvis av forespørsler — massevarianten samler dem i grupper.

| | Én om gangen | Samlet |
|:--|:--|:--|
| Metode | HTTP GET | HTTP POST |
| Format | Parametere i query-strengen | JSON i forespørselens body |
| Innhold | Én enkelt melding | En matrise av poster |

Begge inneholder det samme — både leveringsrapporter og innkommende meldinger.
Varianten med én om gangen er beskrevet på
[Leveringsbekreftelser og innkommende SMS](https://www.bulkgate.com/no/dokumentasjon/api-administrasjon/api-leveringsbekreftelser-og-innkommende-sms/).

## Slik slår du på massesending

Kryss av for `Bulk DLRs - bulk forespørsel` i webhook-innstillingene. Adressen og de
øvrige alternativene forblir de samme — bare måten dataene når deg på, endres.

![Innstillingen for leveringsrapporter med alternativet for massesending avkrysset](docs:api-bulk-delivery-confirmations-and-incoming-sms/bulk-setting_en)

Hele fremgangsmåten, inkludert hvor du finner innstillingen, er beskrevet på
[Webhooks](https://www.bulkgate.com/no/dokumentasjon/api-administrasjon/webhooks/).

## Slik ser forespørselen ut

Den kommer via POST med headeren `Content-Type: application/json`. Body er
en matrise som blander leveringsrapporter og innkommende meldinger — du skiller dem
fra hverandre etter `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": "teksten i svaret"
   }
]
```

## Parametere i postene

| Parameter | Verdi | Når den kommer |
|:--|:--|:--|
| `status` | Statuskoden — se [leveringsstatuser](#leveringsstatuser) | Alltid |
| `smsID` | Den unike ID-en til meldingen | Med en leveringsrapport |
| `price` | Prisen på meldingen i kreditter | Med en leveringsrapport |
| `date` | Tidspunktet for sending og levering atskilt med semikolon, tidssone CET | Med en leveringsrapport |
| `from` | Avsenderens telefonnummer | Bare med `status` `10` |
| `message` | Teksten i meldingen i UTF-8 | Bare med `status` `10` |

Verdien `date` har formen `YYMMDDHHMM;YYMMDDHHMM` — `1904111007;1904111011`
betyr altså sendt 11. april 2019 kl. 10.07 og levert kl. 10.11.

## Leveringsstatuser

| Kode | Betydning |
|:--|:--|
| `1` | Meldingen ble levert |
| `2` | Meldingen står i kø hos operatøren — mottakeren er utilgjengelig for øyeblikket, og leveringen vil bli forsøkt på nytt |
| `3` | Meldingen kunne ikke leveres — mottakeren er ukjent eller permanent utilgjengelig |
| `10` | En innkommende melding eller et svar, ikke en leveringsrapport |
| `13` | Meldingen ble lest (bare Viber) |

> [!NOTE]
> Status `2` er ikke endelig — senere kommer en ny post med den endelige statusen for
> den samme meldingen. Regn med å se den samme `smsID` mer enn én gang, muligens
> til og med i samme gruppe.

## Et eksempel på behandling

Skriptet leser forespørselens body, går gjennom matrisen og behandler hver post etter
`status`:

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

const STATUS = [
    1 => 'levert',
    2 => 'i kø hos operatøren',
    3 => 'ikke levert',
    13 => 'lest',
];

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
{
    // formen YYMMDDHHMM, for eksempel 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) // en innkommende melding
    {
        log_line('inbox', sprintf(
            'Fra: [%s] Melding: [%s]',
            $record['from'] ?? '',
            $record['message'] ?? ''
        ));
    }
    else if (isset(STATUS[$status])) // en leveringsrapport
    {
        [$sent, $delivered] = array_pad(explode(';', $record['date'] ?? ''), 2, '');

        log_line('delivery', sprintf(
            'Melding [%s]: %s, pris %.4f, sendt %s, levert %s',
            $record['smsID'] ?? '',
            STATUS[$status],
            (float) ($record['price'] ?? 0),
            parse_date($sent),
            parse_date($delivered)
        ));
    }
}

http_response_code(200);
```

> [!WARNING]
> Adressen må svare raskt og med statuskoden `200`. Hele
> gruppen venter på ett enkelt svar, så legg tung behandling i en kø og
> bekreft forespørselen med en gang.
