agyson / laravel-webhook-server

在 Laravel 应用中发送 webhooks

1.9.1 2020-04-05 18:02 UTC

This package is auto-updated.

Last update: 2024-09-07 11:10:05 UTC


README

Latest Version on Packagist GitHub Workflow Status Quality Score StyleCI Total Downloads

Webhook 是一种应用向另一应用提供特定事件信息的方式。这两个应用通过简单的 HTTP 请求进行通信。

此包允许您轻松地在 Laravel 应用中配置和发送 webhooks。它支持 签名调用重试调用和回退策略

如果您需要接收和处理 webhooks,请查看我们的 laravel-webhook-client 包。

支持我们

通过观看我们的高级视频课程学习如何创建这样的包

Laravel Package training

我们投入了大量资源来创建 一流的开放源代码包。您可以通过 购买我们的付费产品之一 来支持我们。

我们非常感谢您从您的家乡给我们寄来明信片,说明您正在使用我们的哪个包。您可以在 我们的联系页面 上找到我们的地址。我们将发布所有收到的明信片在我们的 虚拟明信片墙 上。

安装

您可以通过 composer 安装此包

composer require spatie/laravel-webhook-server

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

php artisan vendor:publish --provider="Spatie\WebhookServer\WebhookServerServiceProvider"

这是将在 config/webhook-server.php 中发布的文件的 内容

return [

    /*
     *  The default queue that should be used to send webhook requests.
     */
    'queue' => 'default',

    /*
     * The default http verb to use.
     */
    'http_verb' => 'post',

    /*
     * This class is responsible for calculating the signature that will be added to
     * the headers of the webhook request. A webhook client can use the signature
     * to verify the request hasn't been tampered with.
     */
    'signer' => \Spatie\WebhookServer\Signer\DefaultSigner::class,

    /*
     * This is the name of the header where the signature will be added.
     */
    'signature_header_name' => 'Signature',

    /*
     * These are the headers that will be added to all webhook requests.
     */
    'headers' => [],

    /*
     * If a call to a webhook takes longer that this amount of seconds
     * the attempt will be considered failed.
     */
    'timeout_in_seconds' => 3,

    /*
     * The amount of times the webhook should be called before we give up.
     */
    'tries' => 3,

    /*
     * This class determines how many seconds there should be between attempts.
     */
    'backoff_strategy' => \Spatie\WebhookServer\BackoffStrategy\ExponentialBackoffStrategy::class,

    /*
     * By default we will verify that the ssl certificate of the destination
     * of the webhook is valid.
     */
    'verify_ssl' => true,
];

默认情况下,该包使用队列来重试失败的 webhook 请求。请确保在非本地环境中设置一个真实的队列而不是 sync

使用

这是调用 webhook 的最简单方法

WebhookCall::create()
   ->url('https://other-app.com/webhooks')
   ->payload(['key' => 'value'])
   ->useSecret('sign-using-this-secret')
   ->dispatch();

这将向 https://other-app.com/webhooks 发送 POST 请求。请求体将是传递给 payload 的数组的 JSON 编码版本。请求将包含一个名为 Signature 的标题,其中包含接收应用可以使用 以验证 消息负载未被篡改的签名。

如果接收应用没有以 2 开头的响应代码响应,则包将在 10 秒后重试调用 webhook。如果第二次尝试失败,则包将在 100 秒后尝试调用 webhook 一次。如果这次尝试也失败,则将引发 FinalWebhookCallFailedEvent 事件。

同步发送 webhook

如果您希望立即(同步)调用 webhook,则可以使用 dispatchNow 方法。当使用此方法时,webhook 不会入队,将立即运行。这可以在发送 webhook 是更大作业的一部分且已入队的情况下很有用。

WebhookCall::create()
   ...
   ->dispatchNow();

请求签名的工作方式

在设置时,在您的应用和希望接收 webhooks 的应用之间生成、存储和共享一个密钥是很常见的。生成密钥可以使用 Illuminate\Support\Str::random() 完成,但这完全取决于您。该包将使用密钥来签名 webhook 调用。

默认情况下,该包将添加一个名为 Signature 的头,其中包含接收应用程序可以用来验证有效载荷未被篡改的签名。这是计算该签名的方式

// payload is the array passed to the `payload` method of the webhook
// secret is the string given to the `signUsingSecret` method on the webhook.

$payloadJson = json_encode($payload); 

$signature = hash_hmac('sha256', $payloadJson, $secret);

跳过签名请求

我们不推荐这样做,但如果您不希望网关请求被签名,请调用 doNotSign 方法。

WebhookCall::create()
   ->doNotSign()
    ...

调用此方法后,将不会设置 Signature 头。

自定义签名请求

如果您想自定义签名过程,可以创建自己的自定义签名者。签名者是指实现 Spatie\WebhookServer\Signer 的任何类。

这个接口看起来是这样的。

namespace Spatie\WebhookServer\Signer;

interface Signer
{
    public function signatureHeaderName(): string;

    public function calculateSignature(array $payload, string $secret): string;
}

创建您的签名者后,您可以在 webhook-server 配置文件的 signer 键中指定它的类名。然后,您的签名者将在所有网关调用中默认使用。

您也可以为特定的网关调用指定签名者

WebhookCall::create()
    ->signUsing(YourCustomSigner::class)
    ...
    ->dispatch();

如果您想自定义头名称,您不需要使用自定义签名者,但可以更改 webhook-server 配置文件中的 signature_header_name 的值。

重试失败的网关

当我们发送网关的应用程序未能发送带有 2xx 状态码的响应时,该包将认为调用失败。如果远程应用程序在3秒内没有响应,调用也将被视为失败。

您可以在 webhook-server 配置文件的 timeout_in_seconds 键中配置默认超时。或者,您可以通过以下方式覆盖特定网关的超时

WebhookCall::create()
    ->timeoutInSeconds(5)
    ...
    ->dispatch();

当网关调用失败时,我们将再次尝试调用两次。您可以在配置文件的 tries 键中设置默认的重试次数。或者,您可以通过以下方式为特定网关指定尝试次数

WebhookCall::create()
    ->maximumTries(5)
    ...
    ->dispatch();

为了避免对远程应用程序进行频繁的打击,我们将尝试之间等待一段时间。默认情况下,我们在第一次和第二次尝试之间等待10秒,在第三次和第四次之间等待100秒,在第四次和第五次之间等待1000秒,依此类推。我们将等待的最长时间是100000秒,大约是27小时。这种行为是在默认的 ExponentialBackoffStrategy 中实现的。

您可以通过创建一个实现 Spatie\WebhookServer\BackoffStrategy\BackoffStrategy 的类来自定义回退策略。这个接口看起来是这样的

namespace Spatie\WebhookServer\BackoffStrategy;

interface BackoffStrategy
{
    public function waitInSecondsAfterAttempt(int $attempt): int;
}

您可以通过在 webhook-server 配置文件的 backoff_strategy 中指定它的完全限定类名来将您自定义的策略设置为默认策略。或者,您可以通过以下方式为特定网关指定策略。

WebhookCall::create()
    ->useBackoffStrategy(YourBackoffStrategy::class)
    ...
    ->dispatch();

在底层,网关调用的重试是通过 延迟调度 实现的。Amazon SQS 只支持较小的最大延迟。如果您使用 Amazon SQS 作为您的队列,请确保不要将包配置为在每次尝试之间有超过15分钟的延迟。

自定义HTTP方法

默认情况下,所有网关都将使用 post 方法。您可以通过在 webhook-server 配置文件的 http_verb 键中指定您想要的HTTP方法来自定义它。

您也可以通过使用 useHttpVerb 方法覆盖默认值。

WebhookCall::create()
    ->useHttpVerb('get')
    ...
    ->dispatch();

添加额外头

您可以通过将它们添加到 webhook-server 配置文件的 headers 键中来使用额外头。如果您想为特定网关添加额外的头,您可以使用 withHeaders 调用。

WebhookCall::create()
    ->withHeaders([
        'Another Header' => 'Value of Another Header'
    ])
    ...
    ->dispatch();

验证接收应用程序的SSL证书

当使用以 https:// 开头的URL时,该包将验证接收方的SSL证书是否有效。如果无效,我们将认为网关调用失败。我们不推荐这样做,但您可以通过将 webhook-server 配置文件中的 verify_ssl 键设置为 false 来关闭此验证。

您还可以使用doNotVerifySsl方法禁用每个webhook调用的验证。

WebhookCall::create()
    ->doNotVerifySsl()
    ...
    ->dispatch();

添加元信息

您可以为webhook添加额外的元信息。这些元信息将不会传输,它们只用于传递给此包触发的事件

这是添加元信息的方法

WebhookCall::create()
    ->meta($arrayWithMetaInformation)
    ...
    ->dispatch();

添加标签

如果您使用Laravel Horizon来处理队列,您会很高兴地知道我们支持标签

要为执行webhook调用的底层工作添加标签,只需在webhook-server配置文件的tags键中指定它们,或使用withTags方法

WebhookCall::create()
    ->withTags($tags)
    ...
    ->dispatch();

异常处理

默认情况下,此包不会记录在发送webhook时抛出的任何异常。

要处理异常,您需要创建监听Spatie\WebhookServer\Events\WebhookCallFailedEvent和/或Spatie\WebhookServer\Events|FinalWebhookCallFailedEvent事件。

事件

此包触发以下事件

  • WebhookCallSucceededEvent:远程应用程序以2xx响应代码响应。
  • WebhookCallFailedEvent:远程应用程序以非2xx响应代码响应,或者根本没有响应
  • FinalWebhookCallFailedEvent:调用webhook的最终尝试失败。

所有这些事件都具有以下属性

  • httpVerb:用于执行请求的动词
  • webhookUrl:请求发送到的URL
  • payload:使用的有效载荷
  • headers:发送的头部。此数组包括签名头
  • meta:通过meta调用传递给webhook的值数组
  • tags:使用的标签数组
  • attempt:尝试次数
  • response:远程应用程序返回的响应。可以是\GuzzleHttp\Psr7\Response的实例或null
  • uuid:用于识别此调用的唯一字符串。此uuid将是webhook调用所有尝试的相同。

测试

composer test

更新日志

有关最近更改的更多信息,请参阅更新日志

贡献

有关详细信息,请参阅贡献

安全性

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

明信片软件

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

我们的地址是:Spatie,Kruikstraat 22,2018 安特卫普,比利时。

我们在我们的公司网站上发布所有收到的明信片

致谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件