Repository: symfony/symfony
File: src/Symfony/Component/Notifier/Bridge/Lox24/Webhook/Lox24RequestParser.php (PHP)

Code before:
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Lox24\Webhook;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestMatcher\MethodRequestMatcher;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
use Symfony\Component\RemoteEvent\Event\Sms\SmsEvent;
use Symfony\Component\Webhook\Client\AbstractRequestParser;
use Symfony\Component\Webhook\Exception\RejectWebhookException;

/**
 * @author Andrei Lebedev <andrew.lebedev@gmail.com>
 *
 * @see https://doc.lox24.eu/#section/Introduction/Notifications
 */
final class Lox24RequestParser extends AbstractRequestParser
{
    protected function getRequestMatcher(): RequestMatcherInterface
    {
        return new MethodRequestMatcher('POST');
    }

    /**
     * @throws RejectWebhookException
     */
    protected function doParse(Request $request, #[\SensitiveParameter] string $secret): ?SmsEvent
    {
        $payload = $request->request->all() ?? [];
        $name = $payload['name'] ?? null;
        $data = $payload['data'] ?? [];

        if ('sms.delivery' !== $name) {
            throw new RejectWebhookException(400, 'Notification name is not \'sms.delivery\'');
        }

        if (!isset($data['id'], $data['status_code'])) {
            throw new RejectWebhookException(406, 'Payload is malformed.');
        }

        $code = $data['status_code'];

        if (0 === $code) {
            return null;
        }

        $name = 100 === $code ? SmsEvent::DELIVERED : SmsEvent::FAILED;

        return new SmsEvent($name, $data['id'], $payload);
    }
}


Review comment (suggestion):
```suggestion
            throw new RejectWebhookException(406, 'Missing "id" field.');
```

Code after:
    }

    private function createDeliveryEvent(array $data, array $payload): ?SmsEvent
    {
        if (!isset($data['id'])) {
            throw new RejectWebhookException(406, 'The required field "id" is missing from the delivery event payload.');
        }

        $statusCode = $data['status_code'] ?? null;
        $dlrCode = $data['dlr_code'] ?? null;

        if (null !== $dlrCode) {
            return $this->createEventFromDlrCode($dlrCode, $data, $payload);
        }
        if (null !== $statusCode) {
            return $this->createEventFromStatusCode($statusCode, $data, $payload);
        }

        throw new RejectWebhookException(406, 'The required field "status_code" or "dlr_code" is missing from the delivery event payload.');
    }

    private function createEventFromDlrCode(int $dlrCode, array $data, array $payload): ?SmsEvent
    {
        $eventType = match ($dlrCode) {
            0 => null,
            1 => SmsEvent::DELIVERED,
            2 => null,
            4 => null,
            default => SmsEvent::FAILED,
        };

        if (null === $eventType) {
            return null;
        }

        return new SmsEvent($eventType, $data['id'], $payload);
    }

    private function createEventFromStatusCode(int $statusCode, array $data, array $payload): ?SmsEvent
    {
        if (0 === $statusCode) {
            return null;
        }

        $eventType = match ($statusCode) {
            100 => SmsEvent::DELIVERED,
            default => SmsEvent::FAILED,
        };

        return new SmsEvent($eventType, $data['id'], $payload);
    }