You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 9中如何检测通知是否发送成功并执行后续操作

Laravel 9 通知发送成功后执行自定义操作实现方案

Laravel 9的通知系统原生提供了发送成功的触发钩子,不需要修改Notifiable trait的原有逻辑,以下两种方案可以实现仅在通知发送成功时执行特定逻辑,按需选择即可。

  • 方案1:全局监听NotificationSent事件(推荐多渠道/全局场景使用)
    Illuminate\Notifications\Events\NotificationSent是系统内置事件,仅在通知通过对应渠道实际投递成功时才会触发,发送过程报错、队列任务失败都不会触发该事件,完全匹配需求。

    1. 先在app/Providers/EventServiceProvider.php的$listen数组中注册事件和对应监听器的映射:
      protected $listen = [
          // 保留文件中原有其他事件映射
          \Illuminate\Notifications\Events\NotificationSent::class => [
              \App\Listeners\HandleNotificationSentSuccess::class,
          ],
      ];
      
    2. 执行Artisan命令自动生成监听器文件:
      php artisan make:listener HandleNotificationSentSuccess --event=NotificationSent
      
    3. 打开生成的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:39:19