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

Laravel中使用Mail发送邮件后,如何获取用户回复并处理?

处理Laravel邮件回复的方案(基于Mailgun Webhooks)

1. 配置Mailgun入站路由

在Mailgun后台的「Routes」页面创建一条入站路由:

  • 匹配条件:设置为匹配你用于接收回复的域名地址,比如 match_recipient("reply-*@yourdomain.com")
  • 动作:选择「Forward to URL」,填入Laravel应用的Webhook端点(比如 https://your-app.com/api/mailgun/replies)
  • 开启「Enable Route」开关

2. 配置Laravel的Webhook端点

2.1 添加路由

在 routes/api.php 中添加POST路由,并排除CSRF验证:

use App\Http\Controllers\MailgunWebhookController;

Route::post('/mailgun/replies', [MailgunWebhookController::class, 'handleReply']);

修改 app/Http/Middleware/VerifyCsrfToken.php,将Webhook地址加入例外列表:

protected $except = [
    '/api/mailgun/replies',
];

2.2 创建Webhook控制器

生成控制器并处理Mailgun的请求数据:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class MailgunWebhookController extends Controller
{
    public function handleReply(Request $request)
    {
        // 验证Mailgun请求合法性,防止伪造请求
        $this->validateMailgunSignature($request);

        // 解析核心数据
        $senderEmail = $request->input('sender');
        $recipient = $request->input('recipient'); // 格式:reply-{post_id}@yourdomain.com
        $replyContent = $request->input('stripped-text') ?? $request->input('body-plain');
        $subject = $request->input('subject');

        // 从收件人地址提取post_id
        preg_match('/reply-(\d+)@yourdomain.com/', $recipient, $matches);
        if (empty($matches[1])) {
            Log::error('无法解析回复邮件关联的post_id', ['recipient' => $recipient]);
            return response('Invalid recipient', 400);
        }
        $postId = $matches[1];

        // 执行业务逻辑:保存回复到数据库、触发通知等
        DB::table('post_replies')->insert([
            'post_id' => $postId,
            'sender_email' => $senderEmail,
            'content' => $replyContent,
            'subject' => $subject,
            'created_at' => now(),
        ]);

        // 返回200状态码,告知Mailgun请求已处理完成
        return response('OK', 200);
    }

    /**
     * 验证Mailgun请求签名
     */
    private function validateMailgunSignature(Request $request)
    {
        $timestamp = $request->header('X-Mailgun-Timestamp');
        $token = $request->header('X-Mailgun-Token');
        $signature = $request->header('X-Mailgun-Signature');

        $validSignature = hash_hmac('sha256', $timestamp . $token, config('services.mailgun.secret'));

        if ($validSignature !== $signature) {
            abort(403, 'Invalid Mailgun signature');
        }
    }
}

3. 修改邮件发送逻辑,带上唯一标识

更新你的邮件类 EmailAboutNewPost,设置包含post_id的专用回复地址:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use App\Models\Post;

class EmailAboutNewPost extends Mailable
{
    use Queueable, SerializesModels;

    public $post;

    public function __construct(Post $post)
    {
        $this->post = $post;
    }

    public function build()
    {
        // 生成带post_id的回复地址
        $replyToAddress = "reply-{$this->post->id}@yourdomain.com";

        return $this->view('emails.new-post')
                    ->replyTo($replyToAddress)
                    ->subject("新帖子通知:{$this->post->title}");
    }
}

注意事项

  • 确保你的域名已在Mailgun完成DNS配置,支持入站邮件接收
  • 测试阶段可使用ngrok暴露本地端口,配合Mailgun的「Test Route」功能调试
  • 处理回复内容时,建议过滤恶意代码,避免XSS或注入风险
  • 关键步骤添加日志记录,方便后续排查问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:18:33