Now we have the basic understanding of webhook as in my Webhook: Part I and we also creating our own first Webhook Provider as in Webhook: Part II.
Creating Webhook Consumer Application
First, make sure to create database for the application, I named it as webhook_client
.
Then create the project, install the package and setup queue database:
laravel new webhook-client --git --jet --stack=livewire
composer require spatie/laravel-webhook-client
php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="webhook-client-config"
php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="webhook-client-migrations"
php artisan queue:table
php artisan migrate
Update the .env
so that we are using database queue.
QUEUE_CONNECTION=database
The Webhook Endpoint
The Laravel Webhook Client give you an easy way to setup the route, you simply add the following in your routes/web.php
:
Route::webhooks('webhook/handler');
And don't forget to disable the Verify CSRF Token as previous section.
Handling the Payload
Let's inspect what the Spatie Laravel Webhook Client provide in the configuration.
<?php
return [
'configs' => [
[
'name' => 'default',
'signing_secret' => env('WEBHOOK_CLIENT_SECRET'),
'signature_header_name' => 'Signature',
'signature_validator' => \Spatie\WebhookClient\SignatureValidator\DefaultSignatureValidator::class,
'webhook_profile' => \Spatie\WebhookClient\WebhookProfile\ProcessEverythingWebhookProfile::class,
'webhook_response' => \Spatie\WebhookClient\WebhookResponse\DefaultRespondsTo::class,
'webhook_model' => \Spatie\WebhookClient\Models\WebhookCall::class,
'store_headers' => [],
'process_webhook_job' => '',
],
],
];
Above are the default config and by default, the webhook handler will require the WEBHOOK_CLIENT_SECRET
which will be use for signing the incoming payload.
You can have your own secret key, my favourite always generate it randomly - which achievable via tinker:
php artisan tinker
Psy Shell v0.11.7 (PHP 8.1.3 — cli) by Justin Hileman
>>> str()->random(32)
=> "8pZAOAyXfYKd3aAqdxYHsJf4oSTWafaG"
Copy the generate key and save it .env
file:
WEBHOOK_CLIENT_SECRET=8pZAOAyXfYKd3aAqdxYHsJf4oSTWafaG
Then we need a Queue Job class for handling incoming payload:
php artisan make:job WebhookHandler
Open up the app/Jobs/WebhookHandler.php
and update it's extend class as following:
<?php
namespace App\Jobs;
class WebhookHandler extends \Spatie\WebhookClient\Jobs\ProcessWebhookJob
{
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// do your things here with $this->webhookCall
logger()->info($this->webhookCall->payload);
}
}
And update the config/webhook-client.php
:
'process_webhook_job' => \App\Jobs\WebhookHandler::class,
Update Webhook Provider
And remember in Webhook Provider, we have the useSecret()
method when sending the payload? Yes, you need this secret key to be share in the Webhook Provider, else you will never get to process the payload if the signature is invalid.
Let's do quick update on Webhook Provider:
On app/Models/User.php
, noted on url()
and useSecret()
using the config()
helper, calling our custom webhook
config.
static::created(function(User $model) {
WebhookCall::create()
->url(config('webhook.user.url'))
->payload($model->toArray())
->throwExceptionOnFailure()
->useSecret(config('webhook.user.secret'))
->dispatch();
});
In the Webhook Provider, add a new configuration file config/webhook.php
:
<?php
return [
'user' => [
'name' => 'Webhook Consumer: User',
'url' => env('WEBHOOK_CONSUMER_URL'),
'secret' => env('WEBHOOK_CONSUMER_SECRET')
],
];
Then in .env
:
WEBHOOK_CONSUMER_URL=http://127.0.0.1:8001/webhook/handler
WEBHOOK_CONSUMER_SECRET=8pZAOAyXfYKd3aAqdxYHsJf4oSTWafaG
Note the Webhook Consumer URL, I just run using php artisan serve
for quick setup and testing.
Testing the Webhook
Now we are ready to test our Webhook Provider & Webhook Consumer.
Let's run the application and queue:
php artisan serve
php artisan queue:work
Run in both Webhook Provider and Consumer.
Then go ahead register new account in http://localhost:8000
.
Now inspect in your Webhook Consumer log file, you should get something like the following:
[2022-07-12 04:07:52] local.INFO: array (
'id' => 2,
'name' => 'Malik Rich',
'email' => 'zomunudut@mailinator.com',
'created_at' => '2022-07-12T04:07:48.000000Z',
'updated_at' => '2022-07-12T04:07:48.000000Z',
'profile_photo_url' => 'https://ui-avatars.com/api/?name=M+R&color=7F9CF5&background=EBF4FF',
)
If you get this right, then you on the right path. If not, you may want to look into the queue & route. Make sure it's properly configured.
Top comments (0)