<?php
declare(strict_types=1);
namespace GNexus\GAuth\Webhook;
use GNexus\GAuth\Contract\WebhookParserInterface;
use GNexus\GAuth\DTO\WebhookEvent;
use GNexus\GAuth\Exception\WebhookPayloadException;
final class JsonWebhookParser implements WebhookParserInterface
{
public function parse(string $rawBody): WebhookEvent
{
$payload = json_decode($rawBody, true);
if (! is_array($payload)) {
throw new WebhookPayloadException('Webhook payload is not valid JSON.');
}
if (! isset($payload['type']) || ! is_string($payload['type']) || $payload['type'] === '') {
throw new WebhookPayloadException('Webhook payload is missing event type.');
}
$occurredAt = null;
if (isset($payload['occurred_at']) && is_string($payload['occurred_at']) && $payload['occurred_at'] !== '') {
try {
$occurredAt = new \DateTimeImmutable($payload['occurred_at']);
} catch (\Exception $exception) {
throw new WebhookPayloadException('Webhook payload contains invalid occurred_at.', 0, $exception);
}
}
return new WebhookEvent(
eventId: isset($payload['id']) ? (string) $payload['id'] : null,
eventType: $payload['type'],
occurredAt: $occurredAt,
targetIdentifiers: is_array($payload['target'] ?? null) ? $payload['target'] : [],
actorIdentifiers: is_array($payload['actor'] ?? null) ? $payload['actor'] : [],
metadata: is_array($payload['data'] ?? null) ? $payload['data'] : [],
rawPayload: $payload,
);
}
}