martincamen / laravel-jellyseerr
Laravel integration for Jellyseerr PHP SDK
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/martincamen/laravel-jellyseerr
Requires
- php: ^8.3
- driftingly/rector-laravel: ^2.1.9
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- martincamen/jellyseerr-php: ^0.1
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0|^10.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- roave/security-advisories: dev-latest
README
Laravel integration for the Jellyseerr PHP SDK, providing a seamless experience for interacting with Jellyseerr using unified domain models from php-arr-core.
Important
This project is still being developed and breaking changes might occur even between patch versions.
The aim is to follow semantic versioning as soon as possible.
Ecosystem
| Package | Description |
|---|---|
| radarr-php | PHP SDK for Radarr |
| sonarr-php | PHP SDK for Sonarr |
| jellyseerr-php | PHP SDK for Jellyseerr |
| laravel-radarr | Laravel integration for Radarr |
| laravel-sonarr | Laravel integration for Sonarr |
| laravel-jellyseerr | Laravel integration for Jellyseerr |
Features
- Unified API using canonical domain models from
php-arr-core - Type-safe interactions with Jellyseerr
- Laravel facade with full IDE autocompletion
- Testing utilities for mocking responses
- Automatic service discovery via Laravel's package auto-discovery
Requirements
- PHP 8.3+
- Laravel 10.0+, 11.0+ or 12.0+
Installation
composer require martincamen/laravel-jellyseerr
The package will auto-register its service provider in Laravel.
Configuration
Publish the configuration file:
php artisan vendor:publish --provider="MartinCamen\LaravelJellyseerr\JellyseerrServiceProvider"
Add the following environment variables to your .env file:
JELLYSEERR_HOST=localhost JELLYSEERR_PORT=5055 JELLYSEERR_API_KEY=your-api-key JELLYSEERR_USE_HTTPS=false JELLYSEERR_TIMEOUT=30 JELLYSEERR_URL_BASE=
Configuration Options
| Option | Description | Default |
|---|---|---|
JELLYSEERR_HOST |
Hostname or IP address of your Jellyseerr server | localhost |
JELLYSEERR_PORT |
Port number for your Jellyseerr server | 5055 |
JELLYSEERR_API_KEY |
Your Jellyseerr API key (Settings > General > API Key) | - |
JELLYSEERR_USE_HTTPS |
Use HTTPS for connections | false |
JELLYSEERR_TIMEOUT |
Request timeout in seconds | 30 |
JELLYSEERR_URL_BASE |
URL base for reverse proxy subpaths (e.g., /jellyseerr) |
- |
Usage
Using the Facade
The Jellyseerr facade provides access to the SDK client via an action-based API:
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; // Get all media requests $requests = Jellyseerr::requests()->all(); // Get a specific request by ID $request = Jellyseerr::requests()->find(1); // Search for media $results = Jellyseerr::search()->search('Breaking Bad'); // Get system information $status = Jellyseerr::system()->status();
Dependency Injection
You can also inject Jellyseerr directly:
use MartinCamen\Jellyseerr\Jellyseerr; class RequestController { public function __construct(private Jellyseerr $jellyseerr) {} public function index() { return view('requests.index', ['requests' => $this->jellyseerr->requests()->all()]); } }
Working with Requests
The requests() method provides access to media request management:
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; use MartinCamen\Jellyseerr\Data\Responses\RequestPage; use MartinCamen\Jellyseerr\Data\Responses\MediaRequest; // Get all requests (paginated) /** @var RequestPage $requestPage */ $requestPage = Jellyseerr::requests()->all(); foreach ($requestPage as $request) { echo $request->id; echo $request->status->value; } // Get a specific request $request = Jellyseerr::requests()->find(1); // Get request counts $count = Jellyseerr::requests()->count(); echo "Pending: {$count->pending}"; echo "Approved: {$count->approved}"; // Create a movie request $request = Jellyseerr::requests()->movie(550); // TMDB ID // Create a series request with specific seasons $request = Jellyseerr::requests()->series(1396, [1, 2]); // TMDB ID, seasons // Approve a request $request = Jellyseerr::requests()->approve(1); // Decline a request $request = Jellyseerr::requests()->decline(1); // Retry a failed request $request = Jellyseerr::requests()->retry(1); // Delete a request Jellyseerr::requests()->delete(1);
Working with Movies
The movies() method provides access to movie details via TMDB:
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; use MartinCamen\Jellyseerr\Data\Responses\MovieDetails; // Get movie details by TMDB ID $movie = Jellyseerr::movies()->find(550); echo $movie->title; echo $movie->overview; // Get movie recommendations $recommendations = Jellyseerr::movies()->recommendations(550); // Get similar movies $similar = Jellyseerr::movies()->similar(550);
Working with Series
The series() method provides access to TV series details via TMDB:
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; use MartinCamen\Jellyseerr\Data\Responses\SeriesDetails; // Get series details by TMDB ID $series = Jellyseerr::series()->find(1396); echo $series->name; echo $series->overview; // Get series recommendations $recommendations = Jellyseerr::series()->recommendations(1396); // Get similar series $similar = Jellyseerr::series()->similar(1396); // Get season details $season = Jellyseerr::series()->season(1396, 1);
Searching Media
The search() method provides search and discovery functionality:
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; use MartinCamen\Jellyseerr\Data\Responses\SearchPage; // Search for any media $results = Jellyseerr::search()->search('Breaking Bad'); foreach ($results as $result) { echo $result->title ?? $result->name; echo $result->mediaType; } // Discover movies $movies = Jellyseerr::search()->discoverMovies(); // Discover series $series = Jellyseerr::search()->discoverSeries(); // Get trending media $trending = Jellyseerr::search()->trending(); // Get upcoming movies $upcoming = Jellyseerr::search()->upcoming();
Working with Users
The users() method provides access to user management:
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; use MartinCamen\Jellyseerr\Data\Responses\UserPage; use MartinCamen\Jellyseerr\Data\Responses\User; // Get all users /** @var UserPage $users */ $users = Jellyseerr::users()->all(); foreach ($users as $user) { echo $user->displayName; echo $user->email; } // Get a specific user $user = Jellyseerr::users()->find(1); // Get the current authenticated user $me = Jellyseerr::users()->me(); // Get a user's requests $requests = Jellyseerr::users()->requests(1);
System
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; // Get system status $status = Jellyseerr::system()->status(); echo $status->version; // Get appdata information $appdata = Jellyseerr::system()->appdata(); // Get public settings $settings = Jellyseerr::system()->publicSettings();
Response Types
All responses use typed DTOs from the SDK:
| Type | Description |
|---|---|
RequestPage |
Paginated media requests |
MediaRequest |
Individual media request |
RequestCount |
Request count statistics |
MovieDetails |
Movie details from TMDB |
SeriesDetails |
TV series details from TMDB |
SearchPage |
Paginated search results |
UserPage |
Paginated users |
User |
Individual user |
SystemSummary |
System status information |
Testing
Using the Fake
The package provides JellyseerrFake for testing:
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; class RequestTest extends TestCase { public function testDisplaysRequests(): void { // Create a fake instance $fake = Jellyseerr::fake(); // Make request $response = $this->get('/requests'); // Assert the method was called $fake->assertCalled('requests'); $response->assertOk(); } public function testSearchesMedia(): void { $fake = Jellyseerr::fake(); // Make request that calls search()->search() $this->get('/search?q=test'); // Assert called $fake->assertCalled('search'); } public function testNothingWasCalled(): void { $fake = Jellyseerr::fake(); // No API calls made $this->get('/about'); $fake->assertNothingCalled(); } }
Assertion Methods
The fake provides several assertion methods:
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; $fake = Jellyseerr::fake(); // Assert a method was called $fake->assertCalled('requests'); // Assert a method was not called $fake->assertNotCalled('movies'); // Assert a method was called a specific number of times $fake->assertCalledTimes('requests', 3); // Assert nothing was called $fake->assertNothingCalled(); // Get all recorded calls $calls = $fake->getCalls();
Example: Building a Request Dashboard
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; class DashboardController extends Controller { public function index() { // Get system status $status = Jellyseerr::system()->status(); // Get request counts $counts = Jellyseerr::requests()->count(); // Get recent requests $requests = Jellyseerr::requests()->all(); // Get trending media for suggestions $trending = Jellyseerr::search()->trending(); return view('dashboard', [ 'version' => $status->version, 'pendingCount' => $counts->pending, 'approvedCount' => $counts->approved, 'requests' => $requests, 'trending' => $trending, ]); } }
Error Handling
use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr; use MartinCamen\ArrCore\Exceptions\AuthenticationException; use MartinCamen\ArrCore\Exceptions\ConnectionException; use MartinCamen\ArrCore\Exceptions\NotFoundException; try { $request = Jellyseerr::requests()->find(999); } catch (AuthenticationException $e) { // Invalid API key return back()->with('error', 'Invalid Jellyseerr API key'); } catch (NotFoundException $e) { // Request not found abort(404, 'Request not found'); } catch (ConnectionException $e) { // Connection error logger()->error('Could not connect to Jellyseerr: ' . $e->getMessage()); return back()->with('error', 'Jellyseerr server unavailable'); }
License
The MIT License (MIT). Please see License File for more information.
Credits
Built on top of the Jellyseerr PHP SDK and php-arr-core.