Skip to content

For developers

Most of Webhook Notifier is driven from the control panel, but there are two places where code can hook in: reporting failures from your own code, and registering your own notification sources.

Reporting a failure from your own code

The Integration failure source fires automatically when a queue job fails, but you can also raise a failure directly - from a try/catch, a health check, or anywhere you want to be notified when something goes wrong:

php
use coyshdigital\webhooknotifier\Plugin;

Plugin::getInstance()->sources->reportFailure(
    'CRM sync failed',                        // title
    'Contact 1234 could not be reconciled.',  // detail / message
    ['contactId' => 1234],                    // optional structured data
);

Any enabled rule using the Integration failure source is evaluated against the report, exactly as if a queue job had failed. The title, detail, error and your data are all available to the rule's payload. This is the tidy way to turn an exception your code already catches into a notification, without wiring up your own webhook call.

Registering your own source

If the built-in sources don't cover something you trigger often, you can add your own. A source is a class implementing coyshdigital\webhooknotifier\sources\SourceInterface - or, more easily, extending BaseSource - and you register it through a single event.

1. Write the source

php
use Craft;
use coyshdigital\webhooknotifier\sources\BaseSource;
use yii\base\Event;

class OrderShippedSource extends BaseSource
{
    public static function id(): string
    {
        return 'orderShipped';
    }

    public static function displayName(): string
    {
        return Craft::t('site', 'Order shipped');
    }

    public function description(): string
    {
        return Craft::t('site', 'Fires when an order is marked as shipped.');
    }

    // Fields a rule can test in its conditions, as [key => label].
    public function contextSchema(): array
    {
        return [
            'orderNumber' => Craft::t('site', 'Order number'),
            'total' => Craft::t('site', 'Order total'),
        ];
    }

    // Wire up the underlying event. Called once, after the app has booted.
    public function attachListeners(): void
    {
        Event::on(SomeService::class, SomeService::EVENT_ORDER_SHIPPED, function($e) {
            $this->dispatch([
                'orderNumber' => $e->order->number,
                'total' => $e->order->totalPrice,
                'order' => $e->order,   // full object, available to cards as {{ order }}
                'summary' => "Order {$e->order->number} shipped",
            ]);
        });
    }
}

dispatch() (from BaseSource) hands your context to the rules engine, which matches it against every enabled rule for this source and queues the ones that pass.

A few things worth knowing:

  • contextSchema() declares the fields a rule can test in conditions and use in cards. Anything else you put in the dispatched context (like the full order object above) is still available to card templates - it just doesn't appear in the editor's field pickers.
  • cardVariables() can be overridden to advertise extra template-only variables separately from the testable condition fields (Freeform does this for its {fields.<handle>} values).
  • isAvailable() can return false to hide the source when a dependency isn't present (the Freeform source only appears when Freeform is installed).
  • summary in the context is used as the human-readable line in the delivery log.

contextSchema() doesn't limit what payloads can reach

It only decides what appears in the editor's condition and variable pickers. Anything else you dispatch - full elements included - is still reachable from a payload template.

2. Register it

php
use coyshdigital\webhooknotifier\events\RegisterSourcesEvent;
use coyshdigital\webhooknotifier\services\Sources;
use yii\base\Event;

Event::on(
    Sources::class,
    Sources::EVENT_REGISTER_SOURCES,
    function(RegisterSourcesEvent $event) {
        $event->sources[] = OrderShippedSource::class;
    }
);

Put this in the init() of your module or plugin. Your source then appears in the rule editor's Source dropdown alongside the built-in ones, and everything else - conditions, connections, cards, the delivery log, retries - works exactly the same.

The scheduled monitor command

The Queue size source is fed by a console command rather than an event:

bash
php craft webhook-notifier/monitor/queue                # check now
php craft webhook-notifier/monitor/queue --cooldown=30  # at most one alert / 30 min

Run it from cron at whatever interval you want the queue checked. The --cooldown option (in minutes) uses the cache to suppress repeat alerts while a backlog persists, so a stuck queue doesn't message you every single run. It's a good template if you build your own polled source: check something on a schedule, then call Plugin::getInstance()->rules->handle($sourceId, $context).

Digital help you can trust.