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

Sms Bundle Laravel Package

xi/sms-bundle

xi/sms-bundle adds SMS messaging to your PHP application, providing a configurable service for composing and sending text messages through your chosen gateway. A lightweight option for teams wanting to wire SMS notifications into an existing stack without heavy dependencies.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is a thin Symfony integration for the xi/sms library: it wires up a gateway service you can inject to send SMS messages. It is an old, low-traffic package (2 stars, 0 dependents, likely Symfony 2-era and unmaintained), so treat the first hour as a compatibility audit rather than a quick install.

  1. Check compatibility before anything else. Look at the bundle's composer.json for symfony/symfony and php constraints. If you are on Symfony 4+/Flex, you will almost certainly need to fork or vendor the bundle and adapt it (no AppKernel, no app/config/config.yml). On Symfony 2.x/3.x it should drop in.
  2. Install and enable.
    composer require xi/sms-bundle
    
    Symfony 2/3: register new Xi\Bundle\SmsBundle\XiSmsBundle() in AppKernel.
  3. Configure a gateway in config.yml under the xi_sms key (the exact key is defined in the bundle's DependencyInjection/Configuration.php — read that file first). Typical shape:
    xi_sms:
        gateway: my_gateway
        gateways:
            my_gateway:
                # provider-specific: api key, sender/from number, endpoint
    
  4. Where to look first, in order:
    • DependencyInjection/Configuration.php → what config keys actually exist.
    • DependencyInjection/*Extension.php → the service IDs and gateway aliases.
    • Resources/config/*.xml|yml → the concrete gateway classes and their constructor args.
    • vendor/xi/sms/src/... → the actual SmsService/Gateway interfaces you will code against.
  5. First use case — send one message. Inject the SMS service into a controller or console command and send:
    $message = new \Xi\Sms\SmsMessage('+358401234567', 'Hello from Xi');
    $this->get('xi_sms.sms_service')->send($message);
    
    Confirm the service ID with php app/console container:debug | grep -i sms before writing code — do not trust docs, there are none reliable.

Implementation Patterns

Wrap the bundle behind your own interface. Because this package is unmaintained, do not let Xi\Sms\* types leak across your codebase. Define a one-method SmsSender interface in your app and implement it with the bundle's service. Swapping providers (or the whole package) later becomes a one-class change.

interface SmsSender { public function send(string $to, string $body): void; }

class XiSmsSender implements SmsSender {
    public function __construct(private $smsService) {}
    public function send(string $to, string $body): void {
        $this->smsService->send(new \Xi\Sms\SmsMessage($to, $body));
    }
}

Send from a console command, not the request cycle. SMS providers are slow and rate-limited; a synchronous send in a controller blocks the user and fails loudly on provider timeouts. A command + queue (even a simple DB table) is the sane default:

// app/console sms:send {to} {body}
$output->writeln($this->get('app.sms_sender')->send($args['to'], $args['body']) ? 'sent' : 'failed');

Use one gateway per environment. Point xi_sms.gateway at a "log" or fake gateway in dev/test config and the real one in prod. If the bundle ships no fake gateway, write a trivial one implementing the Gateway interface and register it as a service — this doubles as your test double.

Batch/campaign sends: loop over recipients with a small sleep between sends to respect provider throttling, catch per-recipient exceptions so one bad number does not abort the batch, and persist a send log row (recipient, body hash, gateway response, timestamp) for reconciliation.

Integration points worth wiring:

  • An event listener that fires on user signup, order shipped, etc., and enqueues an SMS job.
  • A kernel.exception or job-failure listener that alerts ops via SMS (dogfooding the bundle is a good smoke test).
  • Symfony's monolog channel tagged for the SMS service so provider errors land in a dedicated log file.

Testing: unit-test your XiSmsSender against a mock of the bundle's service (or your fake gateway). Do not functional-test against a real provider in CI; assert on the message object (to, body) passed to the fake.

Gotchas and Tips

  • Treat it as abandoned. 2 stars / 0 dependents means no security patches, no PHP 8 fixes, and no support. Pin the exact version in composer.json, vendor the source if it breaks, and budget for a rewrite if SMS becomes business-critical.
  • Service IDs and config keys are undocumented. container:debug, config:dump-reference xi_sms, and reading Configuration.php are your only reliable sources. Older bundles sometimes ignore unknown config keys silently — if your setting "does nothing," check the config tree first.
  • Character encoding bites. GSM-7 vs UCS-2, and 160 vs 70 characters per segment, determine whether a long message is split and billed multiple times. If the bundle does not segment, do it yourself or cap body length deliberately; also strip emoji or force UCS-2 knowingly.
  • Phone numbers are not normalized. Pass E.164 (+358401234567) and validate before sending; garbage numbers often return a provider error or, worse, succeed and cost money.
  • No retry, no idempotency, no delivery receipts. The bundle is a fire-and-forget send path. Add your own retry-with-backoff around transient provider errors, an idempotency key or dedupe table for jobs, and a webhook endpoint for delivery-status callbacks if the provider supports them.
  • Credentials belong in parameters/env, not YAML in git. Symfony 2-era bundles often expect raw values in config; use %env()% or parameters.yml and keep the config file as structure only.
  • Exception behavior varies by gateway. Catch a broad \Exception at your sender boundary and translate to your own SmsException; some gateways throw on HTTP failure, others return a falsey value.
  • Extension points: you can override any bundle service by defining it in your app's services.yml with the same ID, and you can register a custom gateway class implementing the bundle's Gateway interface without forking. Check the interface signature in vendor/xi/sms — it is the most stable surface you have.
  • Debugging sends: run with -vvv and a Monolog handler on the SMS channel; if messages "disappear," verify the configured default gateway name matches an entry under gateways: exactly (a typo commonly resolves to a null/default gateway rather than throwing).
  • Upgrade path: if you migrate off, the replacement surface is small (one send(to, body) call). Abstract it now and the eventual swap is mechanical.
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