Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cmsms Laravel Package

laravel-notification-channels/cmsms

A Laravel notification channel for CMS Made Simple (CMSMS). Send notifications from your Laravel app through CMSMS using the familiar Laravel notification API. Easy to install and configure, it extends the laravel-notification-channels ecosystem with a clean, tested driver for CMSMS-powered sites.

View on GitHub
Deep Wiki
Context7

Getting Started

Install, add credentials, then read the source before writing a single notification. There is nothing to publish — no migration, no config stub — so the whole setup is Composer plus four lines of config, and config:cache will not bite you later.

composer require laravel-notification-channels/cmsms
// config/services.php
'cmsms' => [
    'endpoint' => env('CMSMS_ENDPOINT'),
    'token'    => env('CMSMS_TOKEN'),
    'from'     => env('CMSMS_FROM'),
],

Then spend ten minutes in vendor/laravel-notification-channels/cmsms/src/, in this order:

  1. The channel class — this is your actual transport. Authenticated HTTP POST? A CMSMS module route? A direct DB write? That single fact decides your security posture, your version coupling, and whether you can test without a live CMS.
  2. The message class — this is your real API surface. Every ->subject(), ->content(), ->to() you can call lives here. It is short; read it end to end instead of trusting the README to be complete.
  3. The service provider — confirms the literal string you pass to via(). Family convention says 'cmsms', but a typo'd channel name fails silently at runtime, so confirm rather than assume.

Your first use case should be low-stakes and internal: "new enquiry submitted", "content export finished" — sent to yourself or one staff recipient who already lives in the CMSMS admin. Do not make a customer-facing path your smoke test.

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use NotificationChannels\Cmsms\CmsmsMessage; // confirm namespace against src/

class EnquirySubmitted extends Notification implements ShouldQueue
{
    use Queueable;

    public function __construct(public array $payload) {}

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

    public function toCmsms(object $notifiable): CmsmsMessage
    {
        return CmsmsMessage::create()
            ->subject('New enquiry: '.$this->payload['subject'])
            ->content(view('notifications.enquiry', $this->payload)->render());
    }
}

Routing is standard Laravel: implement routeNotificationForCmsms() on the notifiable returning whatever recipient identifier the channel expects (editor ID, email, username — the channel source tells you which), or route on demand:

Notification::route('cmsms', '[email protected]')->notify(new EnquirySubmitted($data));

Implementation Patterns

Keep the package at the leaf of your dependency graph. NotificationChannels\Cmsms\* should appear in exactly two places: one notification class and one via() decision. No imports in services, models, or controllers. When you inevitably fork or replace it, that is a one-file change.

Always pair CMSMS with mail and gate it behind a flag. Cheapest insurance available against a single-maintainer, zero-dependent package:

public function via(object $notifiable): array
{
    $channels = ['mail'];

    if (config('features.cmsms_notifications') && $notifiable->cmsms_recipient_id) {
        $channels[] = 'cmsms';
    }

    return $channels;
}

Flip the flag off and behaviour degrades to email instead of vanishing. The null-recipient guard matters too — a missing ID should not throw inside the channel.

Queue on a dedicated, rate-limited worker. A legacy PHP CMS behind an authenticated endpoint is not built for programmatic throughput, and you do not want a slow CMSMS backing up mail or Slack delivery:

public function viaQueues(): array
{
    return ['cmsms' => 'cmsms'];
}

Set $tries, $backoff, and $timeout explicitly (or retryUntil()). Laravel's defaults are not tuned for an endpoint you don't control.

Test at two layers, deliberately. Notification::fake() proves via() and toCmsms() without touching transport:

Notification::fake();

Notification::route('cmsms', '[email protected]')
    ->notify(new EnquirySubmitted($payload));

Notification::assertSentOnDemand(EnquirySubmitted::class, function ($n, $channels, $notifiable) {
    return $n->payload['subject'] === 'Widget restock';
});

Then add one unfaked test letting the channel run against Http::fake() and asserting outbound payload shape and response handling. That is your contract test — the thing that turns an upstream break into a red build instead of a user complaint.

Wrap it if you'll send more than one notification type. A thin app-level interface (CmsmsNotifier::send(string $recipient, string $subject, string $body)) injected into callers means swapping to an in-house implementation is a container binding change, not a grep-and-replace across the codebase.

Keep recipient mapping out of notification classes. A model column or config lookup for the CMSMS recipient ID lets you point staging at a sandbox CMS and survives editors changing roles.

Local development needs a stub, not real credentials. Point CMSMS_ENDPOINT at a request-recording stub route in your app (or bind a no-op fake channel in the container under local/testing). Otherwise developers either hit a shared CMS or silently skip the code path entirely. The recording stub is what lets you eyeball the rendered body during development — worth the twenty minutes.

Gotchas and Tips

Verify the transport before writing a line of product code. A DB-writing channel means hard schema coupling and CMS database credentials in your Laravel .env — a materially different risk than an authenticated HTTP POST. If it is HTTP, check how the token travels and whether TLS is enforced. This one fact should drive adopt-vs-fork.

Pin the exact version. composer require laravel-notification-channels/cmsms:1.x.y, not ^1.0. Nine stars, zero dependents: you are the first person to hit the bugs.

Check composer.json platform constraints manually. "Laravel 5 and up" is stale framing. Verify the actual illuminate/* requirements against your Laravel/PHP matrix. If you need --ignore-platform-reqs to install, stop — that is a red flag, not a fix.

Notifications fail quietly. A CMSMS 5xx with no queue just means the message is gone. Queue it, set retries, watch failed_jobs, and alert on channel error rate rather than reading logs after someone asks why they never got pinged.

A 200 is not proof of delivery. The package may treat any non-exception as success while the content lands malformed or in the wrong field. During rollout, verify in the CMSMS admin UI — the actual page/post/record, not the HTTP status.

Confirm idempotency before enabling retries. If the transport isn't deduped, a retry after a timeout double-posts. Either tolerate duplicates, include a dedupe key in the body if the transport supports it, or cap retries at one.

Notification::fake() makes payload tests vacuous. It's correct for routing assertions and wrong for transport assertions. Keep both layers.

Message objects are often mutable and single-use. Build a fresh CmsmsMessage per toCmsms() call; don't stash a prebuilt one on a singleton or a static — you'll leak fields between recipients.

Watch escaping when you render views into the body. view(...)->render() produces HTML, and a legacy CMS may escape it, strip it, or execute it depending on where it's stored. Test with a body containing <, &, and a multi-byte character before you trust it, and decide deliberately whether HTML is even appropriate.

Never put the token in a package config file. Credentials in config/services.php reading env() keeps config:cache from baking your secret into a cached PHP file.

Review bodies for PII before they cross over. Notification content leaves your Laravel app and lands in a legacy CMS with its own retention and access model. Decide intentionally what may go in there.

Write the fork plan down before you ship. MIT means vendoring into app/Support/Cmsms is an afternoon. The wrapper interface exists so that afternoon is the entire cost. If it's on a release-critical path with no fallback, write the channel in-house instead — the code is small enough that this is a days-scale decision.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core