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

Nexmo Bundle Laravel Package

javihernandezgil/nexmo-bundle

Symfony bundle that wraps the Nexmo (now Vonage) SMS API in configurable services, making it easy to send text messages from your controllers. It handles client setup through the Symfony service container, so you can start sending SMS with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: javihernandezgil/nexmo-bundle is a Symfony2 bundle, not a Laravel package. It ships no service provider, no facade, and no config/ publish tag — it only registers a DI service around nexmo/client via Resources/config/services.xml and reads credentials from DependencyInjection/Configuration.php. It was last released in 2016 and the repository is archived. You cannot composer require it into a Laravel app and get anything usable; at best you get a tree of Symfony\Component\* classes that Laravel's container will never boot.

So "getting started" for a Laravel dev means transplanting the idea, not the package:

  1. Pull the modern client directly: composer require vonage/client (the successor to nexmo/client; the old namespace Nexmo\Client was renamed to Vonage\Client).
  2. Mirror what the bundle's Configuration.php did — API key/secret pair, plus optional application ID and private key path for voice/verify — into config/services.php:
// config/services.php
'vonage' => [
    'key'      => env('VONAGE_KEY'),
    'secret'   => env('VONAGE_SECRET'),
    'app_id'   => env('VONAGE_APP_ID'),
    'private'  => env('VONAGE_PRIVATE_KEY_PATH'),
    'sms_from' => env('VONAGE_SMS_FROM', 'MyApp'),
],
  1. Register the singleton in a service provider exactly as the bundle registers nexmo.client:
$this->app->singleton(Client::class, function ($app) {
    $c = $app['config']['services.vonage'];
    $credentials = new Credentials($c['key'], $c['secret']);
    $client = new Client($credentials);
    if ($c['app_id'] && $c['private']) {
        $client->setAppId($c['app_id']);
        $client->setPrivateKey(Keypair::read($c['private']));
    }
    return $client;
});

First use case: send one SMS to your own number and assert you get a message-id back — that single round trip validates credentials, sender ID formatting, and outbound connectivity, which is where ~80% of the setup failures land.

Implementation Patterns

Do not inject Vonage\Client into controllers. The bundle's weakness was that it exposed one god-service (nexmo.client) that every consumer reached for. Wrap it:

interface SmsSender { public function send(string $to, string $text, ?string $from = null): string; }

Bind SmsSender to a VonageSmsSender implementation. You get testability, a place to enforce E.164 normalization, and a seam to swap providers later.

Prefer Laravel's built-in notification channel for day-to-day SMS. If your only need is "notify a user," skip the client entirely — Notification::send($user, new OrderShipped($order)) with toVonage() requires no package and no DI wiring. Reach for the raw client only when you need delivery receipts, inbound handling, or Verify/Number Insight APIs.

Queue the send. Network calls inside a request cycle are the classic mistake. Dispatch a SendSms job (ShouldQueue, tries = 3, exponential backoff) so a Nexmo 429 or timeout doesn't 500 your checkout.

Inbound webhooks: register a route outside web middleware (routes/api.php is fine, but disable CSRF and session), validate the payload, and return a bare 200 fast — Nexmo retries on non-2xx and duplicates cost you money.

Map the bundle's config semantics faithfully: the Symfony config tree separated messaging credentials (key/secret) from voice/app credentials (app_id/private_key). Keep that split in your own config array so you don't accidentally require a private key to send an SMS.

Extension point translation: the bundle's compiler pass and service aliasing correspond to Laravel's $this->app->alias() and contextual binding. If you have multiple senders (marketing vs transactional numbers), use when(SmsSender::class)->needs('$from')->give(...) rather than a config switch.

Gotchas and Tips

  • The package is dead. Archived since 2016, zero dependents, requires Symfony 2.x and PHP 5.x. No security fixes, and the underlying nexmo/client SDK namespaces were renamed. Any tutorial referencing Nexmo\Client from this bundle will fail against a current install.
  • env() outside config files is null after config:cache. The bundle read parameters.yml at container compile time; Laravel's equivalent discipline is: env() only inside config/*.php, always config('services.vonage.key') elsewhere.
  • Private key paths break on deploy. Store the absolute path in env, and base_path()-resolve it. Relative paths that work locally silently 401 in production.
  • Error codes are the diagnosis. 401 = bad credentials, 402 = account balance too low (looks identical to a bug in your code until you check the dashboard), 429 = throughput cap. Log response->getStatus() and the message-id, and never retry 401/402.
  • Normalize numbers to E.164 before they hit the client. +1, 01, and spaced formats all fail with a generic "invalid params" that tells you nothing.
  • Unicode SMS bill differently: 70 chars per segment vs 160 for GSM-7, and long messages are split and billed per segment. Truncate or count explicitly.
  • Verify inbound signatures. Nexmo signs requests with an HMAC over the sorted params; without verifying you have an open SMS-to-something endpoint that anyone can POST to. hash_equals the computed signature — constant-time, no exceptions.
  • Testing: bind a fake SmsSender in your test container or use Http::fake(). Never let a test suite hit the live API; a stray integration test in CI will burn balance and trip rate limits.
  • If you inherit an actual Symfony2 codebase using this bundle, the fastest exit is to replace the nexmo.client service definition with Vonage\Client and keep the service ID, so consumers don't change.
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.
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
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle