## O que chega ao seu endereço

O BulkGate comunica-lhe duas coisas: como terminaram as mensagens enviadas e o que
as pessoas responderam. Ambas chegam como um pedido HTTP para o endereço que
definiu.

| O que chega | Como o reconhece |
|:--|:--|
| Relatório de entrega | O parâmetro `status` com um código de estado e o `smsID` da mensagem enviada |
| SMS recebido ou resposta | O parâmetro `status` com o valor `10`, o remetente em `from` e o texto em `message` |

O pedido chega por HTTP **GET**, pelo que encontra os valores na query string.

> [!TIP]
> Com volumes elevados compensa a variante em massa: em vez de um pedido por
> mensagem, chega um único pedido POST com um array de registos em JSON. Está
> descrita em [Confirmações de entrega em massa](https://www.bulkgate.com/pt/documentacao/administracao-da-api/api-confirmacoes-de-entrega-em-massa-e-mensagens-recebidas/).

## Onde se define o endereço

O endereço é definido por si no detalhe da sua aplicação — no separador `Definições`,
na parte `Web hooks`, no cartão `Relatórios de entrega`. O campo `Relatórios de
entrega de URL` da janela que se abre aceita um endereço que comece por `http://`
ou `https://`.

![A janela de definição dos Relatórios de entrega com o envio em massa desligado](docs:api-delivery-confirmations-and-incoming-sms/webhook-single_en)

> [!IMPORTANT]
> Deixe a caixa de verificação `DLRs em massa - solicitação em massa` desmarcada —
> com ela, a entrega passa a ser feita em lotes enviados por POST e aplica-se, em
> vez desta, a página
> [Confirmações de entrega em massa](https://www.bulkgate.com/pt/documentacao/administracao-da-api/api-confirmacoes-de-entrega-em-massa-e-mensagens-recebidas/).

Todo o procedimento, incluindo as restantes opções, está descrito na página
[Webhooks](https://www.bulkgate.com/pt/documentacao/administracao-da-api/webhooks/).

## Parâmetros do relatório de entrega

| Parâmetro | Valor |
|:--|:--|
| `status` | O código de estado da mensagem — consulte os [estados de entrega](#estados-de-entrega) |
| `smsID` | O ID único da mensagem |
| `price` | O preço da mensagem em créditos |
| `channel` | O canal por onde a mensagem passou (`sms`, `viber`, `whatsapp`, `rcs` e outros) |
| `date` | A hora de envio e a hora de entrega separadas por ponto e vírgula, no fuso horário CET |

O valor `date` tem a forma `YYMMDDHHMM;YYMMDDHHMM` — por exemplo,
`1812141317;1812141318` significa enviada a 14 de dezembro de 2018 às 13:17 e
entregue um minuto depois.

## Parâmetros da mensagem recebida

Quando `status` tem o valor `10`, não se trata de um relatório de entrega, mas de
uma mensagem do destinatário. Chega com um conjunto diferente de parâmetros:

| Parâmetro | Valor |
|:--|:--|
| `status` | Sempre `10` |
| `from` | O número de telefone do remetente |
| `to` | O número de telefone do destinatário, ou seja, o seu número |
| `message` | O texto da mensagem em UTF-8 |
| `channel` | O canal por onde a mensagem chegou |
| `smsdetails` | Detalhes, incluindo o protocolo utilizado e a hora de receção |

## Estados de entrega

| Código | Significado |
|:--|:--|
| `1` | A mensagem foi entregue |
| `2` | A mensagem está em fila do lado do operador — o destinatário está de momento indisponível e a entrega será repetida |
| `3` | Não foi possível entregar a mensagem — o destinatário é desconhecido ou está permanentemente indisponível |
| `10` | Uma mensagem recebida ou uma resposta, não um relatório de entrega |
| `13` | A mensagem foi lida (apenas Viber) |

> [!NOTE]
> O estado `2` não é final — mais tarde chega, para a mesma mensagem, outro pedido
> com o estado resultante. Conte com ver o mesmo `smsID` mais do que uma vez.

## Um exemplo de processamento

O script distingue um relatório de entrega de uma mensagem recebida pelo `status` e
escreve cada um no seu próprio log:

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

const STATUS = [
    1 => 'entregue',
    2 => 'em fila no operador',
    3 => 'não entregue',
    13 => 'lida',
];

$status = filter_input(INPUT_GET, 'status', FILTER_VALIDATE_INT);

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
    );
}

if ($status === 10) // uma mensagem recebida
{
    $from = filter_input(INPUT_GET, 'from') ?? '';
    $message = filter_input(INPUT_GET, 'message') ?? '';

    log_line('inbox', sprintf('De: [%s] Mensagem: [%s]', $from, $message));
}
else if (isset(STATUS[$status])) // um relatório de entrega
{
    $sms_id = filter_input(INPUT_GET, 'smsID') ?? '';
    $price = filter_input(INPUT_GET, 'price', FILTER_VALIDATE_FLOAT) ?: 0.0;

    log_line('delivery', sprintf('Mensagem [%s]: %s, preço %.4f', $sms_id, STATUS[$status], $price));
}
else
{
    http_response_code(400);
    exit;
}
```

> [!WARNING]
> O endereço tem de responder rapidamente e com o código de estado `200`. Um
> processamento lento ou com falhas atrasa a entrega dos relatórios seguintes — por
> isso, passe qualquer trabalho pesado para uma fila e confirme o pedido de imediato.
