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

Messagebird Bundle Laravel Package

flosch/messagebird-bundle

Symfony bundle that integrates the MessageBird API, exposing the official PHP client as configurable services and adding a Swiftmailer transport so applications can send SMS messages through MessageBird using familiar mailer APIs and YAML configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. flosch/messagebird-bundle is a Symfony 3 bundle, not a Laravel package. Symfony 3 has been end-of-life since 2021, the bundle has zero stars and zero dependents, and the vendor itself rebranded from MessageBird to Bird. Composer may install it into a Laravel app, but there is no package discovery, no service provider, and no Laravel-facing API. Day-to-day, you "leverage" this package by using the SDK it wraps — not the bundle itself.

Install the underlying SDK instead:

composer require messagebird/php-rest-api

Put the credential in .env:

MESSAGEBIRD_ACCESS_KEY=live_xxxxxxxxxxxxxxxx
MESSAGEBIRD_ORIGINATOR=MyApp

Wire it via a config entry (config/services.php):

return [
    'messagebird' => [
        'access_key' => env('MESSAGEBIRD_ACCESS_KEY'),
        'originator' => env('MESSAGEBIRD_ORIGINATOR', 'MyApp'),
    ],
];

Bind the client as a singleton (dedicated MessageBirdServiceProvider or AppServiceProvider):

use MessageBird\Client;

$this->app->singleton(Client::class, fn () => new Client(
    config('services.messagebird.access_key')
));

First use case — a queued transactional SMS:

namespace App\Services;

use MessageBird\Client;
use MessageBird\Objects\Message;

class SmsSender
{
    public function __construct(private Client $client) {}

    public function send(string $to, string $body, ?string $originator = null): Message
    {
        $message = new Message();
        $message->originator = $originator ?? config('services.messagebird.originator');
        $message->recipients = [$to];          // E.164: +31612345678
        $message->body = $body;

        return $this->client->messages->create($message);
    }
}

Dispatch it from a job (SendSmsJob::dispatch($user, $code)), never inline in a login request.

If you must read the Symfony bundle (e.g., inheriting a Symfony 3 service), open, in order:

  1. DependencyInjection/Configuration.php — exact config keys (usually just access_key).
  2. Resources/config/services.xml — the service ID and class (expect messagebird.client → MessageBird\Client).
  3. DependencyInjection/*Extension.php — how the key reaches the constructor.

The entire surface is one service definition and one config node; ten minutes of reading beats guessing.

Implementation Patterns

Adapter over the SDK, always. The MessageBird\Client is a third-party object with a frozen API. Inject it only into one class, and have the rest of the app depend on an interface:

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

// AppServiceProvider
$this->app->bind(SmsGateway::class, MessageBirdSmsGateway::class);

When the vendor changes or you migrate, you rewrite one class.

Use a Laravel Notification channel. For anything user-facing (OTP, alerts), model it as a notification and add a MessageBirdChannel that delegates to SmsGateway. You get queues, toMessageBird() shaping, and per-notification routing for free.

Queue every outbound send. SMS is a network call with 100–500ms latency and a hard rate limit. SendSmsJob implements ShouldQueue with $tries = 3 and backoff() keeps the request path clean and gives you retry semantics.

Idempotency to survive retries. A retried job will send twice if the first call succeeded but the response was lost. Persist an sms_log row keyed by a message reference before dispatch, and have the job check-and-set status before calling messages->create().

Webhooks for delivery receipts. MessageBird posts status updates to a URL you configure. Add a route that verifies the signature, returns 200 fast, and dispatches a job to update the sms_log row. Do not process receipts synchronously.

Testing. Don't hit the network. Bind SmsGateway to a FakeSmsGateway in tests (or Http::fake() if you wrap the REST endpoints), and assert the job is dispatched with the right recipient and body.

Extension point when the bundle is in the tree. The bundle's value is a service definition you can override — alias MessageBird\Client to your own decorated instance, or decorate messagebird.client — without touching third-party code. That is also the seam you use to swap vendors later.

Gotchas and Tips

  • The bundle is not installable in a modern Laravel app. Symfony 3 transitive constraints will collide with PHP 8+/Laravel 10+ in composer update. If you see it in a dependency tree, treat it as a migration line item, not something to adopt.
  • The vendor rebrand and SDK freeze. MessageBird is now Bird, and messagebird/php-rest-api is effectively frozen. Pin the version and assume no upstream fixes; plan a wrapper swap if you need WhatsApp or voice.
  • MessageBird\Client throws on an empty key. Failing at container boot is better than failing at send time, but it means a missing env var crashes startup — validate MESSAGEBIRD_ACCESS_KEY in a config check and fail loudly in CI.
  • Config caching. php artisan config:cache freezes env() calls. Only read MESSAGEBIRD_ACCESS_KEY inside config/services.php; calling env() from a service class returns null in production.
  • Phone numbers must be E.164. 0612345678 fails; +31612345678 works. Normalize (e.g., via propaganistas/laravel-phone) before it reaches the gateway, and reject rather than let the SDK 400.
  • Sender IDs are country-specific. Alphanumeric originators don't work everywhere; some regions require pre-registered short codes. A one-line default will silently fail in the wrong market.
  • Error handling. The SDK throws MessageBird\Exceptions\* subclasses. Catch broad Throwable in the job, log the API code, and mark the row failed — don't let an uncaught SMS exception take out a queued login job's siblings.
  • Duplicate sends after retries. The classic failure: API succeeds, network drops, job retries, user gets two OTPs. Idempotency keys / a status column are non-optional for auth flows.
  • Rate limits and per-country cost. Batch large sends through a job with a delay, and log per-message country for cost attribution — the bundle (and the SDK) provide neither.
  • Webhook security. Verify the signature and reject replays by checking a message_id + status uniqueness constraint, or you'll get spoofed "delivered" receipts.
  • Never inject MessageBird\Client into controllers, models, or notifications directly. The bundle's biggest trap is that it makes the SDK look first-party — it isn't. One adapter class in, one out.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
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