binary-cats/laravel-mailgun-webhooks

在 Laravel 应用中处理 Mailgun Webhooks

9.3.1 2024-08-03 21:38 UTC

This package is auto-updated.

Last update: 2024-09-03 21:52:08 UTC


README

在 Laravel 应用中处理 Mailgun Webhooks

https://github.com/binary-cats/laravel-mailgun-webhooks/actions https://github.styleci.io/repos/230519748 https://scrutinizer-ci.com/g/binary-cats/laravel-mailgun-webhooks/

Mailgun 可以使用 Webhooks 通知您的应用程序邮件事件。此包可以帮助您处理这些 Webhooks。它默认会验证所有传入请求的 Mailgun 签名。所有有效调用都将记录到数据库中。您可以轻松定义在特定事件击中您的应用程序时应调度的作业或事件。

此包不会处理在验证 Webhook 请求并调用正确的作业或事件之后应该执行的操作。您仍然需要自己编写任何工作(例如,应该发生什么)的代码。

在使用此包之前,我们强烈建议阅读在 Mailgun 上关于 Webhooks 的完整文档

此包是基于极其出色的 spatie/laravel-stripe-webhooks 的改编副本。

升级

如果您是从以前的版本升级,请注意,spatie/laravel-webhook-client 已升级到 ^3.0 - 这将在 Webhooks 表中添加一个额外的字段。有关更多详细信息,请阅读升级说明

安装

您可以通过 composer 安装此包

composer require binary-cats/laravel-mailgun-webhooks

服务提供器将自动注册自己。

您必须使用以下命令发布配置文件

php artisan vendor:publish --provider="BinaryCats\MailgunWebhooks\MailgunWebhooksServiceProvider" --tag="config"

这是将发布到 config/mailgun-webhooks.php 的配置文件内容

return [

    /*
     * Mailgun will sign each webhook using a secret. You can find the used secret at the
     * webhook configuration settings: https://app.mailgun.com/app/account/security/api_keys.
     */
    'signing_secret' => env('MAILGUN_WEBHOOK_SECRET'),

    /*
     * You can define the job that should be run when a certain webhook hits your application
     * here. The key is the name of the Mailgun event type with the `.` replaced by a `_`.
     *
     * You can find a list of Mailgun webhook types here:
     * https://documentation.mailgun.com/en/latest/api-webhooks.html#webhooks.
     * 
     * The package will automatically convert the keys to lowercase, but you should
     * be congnisant of the fact that array keys are case sensitive
     */
    'jobs' => [
        // 'delivered' => \BinaryCats\MailgunWebhooks\Jobs\HandleDelivered::class,
    ],

    /*
     * The classname of the model to be used. The class should equal or extend
     * Spatie\WebhookClient\Models\WebhookCall
     */
    'model' => \Spatie\WebhookClient\Models\WebhookCall::class,

    /*
     * The classname of the model to be used. The class should equal or extend
     * BinaryCats\MailgunWebhooks\ProcessMailgunWebhookJob
     */
    'process_webhook_job' => \BinaryCats\MailgunWebhooks\ProcessMailgunWebhookJob::class,
];

在配置文件的 signing_secret 键中,您应该添加一个有效的 webhook 密钥。您可以在 HTTP webhook 签名密钥 中找到该密钥。

如果您已经安装了 Spatie\WebhookClient,则可以跳过迁移。

接下来,您必须使用以下命令发布迁移

php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="webhook-client-migrations"

迁移发布后,您可以通过运行迁移来创建 webhook_calls

php artisan migrate

路由

最后,注意路由:在 Mailgun 控制台 中,您必须配置 Mailgun Webhooks 应该击中的应用程序的 URL。在应用程序的路由文件中,您必须将该路由传递给 Route::mailgunWebhooks()

我喜欢按域名分组功能,所以我建议使用 webhooks/mailgun(特别是如果您计划有更多 Webhooks),但这取决于您。

# routes\web.php
Route::mailgunWebhooks('webhooks/mailgun');

在幕后,这将在由此包提供的控制器上注册一个 POST 路由。由于 Mailgun 无法获取 csrf-token,您必须将该路由添加到 VerifyCsrfToken 中间件的 except 数组中

protected $except = [
    'webhooks/mailgun',
];

用法

Mailgun 会为几种事件类型发送 Webhooks。您可以在 Mailgun 文档中找到事件类型的完整列表

Mailgun 将签署击中您的应用程序 Webhook URL 的所有请求。此包将自动验证签名是否有效。如果不有效,则请求可能不是由 Mailgun 发送的。

除非发生严重错误,本包将对webhook请求始终响应200。发送200可以防止Mailgun重复发送相同的事件。所有具有有效签名的webhook请求都将记录在webhook_calls表中。该表有一个payload列,其中保存了传入webhook的整个有效负载。

如果签名无效,则请求不会记录在webhook_calls表中,而是抛出BinaryCats\MailgunWebhooks\Exceptions\WebhookFailed异常。如果在webhook请求过程中发生错误,抛出的异常将保存在exception列中。在这种情况下,控制器将发送500而不是200

此包有两种方式使您能够处理webhook请求:您可以选择排队一个作业或监听包将触发的事件。

由于Mailgun沙箱和生产环境事件大小写差异明显,该包将始终将mailgun事件转换为小写 - 因此您配置的密钥也必须是小写的。

该包不处理旧版webhook,因为它们具有不同的架构。 如果这需要,请告诉我。

使用作业处理webhook请求

如果您想在一个特定的事件类型到来时执行某些操作,可以定义一个执行该工作的作业。以下是一个此类作业的示例

<?php

namespace App\Jobs\MailgunWebhooks;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Spatie\WebhookClient\Models\WebhookCall;

class HandleDelivered implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    /** @var \Spatie\WebhookClient\Models\WebhookCall */
    public $webhookCall;

    public function __construct(WebhookCall $webhookCall)
    {
        $this->webhookCall = $webhookCall;
    }

    public function handle()
    {
        // do your work here

        // you can access the payload of the webhook call with `$this->webhookCall->payload`
    }
}

Spatie强烈建议您将此作业排队,因为这将最小化webhook请求的响应时间。这允许您处理更多的Mailgun webhook请求并避免超时。

请记住,mailgun将signatureevent-data都放入响应体中。

创建您的作业后,必须在mailgun-webhooks.php配置文件中的jobs数组中注册它。键应该是mailgun事件类型的名称。值应该是完全限定类名。

// config/mailgun-webhooks.php

'jobs' => [
    'delivered' => \App\Jobs\MailgunWebhooks\HandleDelievered::class,
],

使用事件处理webhook请求

您可以选择监听此包将触发的事件,而不是将作业排队以执行webhook请求到来时的某些操作。每当有效的请求击中您的应用程序时,该包将触发一个mailgun-webhooks::<event-name>事件。

事件的负载将是为传入请求创建的WebhookCall实例。

让我们看看如何监听此类事件。在EventServiceProvider中,您可以注册监听器。

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'mailgun-webhooks::delivered' => [
        App\Listeners\DeliveredSource::class,
    ],
];

以下是一个此类监听器的示例

<?php

namespace App\Listeners;

use Illuminate\Contracts\Queue\ShouldQueue;
use Spatie\WebhookClient\Models\WebhookCall;

class DeliveredSource implements ShouldQueue
{
    public function handle(WebhookCall $webhookCall)
    {
        // do your work here

        // you can access the payload of the webhook call with `$webhookCall->payload`
    }
}

Spatie强烈建议您使事件监听器可排队,因为这将最小化webhook请求的响应时间。这允许您处理更多的Mailgun webhook请求并避免超时。

上述示例只是Laravel中处理事件的一种方式。要了解其他选项,请阅读Laravel处理事件文档

高级使用

重试处理webhook

所有传入的webhook请求都被写入数据库。当处理webhook调用出错时,这非常有价值。您可以在调查并修复失败原因后,轻松重试处理webhook调用,如下所示

use Spatie\WebhookClient\Models\WebhookCall;
use BinaryCats\MailgunWebhooks\ProcessMailgunWebhookJob;

dispatch(new ProcessMailgunWebhookJob(WebhookCall::find($id)));

执行自定义逻辑

您可以使用自己的作业类添加一些应在排队的作业调度之前和/或之后执行的自定义逻辑。您可以通过在mailgun-webhooks配置文件的process_webhook_job键中指定自己的作业类来完成此操作。该类应扩展BinaryCats\MailgunWebhooks\ProcessMailgunWebhookJob

以下是一个示例

use BinaryCats\MailgunWebhooks\ProcessMailgunWebhookJob;

class MyCustomMailgunWebhookJob extends ProcessMailgunWebhookJob
{
    public function handle()
    {
        // do some custom stuff beforehand

        parent::handle();

        // do some custom stuff afterwards
    }
}

处理多个签名密钥

当需要时,可能需要让包处理多个端点和秘密。以下是配置该行为的步骤。

如果您正在使用 Route::mailgunWebhooks 宏,您可以如下添加 configKey

Route::mailgunWebhooks('webhooks/mailgun/{configKey}');

或者,如果您正在手动定义路由,可以像这样添加 configKey

Route::post('webhooks/mailgun/{configKey}', 'BinaryCats\MailgunWebhooks\MailgunWebhooksController');

如果这个路由参数存在,验证中间件将使用不同的配置键来查找秘密,通过将给定的参数值附加到默认配置键。例如,如果Mailgun将邮件发送到 webhooks/mailgun/my-named-secret,您将添加一个名为 signing_secret_my-named-secret 的新配置。

示例配置可能如下所示

// secret for when Mailgun posts to webhooks/mailgun/account
'signing_secret_account' => 'whsec_abc',
// secret for when Mailgun posts to webhooks/mailgun/my-named-secret
'signing_secret_my-named-secret' => 'whsec_123',

关于Mailgun

Mailgun 允许您通过我们的SMTP中继和灵活的HTTP API轻松发送事务性或批量邮件。

变更日志

请参阅 CHANGELOG 了解最近有哪些更改。

测试

composer test

贡献

请参阅 CONTRIBUTING 了解详细信息。

安全性

如果您发现任何与安全相关的问题,请通过电子邮件 cyrill.kalita@gmail.com 联系,而不是使用问题跟踪器。

Postcardware

您可以使用此包,但如果它进入您的生产环境,我们非常感谢您从家乡寄给我们一张明信片,说明您正在使用哪些包。

致谢

Spatie 表示敬意,他们的工作是巨大的灵感来源。

支持我们

Binary Cats 是一家位于美国伊利诺伊州的网页设计公司。

许可

MIT 许可证 (MIT)。请参阅 许可文件 了解更多信息。