<?php
namespace App\Controller\Email;
use App\Message\EmailWebhookQueued;
use App\Model\Email\Webhook\Webhook;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\IpUtils;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
/**
* @see https://developers.brevo.com/docs/how-to-use-webhooks
* @see https://help.brevo.com/hc/en-us/articles/27824932835474-New-webhooks-Create-outbound-webhooks-to-send-real-time-data-from-Brevo-to-an-external-app
* @see https://developers.brevo.com/docs/transactional-webhooks
* @see https://developers.brevo.com/docs/send-a-transactional-email#tracking-your-transactional-activity-through-webhooks
* @see https://developers.brevo.com/reference/sendtransacemail
*
* @Route("/email/webhooks")
*/
class EmailWebhooksController extends AbstractController
{
/**
* @Route("/", name="email_webhooks", methods={"GET", "POST"})
*/
public function webhooks(
Request $request,
SerializerInterface $serializer,
MessageBusInterface $bus,
LoggerInterface $logger): Response
{
// Brevo webhooks IP ranges (@see https://help.brevo.com/hc/en-us/articles/15127404548498-Brevo-IP-ranges-List-of-publicly-exposed-services
$limitIps = ['1.179.112.0/20', '172.246.240.0/20'];
if (!IpUtils::checkIp($request->getClientIp(), $limitIps)) {
throw new AccessDeniedHttpException('Acceso restringido por IP.');
}
if ($request->isMethod('POST')) {
if (str_contains($request->getContentType(), 'json')) {
$body = $request->getContent();
if ($body) {
$logger->info('EmailWebhooksController $body = ' .$body);
$context = [
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT => true
];
$webhook = $serializer->deserialize($body, Webhook::class, 'json', $context); // to deserialize a list of objects, you have to append [] to the type parameter
$logger->info('EmailWebhooksController $webhook = ' .$serializer->serialize($webhook, 'json'));
$bus->dispatch(new EmailWebhookQueued($webhook)); // async worker will process the queued webhook
return new Response('', Response::HTTP_OK);
}
}
}
//$logger->info('EmailWebhooksController BAD REQUEST');
return new Response('', Response::HTTP_BAD_REQUEST);
}
}