binary-cats/laravel-twilio-webhooks

在Laravel应用程序中处理Twilio回调/网络钩子

1.2.0 2024-09-23 21:57 UTC

This package is auto-updated.

Last update: 2024-09-23 21:58:26 UTC


README

https://github.com/binary-cats/laravel-twilio-webhooks/actions

Twilio可以使用网络钩子通知您的应用程序各种参与事件。此包可以帮助您处理这些网络钩子。默认情况下,它将验证所有传入请求的Twilio签名。所有有效的呼叫和消息都将记录到数据库中。您可以轻松定义在特定事件触发您的应用程序时应调度的作业或事件。

此包不会处理验证网络钩子请求后应该执行的操作。您仍然需要自己编写任何工作(例如,应该发生什么)的代码。

在使用此包之前,我们强烈建议您阅读Twilio网站上的网络钩子完整文档

此包是基于一个绝对出色的spatie/laravel-stripe-webhooks的改编副本。

安装

您可以通过Composer安装此包

composer require binary-cats/laravel-twilio-webhooks

服务提供程序将自动注册自身。

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

php artisan vendor:publish --provider="BinaryCats\TwilioWebhooks\TwilioWebhooksServiceProvider" --tag="config"

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

<?php

return [

    /*
     * Twilio will sign each webhook using a token: https://twilio.com/user/account.
     */
    'signing_token' => env('TWILIO_WEBHOOK_SECRET'),

    /*
     * You can define the job that should be run when a certain webhook hits your application
     * here. If Twilio event has a dot it will be replaced with an underscore `_`.
     *
     * You can find a list of Twilio webhook types here:
     * https://www.twilio.com/docs/usage/webhooks
     *
     * The package will automatically convert the keys to lowercase
     * Be cognisant of the fact that array keys are **case sensitive** in PHP
     */
    'jobs' => [
        // 'initiated' => \BinaryCats\TwilioWebhooks\Jobs\HandleInitiated::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,

    /*
     * A class processing the job.
     * The class should extend BinaryCats\TwilioWebhooks\ProcessTwilioWebhookJob
     */
    'process_webhook_job' => \BinaryCats\TwilioWebhooks\ProcessTwilioWebhookJob::class,

    /*
     * When disabled, the package will not verify if the signature is valid.
     */
    'verify_signature' => env('TWILIO_SIGNATURE_VERIFY', true),
];

在配置文件的signing_token键中,您应添加一个有效的令牌。您可以在用户设置中找到使用的密钥。

注意。对于每个项目生成新的API/密钥对是一种更好的安全实践,这将保护您的主API密钥/令牌对免受泄露。

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

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

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

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

php artisan migrate

路由

最后,注意路由:无论您向应用程序发送什么回调,都必须配置Twilio网络钩子应该击中的应用程序的URL。在应用程序的路由文件中,您必须将此路由传递给Route::twilioWebhooks()

我喜欢按域名分组功能,所以我建议使用webhooks/twilio.com(尤其是如果您计划有更多的网络钩子),但这取决于您。

# routes\web.php
Route::twilioWebhooks('webhooks/twilio.com');

幕后,这将注册一个到由本包提供的控制器的POST路由。由于Twilio没有获取csrf-token的方法,因此您必须将此路由添加到VerifyCsrfToken中间件的except数组中

protected $except = [
    'webhooks/twilio.com',
];

用法

Twilio将根据参与类型(语音、短信等)发送多种事件类型的网络钩子。

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

除非发生严重错误,否则此包将始终对网络钩子请求响应200。所有具有有效签名的网络钩子请求都将记录在webhook_calls表中。该表有一个payload列,其中保存了传入网络钩子的整个有效负载。

如果签名无效,则请求将不会记录在webhook_calls表中,但将抛出一个BinaryCats\TwilioWebhooks\Exceptions\WebhookFailed异常。如果在网络钩子请求期间发生错误,则抛出的异常将保存在exception列中。在这种情况下,控制器将发送500而不是200

此软件包提供了两种处理webhook请求的方法:您可以选择排队一个作业或监听该软件包将触发的事件。

请确保您配置的密钥为小写,因为软件包将自动确保它们是小写的。

可编程消息(出站)Webhook事件类型

在撰写本文档时,以下事件类型由可编程消息Webhook使用

  • 排队
  • 已取消
  • 已发送
  • 失败
  • 已投递
  • 未投递
  • 已阅读

有关最新信息和更多详细信息,请参阅官方Twilio文档:Twilio可编程消息:状态回调中的出站消息状态

使用作业处理webhook请求

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

<?php

namespace App\Jobs\TwilioWebhooks;

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

class HandleInitiated 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请求的响应时间。这允许您处理更多的Twilio webhook请求并避免超时。

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

// config/twilio-webhooks.php

'jobs' => [
    'initiated' => \App\Jobs\TwilioWebhooks\HandleInitiated::class,
],

使用事件处理webhook请求

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

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

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

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

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

<?php

namespace App\Listeners;

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

class InitiatedCall 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请求的响应时间。这允许您处理更多的Twilio webhook请求并避免超时。

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

高级使用

向Webhook调用添加元数据

您可以通过将URL参数添加到statusCallback URL来使用Twilio webhooks传递额外的元数据。statusCallback URL添加URL参数。这些元数据将在负载(即$this->webhookCall->payload)中可用,允许您传递在处理webhook时可能需要的额外上下文或信息。

要添加元数据,只需将自定义键值对作为URL参数附加到Twilio API请求中的statusCallback URL。例如

https://yourdomain.com/webhooks/twilio.com?order_id=12345&user_id=67890

在此示例中,order_id=12345和user_id=67890是自定义参数,将随webhook负载返回。Twilio将在webhook请求中包含这些参数,允许您在webhook处理逻辑中直接访问此信息。

注意:在构建您的statusCallback URL时,请确保查询参数键已按字母顺序排序。这是必要的,以防止webhook验证失败,因为Request外观的fullUrl()函数(即$request->fullUrl())自动按字母顺序返回查询参数。

重试处理webhook

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

use Spatie\WebhookClient\Models\WebhookCall;
use BinaryCats\TwilioWebhooks\ProcessTwilioWebhookJob;

$webhook = WebhookCall::find($id);

dispatch(new ProcessTwilioWebhookJob($webhook));

执行自定义逻辑

您可以使用自己的工作类来添加一些在队列工作调度之前和/或之后应执行的自定义逻辑。您可以通过在 twilio-webhooks 配置文件中的 process_webhook_job 键中指定自己的工作类来实现。该类应扩展 BinaryCats\TwilioWebhooks\ProcessTwilioWebhookJob

以下是一个示例

use BinaryCats\TwilioWebhooks\ProcessTwilioWebhookJob;

class MyCustomTwilioWebhookJob extends ProcessTwilioWebhookJob
{
    public function handle()
    {
        // do some custom stuff before handling

        parent::handle();

        // do some custom stuff after handling
    }
}

处理多个签名密钥

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

如果您正在使用 Route::twilioWebhooks 宏,可以按如下方式附加 configKey

Route::twilioWebhooks('webhooks/twilio.com/{configKey}');

或者,如果您手动定义路由,可以添加 configKey 如下

Route::post('webhooks/twilio.com/{configKey}', 'BinaryCats\TwilioWebhooks\TwilioWebhooksController');

如果存在此路由参数,验证中间件将使用不同的配置键来查找密钥,通过将给定的参数值附加到默认配置键。例如,如果 Twilio 向 webhooks/twilio.com/my-named-secret 发送,则添加一个名为 signing_token_my-named-secret 的新配置。

示例配置可能如下所示

// token for when Twilio posts to webhooks/twilio.com/account
'signing_token_account' => 'whsec_abc',
// secret for when Twilio posts to webhooks/twilio.com/my-alternative-token
'signing_token_my-alternative-secret' => 'whsec_123',

关于 Twilio

Twilio 通过个性化的交互和受信任的全全球通信连接您与客户。

变更日志

请参阅 CHANGELOG 了解最近更改的更多信息。

测试

composer test

贡献

请参阅 CONTRIBUTING 了解详细信息。

安全

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

Postcardware

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

鸣谢

Spatie 致以崇高的敬意,他们的工作是一个巨大的灵感来源。

支持我们

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

许可

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