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

Laravel自定义通知渠道:如何捕获外部API调用响应?

解决Laravel按需通知捕获API响应的问题

针对你遇到的AnonymousNotifiable下notify()无返回值、无法直接获取渠道API响应的问题,这里提供两个直接可行的方案,不需要依赖缓存或事件:

方案一:扩展AnonymousNotifiable类,捕获发送结果

Laravel默认的AnonymousNotifiable的notify()方法是无返回值的,我们可以自定义一个可追踪的版本,让它收集每个渠道的发送结果并返回:

1. 创建自定义可追踪通知类

namespace App\Notifications;

use Illuminate\Notifications\AnonymousNotifiable;
use Illuminate\Notifications\Events\NotificationSent;

class TrackableAnonymousNotifiable extends AnonymousNotifiable
{
    protected $sendResults = [];

    public function notify($notification)
    {
        foreach ($this->routes as $channel => $route) {
            $channelClass = $this->channel($channel);
            $method = 'to' . class_basename($channel);

            if (method_exists($notification, $method)) {
                $message = $notification->{$method}($this);
                // 调用渠道发送方法并捕获返回结果
                $result = $channelClass->send($this, $message);
                $this->sendResults[$channel] = $result;
                
                // 保持原有事件触发逻辑(可选,不影响核心功能)
                event(new NotificationSent($this, $notification, $channel, $result));
            } else {
                $this->sendResults[$channel] = [
                    'status' => 'failed',
                    'reason' => 'Notification class does not support this channel'
                ];
            }
        }

        return $this->sendResults;
    }

    // 可选:提供获取结果的额外方法
    public function getSendResults()
    {
        return $this->sendResults;
    }
}

2. 修改调用逻辑使用自定义类

替换原有的Notification::route()调用,改用我们的自定义类:

$notification = new SendVerificationCode([
    "otp" => $otp,
]);

$trackableNotifiable = new \App\Notifications\TrackableAnonymousNotifiable();
// 直接获取各渠道的发送结果
$sendResults = $trackableNotifiable
    ->route('mail', $emailAddress)
    ->route('mobile_number', $phoneNumber)
    ->notify($notification);

// 示例:处理结果
if ($sendResults['mail']['status'] === 'success') {
    // 邮件发送成功逻辑
} else {
    // 邮件发送失败,返回错误信息给用户
}

if ($sendResults['mobile_number']['code'] === 200) {
    // 短信发送成功逻辑
}

方案二:确保自定义渠道返回API响应

上面的方案能生效的前提是你的自定义渠道send()方法会返回API响应结果。如果之前的渠道方法是无返回值的,需要修改它们:

自定义邮件渠道示例

namespace App\Channels;

use Illuminate\Notifications\Notification;

class MailChannel
{
    public function send($notifiable, Notification $notification)
    {
        $message = $notification->toMail($notifiable);
        
        // 调用外部邮件API并获取响应
        $apiResponse = $this->callExternalMailApi($message);
        
        // 返回API响应结果
        return $apiResponse;
    }

    protected function callExternalMailApi($message)
    {
        // 实际调用逻辑,比如用Guzzle请求API
        $client = new \GuzzleHttp\Client();
        $response = $client->post('https://your-mail-provider/api/send', [
            'json' => [
                'to' => $message->to[0]['address'],
                'content' => $message->content
            ]
        ]);
        
        return json_decode($response->getBody(), true);
    }
}

自定义短信渠道示例

namespace App\Channels;

use Illuminate\Notifications\Notification;

class SmsChannel
{
    public function send($notifiable, Notification $notification)
    {
        $message = $notification->toSms($notifiable);
        
        // 调用外部短信API并获取响应
        $apiResponse = $this->callExternalSmsApi($message);
        
        // 返回API响应结果
        return $apiResponse;
    }

    protected function callExternalSmsApi($message)
    {
        $client = new \GuzzleHttp\Client();
        $response = $client->post('https://your-sms-provider/api/send', [
            'form_params' => [
                'phone' => $notifiable->routeNotificationFor('mobile_number'),
                'text' => $message->content
            ]
        ]);
        
        return json_decode($response->getBody(), true);
    }
}

关键说明

  • 方案一的核心是绕过默认的Notification::route(),用自定义类实现有返回值的通知发送逻辑,完全适配OTP场景下即时获取发送状态的需求。
  • 两个方案配合使用,既能捕获每个渠道的API响应,又不需要依赖缓存、会话或事件监听,属于原生逻辑的扩展,没有临时方案的弊端。

内容的提问来源于stack exchange,提问作者UnderIdentityCrisis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:55:55