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

Kudisms Notification Laravel Package

toneflix-code/kudisms-notification

Send SMS notifications from your Laravel app through Kudisms. This package adds a notification channel plus a lightweight API client, so you can deliver messages to one or many recipients using a simple, familiar Notification class.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Confirm your Laravel/PHP floor before you run anything. Version 2.0 requires PHP ^8.3|^8.4 and Illuminate ^12.0|^13.0. On Laravel 10 or 11 this package simply will not install — you stay on toneflix-code/kudisms-notification:1.1.1, which is now on an unmaintained branch. Make that an explicit decision, not a surprise during a composer update.

2. Install under the new name.

composer require toneflix/kudisms-notification:^2.0

Auto-discovery is unchanged in spirit, but every class string moved namespace: ToneflixCode\KudiSmsNotification → Toneflix\KudiSmsNotification. Read three files in vendor/toneflix/kudisms-notification/ before writing code:

  • src/*ServiceProvider.php — the exact provider FQCN (you need it verbatim for vendor:publish), the channel key registered (kudisms?), and any publish tags.
  • config/*.php — the env keys (token vs api_key, sender_id vs from, endpoint). Re-publish rather than hand-editing; the 2.0 config may carry updated comments/keys.
  • src/*Message.php — the fluent builder (content(), from(), to()…), which is the class you'll type most.

3. Publish config with the new provider name.

php artisan vendor:publish --provider="Toneflix\KudiSmsNotification\KudiSmsNotificationServiceProvider"

If that returns "provider not found", the class was renamed in 2.0 — grab the FQCN from step 2 rather than guessing.

KUDI_SMS_TOKEN=your-kudisms-api-token
KUDI_SMS_SENDER_ID=MyApp

4. Upgrading an existing app (this is a rename, not an in-place bump).

composer remove toneflix-code/kudisms-notification
composer require toneflix/kudisms-notification:^2.0

Composer will not resolve the old name to the new one — it's a different package, so no composer update will ever pull 2.0 for you. Then:

  • grep -rn "ToneflixCode" app/ config/ tests/ database/ and fix imports. Notification classes that reference KudiSmsMessage are the usual suspects.
  • Re-publish the config; a published config/kudisms.php from 1.x is fine to delete.
  • php artisan optimize:clear — the cached package manifest in bootstrap/cache/ still points at the old provider and produces a confusing "class not found" on boot.

5. First use case: OTP delivery on the User model.

// app/Models/User.php
public function routeNotificationForKudiSms($notification)
{
    return $this->phone_number;
}
// app/Notifications/SendOtp.php
use Toneflix\KudiSmsNotification\KudiSmsMessage;

class SendOtp extends Notification implements ShouldQueue
{
    public function __construct(public string $code) {}

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

    public function toKudiSms($notifiable)
    {
        return (new KudiSmsMessage)
            ->from(config('kudisms.sender_id'))
            ->content("Your verification code is {$this->code}. Expires in 10 minutes.");
    }
}

The channel key and the to<StudlyChannel>() method must match exactly; if 2.0 changed the registration key, both the via() string and the method name move together.

Implementation Patterns

Dedicated notification classes per intent. Don't build one generic SmsNotification with a $body argument; toKudiSms() is a template method, so keep OTP, delivery updates, and dunning as separate classes. It makes Notification::fake() assertions readable later.

On-demand sends without a notifiable model.

Notification::route('kudisms', '+2348030000000')
    ->notify(new OrderShipped($order));

Thin service wrapper for non-notification sends. If the package exposes its HTTP client (or you bind your own), wrap it so bulk operations don't leak through the notification layer:

final class SmsService
{
    public function __construct(private KudiSmsClient $client) {}

    public function send(string $to, string $message, ?string $sender = null): bool
    {
        return $this->client->send($to, $message, $sender ?? config('kudisms.sender_id'));
    }
}

Type-hint the client by its new namespace; a stale use here is the most common post-upgrade fatal.

Always queue and always rate-limit. Transactional SMS is slow (200–800ms per round-trip) and providers throttle. Combine ShouldQueue with middleware:

public function middleware($notifiable): array
{
    return [(new RateLimited('sms'))->dontRelease()];
}

Define the limiter with RateLimiter::for('sms', fn ($job) => Limit::perMinute(30)).

Test with Notification::fake() plus a fake HTTP layer. Assert the right person got the right notification, then separately assert payload shape against Http::fake():

Notification::fake();
$user->notify(new SendOtp('482913'));
Notification::assertSentTo($user, SendOtp::class);

Post-upgrade, run the suite before touching anything else — passing tests are your proof the namespace swap is complete.

Fallback channel. For OTPs consider return ['kudisms', 'mail'] with a toMail() on the same class — cheap insurance at the cost of one extra method.

Audit trail. Log the send yourself in an Illuminate\Notifications\Events\NotificationSent listener rather than inside every notification class.

Gotchas and Tips

The 2.0 upgrade is a package rename plus a namespace move — treat it as two migrations. Miss either half and you get either a composer.json pointing at a dead package or a Class "ToneflixCode\KudiSmsNotification\KudiSmsMessage" not found at runtime. Grep for both the old vendor string and the old namespace, including published config comments and any queue.php/notifications.php references.

Clear the package manifest, not just config. After swapping the package, bootstrap/cache/packages.php can still list the old provider. Symptom: config('kudisms.*') returns null and the channel key isn't registered, with no error explaining why. php artisan optimize:clear fixes it; config:clear alone doesn't.

Environment floor is a hard gate. If any app in your fleet is on Laravel 10/11 or PHP 8.1/8.2, 2.0 is unavailable to it — and 1.1.1 is now a frozen branch. If you're multi-app, pin per app (toneflix-code/kudisms-notification:1.1.* on the old ones) and keep your usage behind a single wrapper class so the divergence stays one file wide.

Nothing in 2.0 changes the runtime behaviour of the channel — no new builder methods, no new config keys surfaced in the release notes. So any pre-existing bug or quirk you worked around in 1.x is still there: phone normalisation, 200-with-error-body responses, sender-ID limits, character encoding costs. Don't re-read this release as a fix list.

Phone number normalisation is still the #1 failure mode. Nigerian gateways expect 234803... (no +, no leading 0) while your DB probably stores 0803.... Normalise inside routeNotificationForKudiSms(), not in the notification, so every channel benefits. Validate with a regex before dispatching — a malformed recipient often returns 200 OK with a body-level error rather than a 4xx.

The API probably returns 200 on failure. Most KUDI-style gateways respond {"status": "error", "message": "..."} with HTTP 200. A non-throwing Guzzle call does not mean delivery. Check the status/code field and throw so the queue retries — otherwise failed OTPs vanish silently.

Sender ID registration is out-of-band. Alphanumeric sender IDs must be pre-approved on the KUDI dashboard and are typically capped at 11 characters. A wrong sender ID fails at the API layer, not at config validation, so your first staging send is the real test.

Character encoding drives cost. GSM-7 gives 160 chars per segment; one curly quote, emoji, or ₦ drops you to UCS-2 at 70 chars/segment and can triple the bill. Keep templates ASCII-only, add a length guard, and strip \n — some gateways truncate at line breaks.

config:cache will bite you. If the provider reads env vars at boot instead of in the config file, cached config with a missing env var yields a null token at runtime with no error. After adding credentials or upgrading, always php artisan config:clear locally.

Maturity risk is essentially unchanged by the rename. A new vendor name and a Laravel 13 support bump are housekeeping, not community pressure-testing — the package still has negligible dependent count. Pin exactly ("toneflix/kudisms-notification": "2.0.*"), and keep usage concentrated in one notification class or one service wrapper so you can drop to raw Http::withToken() in an afternoon. If the client is constructor-injected and container-bound, you can substitute your own implementation without touching notification classes.

Extension points, in order of usefulness: (1) bind your own HTTP client / gateway wrapper in the container; (2) decorate the channel class with a try/catch + logging wrapper; (3) override config at runtime with config(['kudisms.endpoint' => ...]) for a proxy or sandbox host.

Debugging checklist when a message doesn't arrive: php artisan queue:failed → storage/logs/laravel.log → Http::fake() a test with Http::assertSent(fn ($r) => dd($r->data())) to dump the exact payload → check the KUDI dashboard for the send record. The dashboard is usually faster than log spelunking because it shows provider-side rejection reasons.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle