src/EventListener/Strava/WebhookActivitySubscriber.php line 74

Open in your IDE?
  1. <?php
  2. namespace App\EventListener\Strava;
  3. use App\Entity\Activity;
  4. use App\Entity\SocialToken;
  5. use App\Entity\User;
  6. use App\Message\Event\CompileActivityEvent;
  7. use App\Repository\ActivityRepository;
  8. use App\Repository\SocialTokenRepository;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use NuBox\Strava\Api\DataObject\Activity as StravaActivity;
  11. use NuBox\Strava\Api\Event\StravaApiEvents;
  12. use NuBox\Strava\Api\Event\Webhook\ActivityDeletedEvent;
  13. use NuBox\Strava\Api\Event\Webhook\WebhookEventInterface;
  14. use NuBox\Strava\Api\Service\StravaApi;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\Messenger\MessageBusInterface;
  17. final class WebhookActivitySubscriber implements EventSubscriberInterface
  18. {
  19.     public function __construct(
  20.         private readonly EntityManagerInterface $entityManager,
  21.         private readonly ActivityRepository $activityRepository,
  22.         private readonly SocialTokenRepository $socialTokenRepository,
  23.         private readonly MessageBusInterface $messageBus,
  24.         private readonly StravaApi $stravaApi,
  25.         private readonly string $debugEmail
  26.     ) {
  27.     }
  28.     public static function getSubscribedEvents(): array
  29.     {
  30.         return [
  31.             StravaApiEvents::WEBHOOK_ACTIVITY_CREATED => 'onActivityModified',
  32.             StravaApiEvents::WEBHOOK_ACTIVITY_UPDATED => 'onActivityModified',
  33.             StravaApiEvents::WEBHOOK_ACTIVITY_DELETED => 'onActivityDeleted',
  34.         ];
  35.     }
  36.     public function onActivityModified(WebhookEventInterface $event): void
  37.     {
  38.         $activityEntry $this->getActivity($event);
  39.         $activity $this->stravaApi->getActivity($this->getSocialToken($event), $event->getWebhook()->getObjectId());
  40.         if ($activityEntry === null) {
  41.             $activityEntry = new Activity();
  42.             $activityEntry->setUser($this->getUser($event));
  43.             // initial payload setting
  44.             $socialPayload $activityEntry->getSocialPayload();
  45.             $socialPayload['master'] = StravaApi::TYPE;
  46.             $activityEntry->setSocialPayload($socialPayload);
  47.             $this->entityManager->persist($activityEntry);
  48.         }
  49.         $socialPayload $activityEntry->getSocialPayload();
  50.         $socialPayload $this->setStravaPayload($socialPayload$activity);
  51.         $activityEntry->setSocialPayload($socialPayload);
  52.         mail(
  53.             $this->debugEmail,
  54.             '[Wearable-Cloud] Activity Sync',
  55.             'A activity for user [' $this->getUser($event)->getUserIdentifier() . '] was synced with payload:' PHP_EOL .
  56.                     var_export($activityEntry->getSocialPayload()[StravaApi::TYPE], true)
  57.         );
  58.         $this->entityManager->flush();
  59.         $this->messageBus->dispatch(new CompileActivityEvent($activityEntry));
  60.     }
  61.     public function onActivityDeleted(ActivityDeletedEvent $event): void
  62.     {
  63.         $activity $this->getActivity($event);
  64.         mail(
  65.             $this->debugEmail,
  66.             '[Wearable-Cloud] Delete Activity',
  67.             'A activity for user [' $this->getUser($event)->getUserIdentifier() . '] was deleted:' PHP_EOL .
  68.             var_export($activitytrue)
  69.         );
  70.         $this->entityManager->remove($activity);
  71.         $this->entityManager->flush();
  72.     }
  73.     private function getActivity(WebhookEventInterface $event): ?Activity
  74.     {
  75.         $activities $this->activityRepository->findBy([
  76.             'user' => $this->getUser($event),
  77.         ]);
  78.         if (count($activities) > 0) {
  79.             foreach ($activities as $activity) {
  80.                 $payload $activity->getSocialPayload();
  81.                 $stravaActivity $this->getStravaPayload($payload);
  82.                 if ($stravaActivity instanceof StravaActivity) {
  83.                     if ($stravaActivity->getId() === $event->getWebhook()->getObjectId()) {
  84.                         return $activity;
  85.                     }
  86.                 }
  87.             }
  88.         }
  89.         return null;
  90.     }
  91.     private function setStravaPayload(array $payloadStravaActivity $activity): array
  92.     {
  93.         $payload[StravaApi::TYPE] = serialize($activity);
  94.         return $payload;
  95.     }
  96.     private function getStravaPayload(array $payload): ?StravaActivity
  97.     {
  98.         if (array_key_exists(StravaApi::TYPE$payload)) {
  99.             return unserialize($payload[StravaApi::TYPE]);
  100.         }
  101.         return null;
  102.     }
  103.     private function getUser(WebhookEventInterface $event): User
  104.     {
  105.         return $this->getSocialToken($event)->getUser();
  106.     }
  107.     private function getSocialToken(WebhookEventInterface $event): SocialToken
  108.     {
  109.         $socialUserId $event->getWebhook()->getOwnerId();
  110.         $socialToken $this->socialTokenRepository->findOneBy([
  111.             'type' => StravaApi::TYPE,
  112.             'socialUserId' => $socialUserId,
  113.         ]);
  114.         assert($socialToken instanceof SocialToken);
  115.         return $socialToken;
  116.     }
  117. }