Skip to content

Commit

Permalink
Merge pull request #212 from laravel-notification-channels/events
Browse files Browse the repository at this point in the history
Dispatch additional events
  • Loading branch information
dwightwatson authored Nov 13, 2024
2 parents 622b292 + f1738a5 commit 2685d4f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 22 deletions.
43 changes: 24 additions & 19 deletions src/FcmChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Notifications\Events\NotificationFailed;
use Illuminate\Notifications\Events\NotificationSending;
use Illuminate\Notifications\Events\NotificationSent;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -35,37 +37,40 @@ public function send(mixed $notifiable, Notification $notification): ?Collection
{
$tokens = Arr::wrap($notifiable->routeNotificationFor('fcm', $notification));

if (empty($tokens)) {
return null;
}

$fcmMessage = $notification->toFcm($notifiable);

return Collection::make($tokens)
->chunk(self::TOKENS_PER_REQUEST)
->map(fn ($tokens) => ($fcmMessage->client ?? $this->client)->sendMulticast($fcmMessage, $tokens->all()))
->map(fn (MulticastSendReport $report) => $this->checkReportForFailures($notifiable, $notification, $report));
->map(fn ($tokens) => $this->sendNotifications($notifiable, $notification, $tokens))
->map(fn (MulticastSendReport $report) => $this->dispatchEvents($notifiable, $notification, $report));
}

/**
* Handle the report for the notification and dispatch any failed notifications.
* Send the notification with the provided tokens.
*/
protected function checkReportForFailures(mixed $notifiable, Notification $notification, MulticastSendReport $report): MulticastSendReport
protected function sendNotifications(mixed $notifiable, Notification $notification, Collection $tokens): MulticastSendReport
{
Collection::make($report->getItems())
->filter(fn (SendReport $report) => $report->isFailure())
->each(fn (SendReport $report) => $this->dispatchFailedNotification($notifiable, $notification, $report));
$fcmMessage = $notification->toFcm($notifiable);

return $report;
$this->events->dispatch(
new NotificationSending($notifiable, $notification, self::class)
);

return ($fcmMessage->client ?? $this->client)->sendMulticast($fcmMessage, $tokens->all());
}

/**
* Dispatch failed event.
* Handle the report for the notification and dispatch any failed notifications.
*/
protected function dispatchFailedNotification(mixed $notifiable, Notification $notification, SendReport $report): void
protected function dispatchEvents(mixed $notifiable, Notification $notification, MulticastSendReport $report): MulticastSendReport
{
$this->events->dispatch(new NotificationFailed($notifiable, $notification, self::class, [
'report' => $report,
]));
Collection::make($report->getItems())
->each(function (SendReport $report) use ($notifiable, $notification) {
$event = $report->isSuccess()
? new NotificationSent($notifiable, $notification, self::class, compact('report'))
: new NotificationFailed($notifiable, $notification, self::class, compact('report'));

$this->events->dispatch($event);
});

return $report;
}
}
30 changes: 27 additions & 3 deletions tests/FcmChannelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

use Exception;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Notifications\Events\NotificationFailed;
use Illuminate\Notifications\Events\NotificationSending;
use Illuminate\Notifications\Events\NotificationSent;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -36,7 +39,14 @@ public function test_it_can_be_instantiated()
public function test_it_can_send_notifications()
{
$events = Mockery::mock(Dispatcher::class);
$events->shouldNotReceive('dispatch');
$events->shouldReceive('dispatch')
->once()
->with(Mockery::type(NotificationSending::class));
$events->shouldReceive('dispatch')
->once()
->with(Mockery::type(NotificationSent::class));
$events->shouldNotReceive('dispatch')
->with(Mockery::type(NotificationFailed::class));

$firebase = Mockery::mock(Messaging::class);
$firebase->shouldReceive('sendMulticast')
Expand All @@ -56,7 +66,14 @@ public function test_it_can_send_notifications()
public function test_it_can_send_notifications_with_custom_client()
{
$events = Mockery::mock(Dispatcher::class);
$events->shouldNotReceive('dispatch');
$events->shouldReceive('dispatch')
->once()
->with(Mockery::type(NotificationSending::class));
$events->shouldReceive('dispatch')
->once()
->with(Mockery::type(NotificationSent::class));
$events->shouldNotReceive('dispatch')
->with(Mockery::type(NotificationFailed::class));

$firebase = Mockery::mock(Messaging::class);
$events->shouldNotReceive('sendMulticast');
Expand All @@ -78,7 +95,14 @@ public function test_it_can_send_notifications_with_custom_client()
public function test_it_can_dispatch_events()
{
$events = Mockery::mock(Dispatcher::class);
$events->shouldReceive('dispatch')->once();
$events->shouldReceive('dispatch')
->once()
->with(Mockery::type(NotificationSending::class));
$events->shouldNotReceive('dispatch')
->with(Mockery::type(NotificationSent::class));
$events->shouldReceive('dispatch')
->once()
->with(Mockery::type(NotificationFailed::class));

$firebase = Mockery::mock(Messaging::class);
$firebase->shouldReceive('sendMulticast')
Expand Down

0 comments on commit 2685d4f

Please sign in to comment.