Laravel 9中如何检测通知是否发送成功并执行后续操作
Laravel 9 通知发送成功后执行自定义操作实现方案
Laravel 9的通知系统原生提供了发送成功的触发钩子,不需要修改Notifiable trait的原有逻辑,以下两种方案可以实现仅在通知发送成功时执行特定逻辑,按需选择即可。
方案1:全局监听
NotificationSent事件(推荐多渠道/全局场景使用)Illuminate\Notifications\Events\NotificationSent是系统内置事件,仅在通知通过对应渠道实际投递成功时才会触发,发送过程报错、队列任务失败都不会触发该事件,完全匹配需求。- 先在
app/Providers/EventServiceProvider.php的$listen数组中注册事件和对应监听器的映射:protected $listen = [ // 保留文件中原有其他事件映射 \Illuminate\Notifications\Events\NotificationSent::class => [ \App\Listeners\HandleNotificationSentSuccess::class, ], ]; - 执行Artisan命令自动生成监听器文件:
php artisan make:listener HandleNotificationSentSuccess --event=NotificationSent - 打开生成的
app/Listeners/HandleNotificationSentSuccess.php文件,在handle方法中编写需要执行的业务逻辑即可,事件实例中可以拿到所有需要的上下文信息:
如果你使用队列发送通知,该事件会在队列任务执行完成、通知实际投递成功后才触发,不会在任务入队时提前执行,不需要额外加事务判断。public function handle(NotificationSent $event) { // 可直接调用的上下文属性: // $event->notifiable 接收通知的模型实例,比如触发通知的用户模型 // $event->notification 当前发送完成的通知类实例 // $event->channel 当前发送成功的渠道标识,如mail、database、sms、自定义渠道 // $event->response 对应渠道驱动返回的响应结果,比如短信接口返回的发送记录ID、邮件的messageId // 在这里写你的自定义逻辑即可,比如记录发送日志、更新通知状态、触发后续业务流 \Log::info('通知发送成功', [ 'notifiable_type' => get_class($event->notifiable), 'notifiable_id' => $event->notifiable->id, 'notification' => get_class($event->notification), 'channel' => $event->channel ]); }
- 先在
方案2:单通知类内绑定回调(推荐仅单个通知需要触发逻辑的轻量场景)
如果你要执行的逻辑只针对某一个特定通知,不需要全局监听所有通知的发送结果,可以直接在对应通知类中给渠道消息注册发送成功回调,不需要额外创建事件和监听器。
以邮件渠道为例,在通知类的toMail方法中给邮件消息绑定发送后回调即可:public function toMail($notifiable) { return (new \Illuminate\Notifications\Messages\MailMessage) ->subject('订单发货提醒') ->line('您购买的商品已由顺丰速运发出,预计3天内送达') ->action('查看物流', url('/orders/'.$this->order->id)) // 仅当前邮件发送成功后执行以下逻辑 ->send(function ($message, $sentMessage) { // 自定义逻辑:比如标记该用户的发货通知已成功送达 $this->order->update([ 'notify_sent_at' => now(), 'mail_message_id' => $sentMessage->getMessageId() ]); }); }注意该方式仅对当前绑定的渠道生效,如果你的通知同时配置了邮件、短信、站内信多个渠道,需要分别给每个渠道的消息实例注册对应回调,多渠道场景下用方案1的全局事件更易维护。
避坑提醒:不要把自定义逻辑写在通知类的构造函数、
toXxx格式转换方法里,这些方法在通知初始化、待发送阶段就会执行,无论最终发送成功还是失败都会运行,达不到「仅发送成功才执行」的要求。
如果需要同时处理通知发送失败的场景,直接监听内置的NotificationFailed事件即可,逻辑和上述成功事件一致。
内容的提问来源于stack exchange,提问作者archille gael
相关产品推荐
相关产品推荐

