<?php
declare(strict_types=1);
namespace Harmonizely\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Harmonizely\CalendarEvents;
use Harmonizely\EventTypes\LocationTypeProvider;
use Harmonizely\Integration\Whereby\ClientFactory;
use Harmonizely\Integration\Whereby\WherebyApi;
use Harmonizely\Model\EventInterface;
use Harmonizely\Model\EventTypeInterface;
use Harmonizely\Model\Integration;
use Harmonizely\Model\IntegrationInterface;
use Harmonizely\Model\UserInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Webmozart\Assert\Assert;
use Harmonizely\Types\IntegrationType;
final class CreateWherebyMeetingLinkSubscriber implements EventSubscriberInterface
{
private $entityManager;
private $logger;
private LocationTypeProvider $locationTypeProvider;
public function __construct(
EntityManagerInterface $entityManager,
LoggerInterface $logger,
LocationTypeProvider $locationTypeProvider
) {
$this->entityManager = $entityManager;
$this->logger = $logger;
$this->locationTypeProvider = $locationTypeProvider;
}
public static function getSubscribedEvents(): array
{
return [
CalendarEvents::EVENT_PRE_CREATE => 'createMeeting',
];
}
public function createMeeting(GenericEvent $event): void
{
/** @var EventInterface $event */
$event = $event->getSubject();
Assert::isInstanceOf($event, EventInterface::class);
$eventType = $event->getEventType();
$user = $event->getUser();
$locationType = $this->locationTypeProvider->provideFor($eventType, $user, $event);
if (EventTypeInterface::LOCATION_TYPE_WHEREBY !== $locationType) {
return;
}
$integration = $this->findIntegration($user);
if (null === $integration || (null !== $integration && !$integration->isEnabled())) {
return;
}
if ($eventType->isGroupMeetingType() && $event->getLocation()) {
return;
}
$wherebyClientFactory = new ClientFactory($integration->getConfig()['key']);
$wherebyApi = new WherebyApi($wherebyClientFactory->create());
$invitee = $event->getInvitee();
try {
$meeting = $wherebyApi->createMeeting($event->getScheduledAt(), $event->getEndDate());
} catch (\Exception $e) {
$this->logger->critical('Whereby create meeting failed.', [
'message' => $e->getMessage(),
'user_email' => $user->getEmail(),
'invitee_email' => $invitee->getEmail(),
]);
return;
}
$event->setLocation($meeting->getRoomUrl());
}
private function findIntegration(UserInterface $user): ?IntegrationInterface
{
$integrationRepository = $this->entityManager->getRepository(Integration::class);
return $integrationRepository->findOneBy([
'type' => IntegrationType::TYPE_WHEREBY,
'user' => $user,
]);
}
}