NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Every state change dispatches a plain event in RoundlyConsulting\Teams\Events, so you can send notifications, write audit logs or sync other systems without forking:

EventPropertiesFired when
TeamMemberAdded$memberA new membership is created.
TeamMemberRoleChanged$member, $previousRoleA member’s role changes.
TeamMemberDeleted$memberA membership is removed (soft-deleted).
InviteCreated$inviteAn invite is created.
InviteAccepted$invite, $memberAn invite is accepted.
InviteResent$inviteAn invite’s code and expiry are rotated.
InviteRevoked$inviteAn invite is revoked.
TeamOwnershipTransferred$team, $previousOwner, $newOwnerOwnership is transferred.
JoinRequestCreated$joinRequestA user requests to join.
JoinRequestApproved$joinRequestA request is approved (also on auto-approval).
JoinRequestDenied$joinRequestA request is denied.
JoinRequestExpired$requestA pending request auto-declines on expiry.
MembershipExpiringSoon$memberA membership lapses within the report window (--notify).
MembershipExpired$memberAn expired membership is pruned — by teams:members:prune, Teams::members()->prune() or model:prune.

Note the property name: JoinRequestExpired carries $request, the other join-request events carry $joinRequest.

use Illuminate\Support\Facades\Event;
use RoundlyConsulting\Teams\Events\InviteAccepted;
use RoundlyConsulting\Teams\Events\TeamMemberRoleChanged;

Event::listen(function (InviteAccepted $event): void {
    logger()->info('Invite accepted', [
        'invite' => $event->invite->id,
        'member' => $event->member->id,
    ]);
});

Event::listen(function (TeamMemberRoleChanged $event): void {
    // $event->member->role is the new role; $event->previousRole the old one
});

Notification bridge

Publish teams-stubs to get App\Listeners\TeamEventSubscriber — a queued subscriber with handlers for TeamMemberAdded, TeamMemberRoleChanged and InviteCreated. Drop your own Notification classes into its handlers; it runs on notifications.queue_connection, falling back to queue.default. Register it:

// app/Providers/AppServiceProvider.php → boot()
use App\Listeners\TeamEventSubscriber;
use Illuminate\Support\Facades\Event;

Event::subscribe(TeamEventSubscriber::class);

Extend its subscribe() map to react to any other event. The package ships the wiring; your app owns the content.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.