getBody(); $this->logger->debug('Received webhook payload', ['body' => $payload]); if (empty($payload)) { throw new SerializationException('Webhook body is empty.'); } $this->verifySignature($request->getHeaderLine('X-Max-Bot-Api-Secret')); try { $data = json_decode($payload, true, 512, JSON_THROW_ON_ERROR); } catch (\JsonException $e) { $this->logger->error('Failed to decode webhook JSON', ['payload' => $payload, 'exception' => $e]); throw new SerializationException('Failed to decode webhook body as JSON.', 0, $e); } $update = $this->modelFactory->createUpdate($data); $this->dispatcher->dispatch($update); if (!headers_sent()) { http_response_code(200); } } /** * Verifies the 'X-Max-Bot-Api-Secret' header if a secret is configured. * * @param string $signature * * @throws SecurityException */ private function verifySignature(string $signature): void { if ($this->secret === null) { return; } if (!hash_equals($this->secret, $signature)) { $this->logger->warning('Webhook signature verification failed', ['received_signature' => $signature]); throw new SecurityException('Signature verification failed.'); } } }