Skip to content

Commit

Permalink
Merge pull request #510 from leepeuker/move-webhook-endpoints-to-api
Browse files Browse the repository at this point in the history
Move webhook endpoints to the REST API
  • Loading branch information
leepeuker authored Oct 1, 2023
2 parents 5bd1b99 + c0b3e7f commit 31aeca5
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 3 deletions.
81 changes: 81 additions & 0 deletions docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,87 @@
}
]
}
},
"/webhook/plex/{uuid}": {
"post": {
"tags": [
"Webhooks"
],
"description": "Endpoint to scrobble your Plex watches to Movary.",
"parameters": [
{
"name": "UUID",
"in": "query",
"description": "An UUID that is generated by the user in the Plex settings.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK"
},
"404": {
"$ref": "#/components/responses/404"
}
}
}
},
"/webhook/jellyfin/{uuid}": {
"post": {
"tags": [
"Webhooks"
],
"description": "Endpoint to scrobble your Jellyfin watches to Movary.",
"parameters": [
{
"name": "UUID",
"in": "query",
"description": "An UUID that is generated by the user in the Jellyfin settings.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK"
},
"404": {
"$ref": "#/components/responses/404"
}
}
}
},
"/webhook/emby/{uuid}": {
"post": {
"tags": [
"Webhooks"
],
"description": "Endpoint to scrobble your Emby watches to Movary.",
"parameters": [
{
"name": "UUID",
"in": "query",
"description": "An UUID that is generated by the user in the Emby settings.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK"
},
"404": {
"$ref": "#/components/responses/404"
}
}
}
}
},
"components": {
Expand Down
6 changes: 5 additions & 1 deletion settings/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function addWebRoutes(RouterService $routerService, FastRoute\RouteCollector $ro
$routes->add('GET', '/docs/api', [Web\OpenApiController::class, 'renderPage']);

#####################
# Webhook listeners #
# Webhook listeners # !!! Deprecated use new api routes
#####################
$routes->add('POST', '/plex/{id:.+}', [Web\PlexController::class, 'handlePlexWebhook']);
$routes->add('POST', '/jellyfin/{id:.+}', [Web\JellyfinController::class, 'handleJellyfinWebhook']);
Expand Down Expand Up @@ -216,6 +216,10 @@ function addApiRoutes(RouterService $routerService, FastRoute\RouteCollector $ro

$routes->add('GET', '/movies/search', [Api\MovieSearchController::class, 'search'], [Api\Middleware\IsAuthenticated::class]);

$routes->add('POST', '/webhook/plex/{id:.+}', [Api\PlexController::class, 'handlePlexWebhook']);
$routes->add('POST', '/webhook/jellyfin/{id:.+}', [Api\JellyfinController::class, 'handleJellyfinWebhook']);
$routes->add('POST', '/webhook/emby/{id:.+}', [Api\EmbyController::class, 'handleEmbyWebhook']);

$routes->add('GET', '/feed/radarr/{id:.+}', [Api\RadarrController::class, 'renderRadarrFeed']);

$routerService->addRoutesToRouteCollector($routeCollector, $routes);
Expand Down
38 changes: 38 additions & 0 deletions src/HttpController/Api/EmbyController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php declare(strict_types=1);

namespace Movary\HttpController\Api;

use Movary\Domain\User\UserApi;
use Movary\Service\Emby\EmbyScrobbler;
use Movary\Util\Json;
use Movary\ValueObject\Http\Request;
use Movary\ValueObject\Http\Response;
use Psr\Log\LoggerInterface;

class EmbyController
{
public function __construct(
private readonly UserApi $userApi,
private readonly EmbyScrobbler $embyScrobbler,
private readonly LoggerInterface $logger,
) {
}

public function handleEmbyWebhook(Request $request) : Response
{
$webhookId = $request->getRouteParameters()['id'];

$userId = $this->userApi->findUserIdByEmbyWebhookId($webhookId);
if ($userId === null) {
return Response::createNotFound();
}

$requestPayload = $request->getPostParameters()['data'];

$this->logger->debug('Emby: Webhook triggered with payload: ' . $requestPayload);

$this->embyScrobbler->processEmbyWebhook($userId, Json::decode($requestPayload));

return Response::createOk();
}
}
37 changes: 37 additions & 0 deletions src/HttpController/Api/JellyfinController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types=1);

namespace Movary\HttpController\Api;

use Movary\Domain\User\UserApi;
use Movary\Service\Jellyfin\JellyfinScrobbler;
use Movary\Util\Json;
use Movary\ValueObject\Http\Request;
use Movary\ValueObject\Http\Response;
use Psr\Log\LoggerInterface;

class JellyfinController
{
public function __construct(
private readonly UserApi $userApi,
private readonly JellyfinScrobbler $jellyfinScrobbler,
private readonly LoggerInterface $logger,
) {
}
public function handleJellyfinWebhook(Request $request) : Response
{
$webhookId = $request->getRouteParameters()['id'];

$userId = $this->userApi->findUserIdByJellyfinWebhookId($webhookId);
if ($userId === null) {
return Response::createNotFound();
}

$requestPayload = $request->getBody();

$this->logger->debug('Jellyfin: Webhook triggered with payload: ' . $requestPayload);

$this->jellyfinScrobbler->processJellyfinWebhook($userId, Json::decode($requestPayload));

return Response::createOk();
}
}
41 changes: 41 additions & 0 deletions src/HttpController/Api/PlexController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php declare(strict_types=1);

namespace Movary\HttpController\Api;

use Movary\Domain\User\UserApi;
use Movary\Service\Plex\PlexScrobbler;
use Movary\Util\Json;
use Movary\ValueObject\Http\Request;
use Movary\ValueObject\Http\Response;
use Psr\Log\LoggerInterface;

class PlexController
{
public function __construct(
private readonly UserApi $userApi,
private readonly PlexScrobbler $plexScrobbler,
private readonly LoggerInterface $logger,
) {
}

public function handlePlexWebhook(Request $request) : Response
{
$webhookId = $request->getRouteParameters()['id'];

$userId = $this->userApi->findUserIdByPlexWebhookId($webhookId);
if ($userId === null) {
return Response::createNotFound();
}

$requestPayload = $request->getPostParameters()['payload'] ?? null;
if ($requestPayload === null) {
return Response::createOk();
}

$this->logger->debug('Plex: Webhook triggered with payload: ' . $requestPayload);

$this->plexScrobbler->processPlexWebhook($userId, Json::decode((string)$requestPayload));

return Response::createOk();
}
}
5 changes: 5 additions & 0 deletions src/HttpController/Web/EmbyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public function deleteEmbyWebhookUrl() : Response
return Response::createOk();
}

/**
* @deprecated
* @see \Movary\HttpController\Api\EmbyController::handleEmbyWebhook()
*/
public function handleEmbyWebhook(Request $request) : Response
{
$webhookId = $request->getRouteParameters()['id'];
Expand All @@ -41,6 +45,7 @@ public function handleEmbyWebhook(Request $request) : Response
$requestPayload = $request->getPostParameters()['data'];

$this->logger->debug('Emby: Webhook triggered with payload: ' . $requestPayload);
$this->logger->warning('This emby webhook url is deprecated and will stop to work soon, regenerate the url');

$this->embyScrobbler->processEmbyWebhook($userId, Json::decode($requestPayload));

Expand Down
6 changes: 6 additions & 0 deletions src/HttpController/Web/JellyfinController.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public function deleteJellyfinWebhookUrl() : Response
return Response::createOk();
}


/**
* @deprecated
* @see \Movary\HttpController\Api\JellyfinController::handleJellyfinWebhook()
*/
public function handleJellyfinWebhook(Request $request) : Response
{
$webhookId = $request->getRouteParameters()['id'];
Expand All @@ -78,6 +83,7 @@ public function handleJellyfinWebhook(Request $request) : Response
$requestPayload = $request->getBody();

$this->logger->debug('Jellyfin: Webhook triggered with payload: ' . $requestPayload);
$this->logger->warning('This jellyfin webhook url is deprecated and will stop to work soon, regenerate the url');

$this->jellyfinScrobbler->processJellyfinWebhook($userId, Json::decode($requestPayload));

Expand Down
5 changes: 5 additions & 0 deletions src/HttpController/Web/PlexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public function generatePlexAuthenticationUrl() : Response
return Response::createJson(Json::encode(['authenticationUrl' => $plexAuthenticationUrl]));
}

/**
* @deprecated
* @see \Movary\HttpController\Api\PlexController::handlePlexWebhook()
*/
public function handlePlexWebhook(Request $request) : Response
{
$webhookId = $request->getRouteParameters()['id'];
Expand All @@ -68,6 +72,7 @@ public function handlePlexWebhook(Request $request) : Response
}

$this->logger->debug('Plex: Webhook triggered with payload: ' . $requestPayload);
$this->logger->warning('This plex webhook url is deprecated and will stop to work soon, regenerate the url');

$this->plexScrobbler->processPlexWebhook($userId, Json::decode((string)$requestPayload));

Expand Down
2 changes: 1 addition & 1 deletion src/Service/WebhookUrlBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ private function buildUrl(string $webhookType, string $webhookId) : ?string
return null;
}

return rtrim($applicationUrl, '/') . '/' . $webhookType . '/' . $webhookId;
return rtrim($applicationUrl, '/') . '/api/webhook/' . $webhookType . '/' . $webhookId;
}
}
2 changes: 1 addition & 1 deletion tests/rest/web/plex-scrobble.http
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
POST http://127.0.0.1/plex/16914287-329d-4f3b-ba57-4a092f13058d
POST http://127.0.0.1/api/webhook/plex/14f14d6b-695f-41b9-a856-5ba401bcc040
Accept: */*
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
Expand Down

0 comments on commit 31aeca5

Please sign in to comment.