Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Github Webhooks Laravel Package

spatie/laravel-github-webhooks

Handle GitHub webhooks in Laravel with signature verification, automatic logging to the database, and easy job/event dispatching per webhook type. Configure handlers, queue processing, and access the webhook payload via a stored call model.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-github-webhooks
    php artisan vendor:publish --provider="Spatie\GitHubWebhooks\GitHubWebhooksServiceProvider"
    

    Publish the config and migration files.

  2. Configure GitHub Webhook:

    • Add your webhook URL in GitHub repo settings (Settings > Webhooks > Add webhook).
    • Use the route provided by the package (e.g., POST /github-webhook).
  3. First Use Case:

    • Define a job to handle a specific GitHub event (e.g., push, issues).
    • Example:
      php artisan make:job HandlePushWebhookJob
      
    • Register the job in config/github-webhooks.php under webhook_events.
  4. Test Locally:

    • Use GitHub’s webhook testing tool or tools like ngrok to simulate webhooks.
    • Verify logs in spatie_github_webhook_calls table.

Implementation Patterns

Core Workflow

  1. Event Handling:

    • Map GitHub events to Laravel jobs in config/github-webhooks.php:
      'webhook_events' => [
          'push' => \App\Jobs\GitHubWebhooks\HandlePushWebhookJob::class,
          'issues' => \App\Jobs\GitHubWebhooks\HandleIssueOpenedWebhookJob::class,
      ],
      
    • Use GitHubWebhookCall model to access payload and metadata.
  2. Job Structure:

    • Inject GitHubWebhookCall into jobs to access:
      public function handle(GitHubWebhookCall $call) {
          $payload = $call->payload; // Decoded JSON payload
          $event = $call->event;     // Event name (e.g., 'push')
      }
      
    • Dispatch jobs in HandleWebhook middleware (auto-applied to /github-webhook).
  3. Queue Integration:

    • Queue jobs for async processing (default in the example).
    • Configure queue connection in config/queue.php.
  4. Payload Validation:

    • Use Spatie\GitHubWebhooks\Webhook to validate payloads:
      use Spatie\GitHubWebhooks\Webhook;
      
      $webhook = new Webhook($payload, $signature, $secret);
      if ($webhook->isValid()) {
          // Process
      }
      
  5. Logging:

    • All valid calls are logged to spatie_github_webhook_calls.
    • Customize logging in config/github-webhooks.php:
      'log_webhook_calls' => true,
      'log_webhook_call_model' => \App\Models\CustomWebhookLog::class,
      

Advanced Patterns

  1. Dynamic Event Handling:

    • Use middleware to filter events dynamically:
      public function handle($request, Closure $next) {
          if ($request->input('event') === 'custom_event') {
              return $next($request);
          }
          return response('Unauthorized', 403);
      }
      
  2. Webhook Secrets:

    • Store secrets in .env:
      GITHUB_WEBHOOK_SECRET=your_secret_here
      
    • Rotate secrets by updating GitHub’s webhook config and Laravel’s .env.
  3. Testing:

    • Use Spatie\GitHubWebhooks\Testing\WebhookTestCase:
      use Spatie\GitHubWebhooks\Testing\WebhookTestCase;
      
      class PushWebhookTest extends WebhookTestCase {
          public function test_push_webhook() {
              $this->assertDispatches(
                  HandlePushWebhookJob::class,
                  'push'
              );
          }
      }
      
  4. Custom Payload Parsing:

    • Extend GitHubWebhookCall or use accessors:
      public function getRepoName(): string {
          return $this->payload['repository']['full_name'];
      }
      
  5. Rate Limiting:

    • Protect /github-webhook with Laravel’s throttle middleware:
      Route::middleware(['throttle:100,1'])->post('/github-webhook', ...);
      

Gotchas and Tips

Common Pitfalls

  1. Signature Mismatch:

    • Ensure GITHUB_WEBHOOK_SECRET matches GitHub’s webhook secret.
    • Debug with:
      \Log::debug('Expected signature:', $webhook->expectedSignature());
      \Log::debug('Received signature:', $request->header('X-Hub-Signature-256'));
      
  2. Payload Size:

    • GitHub webhooks may send large payloads (e.g., push with many files).
    • Increase Laravel’s max_input_vars or use input() instead of json() in middleware.
  3. Queue Failures:

    • Failed jobs may retry indefinitely. Use ShouldQueue with backoff:
      public function retryUntil() {
          return now()->addMinutes(5);
      }
      
  4. Event Naming:

    • GitHub’s event names (e.g., pull_request.opened) differ from Laravel’s job keys.
    • Map events explicitly in config/github-webhooks.php:
      'webhook_events' => [
          'pull_request.opened' => HandlePROpenedJob::class,
      ],
      
  5. Testing Locally:

    • Use ngrok to expose localhost to GitHub:
      ngrok http 8000
      
    • Update GitHub’s webhook URL to https://your-ngrok-url.ngrok.io/github-webhook.

Debugging Tips

  1. Log Payloads:

    • Enable debug logging in config/github-webhooks.php:
      'log_webhook_calls' => true,
      'log_level' => 'debug',
      
  2. Validate Payloads Manually:

  3. Check Middleware:

    • Ensure Spatie\GitHubWebhooks\HandleWebhook is registered in app/Http/Kernel.php:
      protected $middleware = [
          // ...
          \Spatie\GitHubWebhooks\HandleWebhook::class,
      ];
      
  4. Database Logs:

    • Query spatie_github_webhook_calls for failed calls:
      SELECT * FROM spatie_github_webhook_calls WHERE failed_at IS NOT NULL;
      

Extension Points

  1. Custom Models:

    • Extend Spatie\GitHubWebhooks\Models\GitHubWebhookCall:
      class CustomWebhookCall extends GitHubWebhookCall {
          public function getAuthorName() {
              return $this->payload['sender']['login'];
          }
      }
      
    • Update config/github-webhooks.php:
      'webhook_call_model' => \App\Models\CustomWebhookCall::class,
      
  2. Custom Verification:

    • Override Spatie\GitHubWebhooks\Webhook for custom signature logic:
      class CustomWebhook extends Webhook {
          public function isValid(): bool {
              // Custom validation
              return true;
          }
      }
      
  3. Webhook Routes:

    • Customize the route in routes/web.php:
      Route::post('/custom-webhook', \Spatie\GitHubWebhooks\WebhookController::class)
           ->middleware(['github.webhook']);
      
  4. Event Filtering:

    • Use middleware to filter events dynamically:
      public function handle($request, Closure $next) {
          if (!in_array($request->input('event'), ['push', 'issues'])) {
              return response('Forbidden', 403);
          }
          return $next($request);
      }
      
  5. Webhook Retries:

    • Implement exponential backoff for failed jobs:
      public function retryUntil() {
          return now()->addSeconds(2 ** $this->attempts());
      }
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport