laravel-grok-bot
Open source Laravel notification channel

Laravel notifications, resolved by your Grok Bot.

The Grok Bot notification channel for Laravel. Each notification starts a run of a Grok Bot routine with your JSON, and the Bot works it out: fixes the bug, answers the ticket, investigates, or asks you first.

composer require alfonsobries/laravel-grok-bot
Read the docs
Animation: a Laravel app logs an exception, a support ticket and a failed payment. Each one travels as a notification to its own Grok Bot routine, and each Bot reacts and resolves it: it opens a pull request with the fix, refunds a duplicate charge, and emails the customer a new payment link.

How do I send a Laravel notification to Grok Bot?

Return grok-bot from via() and build the message in toGrokBot(). This one hands every production exception to a Bot that fixes it.

app/Notifications/ExceptionReported.php
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use NotificationChannels\GrokBot\GrokBotMessage;
use Throwable;

class ExceptionReported extends Notification implements ShouldQueue
{
    use Queueable;

    public function __construct(
        public string $class,
        public string $message,
        public string $location,
        public string $trace,
        public ?string $url,
    ) {}

    public static function from(Throwable $e): self
    {
        return new self(
            $e::class,
            $e->getMessage(),
            $e->getFile().':'.$e->getLine(),
            mb_substr($e->getTraceAsString(), 0, 4000),
            app()->runningInConsole() ? null : request()->fullUrl(),
        );
    }

    public function via(object $notifiable): array
    {
        return ['grok-bot'];
    }

    public function toGrokBot(object $notifiable): GrokBotMessage
    {
        return GrokBotMessage::create("{$this->class}: {$this->message}")
            ->data([
                'event' => 'exception.reported',
                'repository' => 'acme/shop',
                'commit' => config('app.commit'),
                'location' => $this->location,
                'url' => $this->url,
                'trace' => $this->trace,
            ]);
    }
}
bootstrap/app.php
use NotificationChannels\GrokBot\Exceptions\CouldNotSendNotification;

->withExceptions(function (Exceptions $exceptions): void {
    $exceptions->dontReportDuplicates();

    $exceptions->report(function (Throwable $e): void {
        if (app()->isProduction() && ! $e instanceof CouldNotSendNotification) {
            Notification::route('grok-bot', 'bugs')->notify(ExceptionReported::from($e));
        }
    });
})

What does the Grok Bot routine receive?

A JSON body, next to the routine's instruction. The app sends the facts; the instruction says how to resolve them.

POST to the routine's webhook
{
    "message": "ErrorException: Undefined array key \"currency\"",
    "event": "exception.reported",
    "repository": "acme/shop",
    "commit": "4f5177f",
    "location": "/app/Services/CheckoutService.php:88",
    "url": "https://shop.example.com/checkout",
    "trace": "#0 /app/Http/Controllers/CheckoutController.php(41): ..."
}
Routine instruction, written in Grok Bot
An exception from production arrives as JSON. Find the cause in the
GitHub repo named in "repository" at "commit". If it is a bug in our code,
write a failing test, fix it, and open a draft pull request; send me the
link here. If it is not (a third-party outage, a bad deploy, a bot hitting
a bad URL), tell me in one line and do nothing else.
Ignore bodies with "type": "ping".

More things a Bot can resolve

A production exception

Opens a draft pull request with a test and the fix.

A support ticket

Looks the customer up, answers from your help center, asks before refunds.

A failed payment

Checks the processor, retries or emails the customer with the right link.

A queue job that keeps failing

Reads the payload and the error, and tells you what to change.

How do I connect a Grok Bot routine?

Four steps, once per routine.

  1. Add a webhook trigger

    Ask your Bot to add a webhook trigger to a routine, write its instruction, and make sure it is active.

  2. Copy the URL and key

    Open the routine on desktop. The Webhook section has the POST to URL and the key.

  3. Add them to .env

    GROK_BOT_WEBHOOK_URL and GROK_BOT_WEBHOOK_KEY. More routines go in config/grok-bot.php.

  4. Ping it

    php artisan grok-bot:ping confirms the routine starts a run.

Can I use one routine per purpose?

Yes. The message wins, then the notifiable, then the default routine.

// On demand
Notification::route('grok-bot', 'bugs')->notify(ExceptionReported::from($e));

// From the message
GrokBotMessage::create('...')->routine('bugs');

// From a model, with a routine stored per team
public function routeNotificationForGrokBot(): GrokBotRoutine
{
    return GrokBotRoutine::make($this->grok_bot_url, $this->grok_bot_key);
}

Built for production

What happens around the request.

Clear failures

An invalid key, a paused routine or a rate limit throws an exception that says which, and fires NotificationFailed.

Retries that make sense

Connection errors and 5xx are retried. A refused key is not.

Keys stay secret

The key never shows in an exception, an event or the command output.

Agent ready

Ships a Laravel Boost guideline and skill, so your coding agent can wire new notifications end to end.

Questions

About runs, limits and failures.

Does a successful notification mean the Bot finished?
No. A 200 means the routine started a run. The result shows in the Bot's chat.
How many notifications can a Grok Bot routine take?
A routine runs at most 200 times an hour, and 300 across all routines. Batch or debounce events that come in bursts.
What happens when the routine refuses?
The channel throws CouldNotSendNotification with the cause: 401 invalid or regenerated key, 400 routine not active or over its rate limit, 404 webhook gone. Connection errors and 5xx are retried first.
Which Laravel versions are supported?
Laravel 12 and 13 on PHP 8.2 and newer.