Weave 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 Ohdear Webhooks Laravel Package

ohdearapp/laravel-ohdear-webhooks

Handle Oh Dear webhooks in your Laravel app with automatic signature verification and configurable jobs or events dispatched for each webhook type. Just install, publish the config, set your signing secret, and register the route.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing and wiring the package into the app’s existing webhook surface area:

composer require ohdearapp/laravel-ohdear-webhooks
php artisan vendor:publish --provider="OhDear\LaravelWebhooks\OhDearWebhooksServiceProvider" --tag="config"

Then:

  1. Set OH_DEAR_SIGNING_SECRET in .env using the secret from the Oh Dear team notification settings.
  2. Register the endpoint in a routes file:
    Route::ohDearWebhooks('ohdear-webhook');
    
  3. Add that same path to App\Http\Middleware\VerifyCsrfToken::$except, since Oh Dear cannot send a CSRF token.
  4. Map at least one event type to a queued job in config/ohdear-webhooks.php:
    'jobs' => [
        'uptimeCheckFailed' => \App\Jobs\OhDear\HandleFailedUptimeCheck::class,
    ],
    
  5. Configure the same URL in the Oh Dear dashboard and use its test webhook to confirm delivery.

The first place to look after publishing is config/ohdear-webhooks.php, followed by the package’s OhDearWebhookCall class and the Oh Dear webhook event documentation. The first useful implementation is usually an uptimeCheckFailed job that sends a notification or opens an incident, paired with an uptimeCheckRecovered job that closes it.

Implementation Patterns

One queued job per event type. This is the primary day-to-day pattern. Keep the job focused: read $webhookCall->monitor(), $webhookCall->run(), and $webhookCall->type(), then perform a single side effect such as Slack notification, email, SMS, PagerDuty-style escalation, or incident creation. Jobs should implement ShouldQueue so the webhook endpoint returns quickly.

class HandleFailedUptimeCheck implements ShouldQueue
{
    public function __construct(public OhDearWebhookCall $webhookCall) {}

    public function handle(): void
    {
        $monitor = $this->webhookCall->monitor();
        $run = $this->webhookCall->run();

        // open incident keyed by monitor id, notify on-call, etc.
    }
}

Event listeners for cross-cutting behavior. Every valid webhook can also be consumed as a Laravel event named ohdear-webhooks::<event-type>. Use listeners for audit logging, metrics, or a generic “store every webhook payload” listener rather than duplicating that logic in every job.

protected $listen = [
    'ohdear-webhooks::uptimeCheckFailed' => [
        \App\Listeners\StoreOhDearWebhook::class,
    ],
];

For broad capture, register a wildcard listener in EventServiceProvider::boot():

Event::listen('ohdear-webhooks::*', function (OhDearWebhookCall $call) {
    // append to audit log, increment metrics, etc.
});

Correlate failure and recovery events. Treat monitor() as the join key. On uptimeCheckFailed, open or update an incident using the monitor id/url. On uptimeCheckRecovered, close the matching incident. This is the simplest way to build an on-call workflow without building custom webhook parsing.

Use jobs for side effects, events for observation. A practical split is: jobs own “do the thing” behavior (notify, page, create ticket), while event listeners own “record that it happened” behavior (audit trail, analytics, replay storage). This keeps the config mapping small and makes failures easier to reason about.

Test locally by simulating signed requests. Oh Dear cannot reach localhost, so use a tunnel or generate a signed POST in a feature test. Inspect the package’s signature validator to replicate the exact header and signing input; then assert that the configured job is dispatched and that invalid signatures throw OhDear\LaravelWebhooks\WebhookFailed.

Deploy with config caching in mind. After changing the jobs mapping, run php artisan config:cache as part of deployment. A stale config cache is a common reason a newly mapped job never runs.

Gotchas and Tips

  • CSRF is mandatory to handle. The route macro registers a POST route, but it does not bypass Laravel’s CSRF middleware. If the path is not in VerifyCsrfToken::$except, Oh Dear requests will fail before signature verification.
  • A queued job means Oh Dear already got a 200. The package validates and dispatches, then responds. If your queued job later fails, Oh Dear will not retry the webhook. Rely on Laravel queue retries and failed-job monitoring; for critical flows, persist the webhook before dispatch or add explicit retry/alerting around the job.
  • Make handlers idempotent. Retries and duplicate deliveries are possible. Deduplicate using monitor id plus event type plus dateTime(), or store a processed-event key before performing side effects.
  • Signature failures throw WebhookFailed. Check the signing secret, the environment actually loaded by the app, and whether config is cached. A mismatched secret produces a failed request, not a silent skip.
  • Event names must match Oh Dear exactly. Config keys are camelCase event types such as uptimeCheckFailed. A typo means no job is dispatched; verify names against the Oh Dear webhook event docs and the package’s published config comments.
  • The package does not persist anything. There is no webhook log, replay mechanism, or incident store. If you need auditability, add a listener that stores $webhookCall->payload and the typed accessors yourself.
  • Treat payload accessors defensively. monitor() and run() return arrays whose keys can vary by event type. Use null coalescing and avoid assuming every event has a full run payload.
  • dateTime() is a string. Parse it explicitly rather than relying on implicit string-to-date conversion, and avoid assuming a timezone beyond what Oh Dear sends.
  • Do not do slow work synchronously. Mail, HTTP calls, and ticket creation inside a non-queued listener can cause webhook timeouts and Oh Dear retries. Queue jobs and listeners.
  • The endpoint is public by design. Do not put auth middleware in front of it; rely on signature verification. Keep the secret in .env, rotate it in both Oh Dear and the app when needed, and use HTTPS.
  • Multiple Oh Dear teams are not a first-class case. The package is built around one signing_secret. If you need per-team verification, you will need separate endpoints/apps or custom handling outside the package.
  • Know the scope boundary. The package validates and dispatches; it does not decide what should happen next. Incident lifecycle, notification routing, deduplication, escalation, and persistence are application responsibilities.
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.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk