fix: send the correct body when chat notification

This commit is contained in:
Maël Gangloff 2024-08-28 17:35:32 +02:00
parent 83a97b429b
commit 02c9ce7eec
No known key found for this signature in database
GPG Key ID: 11FDC81C24A7F629
10 changed files with 62 additions and 103 deletions

View File

@ -13,14 +13,12 @@ identifiers:
- type: url
value: >-
https://github.com/maelgangloff/domain-watcher/releases
description: Release of domain-watchdog
description: Release of Domain Watchdog
repository-code: 'https://github.com/maelgangloff/domain-watchdog'
abstract: An app that utilizes RDAP to gather publicly accessible information about domain names, track their history, and automatically purchase them
abstract: An app that uses RDAP to collect publicly available info about domains, track their history, and purchase them
keywords:
- DOMAIN
- RDAP
- WHOIS
license: AGPL-3.0-or-later
version: 0.1.0
date-released: '2024-08-08'
license-url: 'https://github.com/maelgangloff/domain-watchdog/blob/master/LICENSE'

View File

@ -3,7 +3,6 @@
namespace App\Controller;
use App\Config\Provider\AbstractProvider;
use App\Config\WebhookScheme;
use App\Entity\Connector;
use App\Entity\Domain;
use App\Entity\DomainEntity;
@ -12,6 +11,7 @@ use App\Entity\User;
use App\Entity\WatchList;
use App\Notifier\TestChatNotification;
use App\Repository\WatchListRepository;
use App\Service\ChatNotificationService;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Exception\ORMException;
@ -39,9 +39,6 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
@ -55,7 +52,8 @@ class WatchListController extends AbstractController
private readonly LoggerInterface $logger,
private readonly HttpClientInterface $httpClient,
private readonly CacheItemPoolInterface $cacheItemPool,
private readonly KernelInterface $kernel
private readonly KernelInterface $kernel,
private readonly ChatNotificationService $chatNotificationService
) {
}
@ -124,7 +122,7 @@ class WatchListController extends AbstractController
}
}
$this->verifyWebhookDSN($watchList);
$this->chatNotificationService->sendChatNotification($watchList, new TestChatNotification());
$this->verifyConnector($watchList, $watchList->getConnector());
$this->logger->info('User {username} registers a Watchlist ({token}).', [
@ -155,47 +153,6 @@ class WatchListController extends AbstractController
return $user->getWatchLists();
}
private function verifyWebhookDSN(WatchList $watchList): void
{
$webhookDsn = $watchList->getWebhookDsn();
if (null !== $webhookDsn && 0 !== count($webhookDsn)) {
foreach ($webhookDsn as $dsnString) {
try {
$dsn = new Dsn($dsnString);
} catch (InvalidArgumentException $exception) {
throw new BadRequestHttpException($exception->getMessage());
}
$scheme = $dsn->getScheme();
$webhookScheme = WebhookScheme::tryFrom($scheme);
if (null === $webhookScheme) {
throw new BadRequestHttpException("The DSN scheme ($scheme) is not supported");
}
$transportFactoryClass = $webhookScheme->getChatTransportFactory();
/** @var AbstractTransportFactory $transportFactory */
$transportFactory = new $transportFactoryClass();
$push = (new TestChatNotification())->asPushMessage();
$chat = (new TestChatNotification())->asChatMessage();
try {
$factory = $transportFactory->create($dsn);
if ($factory->supports($push)) {
$factory->send($push);
} elseif ($factory->supports($chat)) {
$factory->send($chat);
} else {
throw new BadRequestHttpException('Unsupported message type');
}
} catch (\Throwable $exception) {
throw new BadRequestHttpException($exception->getMessage());
}
}
}
}
/**
* @throws \Exception
*/
@ -285,7 +242,7 @@ class WatchListController extends AbstractController
}
}
$this->verifyWebhookDSN($watchList);
$this->chatNotificationService->sendChatNotification($watchList, new TestChatNotification());
$this->verifyConnector($watchList, $watchList->getConnector());
$this->logger->info('User {username} updates a Watchlist ({token}).', [

View File

@ -75,12 +75,11 @@ final readonly class OrderDomainHandler
$connectorProvider = new $connectorProviderClass($connector->getAuthData(), $this->client, $this->cacheItemPool, $this->kernel);
$connectorProvider->orderDomain($domain, $this->kernel->isDebug());
$this->statService->incrementStat('stats.domain.purchased');
$notification = (new DomainOrderNotification($this->sender, $domain, $connector));
$this->mailer->send($notification->asEmailMessage(new Recipient($watchList->getUser()->getEmail()))->getMessage());
$this->chatNotificationService->sendChatNotification($watchList, $notification);
$this->statService->incrementStat('stats.domain.purchased');
} catch (\Throwable $exception) {
$this->logger->warning('Unable to complete purchase. An error message is sent to user {username}.', [
'username' => $watchList->getUser()->getUserIdentifier(),

View File

@ -8,14 +8,11 @@ use Symfony\Component\Mime\Address;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\EmailMessage;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\PushNotificationInterface;
use Symfony\Component\Notifier\Recipient\EmailRecipientInterface;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
class DomainOrderErrorNotification extends Notification implements ChatNotificationInterface, EmailNotificationInterface, PushNotificationInterface
class DomainOrderErrorNotification extends DomainWatchdogNotification
{
public function __construct(
private readonly Address $sender,

View File

@ -10,14 +10,11 @@ use Symfony\Component\Mime\Email;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\EmailMessage;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\PushNotificationInterface;
use Symfony\Component\Notifier\Recipient\EmailRecipientInterface;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
class DomainOrderNotification extends Notification implements ChatNotificationInterface, EmailNotificationInterface, PushNotificationInterface
class DomainOrderNotification extends DomainWatchdogNotification
{
public function __construct(
private readonly Address $sender,

View File

@ -8,14 +8,11 @@ use Symfony\Component\Mime\Address;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\EmailMessage;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\PushNotificationInterface;
use Symfony\Component\Notifier\Recipient\EmailRecipientInterface;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
class DomainUpdateErrorNotification extends Notification implements ChatNotificationInterface, EmailNotificationInterface, PushNotificationInterface
class DomainUpdateErrorNotification extends DomainWatchdogNotification
{
public function __construct(
private readonly Address $sender,

View File

@ -9,14 +9,11 @@ use Symfony\Component\Mime\Email;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\EmailMessage;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\PushNotificationInterface;
use Symfony\Component\Notifier\Recipient\EmailRecipientInterface;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
class DomainUpdateNotification extends Notification implements ChatNotificationInterface, EmailNotificationInterface, PushNotificationInterface
class DomainUpdateNotification extends DomainWatchdogNotification
{
public function __construct(
private readonly Address $sender,

View File

@ -0,0 +1,11 @@
<?php
namespace App\Notifier;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\PushNotificationInterface;
abstract class DomainWatchdogNotification extends Notification implements ChatNotificationInterface, PushNotificationInterface
{
}

View File

@ -4,12 +4,10 @@ namespace App\Notifier;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\PushNotificationInterface;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
class TestChatNotification extends Notification implements ChatNotificationInterface, PushNotificationInterface
class TestChatNotification extends DomainWatchdogNotification
{
public function asChatMessage(?RecipientInterface $recipient = null, ?string $transport = null): ?ChatMessage
{

View File

@ -4,10 +4,11 @@ namespace App\Service;
use App\Config\WebhookScheme;
use App\Entity\WatchList;
use App\Notifier\TestChatNotification;
use App\Notifier\DomainWatchdogNotification;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\Notifier\Recipient\NoRecipient;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;
@ -18,23 +19,30 @@ readonly class ChatNotificationService
) {
}
public function sendChatNotification(WatchList $watchList, ChatNotificationInterface $notification): void
public function sendChatNotification(WatchList $watchList, DomainWatchdogNotification $notification): void
{
$webhookDsn = $watchList->getWebhookDsn();
if (null !== $webhookDsn && 0 !== count($webhookDsn)) {
foreach ($webhookDsn as $dsnString) {
try {
$dsn = new Dsn($dsnString);
} catch (InvalidArgumentException $exception) {
throw new BadRequestHttpException($exception->getMessage());
}
$scheme = $dsn->getScheme();
$webhookScheme = WebhookScheme::tryFrom($scheme);
if (null !== $webhookScheme) {
if (null === $webhookScheme) {
throw new BadRequestHttpException("The DSN scheme ($scheme) is not supported");
}
$transportFactoryClass = $webhookScheme->getChatTransportFactory();
/** @var AbstractTransportFactory $transportFactory */
$transportFactory = new $transportFactoryClass();
$push = (new TestChatNotification())->asPushMessage();
$chat = (new TestChatNotification())->asChatMessage();
$push = $notification->asPushMessage(new NoRecipient());
$chat = $notification->asChatMessage(new NoRecipient());
try {
$factory = $transportFactory->create($dsn);
@ -52,13 +60,13 @@ readonly class ChatNotificationService
'scheme' => $webhookScheme->name,
'token' => $watchList->getToken(),
]);
} catch (\Throwable) {
} catch (\Throwable $exception) {
$this->logger->error('Unable to send a chat message to {scheme} for Watchlist {token}',
[
'scheme' => $webhookScheme->name,
'token' => $watchList->getToken(),
]);
}
throw new BadRequestHttpException($exception->getMessage());
}
}
}