Cut PHP Code Review Time & Bugs into Half with CodeRabbit

Get insights into all your Laravel notifications with Paragraphs new package

Last updated on by

Get insights into all your Laravel notifications with Paragraphs new package image

When Laravel introduced Notification classes back in 2016, it allowed all of us to begin sending any transactional communications to our customers in a very simple, intuitive way. Chances are, by now you got tens of Notification classes in your product and you are sending hundreds or thousands of emails and text messages every single day.

Wouldn’t it be nice to have a better control over it? Let’s say, after a client comes to the customer support, I want to be able to see what exactly did I send to him or her in the last 30 days. What did the notification say – was it accurate information in it or did we cause confusion? How many notifications are we sending every day? Which notification type costs us the most money? Do all notifications look great on phones? Do we have typos, do we have stylistic inconsistencies?

How is notification X triggered? How often do our users open notification Y? Maybe we should just remove it?

And so on.

The point is – the notifications are an important part of our product, it’s how we tell our customers what just happened and what to do or expect next, and so it could be very, very helpful to start managing them better. This would allow us to increase customer satisfaction and decrease our costs.

A new package that helps

Good news is that a tool like that is already available – we at Paragraph just released a Laravel composer package. In just a few seconds you could get way more visibility over your outgoing communications.

The installation is as simple as installing one composer package:

$ composer require paragraph/laravel-notifications

That’s it! The package auto-registered itself and is now hooked into the notification rendering process. If you send any notifications in your Laravel app, you should be able to see new little files popping up in the storage/app/comms folder.

Now that the data is being collected, we have to send it to Paragraph dashboard from time to time, ideally as a scheduled cron command. To do that we need to provide API credentials in the environment file (or the real OS environment):

# Anywhere in your .env file
PARAGRAPH_PROJECT_ID=XXX
PARAGRAPH_API_KEY=YYY

To get your API key and project ID, just create a project on Paragraph which really only takes a minute or less: https://paragraph.ph/repos/import

You can now run a console command that will submit the history and remove any temporary files:

$ php artisan paragraph:submit

Voila, we can see the notification history in Paragraph dashboard now:

The data includes notification channels used, recipient ID (which can be and should be anonymised), current status (if available through an integration) and preview button.

But this is just the start, of course.

Notification triggers

If you click on any notification type in the first column, you will get to a page that has some advanced information about this notification class including its triggers:

Our package automatically discovers the notification journey – when and how it’s triggered, so that you can make sure that everything is working according to the design.

In this example above, we can see that the notification was sent from a listener that was triggered by an event that was fired in a web controller, and therefore the root cause was an action that user took on your website.

Open rate and cost analysis

One the very same page you can see some stats about this specific notification type – how many times it was sent during the given period, the open rate (coming back from an integration, eg. Mailgun API) and total cost spent.

This can allow you to quickly identify transactional emails or text messages that cost company a lot but potentially don’t even get opened often.

Copy review and updates

If you click “View” you can see a rendered HTML of the email that was sent, a full copy of the SMS message and so on:

Click “View in GitHub” to quickly jump to the file containing this text in GitHub and make some easy text updates.

As a bonus, we will also check the copy for any grammar errors and typos and we will display anything we found on the Notification class page.

Localization? Trivial!

Need to translate your notifications into different languages? Oh, too easy! You can use Paragraph’s localization package to automatically submit all your texts to online marketplaces like Gengo and then apply the translations received, no manual work involved.

You can do this using a helper function:

public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->line(text('The introduction to the notification.'))
->line(text('Thank you for using our application!'));
}

Or a Blade component:

<p>
<x-text comment="This paragraph explains how Paragraph can help localize an app">
Need to translate your notifications into different languages? Oh, too easy!
You can use Paragraph’s localization package to automatically submit all
your texts to online marketplaces like Gengo and then apply the
translations received, no manual work involved.
</x-text>
</p>

Performance impact

You might be wondering what’s the impact on your application performance. After all, we are running some extra code every time there is a notification being sent and there could be thousands or millions of notifications delivered every day.

Our code running time on average is 1ms (millisecond) or less, and the sync component of it tries to do as little as possible to make sure the impact is minimum. The hook saves a rendered snapshot to a temporary file and stops right there – any API calls will be made separately at a later stage, asynchronously.

Snapshot files are compressed with Zip to ensure there is a minimum footprint in terms of hard disk usage, and our code actually runs AFTER the notification is already sent. Moreover, it’s wrapped in the try-catch clause so that any Throwable is caught and your code can proceed as if nothing happened:

try {
$html = $message->getSymfonySentMessage()->getOriginalMessage()->getHtmlBody();
 
$this->save(
$html,
get_class($notification)
);
} catch (\Throwable $e) {
}

Therefore, using this package is very safe from both performance and customer experience perspectives.

Join for free now

Sounds interesting? Then go to Paragraph, import a project https://paragraph.ph/repos/import and you can make your product notifications better, your customers happier and your balance sheet lighter. Joining is absolutely free this month as a part of the public beta launch!

Eric L. Barnes photo

Eric is the creator of Laravel News and has been covering Laravel since 2012.

Filed in:
Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Bacancy

Outsource a dedicated Laravel developer for $3,200/month. With over a decade of experience in Laravel development, we deliver fast, high-quality, and cost-effective solutions at affordable rates.

Visit Bacancy
Curotec logo

Curotec

World class Laravel experts with GenAI dev skills. LATAM-based, embedded engineers that ship fast, communicate clearly, and elevate your product. No bloat, no BS.

Curotec
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $3200/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
Cut PHP Code Review Time & Bugs into Half with CodeRabbit logo

Cut PHP Code Review Time & Bugs into Half with CodeRabbit

CodeRabbit is an AI-powered code review tool that specializes in PHP and Laravel, running PHPStan and offering automated PR analysis, security checks, and custom review features while remaining free for open-source projects.

Cut PHP Code Review Time & Bugs into Half with CodeRabbit
Get expert guidance in a few days with a Laravel code review logo

Get expert guidance in a few days with a Laravel code review

Expert code review! Get clear, practical feedback from two Laravel devs with 10+ years of experience helping teams build better apps.

Get expert guidance in a few days with a Laravel code review
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit

The latest

View all →
Laravel 12.44 Adds HTTP Client afterResponse() Callbacks image

Laravel 12.44 Adds HTTP Client afterResponse() Callbacks

Read article
Handle Nested Data Structures in PHP with the Data Block Package image

Handle Nested Data Structures in PHP with the Data Block Package

Read article
Detect and Clean Up Unchanged Vendor Files with Laravel Vendor Cleanup image

Detect and Clean Up Unchanged Vendor Files with Laravel Vendor Cleanup

Read article
Seamless PropelAuth Integration in Laravel with Earhart image

Seamless PropelAuth Integration in Laravel with Earhart

Read article
Laravel API Route image

Laravel API Route

Read article
Laravel News 2025 Recap image

Laravel News 2025 Recap

Read article