hotmeteor / receiver
Laravel的即插即用webhook处理库
Requires
- php: ^8.2
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- nunomaduro/collision: ^7.0|^8.0
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0|^11.0
- stripe/stripe-php: ^13.0
Suggests
- stripe/stripe-php: Required to use the Stripe provider
README
Receiver
Receiver是一个为Laravel提供的即插即用webhook处理库。
Webhooks是任何API生命周期中的强大部分。《Receiver》旨在使在Laravel应用程序中处理传入的webhooks变得一致且简单。
默认情况下,Receiver内置了对以下内容的支持
当然,Receiver可以使用自定义提供者接收来自任何来源的webhooks。
目录
安装
需求
- PHP ^8.1
- Laravel 9+
composer require hotmeteor/receiver
可选
Stripe支持需要stripe/stripe-php
接收Webhooks
基础知识
Webhooks需要一个暴露的端点来POST到。Receiver旨在使这成为一个一次性的设置,支持任何传入的webhooks。
- 为预期的webhooks创建一个控制器和路由。
- 接收webhook并按需处理它
<?php namespace App\Http\Controllers\Webhooks; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class WebhooksController extends Controller { public function store(Request $request) { return Receiver::driver('slack') ->receive($request) ->ok(); } }
所使用的方法很简单
- 定义应该处理webhook的
driver
- 接收用于处理的请求
receive
- 向发送方响应一个
200
ok
响应
接收来自多个应用程序的数据
也许你的webhooks来自多个服务 -- 使用路由中的驱动变量从一个控制器处理它们所有。
<?php namespace App\Http\Controllers\Webhooks; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class WebhooksController extends Controller { public function store(Request $request, string $driver) { return Receiver::driver($driver) ->receive($request) ->ok(); } }
提供的ReceivesWebhooks
特质将为你处理这些。
<?php namespace App\Http\Controllers\Webhooks; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Receiver\ReceivesWebhooks; class WebhooksController extends Controller { use ReceivesWebhooks; }
注意:你仍然需要创建到这个操作的路线。 示例
Route::post('/hooks/{driver}', [\App\Http\Controllers\Webhooks\WebhooksController::class, 'store']) ->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class);
高级使用
回退
Receiver允许你安全地处理你未处理的事件的webhooks。在ok
之前添加一个fallback
方法 -- 它接受一个回调,该回调接收webhook对象。
<?php namespace App\Http\Controllers\Webhooks; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Receiver\Providers\Webhook; class WebhooksController extends Controller { public function store(Request $request, string $driver) { return Receiver::driver($driver) ->receive($request) ->fallback(function(Webhook $webhook) { // Do whatever you like here... }) ->ok(); } }
处理Webhooks
基础知识
现在webhooks已被接收,需要处理。Receiver将在App\Http\Handlers\[Driver]
命名空间中寻找为每个事件类型指定的Handler
类。Receiver 不 提供这些处理器 -- 你需要根据需要提供。如果Receiver找不到匹配的处理器,它将简单地忽略该事件并响应200状态码。
例如,Stripe webhook处理器对于传入的customer.created
事件将是App\Http\Handlers\Stripe\CustomerCreated
。
每个处理器都使用event
(webhook事件的名称)和data
属性构建。
每个处理器还必须使用Dispatchable
特质。
<?php namespace App\Http\Handlers\Stripe; use Illuminate\Foundation\Bus\Dispatchable; class CustomerCreated { use Dispatchable; public function __construct(public string $event, public array $data) { } public function handle() { // Your code here } }
队列处理器
当然,由于你的应用程序可能正在接收大量的webhooks,所以将处理器排队可能是一个更好的做法。这样,你的应用程序可以高效地响应接收webhook的服务,并且请求在处理事件时不会被阻塞。
Receiver尝试为每个处理的事件执行dispatch
,所以排队处理器只是像设置任何Laravel队列作业一样设置它们。
<?php namespace App\Http\Handlers\Stripe; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class CustomerCreated implements ShouldQueue { use Dispatchable; use InteractsWithQueue; use Queueable; use SerializesModels; public function __construct(public string $event, public array $data) { } public function handle() { // Your code here } }
扩展Receiver
如前所述,接收器可以处理来自任何来源的webhooks。尽管该软件包中包含了一些提供者,但接收器可以轻松扩展以与其他应用程序协同工作。
添加自定义提供者
添加新提供者的最简单方法是使用包含的Artisan命令
php artisan receiver:make <name>
此命令将根据您定义的名称生成一个新提供者。此类将在App\Http\Receivers
命名空间中创建。
如果您的提供者需要能够验证webhook签名,请将--verified
标志添加到命令中
php artisan receiver:make <name> --verified
一旦您创建了新的提供者,您可以在您的AppServiceProvider
中简单地扩展接收器,以便接收器可以使用它
<?php namespace App\Providers; use App\Http\Receivers\MailchimpProvider; use App\Http\Receivers\MailgunProvider; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { $receiver = app('receiver'); $receiver->extend('mailchimp', function ($app) { return new MailchimpProvider( config('services.mailchimp.webhook_secret') ); }); $receiver->extend('mailgun', function ($app) { return new MailgunProvider( config('services.mailgun.webhook_secret') ); }); } }
定义属性
接收器需要两块信息来接收和处理webhook事件
- 事件
name
- 事件的
data
由于这些信息可能位于webhook的不同属性或头中,因此接收器使您能够在提供者中轻松定义它们。
<?php namespace Receiver\Providers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class CustomProvider extends AbstractProvider { /** * @param Request $request * @return string */ public function getEvent(Request $request): string { return $request->input('event.name'); } /** * @param Request $request * @return array */ public function getData(Request $request): array { return $request->all(); } }
使用getEvent()
方法返回webhook事件的名称,即customer.created
。
使用getData()
方法返回可以在您的处理器内部使用的数据负载。默认情况下,这设置为$request->all()
。
保护webhooks
许多webhooks都有在接收时验证其真实性的方式,最常见的是通过签名或基本认证。无论策略如何,接收器都允许您根据需要编写自定义验证代码。只需在您的提供者中实现verify
方法并返回true或false即可。
返回false
将导致返回401响应给webhook发送者。
<?php namespace Receiver\Providers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class CustomProvider extends AbstractProvider { public function verify(Request $request): bool { // return result of verification } }
握手
某些webhooks希望在首次设置时执行“握手”以检查您的端点是否存在,并返回有效的响应。为此,在您的提供者中实现handshake
方法
<?php namespace Receiver\Providers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class CustomProvider extends AbstractProvider { public function handshake(Request $request): array { // return result of handshake } }
与verify
方法不同,handshake
期望返回一个数组,因为很多时候webhook发送者期望一个特定的“挑战”响应。握手方法的返回值将发送回webhook发送者。
分享您的接收器!
您是否创建了一个自定义接收器? 在我们的 接收器讨论主题 中与社区分享!
致谢
由contributors-img制作。
许可
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。