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

Gammu Laravel Package

laravel-notification-channels/gammu

A Laravel notification channel for sending SMS messages through Gammu, the open-source SMS gateway. Integrate Gammu into your Laravel app and deliver notifications as text messages using Laravel’s familiar notification API.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is thin glue between Laravel's notification system and a running Gammu SMSD daemon. It does not talk to a modem itself—Gammu does—so your first step is confirming you have an SMSD database backend (usually MySQL/MariaDB with outbox, sentitems, inbox tables) and a modem/SIM registered and sending.

  1. Confirm your Gammu transport before touching Laravel. Read src/GammuChannel.php first. The channel is small; the one thing that determines your whole integration is whether it inserts a row into SMSD's outbox table or shells out to gammu-smsd-inject. Everything else (config keys, DB grants, testing strategy) follows from that.
  2. Install with expectations set. The package pins Laravel 5.3-era illuminate/* constraints, so composer require laravel-notification-channels/gammu will likely fail on Laravel 8+. Either fork and widen the constraints, or copy src/ into app/Support/Gammu and keep the NotificationChannels\Gammu namespace. The channel itself is a few dozen lines; don't fight Composer for it.
  3. Register and configure. On 5.3 there is no auto-discovery, so add NotificationChannels\Gammu\GammuServiceProvider::class to config/app.php, then publish the config (vendor:publish --tag=gammu) and point it at your SMSD database or binary. Put credentials in .env, never in the published config.
  4. First notification. php artisan make:notification SendSms, return [GammuChannel::class] from via(), and implement toGammu():
use NotificationChannels\Gammu\GammuChannel;
use NotificationChannels\Gammu\GammuMessage;

public function via($notifiable)
{
    return [GammuChannel::class];
}

public function toGammu($notifiable)
{
    return GammuMessage::create()
        ->to($notifiable->phone_number)   // E.164, e.g. +31612345678
        ->content('Your code is 123456');
}

Trigger it with $user->notify(new SendSms()) and verify a row appears in outbox and then sentitems. If nothing appears, the problem is your config/DB grant, not Laravel.

Implementation Patterns

Centralize routing on the notifiable. Implement routeNotificationForGammu() returning the phone number. Then notifications don't need ->to() and you can use anonymous routing for non-users:

public function routeNotificationForGammu()
{
    return $this->phone_number;
}

Notification::route('gammu', $number)->notify(new SendSms('...'));

Always queue SMS notifications. The channel's work is a fast DB insert, but the modem drains at roughly 6–10 messages/minute. Implement ShouldQueue, put them on a dedicated queue, and rate-limit the job rather than the request:

class SendSms extends Notification implements ShouldQueue
{
    public $tries = 3;
    public $backoff = [10, 60, 300];

    public function middleware()
    {
        return [new RateLimited(Limit::perMinute(10)->by('gammu'))];
    }
}

Build a small base notification/trait for number normalization, 160-character (or 70 for UCS-2) validation, localization via __(), and a consistent content(). Keeping message construction in one place is worth more than any feature the package offers.

Treat delivery tracking as your job, not the package's. The package hands a message to Gammu and stops. Build a read-only connection to the SMSD database and a scheduled command that reconciles outbox/sentitems rows by ID or CreatorID into your own audit table. Do not let the app's primary DB user touch SMSD tables.

Test at two levels. Use Notification::fake() and assertSentTo($user, SendSms::class, fn ($n) => $n->toGammu($user)->content === '...') for notification logic. Add one integration test against a test schema containing the real outbox column set, because Notification::fake() hides SQL and schema errors entirely.

Integration tip: if you need SenderID, DeliveryReport, Priority, SendAfter, or multipart control, check whether GammuMessage exposes it. In this package's era it usually does not—fork the message class or write a 30-line custom channel. The integration surface is one INSERT; owning it is often cheaper than owning an abandoned dependency.

Gotchas and Tips

  • Abandoned since December 2016. Fourteen stars, zero dependents, no releases in years. It is a reference implementation, not a maintained dependency. Budget for a fork or inline copy, and expect to update via(object $notifiable): array and PHP 8 signatures yourself.
  • Silent no-ops. If routeNotificationForGammu() returns null or empty, most channels in this family simply return. Your test suite passes, nothing is sent, and nobody notices. Guard and log missing numbers.
  • Phone format is the #1 production failure. Normalize to international format before insert. A local 0612345678 will fail or route incorrectly; +31... vs 31... must be consistent with your SMSD configuration.
  • Encoding traps. Gammu's Coding column must match the text. Accented characters and emoji require UCS-2, which drops the segment size from 160 to 70 and may require MultiPart. Validate length and encoding before insert, not after a failed send.
  • Modem reality. No credit, a PIN-locked SIM, lost network registration, or a dead gammu-smsd process all look identical from Laravel: rows accumulating in outbox. Add a health check on the daemon and alert on outbox backlog or rows stuck in Reserved/Sending.
  • Scheduling windows. SMSD uses SendBefore/SendAfter and SendingTimeOut. Messages can silently expire if the daemon is down past the window. Check the defaults for your version.
  • DB least privilege. The Laravel app only needs INSERT on outbox (and SELECT on sentitems if you track delivery). Never reuse the SMSD user that performs deletes and status updates.
  • Config caching. config:cache is fine, but make sure the Gammu connection is defined as a separate entry in config/database.php with env-driven credentials—otherwise config caching in CI/production can surprise you.
  • Logging PII. SMS bodies often contain OTPs and personal data. Don't log message content on failure; log the notification ID, destination hash, and the exception.
  • Extension points are limited but sufficient: subclass GammuChannel for custom transport behavior, subclass or replace GammuMessage for extra columns, and hook Laravel's notification events for metrics. If you find yourself extending heavily, the honest answer is that a first-party channel writing to outbox is a half-day of work and removes the maintenance question entirely.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo