OneSignal notification channel for Laravel applications. Send push notifications to iOS, Android, and web browsers through OneSignal's API with a clean, fluent interface.
- Laravel Notification Channel integration
- Fluent message builder API
- Event system for notification lifecycle
- Comprehensive configuration options
- Custom exception handling
- PSR-3 logging support
- Type-safe implementation with PHP 8.3
- Full test coverage
- PHP 8.3 or higher
- Laravel 12.x or 13.x
- OneSignal account and API credentials
Install the package via Composer:
composer require lepresk/laravel-onesignalThe service provider will be automatically registered through Laravel's package auto-discovery.
Publish the configuration file to customize package behavior:
php artisan vendor:publish --tag=onesignal-configAdd your OneSignal credentials to your .env file:
ONESIGNAL_APP_ID=your-app-id
ONESIGNAL_REST_API_KEY=your-rest-api-key
ONESIGNAL_ANDROID_CHANNEL_ID=your-android-channel-iduse Lepresk\LaravelOnesignal\Facades\OneSignal;
use Lepresk\LaravelOnesignal\PushMessage;
$message = (new PushMessage())
->withTitle('Hello World')
->withBody('This is a test notification')
->toExternalUserIds([1, 2, 3]);
$response = OneSignal::send($message);
if ($response->isSuccessful()) {
echo "Notification sent! ID: " . $response->getNotificationId();
}Create a notification class:
<?php
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use Lepresk\LaravelOnesignal\PushMessage;
class WelcomeNotification extends Notification
{
public function via($notifiable): array
{
return ['push'];
}
public function toPush($notifiable): PushMessage
{
return (new PushMessage())
->withTitle('Welcome!')
->withBody('Thanks for joining our platform')
->toUser($notifiable->onesignal_id);
}
}Send the notification:
$user->notify(new WelcomeNotification());$message = (new PushMessage())
->withTitle('Title', 'en')
->withTitle('Titre', 'fr')
->withBody('Body', 'en')
->withBody('Corps', 'fr');$message = (new PushMessage())
->withTitle('Urgent!')
->withBody('This is urgent')
->withHighPriority();External User IDs are custom identifiers you assign to your users in OneSignal (via OneSignal.login() in the SDK). They are sent with OneSignal's include_aliases (external_id) on the push channel. They cannot be combined with segments or filters in the same message.
// Single user by external user ID
$message->toUser(123);
// Multiple users by external user IDs
$message->toExternalUserIds([1, 2, 3]);Segments are groups of users defined in your OneSignal dashboard based on various criteria.
// Target a custom segment
$message->toSegment('Premium Users');
// Target multiple segments
$message->toSegments(['Premium Users', 'Active Users']);
// Built-in segments
$message->toSubscribedSegment(); // All subscribed users
$message->toActiveSegment(); // Active users
$message->toInactiveSegment(); // Inactive users
$message->toEngagedSegment(); // Engaged usersTags are key-value pairs you set on user devices to create custom targeting rules.
// Target by tag
$message->toTag('user_type', 'premium');
$message->toTag('subscription_level', 'gold', '=');$message = (new PushMessage())
->withTitle('New Message')
->withBody('You have a new message')
->addData('message_id', 456)
->addData('conversation_id', 789);$message = (new PushMessage())
->withTitle('Check this out!')
->withBody('New image available')
->withImage('https://example.com/image.jpg')
->addButton('view', 'View Details', 'https://example.com/details')
->addButton('dismiss', 'Dismiss');The third parameter in addButton() is optional and specifies the URL to open when the button is clicked.
$message = (new PushMessage())
->withTitle('Title')
->withBody('Body')
->setTTL(3600)
->withIntelligentDeliveryDelayed()
->withName('campaign-2024-01');Listen to notification lifecycle events:
use Lepresk\LaravelOnesignal\Events\NotificationSending;
use Lepresk\LaravelOnesignal\Events\NotificationSent;
use Lepresk\LaravelOnesignal\Events\NotificationFailed;
// In your EventServiceProvider
protected $listen = [
NotificationSending::class => [
// Handle before sending
],
NotificationSent::class => [
// Handle after successful send
],
NotificationFailed::class => [
// Handle when send fails
],
];Example listener implementation:
<?php
namespace App\Listeners;
use Lepresk\LaravelOnesignal\Events\NotificationSent;
use Illuminate\Support\Facades\Log;
class LogNotificationSent
{
public function handle(NotificationSent $event): void
{
Log::info('OneSignal notification sent', [
'notification_id' => $event->response->getNotificationId(),
'recipients' => $event->response->getRecipients(),
]);
}
}The package provides extensive configuration options in config/onesignal.php:
The package applies default values from the configuration file. These defaults are used only when values are not explicitly set on the message.
return [
'app_id' => env('ONESIGNAL_APP_ID'),
'rest_api_key' => env('ONESIGNAL_REST_API_KEY'),
'user_auth_key' => env('ONESIGNAL_USER_AUTH_KEY', ''),
'android_channel_id' => env('ONESIGNAL_ANDROID_CHANNEL_ID'),
'defaults' => [
'ttl' => (int) env('ONESIGNAL_DEFAULT_TTL', 604800), // 7 days
'priority' => (int) env('ONESIGNAL_DEFAULT_PRIORITY', 5), // Normal priority
],
'logging' => [
'enabled' => (bool) env('ONESIGNAL_LOGGING_ENABLED', true),
'channel' => env('ONESIGNAL_LOG_CHANNEL'),
'level' => env('ONESIGNAL_LOG_LEVEL', 'info'),
],
'throw_exceptions' => (bool) env('ONESIGNAL_THROW_EXCEPTIONS', true),
'http' => [
'timeout' => (int) env('ONESIGNAL_HTTP_TIMEOUT', 30),
'retry' => [
'times' => (int) env('ONESIGNAL_RETRY_TIMES', 3),
'sleep' => (int) env('ONESIGNAL_RETRY_SLEEP', 1000),
],
],
];Requests time out after http.timeout seconds. Failed requests are retried only when OneSignal did not process them (HTTP 423, 425, 429, 502, 503), so a notification is never sent twice.
Logs never include message contents or recipient identifiers: only the audience size, segment names, notification ID and recipient count.
Run the test suite:
composer testRun tests with coverage:
composer test-coverageFormat code with Laravel Pint:
composer formatRun static analysis with PHPStan:
composer analyse- Laravel 11 is no longer supported.
- External user IDs are sent as
include_aliases.external_id(strings) withtarget_channel: push, replacing OneSignal's deprecatedinclude_external_user_ids. UpdateNotificationSendinglisteners that read the payload. - Combining
toUser()/toExternalUserIds()with segments or tags now throwsInvalidMessageException.
| Deprecated | Replacement | Removal |
|---|---|---|
PushMessage::withHightPriority() |
PushMessage::withHighPriority() |
3.0 |
Deprecated methods trigger an E_USER_DEPRECATED notice, which Laravel writes to the log channel set by LOG_DEPRECATIONS_CHANNEL.
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
If you discover any security-related issues, please email lepresk@gmail.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.