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

Laravel Sms Laravel Package

toplan/laravel-sms

Laravel SMS is a flexible package for sending text messages and verification codes in Laravel apps. It offers pluggable gateways, message templates, rate limiting, queue support, events, and a clean API for reliable SMS delivery, ideal for OTP logins and notifications.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a patch release (2.6.5) of a database-backed logging package, so there is no migration path from a prior assessment — treat this as the baseline. Two changes matter: log records can now store an array of phone numbers in a single entry, and an update failure bug is fixed.

  1. Require the package at ^2.6.5, then publish and run its migrations so the log table matches what the new array-storage code expects:

    composer require <vendor>/<package>:^2.6.5
    php artisan vendor:publish --tag=<package>-config
    php artisan vendor:publish --tag=<package>-migrations
    php artisan migrate
    
  2. Read the config file first. Look for the log connection, table name, retention/pruning settings, and any queue toggle. Confirm the phone-number column is a JSON-capable type (json/longtext with a cast) rather than varchar, since 2.6.5 writes arrays into it.

  3. First use case: log an outbound SMS/notification to one or more recipients in one write.

    Log::channel('database')->info('sms.sent', [
        'phones'  => ['+8613800000001', '+8613800000002'],
        'message' => 'Your code is 123456',
    ]);
    

    If the package exposes a model/record API rather than a channel, the equivalent is a single create() with an array of numbers — check the package's formatter or DTO for the exact key name.

Implementation Patterns

One record per event, many recipients. Before this release you either wrote one row per number or stored a delimiter-joined string. Now the natural pattern is a single log row per send, with the recipient list as an array. This keeps message-level metadata (template, provider response, cost) attached once instead of duplicated per recipient.

Querying by recipient. Array storage changes how you look logs up. Prefer the package's scopes if it ships any; otherwise use JSON containment, and index accordingly:

// MySQL 5.7+ / MariaDB 10.2+
Model::whereJsonContains('phones', $normalizedNumber)->latest()->get();

// SQLite / Postgres
Model::whereJsonContains('phones', $normalizedNumber); // Postgres uses jsonb

If your database can't index JSON containment efficiently at your volume, keep a denormalized primary_phone column alongside the array for the hot lookup path.

Delivery-status updates. The fixed update path is the one to build on. A typical workflow: create the log row at dispatch, then update it from the provider's webhook or callback with status, provider_message_id, and delivered_at. Since the update bug is resolved in 2.6.5, remove any saveQuietly() / raw-query / delete-and-recreate workarounds you added previously — they'll now mask real failures.

Wrap it in a service, not in controllers. Put logging behind a small class (SmsLogger::sent(), SmsLogger::failed()) that normalizes numbers, redacts message bodies if needed, and dispatches to the package. That isolates you from future key/schema renames — this package is on a 2.x line and the array format is brand new.

Queue the writes. A database log written synchronously inside a request adds latency and a failure mode to your critical path. If the package supports a queued channel or you wrap it in a job, use it — especially for bulk SMS where you might log hundreds of recipients per request.

Custom model / channel extension. If the package allows swapping the log model, extend the shipped one and add casts ('phones' => 'array'), scopes (scopeForPhone), and accessors there rather than in application code.

Gotchas and Tips

  • Normalize before storing. Store E.164 (+8613800000001), not the raw user input. Array storage makes whereJsonContains exact-match against whatever formatting you happened to persist; mixed formats will silently fail to match in lookups.
  • Deduplicate and order. Passing an array invites duplicate numbers and unstable ordering. Run array_unique() and array_values() before handing it over, otherwise log rows differ for identical sends and comparisons become unreliable.
  • JSON column vs text column. If an earlier version stored a delimited string, the column may still be varchar/text. The new array writes will succeed on text but whereJsonContains will not. Check the actual column type after migrating and cast the attribute to array/json on the model.
  • The update fix may change behaviour you relied on. If updates were previously failing silently (e.g. updated_at never moved, or partial attribute writes), any code branching on those stale values will now start seeing fresh data. Audit webhook handlers and status dashboards after upgrading.
  • Mass assignment. A previously failing update is sometimes a $fillable/$guarded problem that looked like a package bug. If an update still doesn't persist after 2.6.5, check fillable attributes and dirty-attribute detection before reopening an issue.
  • Phone numbers are personal data. Array storage multiplies PII density per row. Apply retention/pruning aggressively, consider masking in non-production, and confirm whether the package encrypts at rest (most log packages do not).
  • Debugging. Enable query logging around the write path and check that the configured connection isn't a read replica; a "silent update failure" is often just writes going to a connection you didn't expect.
  • Pin the version. Patch-level changes to how arrays are serialized can affect downstream parsers. Lock to ~2.6.5 and add a test asserting the stored JSON shape so a future 2.x patch can't quietly change it.
  • Retention on JSON columns. Table bloat hits harder with wide JSON columns; schedule pruning or partitioning on the log table before enabling array storage in high-volume notification flows.
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package