usenoty / noty-laravel
Non-blocking Noty Notification Channel for Laravel.
Installs: 3
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/usenoty/noty-laravel
Requires
- php: ^8.2|^8.3|^8.4
- guzzlehttp/guzzle: ^7.0
- illuminate/notifications: ^10.0|^11.0|^12.0
- illuminate/queue: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.89
- mockery/mockery: ^1.5
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0
This package is not auto-updated.
Last update: 2025-12-29 19:51:47 UTC
README
A non-blocking notification channel for Laravel that sends events to Noty API. Perfect for tracking user activities, application events, and telemetry data without impacting your app's performance.
โจ Features
- ๐ Non-Blocking: Uses async HTTP requests that don't slow down your app
- ๐ก๏ธ Fail-Silent: Never breaks your app, even if the tracking service is down
- โก Auto-Flush: Automatically sends pending events after response is sent
- ๐ฏ Simple API: Just like Sentry - use
captureEvent()or Laravel notifications - ๐ Fluent Builder: Type-safe
NotyMessageclass for elegant event building - ๐ Queue Support: Optional queue-based transport for high-volume applications
- ๐ Rich Events: Support for actions, tags, attachments, and emojis
๐ฆ Installation
Install via Composer:
composer require usenoty/noty-laravel
Publish the configuration file:
php artisan vendor:publish --provider="Noty\Laravel\Providers\NotyServiceProvider"
โ๏ธ Configuration
Set your Noty API credentials in .env:
# API Configuration NOTY_DSN=http://localhost:3020 NOTY_TOKEN=p7362mdlvmixjbvle01q7oeooqhfzq33 # Define your channels (named channels or channel IDs) NOTY_DEFAULT_CHANNEL=general NOTY_CHANNEL_GENERAL=channel_Arys9gID0J0HKv NOTY_CHANNEL_AUTH=channel_xyz123auth NOTY_CHANNEL_PAYMENTS=channel_abc456pay # Transport (http or queue) NOTY_TRANSPORT=http NOTY_DEFAULT_PRIORITY=NORMAL
๐ Quick Start
Method 1: Using NotyMessage (Recommended)
The NotyMessage class provides a fluent, type-safe API:
use Noty\Laravel\NotyMessage; NotyMessage::create('Order Created') ->message('Order #1234 has been created') ->channel('orders') ->priority(NotyMessage::PRIORITY_HIGH) ->action('View Order', route('orders.show', 1234), true) ->tag('order_id', 1234) ->tag('amount', 99.99) ->emoji('๐') ->send();
Method 2: Using Laravel Notifications
Create a notification class:
namespace App\Notifications; use Illuminate\Notifications\Notification; class UserLoggedIn extends Notification { public function __construct(private $user) {} public function via($notifiable) { return ['noty']; } public function toNoty($notifiable) { return [ 'title' => 'User logged in: ' . $this->user->email, 'message' => 'User logged in from IP: ' . request()->ip(), 'channel' => 'auth', 'priority' => 'HIGH', 'actions' => [ [ 'name' => 'View Profile', 'url' => route('users.show', $this->user), 'browser' => true ] ], 'tags' => [ 'ip_address' => request()->ip(), 'user_id' => $this->user->id, ] ]; } }
Send the notification:
$user->notify(new UserLoggedIn($user));
Method 3: Using captureEvent (Like Sentry)
use Noty\Laravel\Facades\Noty; Noty::captureEvent([ 'title' => 'Payment Received', 'message' => 'Payment of $100.00 received', 'channel' => 'payments', 'priority' => 'HIGH', 'actions' => [ [ 'name' => 'View Order', 'url' => route('orders.show', $order->id), 'browser' => true ] ], 'tags' => [ 'order_id' => $order->id, 'amount' => 100.00, 'currency' => 'USD', ] ]);
Or using the helper function:
noty()->captureEvent([ 'title' => 'User Registered', 'channel' => 'auth', ]);
๐ NotyMessage API Reference
Basic Usage
use Noty\Laravel\NotyMessage; // Simple notification NotyMessage::create('Order Created') ->channel('orders') ->send(); // With message and priority NotyMessage::create('Payment Received') ->message('Payment of $100.00 received') ->channel('payments') ->priority(NotyMessage::PRIORITY_HIGH) ->send();
Priority Constants
NotyMessage::PRIORITY_HIGH // High priority NotyMessage::PRIORITY_NORMAL // Normal priority (default) NotyMessage::PRIORITY_LOW // Low priority
Actions
// Single action NotyMessage::create('Order #123') ->action('View Order', route('orders.show', 123), true) ->send(); // Multiple actions NotyMessage::create('Order #123') ->action('View Order', route('orders.show', 123), true) ->action('Download Invoice', route('orders.invoice', 123)) ->send(); // Actions array NotyMessage::create('Order #123') ->actions([ ['name' => 'View Order', 'url' => route('orders.show', 123), 'browser' => true], ['name' => 'Download Invoice', 'url' => route('orders.invoice', 123)] ]) ->send();
Tags
// Single tag NotyMessage::create('User Login') ->tag('user_id', $user->id) ->send(); // Multiple tags NotyMessage::create('User Login') ->tag('user_id', $user->id) ->tag('ip_address', request()->ip()) ->tags(['browser' => 'Chrome', 'os' => 'MacOS']) ->send();
Emojis
NotyMessage::create('New Event') ->emoji('๐') ->message('A new event has been created') ->send();
๐ง Channel Configuration
Named Channels (Recommended)
Define channel names in .env:
NOTY_CHANNEL_AUTH=channel_Arys9gID0J0HKv NOTY_CHANNEL_PAYMENTS=channel_abc123xyz NOTY_CHANNEL_ORDERS=channel_def456uvw
Use in code:
NotyMessage::create('Event') ->channel('auth') // Uses channel_Arys9gID0J0HKv ->send();
Direct Channel IDs
NotyMessage::create('Event') ->channel('channel_Arys9gID0J0HKv') ->send();
๐ Transport Options
HTTP Transport (Default)
Events are sent asynchronously via HTTP after the response is sent to the user.
NOTY_TRANSPORT=http
Queue Transport
For high-volume applications, use queue transport:
NOTY_TRANSPORT=queue NOTY_QUEUE_CONNECTION=redis NOTY_QUEUE_NAME=noty-events NOTY_QUEUE_BATCH_SIZE=10
๐ Event Data Structure
Events are sent to the Noty API with the following structure:
{
"channel": "channel_Arys9gID0J0HKv",
"title": "User logged in: user@example.com",
"message": "User logged in from IP: 172.38.21.134",
"priority": "HIGH",
"actions": [
{
"name": "View Profile",
"url": "https://app.example.com/users/123",
"browser": true
}
],
"attachments": [],
"tags": {
"ip_address": "172.38.21.134",
"user_email": "user@example.com"
}
}
๐ How It Works
- Non-Blocking: When you call
captureEvent(), the event is queued but not sent immediately - Async Requests: HTTP requests are made asynchronously using Guzzle promises
- Auto-Flush: After Laravel sends the response, pending events are flushed in the background
- Fail-Silent: If the Noty API is unreachable, your app continues working normally
Request โ Your App Logic โ Response to User โ Flush Events (async)
โ
captureEvent() stores promise
๐ Complete Example
use Noty\Laravel\Facades\Noty; // In a controller public function login(Request $request) { $user = Auth::user(); // Using NotyMessage (recommended) NotyMessage::create('User Login') ->message($user->email . ' logged in') ->channel('auth') ->priority(NotyMessage::PRIORITY_HIGH) ->action('View Profile', route('users.show', $user), true) ->tag('ip', request()->ip()) ->tag('user_id', $user->id) ->emoji('๐') ->send(); return redirect('/dashboard'); }
๐ฏ When to Use Each Method
- NotyMessage: Best for most cases - type-safe, fluent, and readable
- Laravel Notifications: Best for reusable notifications sent to multiple users
- captureEvent: Best for simple, one-off events or custom builders
๐ Requirements
- PHP: 8.2, 8.3, or 8.4
- Laravel: 10.x, 11.x, or 12.x
- Guzzle: 7.x
๐ Supported Versions
| Laravel | PHP | Status |
|---|---|---|
| 12.x | 8.2+ | โ Active |
| 11.x | 8.2+ | โ Active |
| 10.x | 8.1+ | โ Active |
| 9.x | 8.0+ | โ Unsupported |
| 8.x | 7.3+ | โ Unsupported |
๐งช Testing
This package is thoroughly tested with:
- 50 tests covering all functionality
- 100+ assertions ensuring reliability
- PHPStan Level 5 static analysis
- Multiple PHP versions (8.2, 8.3, 8.4)
- Multiple Laravel versions (10.x, 11.x, 12.x)
Running Tests
# Run all tests composer test # Run with coverage composer test-coverage # Run static analysis composer phpstan
๐ License
This project is licensed under the MIT License. See the LICENSE file for details.
Made with โค๏ธ for Laravel developers