2024-07-21 16:55:39 +02:00
< ? php
namespace App\MessageHandler ;
2024-08-07 01:10:56 +02:00
use App\Config\Connector\ConnectorInterface ;
2024-07-21 16:55:39 +02:00
use App\Config\TriggerAction ;
2024-08-16 23:23:51 +02:00
use App\Config\WebhookScheme ;
2024-07-21 16:55:39 +02:00
use App\Entity\Domain ;
use App\Entity\DomainEvent ;
use App\Entity\WatchList ;
use App\Entity\WatchListTrigger ;
use App\Message\ProcessDomainTrigger ;
2024-08-16 23:23:51 +02:00
use App\Notifier\DomainOrderErrorNotification ;
use App\Notifier\DomainOrderNotification ;
use App\Notifier\DomainUpdateNotification ;
2024-07-21 16:55:39 +02:00
use App\Repository\DomainRepository ;
use App\Repository\WatchListRepository ;
2024-08-04 14:45:27 +02:00
use Psr\Log\LoggerInterface ;
2024-07-29 15:28:05 +02:00
use Symfony\Component\HttpKernel\KernelInterface ;
2024-07-21 16:55:39 +02:00
use Symfony\Component\Mailer\Exception\TransportExceptionInterface ;
use Symfony\Component\Mailer\MailerInterface ;
use Symfony\Component\Messenger\Attribute\AsMessageHandler ;
2024-08-16 23:23:51 +02:00
use Symfony\Component\Messenger\Exception\ExceptionInterface ;
2024-08-05 01:30:27 +02:00
use Symfony\Component\Mime\Address ;
2024-08-16 23:23:51 +02:00
use Symfony\Component\Notifier\Recipient\Recipient ;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory ;
2024-08-06 03:38:00 +02:00
use Symfony\Contracts\HttpClient\HttpClientInterface ;
2024-07-21 16:55:39 +02:00
#[AsMessageHandler]
final readonly class ProcessDomainTriggerHandler
{
2024-08-16 23:23:51 +02:00
private Address $sender ;
2024-07-21 16:55:39 +02:00
public function __construct (
2024-08-16 23:23:51 +02:00
string $mailerSenderEmail ,
string $mailerSenderName ,
2024-07-21 16:55:39 +02:00
private WatchListRepository $watchListRepository ,
2024-08-02 23:24:52 +02:00
private DomainRepository $domainRepository ,
2024-08-04 14:45:27 +02:00
private KernelInterface $kernel ,
2024-08-06 03:38:00 +02:00
private LoggerInterface $logger ,
2024-08-16 23:23:51 +02:00
private HttpClientInterface $client ,
private MailerInterface $mailer
2024-08-02 23:24:52 +02:00
) {
2024-08-16 23:23:51 +02:00
$this -> sender = new Address ( $mailerSenderEmail , $mailerSenderName );
2024-07-21 16:55:39 +02:00
}
/**
* @ throws TransportExceptionInterface
2024-08-02 23:24:52 +02:00
* @ throws \Exception
2024-08-16 23:23:51 +02:00
* @ throws ExceptionInterface
2024-07-21 16:55:39 +02:00
*/
public function __invoke ( ProcessDomainTrigger $message ) : void
{
/** @var WatchList $watchList */
2024-08-02 23:24:52 +02:00
$watchList = $this -> watchListRepository -> findOneBy ([ 'token' => $message -> watchListToken ]);
2024-07-21 16:55:39 +02:00
/** @var Domain $domain */
2024-08-02 23:24:52 +02:00
$domain = $this -> domainRepository -> findOneBy ([ 'ldhName' => $message -> ldhName ]);
2024-07-21 16:55:39 +02:00
2024-07-30 21:34:48 +02:00
$connector = $watchList -> getConnector ();
if ( null !== $connector && $domain -> getDeleted ()) {
2024-08-04 14:45:27 +02:00
$this -> logger -> notice ( 'Watchlist {watchlist} is linked to connector {connector}. A purchase attempt will be made for domain name {ldhName} with provider {provider}.' , [
'watchlist' => $message -> watchListToken ,
'connector' => $connector -> getId (),
'ldhName' => $message -> ldhName ,
'provider' => $connector -> getProvider () -> value ,
]);
2024-07-30 21:34:48 +02:00
try {
2024-08-07 01:10:56 +02:00
$provider = $connector -> getProvider ();
if ( null === $provider ) {
throw new \Exception ( 'Provider not found' );
2024-08-02 23:24:52 +02:00
}
2024-08-06 03:38:00 +02:00
2024-08-07 01:10:56 +02:00
$connectorProviderClass = $provider -> getConnectorProvider ();
/** @var ConnectorInterface $connectorProvider */
$connectorProvider = new $connectorProviderClass ( $connector -> getAuthData (), $this -> client );
$connectorProvider -> orderDomain ( $domain , $this -> kernel -> isDebug ());
2024-08-06 11:58:41 +02:00
2024-08-16 23:23:51 +02:00
$email = ( new DomainOrderNotification ( $this -> sender , $domain , $connector ))
-> asEmailMessage ( new Recipient ( $watchList -> getUser () -> getEmail ()));
$this -> mailer -> send ( $email -> getMessage ());
2024-08-02 23:24:52 +02:00
} catch ( \Throwable ) {
2024-08-04 14:45:27 +02:00
$this -> logger -> warning ( 'Unable to complete purchase. An error message is sent to user {username}.' , [
'username' => $watchList -> getUser () -> getUserIdentifier (),
]);
2024-08-16 23:23:51 +02:00
$email = ( new DomainOrderErrorNotification ( $this -> sender , $domain ))
-> asEmailMessage ( new Recipient ( $watchList -> getUser () -> getEmail ()));
$this -> mailer -> send ( $email -> getMessage ());
2024-07-29 16:10:34 +02:00
}
2024-07-30 21:34:48 +02:00
}
/** @var DomainEvent $event */
2024-08-03 16:14:46 +02:00
foreach ( $domain -> getEvents () -> filter ( fn ( $event ) => $message -> updatedAt < $event -> getDate () && $event -> getDate () < new \DateTime ()) as $event ) {
2024-07-30 21:34:48 +02:00
$watchListTriggers = $watchList -> getWatchListTriggers ()
2024-08-02 23:24:52 +02:00
-> filter ( fn ( $trigger ) => $trigger -> getEvent () === $event -> getAction ());
2024-07-29 16:10:34 +02:00
2024-07-30 21:34:48 +02:00
/** @var WatchListTrigger $watchListTrigger */
foreach ( $watchListTriggers -> getIterator () as $watchListTrigger ) {
2024-08-04 14:45:27 +02:00
$this -> logger -> info ( 'Action {event} has been detected on the domain name {ldhName}. A notification is sent to user {username}.' , [
'event' => $event -> getAction (),
'ldhName' => $message -> ldhName ,
'username' => $watchList -> getUser () -> getUserIdentifier (),
]);
2024-08-16 23:23:51 +02:00
$recipient = new Recipient ( $watchList -> getUser () -> getEmail ());
$notification = new DomainUpdateNotification ( $this -> sender , $event );
2024-08-02 23:24:52 +02:00
if ( TriggerAction :: SendEmail == $watchListTrigger -> getAction ()) {
2024-08-16 23:23:51 +02:00
$this -> mailer -> send ( $notification -> asEmailMessage ( $recipient ) -> getMessage ());
} elseif ( TriggerAction :: SendChat == $watchListTrigger -> getAction ()) {
if ( null !== $watchList -> getWebhookDsn ()) {
foreach ( $watchList -> getWebhookDsn () as $dsnString ) {
$dsn = new \Symfony\Component\Notifier\Transport\Dsn ( $dsnString );
$scheme = $dsn -> getScheme ();
$webhookScheme = WebhookScheme :: tryFrom ( $scheme );
if ( null !== $webhookScheme ) {
$transportFactoryClass = $webhookScheme -> getChatTransportFactory ();
/** @var AbstractTransportFactory $transportFactory */
$transportFactory = new $transportFactoryClass ();
$transportFactory -> create ( $dsn ) -> send ( $notification -> asChatMessage ());
}
}
}
2024-07-21 16:55:39 +02:00
}
}
}
}
}