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

Turbosms Bundle Laravel Package

sunra/turbosms-bundle

Symfony bundle that integrates the TurboSMS SMS gateway, helping you configure API credentials and send SMS messages from your application through a simple service-based interface.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to internalize: this is a Symfony2 bundle, not a Laravel package. There is no service provider, no facade, no config/turbosms.php. If you install it into a Laravel app you will be pulling in symfony/dependency-injection, symfony/http-kernel, and friends from the 2016 era, and you will spend more time wiring the container than sending an SMS. Treat the repository as a reference implementation of the TurboSMS HTTP API rather than a dependency you composer require.

That said, if you inherit a project (or a legacy Symfony2 service) that already uses it, here is where to look first:

  1. The bundle's DI extension (DependencyInjection/*Extension.php) — this defines the config keys (login, password, sender, debug, etc.). Your credentials and default sender live here.
  2. The service class (Services/*.php or Service/Turbosms.php) — this is the thin wrapper around https://api.turbosms.ua. Every method you care about (send, getMessageStatus, getBalance) is a file_get_contents/cURL call to a JSON endpoint.
  3. The API itself — once you see the request shape, you can bypass the bundle entirely.

Minimal first use case, in a Laravel app, by calling the API directly (which is what the bundle does under the hood):

// config/services.php
'turbosms' => [
    'token'  => env('TURBOSMS_TOKEN'),
    'sender' => env('TURBOSMS_SENDER', 'Msg'),
],
$response = Http::withToken(config('services.turbosms.token'))
    ->post('https://api.turbosms.ua/message/send.json', [
        'recipients' => ['380501234567'],
        'sms' => [
            'sender' => config('services.turbosms.sender'),
            'text'   => 'Your code is 1234',
        ],
    ]);

// $response['response_code'] === 0 means accepted
// $response['response_result'][0]['message_id'] is what you persist

If you genuinely need the bundle in a Symfony app, the steps are: add the repo to composer.json, register Sunra\TurbosmsBundle\TurbosmsBundle in AppKernel, add turbosms: { login: ..., password: ... } to config.yml, then inject turbosms (the service id) into your controller.

Implementation Patterns

Wrap it, don't touch it. Whether you keep the bundle or reimplement, put a single interface in front of SMS sending so the choice is reversible:

interface SmsSender {
    public function send(string $phone, string $text): string; // returns message_id
}

Prefer a Laravel Notification channel for anything user-facing. This keeps controllers clean and gives you via(), queueing, and per-channel throttling for free:

class SmsChannel
{
    public function send($notifiable, SmsNotification $notification): void
    {
        app(SmsSender::class)->send(
            $notifiable->routeNotificationFor('sms'),
            $notification->toSms($notifiable)
        );
    }
}

Always queue. TurboSMS is a network call with real latency and occasional 5xx responses. Dispatch a SendSmsJob with $tries = 3 and backoff = [10, 60, 300]. Never send synchronously from a request that a user is waiting on.

Persist the message_id immediately in your own table (sms_messages: id, user_id, phone, text, provider_id, status, sent_at). The bundle does not give you delivery receipts; the only way to reconcile is polling getMessageStatus with the ID, or accepting the "accepted" response as good enough.

Batch carefully. The API accepts an array of recipients. A common pattern is to chunk recipients (10–50 per call) and let the job handle each chunk, so a single failure doesn't lose the whole campaign.

Config over constants. If you inherit the bundle, check whether sender name is hardcoded in the service. Move it to .env. The sender must be pre-approved in your TurboSMS account; if it isn't, the API silently substitutes Msg.

Gotchas and Tips

  • The bundle is abandoned. No releases since 2016, zero dependents, and a Symfony2-only structure. Install it only if you are maintaining a Symfony2 app; otherwise read the source and reimplement in ~40 lines.
  • Phone format is strict. TurboSMS expects 380XXXXXXXXX — no +, no spaces, no leading 0. Normalize on the way in; otherwise numbers are accepted into the batch and then rejected per-recipient with a non-zero response_code, which is easy to miss if you only check the top-level response_code.
  • Two levels of status. The top-level response_code tells you whether the request succeeded; response_result[*].response_code tells you whether each recipient was accepted. Log both. A 0 at the top with failures inside the array is the classic silent failure.
  • Cyrillic/Unicode encoding. If the text is not pure GSM-7, it is sent as UCS-2 and the effective per-segment length drops from 160 to 70 characters. Truncation mid-codepoint produces garbled SMS. Validate length after normalizing to UCS-2 if you support Ukrainian/Russian text.
  • Credentials, not a token, in the old bundle. The 2016 implementation uses login/password query parameters. The modern API uses a bearer token. Do not assume the bundle's auth flow is current — verify against the provider docs before deploying.
  • No delivery receipts / webhooks. Status is pull-only. If you need "delivered" state in your UI, schedule a polling job and give up after N attempts. Do not block the request.
  • Timeouts are your friend. The bundle's file_get_contents calls have no timeout. Wrap direct calls with Http::timeout(10)->retry(3, 200). An SMS to a marketing list should not be able to hang a queue worker.
  • Extension points are thin. There is no event dispatcher hook, no transport interface. If you want per-sender routing, template rendering, or fallback providers, you are writing that yourself one layer above.
  • The real takeaway: the value here is the ~100 lines documenting TurboSMS's request/response contract. Copy that knowledge, own the client, and pin the provider behind an interface so switching to another Ukrainian gateway later is a one-class 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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
cgv/localized-resource