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: verify signatures, log valid calls, and dispatch jobs/events per webhook type. Includes a GitHubWebhookCall model to access payloads and queueable handlers for event-driven integrations.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require spatie/laravel-github-webhooks
    php artisan vendor:publish --provider="Spatie\GitHubWebhooks\GitHubWebhooksServiceProvider" --tag="github-webhooks-config"
    php artisan vendor:publish --provider="Spatie\GitHubWebhooks\GitHubWebhooksServiceProvider" --tag="github-webhooks-migrations"
    php artisan migrate
    
  2. Configure GitHub Webhook:

    • Set GITHUB_WEBHOOK_SECRET in .env (found in GitHub repo settings).
    • Add route in routes/api.php:
      Route::githubWebhooks('github-webhook');
      
  3. First Use Case: Create a job for a specific event (e.g., issues.opened) in app/Jobs/GitHubWebhooks/HandleIssueOpenedWebhookJob.php:

    namespace App\Jobs\GitHubWebhooks;
    
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Spatie\GitHubWebhooks\Models\GitHubWebhookCall;
    
    class HandleIssueOpenedWebhookJob implements ShouldQueue
    {
        use InteractsWithQueue, Queueable, SerializesModels;
    
        public function __construct(public GitHubWebhookCall $webhookCall) {}
    
        public function handle()
        {
            $issue = $this->webhookCall->payload('issue');
            // Logic to handle new issue
        }
    }
    
  4. Register Job: Update config/github-webhooks.php:

    'jobs' => [
        'issues.opened' => \App\Jobs\GitHubWebhooks\HandleIssueOpenedWebhookJob::class,
    ],
    

Implementation Patterns

Usage Patterns

  1. Job-Based Handling:

    • Define jobs for specific GitHub events (e.g., pull_request.opened, push).
    • Use * in config to handle all events with a fallback job.
    • Example:
      'jobs' => [
          'push' => \App\Jobs\GitHubWebhooks\HandlePushWebhook::class,
          '*' => \App\Jobs\GitHubWebhooks\HandleAllWebhooks::class,
      ],
      
  2. Event-Based Handling:

    • Listen to github-webhooks::<event> events in EventServiceProvider:
      protected $listen = [
          'github-webhooks::issues.opened' => [
              \App\Listeners\NotifyIssueOpened::class,
          ],
      ];
      
  3. Payload Access:

    • Use GitHubWebhookCall methods to access data:
      $login = $webhookCall->payload('issue.user.login');
      $action = $webhookCall->eventActionName(); // e.g., "issues.opened"
      
  4. Queue Optimization:

    • Always queue jobs to minimize response time:
      class HandleWebhookJob implements ShouldQueue { ... }
      

Workflows

  1. Local Development:

    • Disable signature verification in config/github-webhooks.php:
      'verify_signature' => env('APP_ENV') !== 'local',
      
  2. Testing:

    • Use GitHubWebhookCall factory or seeders to simulate webhooks:
      $webhook = GitHubWebhookCall::factory()->create(['event' => 'issues.opened']);
      
  3. Logging and Debugging:

    • Check github_webhook_calls table for payloads and exceptions.
    • Use Laravel’s logging to track job failures:
      try {
          $this->handle();
      } catch (\Exception $e) {
          \Log::error('Webhook failed', ['error' => $e->getMessage()]);
      }
      

Integration Tips

  1. GitHub Actions:

    • Trigger workflows based on webhook events (e.g., deploy on push to main):
      on:
        repository_dispatch:
          types: [deploy]
      
  2. Third-Party Services:

    • Forward webhook data to external APIs (e.g., Slack, Zapier) via jobs:
      public function handle()
      {
          Http::post('https://api.slack.com/...', ['text' => 'New issue: ' . $this->webhookCall->payload('issue.title')]);
      }
      
  3. Webhook Retries:

    • Use ProcessGitHubWebhookJob to retry failed calls:
      dispatch(new ProcessGitHubWebhookJob(GitHubWebhookCall::find($id)));
      

Gotchas and Tips

Pitfalls

  1. Signature Verification:

    • Issue: Forgetting to set GITHUB_WEBHOOK_SECRET or misconfiguring it in GitHub repo settings.
    • Fix: Double-check the secret in .env and GitHub’s webhook configuration.
    • Debug: Enable APP_DEBUG to see WebhookFailed exceptions.
  2. Route Misconfiguration:

    • Issue: Webhooks fail silently if the route is misconfigured (e.g., wrong URL or HTTP method).
    • Fix: Verify the route in routes/api.php matches GitHub’s webhook URL exactly.
    • Tip: Use Route::get('/health', fn() => 'OK'); to test connectivity.
  3. Payload Parsing:

    • Issue: Nested payload keys may fail if dot notation is incorrect.
    • Fix: Use payload('key.subkey') for nested data.
    • Example:
      $title = $webhookCall->payload('issue.title'); // Correct
      $title = $webhookCall->payload('issue.title'); // Works
      $title = $webhookCall->payload('issue.title'); // Fails if 'title' is missing
      
  4. Queue Timeouts:

    • Issue: Long-running jobs may timeout or delay webhook responses.
    • Fix: Offload heavy tasks to separate queues or processes (e.g., Laravel Horizon).
  5. CSRF Exemptions:

    • Issue: Forgetting to add the webhook route to VerifyCsrfToken::$except if using web.php.
    • Fix: Add the route to the except array in app/Http/Middleware/VerifyCsrfToken.php.

Debugging

  1. Log Webhook Payloads:

    • Add a listener to log all incoming payloads:
      protected $listen = [
          'github-webhooks::*' => [
              \App\Listeners\LogWebhookPayload::class,
          ],
      ];
      
      class LogWebhookPayload
      {
          public function handle(GitHubWebhookCall $webhookCall)
          {
              \Log::info('Webhook received', ['event' => $webhookCall->event, 'payload' => $webhookCall->payload]);
          }
      }
      
  2. Inspect Database:

    • Query the github_webhook_calls table for failed calls:
      SELECT * FROM github_webhook_calls WHERE exception IS NOT NULL;
      
  3. Test Locally:

    • Use tools like ngrok to expose a local endpoint for testing:
      ngrok http 8000
      
    • Configure GitHub webhook to point to https://<ngrok-subdomain>.ngrok.io/github-webhook.

Config Quirks

  1. ProcessEverythingWebhookProfile:

    • Behavior: Processes all webhooks unless overridden by a custom profile.
    • Customization: Extend ProcessEverythingWebhookProfile to filter events:
      class CustomWebhookProfile extends ProcessEverythingWebhookProfile
      {
          public function shouldProcess(GitHubWebhookCall $webhookCall): bool
          {
              return $webhookCall->event === 'issues.opened';
          }
      }
      
      Update config:
      'profile' => \App\Profiles\CustomWebhookProfile::class,
      
  2. Pruning:

    • Behavior: Automatically deletes old webhook calls (configurable via prune_webhook_calls_after_days).
    • Tip: Schedule pruning in app/Console/Kernel.php:
      $schedule->command('model:prune', [
          '--model' => [\Spatie\GitHubWebhooks\Models\GitHubWebhookCall::class],
      ])->daily();
      

Extension Points

  1. Custom Models:
    • Extend GitHubWebhookCall to add fields or logic:
      class CustomGitHubWebhookCall extends GitHubWebhookCall
      {
          public function getIssueUrl(): string
          {
              return 'https://github.com/' . $this->payload('repository.full_name') . '/issues/' . $this->payload('issue.number');
          }
      }
      
      Update config:
      'model' => \App\Models\CustomGitHub
      
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony