How to create a webhook in Laravel

How to create a webhook in Laravel

Certainly! A webhook in Laravel can be used to handle events triggered by an external service. Let’s walk through an example where we set up a webhook to handle events from a service like GitHub.

Step-by-Step Guide to Setting Up a Webhook in Laravel

1. Set Up the Route

First, you’ll need to define a route that GitHub (or any other service) can call when an event occurs. In your routes/web.php file, add the following route:

use App\Http\Controllers\WebhookController;

Route::post('/webhook/github', [WebhookController::class, 'handle']);

2. Create the Webhook Controller

Next, create a controller to handle the incoming webhook requests. You can create a controller using the Artisan command:

php artisan make:controller WebhookController

Then, in app/Http/Controllers/WebhookController.php, add the following code:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class WebhookController extends Controller
{
    public function handle(Request $request)
    {
        // Verify the request signature if needed (for security)
        $this->verifySignature($request);

        // Get the event type from the request header
        $eventType = $request->header('X-GitHub-Event');

        // Handle the event
        switch ($eventType) {
            case 'push':
                $this->handlePushEvent($request);
                break;
            case 'issues':
                $this->handleIssuesEvent($request);
                break;
            // Add more cases for different event types as needed
            default:
                Log::warning('Unhandled event type: ' . $eventType);
                break;
        }

        return response()->json(['message' => 'Event received']);
    }

    protected function handlePushEvent(Request $request)
    {
        $payload = $request->json()->all();
        Log::info('Push event received', ['payload' => $payload]);

        // Process the push event (e.g., update a database, trigger a CI job, etc.)
    }

    protected function handleIssuesEvent(Request $request)
    {
        $payload = $request->json()->all();
        Log::info('Issues event received', ['payload' => $payload]);

        // Process the issues event (e.g., create a new issue in your system)
    }

    protected function verifySignature(Request $request)
    {
        $signature = 'sha1=' . hash_hmac('sha1', $request->getContent(), config('services.github.secret'), false);

        if (!hash_equals($signature, $request->header('X-Hub-Signature'))) {
            abort(403, 'Invalid signature.');
        }
    }
}

3. Verify the Webhook Signature (Optional)

For security reasons, verifying that the request is coming from GitHub and not from some malicious actor is a good idea. GitHub sends a signature with each request that you can use to verify the request’s authenticity. The verifySignature a method in the controller does this.

Make sure you add your GitHub webhook secret to your .env file:

GITHUB_WEBHOOK_SECRET=your_secret_here

And then add it to your config/services.php file:

'github' => [
    'secret' => env('GITHUB_WEBHOOK_SECRET'),
],

4. Configure the Webhook on GitHub

Finally, configure the webhook on GitHub to point to your Laravel application. In your GitHub repository, go to Settings > Webhooks > Add webhook. Enter the payload URL (e.g., https://yourapp.com/webhook/github), choose the content type as application/json, and provide the secret you configured.

Testing the Webhook

You can use tools like ngrok to expose your local development environment to the internet for testing purposes. This way, you can set up your GitHub webhook to point to your local Laravel instance.

Conclusion

Following these steps, you can set up a webhook in Laravel to handle events from external services like GitHub. This example includes handling and logging different events, verifying request signatures for security, and configuring the webhook endpoint. This can be adapted to handle webhooks from other services by adjusting the request-handling logic accordingly.

Author: Danyal
I'm a skilled programmer specializing in Vue.js/Nuxt.js for front-end development and PHP Laravel for back-end solutions. I have a strong focus on API design and development, complemented by experience in web server setup and maintenance. My versatile expertise ensures seamless creation and maintenance of web applications, covering everything from intuitive user interfaces to robust server-side functionality. Passionate about coding and driven by a lifelong learning mindset, I invite you to explore more at danyal.dk.