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

Clickatell Laravel Package

laravel-notification-channels/clickatell

Send SMS notifications through Clickatell with this Laravel notification channel. Install via Composer, configure your API token, and deliver messages using a simple toClickatell method.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a thin adapter, not a subsystem. It plugs into Laravel's existing notification pipeline as one more channel alongside mail, database, and broadcast — meaning it inherits queueing, retries, via() routing, shouldSend() gating, and Notification::fake() testability for free. That is the right architectural shape for a first SMS capability: no new abstraction, no parallel messaging layer, no bespoke job queue. The integration surface is deliberately small — a channel class, a fluent message builder, and one config file — which means the blast radius of adopting it is limited to the notification classes that opt in. For a TPM, the important read is that this package does not commit the product to Clickatell architecturally; it commits it commercially and operationally, which is a cheaper and more reversible decision.

Integration feasibility. Feasible in days, not weeks, on a Laravel 8-era codebase. The work breaks into four tracks: (1) install and publish config, (2) add routeNotificationForClickatell() to notifiable models plus a phone field with E.164 normalisation, (3) author one or two notification classes, (4) wire credentials and sender ID in the Clickatell account. Only step 4 is outside engineering's control, and it is the one most likely to consume calendar time — alphanumeric sender ID registration is per-country and account-side. The build-vs-buy question is genuinely marginal here: the driver is roughly one small class plus config, so "buy" mostly buys a maintained naming convention rather than meaningful engineering. The honest framing is adopt temporarily, replace deliberately.

Technical risk. Four risks dominate, in descending order of business impact:

  • Vendor and maintenance risk (high confidence, high impact). Nine stars, one maintainer, last tagged release September 2021, zero dependents. There is no community-tested compatibility matrix to lean on. This should be logged as a dependency with an owner and a review date, pinned to an exact version.
  • Delivery observability gap (certain, high impact). The package is outbound-only. No delivery receipts, no status webhooks, no callback parsing. A 202 Accepted from Clickatell is not proof of delivery — per-message accepted flags can be false inside a successful HTTP response. "Did the OTP arrive?" is unanswerable with this dependency alone, which materially changes the effort estimate for anything on the auth path.
  • Compliance exposure (certain, regulatory). Consent capture, STOP keyword handling, and suppression lists are entirely the product's responsibility. Inbound STOP requires a Clickatell webhook and a suppression table that via() reads. This is a launch prerequisite, not a follow-up ticket.
  • Credential fragility (low probability, high severity). If the service provider reads env() directly rather than through config(), php artisan config:cache in production silently nulls the token. Must be validated in a config-cached staging environment before launch.

Key questions.

  1. Which markets are in scope, and does Clickatell's carrier coverage in Africa and the Middle East actually justify the vendor choice — or is this a US/EU product where Twilio, Vonage, or AWS SNS offer better webhooks and compliance tooling with better-maintained Laravel packages?
  2. Is SMS going on the authentication path (OTP/2FA, password reset)? If yes, the missing delivery receipts must be scoped and budgeted before commitment, not after.
  3. Who owns consent, STOP handling, and the suppression list, and is that work scheduled against launch or against "later"?
  4. What is our supported Laravel version at the time of adoption, and has anyone run composer why-not against the real lockfile?
  5. What is the monthly SMS budget ceiling, and which message classes are approved to spend against it?
  6. Is Clickatell already a commercial relationship, or would this create a new vendor onboarding (contract, billing, sender ID provisioning) with its own lead time?

Integration Approach

Stack fit. Strong on Laravel 8.x; progressively weaker on 9, 10, and 11. The value proposition depends entirely on reusing the existing notification pipeline rather than building a separate SMS path — the moment we fork into a bespoke sender, we lose the argument for the package. This means the channel should be adopted behind our own SmsSender seam from day one: an interface plus a ClickatellSmsSender implementation that delegates to notify(). That single hour of work is what converts the eventual vendor swap from an incident into a scheduled afternoon, and it also allows a second vendor for a second region without touching call sites.

Migration path. Three realistic routes, and the decision should be made explicitly rather than by default:

  • Adopt as-is — viable only on Laravel 8.x with a pinned exact version. Accept the maintenance risk knowingly.
  • Vendor the package — copy into the codebase, take ownership, patch constraints as Laravel versions advance. Preserves the API and removes the abandonment risk at the cost of owning ~50 lines plus tests.
  • Rebuild the channel — write the driver ourselves against Clickatell's messaging API. Given the size, this is a small, bounded piece of work and is the honest end state on Laravel 10+. The SmsSender seam makes this a swap rather than a rewrite.

The recommendation is to adopt on 8.x if that is the current target, with a pre-agreed trigger — a Laravel upgrade, or a delivery-observability requirement — that converts the dependency into vendored or rebuilt code.

Compatibility. Compatibility is ours to prove, not the release notes'. Pre-1.0, single-maintainer, released for Laravel 8, zero dependents: there is no tested matrix. The gate is composer why-not laravel-notification-channels/clickatell run against the actual lockfile, not against documentation. --ignore-platform-reqs in production is not an acceptable answer. A second compatibility axis is the Clickatell account itself: the from sender ID must be provisioned and approved for every destination country in the user base. A failing send that looks like a code defect is frequently a sender-ID provisioning issue in the account, and that distinction needs to be visible in the runbook.

Sequencing. The package gives no reason to launch all SMS flows at once; treat each as a separate product bet with its own success criteria.

  1. Prove credentials and sender ID with an on-demand Notification::route('clickatell', ...) smoke test — no notifiable model, no migration, no product surface. This de-risks the account-side work before any code depends on it.
  2. Ship one high-value flow. OTP/2FA or password reset. High value per message, tiny blast radius, and failure is loud and immediate rather than a silent marketing miss. Gate this on the delivery-observability decision in step 0 — if SMS is on the auth path, "did it arrive?" must have an answer.
  3. Transactional alerts. Order shipped, appointment reminder, payment failed. Lower urgency, broader audience, same infrastructure.
  4. Broadcast and marketing last. Highest unit cost, highest consent exposure, and the flow most likely to surface throughput and encoding cost surprises.

Cross-cutting work that must run in parallel with step 2, not after it: consent capture and the suppression table that via() reads, phone normalisation to E.164 enforced at write time on the model, a base SmsNotification abstract class to stop seven near-identical notification classes proliferating, and an outbound send log (recipient, channel, body hash, response ID) driven by NotificationSent / NotificationFailed.

Operational Impact

Maintenance. Low volume of work, non-zero probability of forced work. The package is small enough to read end-to-end in ten minutes, which means maintenance cost sitting on it is negligible — the risk is that it stops being installable on a future Laravel version and the fix arrives on the framework upgrade's critical path rather than on a schedule. Mitigation: pin the exact version, log it with an owner and a review date, and keep the SmsSender seam so remediation is a planned task. Budget the replacement as a known, small, scheduled cost rather than treating this as strategic infrastructure.

Support. Two support surfaces, and only one of them is engineering's. Internally, support load is mostly "I never got my code" investigations, which the outbound send log turns from a two-hour investigation into a five-minute answer. Externally, vendor support is Clickatell's, and its quality depends on the commercial tier — a self-serve account and an enterprise contract get very different response times on delivery issues and sender-ID provisioning. Someone must own the Clickatell account relationship: sender ID approvals, rate limits, billing, and the status-API work if delivery receipts are required.

Scaling. Throughput is a queue-and-plan question, not a library question. Concurrency is set by our workers and Clickatell's plan rate limit. Two scaling costs need to be forecast rather than discovered:

  • Segment economics. GSM-7 gives 160 characters per segment; a single emoji or curly quote forces UCS-2 at 70. Clickatell bills per segment. Bodies must stay ASCII, smart punctuation must be stripped, and any templated user-supplied name must be sanitised. This is a per-message multiplier on the bill, and it is invisible until someone reads the invoice.
  • Burst behaviour. A broadcast to 5,000 users will surface 429s in staging or in production. Test under realistic burst before launch. Queue every SMS on a dedicated sms queue so a stuck worker cannot starve mail; add tries, backoff(), and RateLimited middleware on OTP flows specifically so a retry storm does not become a Clickatell bill.

Failure modes. Ranked by how quietly they fail:

  • Rejected send reported as success. A 202 with per-message accepted: false — bad sender ID, blocked route, invalid destination — looks like a successful send in logs if the channel only asserts HTTP status. Highest-severity failure mode because it is silent. Mitigation: inspect and validate the response body, or wrap the call.
  • Missing route throws inside a queued job. If routeNotificationForClickatell() returns null and the message has no explicit to(), the exception lands in the queue and disappears. Mitigation: gate in via() and shouldSend(), and make the phone field non-nullable for opted-in users.
  • Config cache nulls the credential. Covered above; test in config-cached staging.
  • Unnormalised phone numbers. The channel passes the string straight through. Reject at write time, not send time — send-time failures land in a queue.
  • Sender ID not provisioned for a destination country. Presents as a code bug; diagnose via the account, not the logs.
  • No delivery receipts. Failures after acceptance are invisible. This is the structural gap, and for anything on the auth path it needs an outbound fallback design (SMS failed → voice call → email) built against Clickatell's status API, separately from this package.

Ramp-up. Fast and bounded. Engineers comfortable with Laravel notifications need perhaps half a day to read the three relevant source files, publish config, and ship the smoke test. The real ramp-up cost is not technical — it is the compliance and account onboarding track: consent capture, STOP handling, suppression lists, sender ID approvals per country, and the decision on delivery observability. Those items carry regulatory consequences if skipped and calendar lead time if handled properly, and they sit on the critical path regardless of how quickly the code lands. Plan the launch around that track, not around the package install.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource