Striker
Striker

Reputation: 666

Send Slack notification every time a Status is changed in Laravel

I have a Status Notification class, so that when a status is created it sends me a slack message.The issue I am running into is that a new status is created every few minutes and getting a slack message every couple minutes is repetitive and nonconstructive. Especially because there are dozens of servers posting these statuses.

Would there be a way to only post the slack message if a specific servers status has changed? e.g. server was up then went down.

I've tried getting all of the server statuses but cant figure out how to only get the last two with a specific server id.

---------------------------------------------------------EDITS------------------------------------------------------------ Previously tried attempt: except the last else I wouldn't want there

 $statuses = ServerStatus::all();
    $first = ServerStatus::where('server_id', $notifiable->server_id)->first();
    //dump($first);

    foreach($statuses as $status){
        if($status->server_id === $notifiable->server_id){
            //dump($status);
            if($status->status_id !== $first->status_id){
                return (new SlackMessage)
                    ->content('One of your statuses has been updated!');
            }
            else{
                return (new SlackMessage)
                    ->content('One of your statuses has been not updated!');
            }
        }
    }

also my boot for sending the notification every time a ServerStatus is created:

protected static function boot(){

    parent::boot();

    ServerStatus::created(function($model) {

        $original = ServerStatus::where('server_id', $model->server_id)->skip(1)->first();

        dump('original',$original->status_id);
        dump('serverStatus', $model->status_id);

        if ($original && $model->status_id != $original->status_id) {
            $model->notify(new ServerStatusNotification());
        }
    });
}

enter image description here

Upvotes: 1

Views: 530

Answers (1)

Ohgodwhy
Ohgodwhy

Reputation: 50767

I would bind to the updating event in the boot function of your ServerStatus model so you can make an isDirty comparison. You can call isDirty('status_id') to determine if the status id has been changed, something like this:

protected static function boot() 
{

    parent::boot();

    ServerStatus::created(function(ServerStatus $serverStatus) {
        $original = ServerStatus::where('server_id', $serverStatus->server_id)->last();
        if ($original && $serverStatus->status_id !== $original->status_id) {
            // send slack notification, status id differs
        }
    });
}

If you need more control over the specific status, you can call getOriginal() to get the original value and determine, such as in your case, the specific status transitions:

ServerStatus::created(function(ServerStatus $serverStatus) {
    $original = ServerStatus::where('server_id', $serverStatus->server_id)->last();

    if ($original && $original->status->description === 'up' && $serverStatus->status->description === 'down') {
        //send server went down notification
    } else if ($original && $original->status->description === 'down' && $serverStatus->status->description === 'up') {
        //send server is up notification
    }
});

I don't actually know what your relationship name is, or the column that stores the text version of the status is, but something like the above should work for you.

Upvotes: 2

Related Questions