codewithathis / paperless-ngx
A Laravel package for managing Paperless-ngx via its API, providing easy integration, document upload, search, tagging, and workflow automation.
Requires
- php: ^8.0
- guzzlehttp/guzzle: ^7.0
- laravel/framework: ^9.0|^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^7.0|^8.0
- phpunit/phpunit: ^9.0|^10.0
README
A comprehensive Laravel package for integrating with Paperless-ngx document management system. This package provides authentication, document management, search capabilities, and bulk operations through a clean Laravel interface.
Features
- ✅ Authentication Support: Token-based and Basic authentication
- ✅ Document Management: Upload, download, update, delete documents
- ✅ Search & Filtering: Full-text search with various filters
- ✅ Bulk Operations: Bulk edit and download documents
- ✅ Metadata Management: Tags, correspondents, document types, storage paths
- ✅ Custom Fields: Support for custom field operations
- ✅ Share Links: Create and manage document share links
- ✅ Statistics: Get system statistics and user profile
- ✅ Error Handling: Comprehensive error handling and logging
- ✅ Configuration: Flexible configuration system
- ✅ Facade Support: Easy access via Laravel Facade
- ✅ Artisan Commands: Built-in testing and management commands
- ✅ API Routes: Pre-configured REST API endpoints
Installation
Via Composer
composer require codewithathis/paperless-ngx
Manual Installation
- Add to your
composer.json
:
{ "require": { "codewithathis/paperless-ngx": "^1.0" } }
- Run composer install:
composer install
- Publish Configuration:
php artisan vendor:publish --provider="Codewithathis\PaperlessNgx\PaperlessServiceProvider" --tag="paperless-config"
- Environment Variables
Add the following variables to your .env
file:
# Paperless-ngx Configuration PAPERLESS_BASE_URL=http://your-paperless-instance.com PAPERLESS_TOKEN=your_api_token_here PAPERLESS_USERNAME=your_username PAPERLESS_PASSWORD=your_password PAPERLESS_AUTH_METHOD=token # Optional Settings PAPERLESS_PAGE_SIZE=25 PAPERLESS_TIMEOUT=30 PAPERLESS_MAX_FILE_SIZE=52428800 PAPERLESS_LOGGING_ENABLED=true PAPERLESS_LOG_LEVEL=error
Configuration
The package can be configured through the config/paperless.php
file. Key configuration options:
Authentication
'auth' => [ 'token' => env('PAPERLESS_TOKEN', null), 'username' => env('PAPERLESS_USERNAME', null), 'password' => env('PAPERLESS_PASSWORD', null), 'method' => env('PAPERLESS_AUTH_METHOD', 'token'), ],
Document Upload Settings
'upload' => [ 'max_file_size' => env('PAPERLESS_MAX_FILE_SIZE', 50 * 1024 * 1024), 'allowed_mime_types' => [ 'application/pdf', 'image/jpeg', 'image/png', 'image/tiff', // ... more types ], 'auto_ocr' => env('PAPERLESS_AUTO_OCR', true), 'auto_tag' => env('PAPERLESS_AUTO_TAG', false), ],
Usage
Basic Usage
Using Dependency Injection
use Codewithathis\PaperlessNgx\PaperlessService; class DocumentController extends Controller { public function __construct(private PaperlessService $paperlessService) { } public function index() { $documents = $this->paperlessService->getDocuments(); return response()->json($documents); } }
Using the Facade
use Codewithathis\PaperlessNgx\Facades\Paperless; // Test connection $isConnected = Paperless::testConnection(); // Get documents $documents = Paperless::getDocuments(['title__icontains' => 'invoice']); // Upload document $documentId = Paperless::uploadDocument($file, [ 'title' => 'Invoice #123', 'correspondent' => 1, 'tags' => [1, 2, 3], ]);
Authentication
Token Authentication (Recommended)
// Set token $paperlessService->setToken('your_api_token'); // Or in constructor $paperlessService = new PaperlessService( 'http://your-paperless-instance.com', 'your_api_token' );
Basic Authentication
// Set credentials $paperlessService->setBasicAuth('username', 'password'); // Or in constructor $paperlessService = new PaperlessService( 'http://your-paperless-instance.com', null, 'username', 'password' );
Document Operations
Upload Document
use Illuminate\Http\UploadedFile; $file = $request->file('document'); $metadata = [ 'title' => 'Invoice #123', 'correspondent' => 1, 'document_type' => 2, 'tags' => [1, 2, 3], 'storage_path' => 1, 'archive_serial_number' => 1001, ]; $documentId = $paperlessService->uploadDocument($file, $metadata);
Get Documents with Filters
$filters = [ 'title__icontains' => 'invoice', 'correspondent__id' => 1, 'tags__id__in' => [1, 2, 3], 'created__gte' => '2024-01-01', 'created__lte' => '2024-12-31', ]; $documents = $paperlessService->getDocuments($filters, 1, 25);
Update Document
$data = [ 'title' => 'Updated Invoice Title', 'correspondent' => 2, 'tags' => [1, 4, 5], ]; $document = $paperlessService->updateDocument(123, $data);
Download Document
// Download processed version $content = $paperlessService->downloadDocument(123); // Download original version $originalContent = $paperlessService->downloadDocument(123, true);
Delete Document
$deleted = $paperlessService->deleteDocument(123);
Search Operations
Search Documents
// Search in database only $results = $paperlessService->searchDocuments('invoice', true); // Search in full content $results = $paperlessService->searchDocuments('invoice', false);
Get Search Autocomplete
$suggestions = $paperlessService->getSearchAutocomplete('inv', 10);
Bulk Operations
Bulk Edit Documents
$documentIds = [1, 2, 3, 4, 5]; $editData = [ 'correspondent' => 1, 'tags' => [1, 2], 'document_type' => 2, ]; $result = $paperlessService->bulkEditDocuments($documentIds, $editData);
Bulk Download Documents
$documentIds = [1, 2, 3, 4, 5]; $downloadInfo = $paperlessService->bulkDownloadDocuments($documentIds);
Metadata Management
Tags
// Get all tags $tags = $paperlessService->getTags(); // Create tag $tag = $paperlessService->createTag([ 'name' => 'Important', 'color' => '#ff0000', ]); // Update tag $updatedTag = $paperlessService->updateTag(1, [ 'name' => 'Very Important', 'color' => '#00ff00', ]); // Delete tag $deleted = $paperlessService->deleteTag(1);
Correspondents
// Get correspondents $correspondents = $paperlessService->getCorrespondents(); // Create correspondent $correspondent = $paperlessService->createCorrespondent([ 'name' => 'ABC Company', 'matching_algorithm' => 1, 'match' => 'ABC', ]); // Update correspondent $updatedCorrespondent = $paperlessService->updateCorrespondent(1, [ 'name' => 'ABC Corporation', ]); // Delete correspondent $deleted = $paperlessService->deleteCorrespondent(1);
Document Types
// Get document types $documentTypes = $paperlessService->getDocumentTypes(); // Create document type $documentType = $paperlessService->createDocumentType([ 'name' => 'Invoice', 'matching_algorithm' => 1, 'match' => 'invoice', ]); // Update document type $updatedDocumentType = $paperlessService->updateDocumentType(1, [ 'name' => 'Invoice Document', ]); // Delete document type $deleted = $paperlessService->deleteDocumentType(1);
Document Notes
// Get document notes $notes = $paperlessService->getDocumentNotes(123); // Add note $note = $paperlessService->addDocumentNote(123, 'This is an important document'); // Delete note $deleted = $paperlessService->deleteDocumentNote(123, 1);
Document History
// Get document history $history = $paperlessService->getDocumentHistory(123);
Share Links
// Get document share links $shareLinks = $paperlessService->getDocumentShareLinks(123); // Create share link $shareLink = $paperlessService->createShareLink([ 'document' => 123, 'expiration' => '2024-12-31', ]); // Update share link $updatedShareLink = $paperlessService->updateShareLink(1, [ 'expiration' => '2024-06-30', ]); // Delete share link $deleted = $paperlessService->deleteShareLink(1);
Statistics
// Get system statistics $statistics = $paperlessService->getStatistics();
System Information
// Get system status $status = $paperlessService->getStatus(); // Get remote version $version = $paperlessService->getRemoteVersion(); // Get user profile $profile = $paperlessService->getProfile(); // Generate auth token $token = $paperlessService->generateAuthToken();
Artisan Commands
The package includes several Artisan commands for testing and management:
Test Connection
php artisan paperless:test
Test with File Upload
php artisan paperless:test --upload=/path/to/document.pdf
Test Search
php artisan paperless:test --search="invoice"
API Routes
The package automatically registers the following API routes:
// Test connection GET /api/paperless/test-connection // Documents GET /api/paperless/documents GET /api/paperless/documents/{id} POST /api/paperless/documents PUT /api/paperless/documents/{id} DELETE /api/paperless/documents/{id} GET /api/paperless/documents/{id}/download // Search GET /api/paperless/search // Metadata GET /api/paperless/tags GET /api/paperless/correspondents GET /api/paperless/document-types // Statistics GET /api/paperless/statistics // Bulk operations POST /api/paperless/bulk-edit
Error Handling
The service includes comprehensive error handling:
try { $documents = $paperlessService->getDocuments(); } catch (Exception $e) { Log::error('Paperless API Error', [ 'message' => $e->getMessage(), 'code' => $e->getCode(), ]); return response()->json([ 'error' => 'Failed to get documents', 'message' => $e->getMessage(), ], 500); }
Logging
The service logs all API interactions when logging is enabled:
'logging' => [ 'enabled' => env('PAPERLESS_LOGGING_ENABLED', true), 'level' => env('PAPERLESS_LOG_LEVEL', 'error'), 'channel' => env('PAPERLESS_LOG_CHANNEL', 'paperless'), ],
Caching
The service supports caching for improved performance:
'cache' => [ 'enabled' => env('PAPERLESS_CACHE_ENABLED', true), 'ttl' => env('PAPERLESS_CACHE_TTL', 3600), 'prefix' => env('PAPERLESS_CACHE_PREFIX', 'paperless'), ],
Security
Security settings for SSL verification and timeouts:
'security' => [ 'verify_ssl' => env('PAPERLESS_VERIFY_SSL', true), 'allow_self_signed' => env('PAPERLESS_ALLOW_SELF_SIGNED', false), 'timeout' => env('PAPERLESS_REQUEST_TIMEOUT', 30), ],
Testing
Test the connection to your Paperless-ngx instance:
// Test connection $isConnected = $paperlessService->testConnection(); if ($isConnected) { echo "Successfully connected to Paperless-ngx"; } else { echo "Failed to connect to Paperless-ngx"; }
Examples
Complete Document Management Workflow
use Codewithathis\PaperlessNgx\PaperlessService; use Illuminate\Http\UploadedFile; class DocumentService { public function __construct(private PaperlessService $paperlessService) { } public function processInvoice(UploadedFile $file, array $data) { try { // 1. Upload document $documentId = $this->paperlessService->uploadDocument($file, [ 'title' => $data['title'], 'correspondent' => $data['correspondent_id'], 'document_type' => $data['document_type_id'], 'tags' => $data['tag_ids'], ]); // 2. Add note $this->paperlessService->addDocumentNote($documentId, 'Processed automatically'); // 3. Get document details $document = $this->paperlessService->getDocument($documentId); return [ 'success' => true, 'document_id' => $documentId, 'document' => $document, ]; } catch (Exception $e) { Log::error('Failed to process invoice', [ 'error' => $e->getMessage(), 'file' => $file->getClientOriginalName(), ]); return [ 'success' => false, 'error' => $e->getMessage(), ]; } } public function searchInvoices(string $query) { $filters = [ 'title__icontains' => $query, 'document_type__name__icontains' => 'invoice', ]; return $this->paperlessService->getDocuments($filters); } public function bulkTagDocuments(array $documentIds, array $tagIds) { return $this->paperlessService->bulkEditDocuments($documentIds, [ 'tags' => $tagIds, ]); } }
Using with Laravel Jobs
use Codewithathis\PaperlessNgx\PaperlessService; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProcessDocumentJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public function __construct( private string $filePath, private array $metadata ) { } public function handle(PaperlessService $paperlessService) { $file = new UploadedFile($this->filePath, basename($this->filePath)); $documentId = $paperlessService->uploadDocument($file, $this->metadata); // Process the uploaded document Log::info('Document uploaded successfully', ['document_id' => $documentId]); } }
Troubleshooting
Common Issues
-
Authentication Failed
- Verify your API token or credentials
- Check if the Paperless-ngx instance is accessible
- Ensure the authentication method is correctly configured
-
Upload Fails
- Check file size limits
- Verify supported file types
- Ensure proper permissions on the Paperless-ngx instance
-
Connection Timeout
- Increase timeout settings in configuration
- Check network connectivity
- Verify Paperless-ngx instance is running
-
SSL Certificate Issues
- Set
PAPERLESS_VERIFY_SSL=false
for self-signed certificates - Update SSL certificates on your Paperless-ngx instance
- Set
Debug Mode
Enable debug logging to troubleshoot issues:
PAPERLESS_LOGGING_ENABLED=true PAPERLESS_LOG_LEVEL=debug
Package Structure
codewithathis/paperless-ngx/
├── src/
│ ├── PaperlessService.php
│ ├── PaperlessServiceProvider.php
│ ├── Facades/
│ │ └── Paperless.php
│ ├── Http/
│ │ └── Controllers/
│ │ └── PaperlessController.php
│ └── Commands/
│ └── TestPaperlessConnection.php
├── config/
│ └── paperless.php
├── routes/
│ └── api.php
├── composer.json
└── README.md
Requirements
- PHP >= 8.0
- Laravel >= 9.0
- Guzzle HTTP Client (included with Laravel)
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Testing
# Run the test command php artisan paperless:test # Test with file upload php artisan paperless:test --upload=/path/to/test.pdf # Test search functionality php artisan paperless:test --search="invoice"
Changelog
Please see CHANGELOG for more information on what has changed recently.
License
This package is open-sourced software licensed under the MIT license.
Support
If you encounter any issues or have questions, please:
- Check the troubleshooting section
- Search existing issues
- Create a new issue with detailed information
Credits
- Paperless-ngx - The document management system
- Laravel - The PHP framework for web artisans