Skip to content
Laravel package

Laravel Textify

Send SMS from Laravel through one API across Bangladeshi and international gateways, with queues, fallback and activity tracking.

composer require devwizardhq/laravel-textify
View on GitHub
On this page

Overview

Laravel Textify is an SMS layer for Laravel applications. You write Textify::send($number, $message) once and pick the gateway through configuration, so moving from a local provider to Twilio, or running two providers side by side, does not touch your application code.

It ships with drivers for six Bangladeshi gateways and two international ones, plus log and array drivers for local development and tests. Sending can be queued, a fallback provider can take over when the primary one fails, and every send can be recorded for auditing. Textify is built by the DevWizard core team and is MIT licensed.

Features

  • One fluent API: Textify::to()->message()->via()->send().
  • Drivers for DhorolaSMS, BulkSMSBD, MimSMS, eSMS, REVE SMS and Alpha SMS (Bangladesh), and Twilio and Vonage (the nexmo driver).
  • log and array drivers for development and automated tests.
  • Provider fallback: set a second provider with fallback() and send with sendWithFallback(), which retries on it when the first fails.
  • Queued sending through a dispatchable job, with an optional queue name.
  • A native Laravel notification channel, textify.
  • Provider balance checks with getBalance().
  • Lifecycle events: TextifySending, TextifySent, TextifyFailed and TextifyJobFailed.
  • Activity tracking to the database or a file, separate from debug logging.
  • Configurable message validation (required, minimum and maximum length).
  • Custom providers by extending TextifyProvider.

Requirements

  • PHP 8.3 or newer.
  • Laravel 10, 11, 12 or 13.
  • Guzzle ^7.0 or ^8.0 (installed automatically).
  • Credentials from at least one supported SMS gateway for production use.

Installation

Terminal
composer require devwizardhq/laravel-textify

Publish the configuration file:

Terminal
php artisan vendor:publish --provider="DevWizard\Textify\TextifyServiceProvider" --tag="textify-config"

If you want database activity tracking, publish and run the migration:

Terminal
php artisan textify:table
php artisan migrate

Configuration

Set the default provider in .env. The default is log, which writes messages to your log instead of sending them.

.env
TEXTIFY_PROVIDER=revesms

Each provider has its own block in config/textify.php under providers, driven by environment variables:

Provider key Main environment variables
dhorola DHOROLA_API_KEY, DHOROLA_SENDER_ID
bulksmsbd BULKSMSBD_API_KEY, BULKSMSBD_SENDER_ID
mimsms MIMSMS_USERNAME, MIMSMS_APIKEY, MIMSMS_SENDER_ID, MIMSMS_TRANSACTION_TYPE
esms ESMS_API_TOKEN, ESMS_SENDER_ID
revesms REVESMS_APIKEY, REVESMS_SECRETKEY, REVESMS_CLIENT_ID, REVESMS_SENDER_ID
alphasms ALPHASMS_API_KEY, ALPHASMS_SENDER_ID
twilio TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM
nexmo NEXMO_API_KEY, NEXMO_API_SECRET, NEXMO_FROM

Every HTTP provider also accepts *_TIMEOUT, *_CONNECT_TIMEOUT and *_VERIFY_SSL variables with the provider prefix, for example REVESMS_TIMEOUT.

Other sections of the config file:

  • activity_tracking.enabled (TEXTIFY_ACTIVITY_TRACKING_ENABLED, default false) and activity_tracking.driver (TEXTIFY_ACTIVITY_DRIVER: database, file or null).
  • logging.enabled, log_successful, log_failed and log_channel for debug logging.
  • events.enabled (TEXTIFY_EVENTS_ENABLED) to switch lifecycle events on or off.
  • validation.message.required, min and max for message checks.

Usage

Send a message with the default provider, or name a provider for a single call:

PHP
use DevWizard\Textify\Facades\Textify;

Textify::send('01712345678', 'Your verification code is 482913');

Textify::via('revesms')->send('01712345678', 'Sent through REVE SMS');

Use the fluent form for multiple recipients or queued delivery:

PHP
Textify::to(['01712345678', '01887654321'])
    ->message('Your order has shipped')
    ->send();

Textify::to('01712345678')->message('Queued message')->queue('sms');

Use it as a notification channel by returning textify from via() and implementing toTextify():

PHP
use DevWizard\Textify\Notifications\TextifyMessage;

public function via($notifiable): array
{
    return ['textify'];
}

public function toTextify($notifiable): TextifyMessage
{
    return TextifyMessage::create('Your order #123 has shipped');
}

The channel finds the phone number through routeNotificationForTextify() on the notifiable. Define that method on your User model to return the right attribute.

API Reference

Textify facade

Method Description
send($to = null, $message = null, $from = null) Send now; accepts a number, an array of numbers or structured arrays
to($contacts), message($text), from($sender) Prepare a message fluently
via($driver), driver($driver) Choose a provider for this send
queue($queueName = null) Dispatch the prepared message as queued jobs
fallback($driver) Set a fallback provider
sendWithFallback($to, $message, $from = null) Send to one number, retrying on the fallback provider if the first fails
getBalance($provider = null) Provider balance as a float
getProviders(), hasProvider($name), getProvider($name), getDriver($name = null) Inspect registered providers
reset() Clear prepared recipients and message

Responses and messages

send() returns a TextifyResponse for a single recipient. Useful methods are isSuccessful(), isFailed(), getMessageId(), getErrorMessage(), getErrorCode(), getCost(), getStatus(), getRawResponse() and toArray().

DevWizard\Textify\Notifications\TextifyMessage is a fluent builder with create(), message(), from(), driver() and metadata(). The toTextify() method can also return a plain string or an array.

Provider contract

Custom providers implement TextifyProviderInterface: send(), sendBulk(), getDeliveryStatus(), getBalance(), getName(), supportsCountry(), validatePhoneNumber(), formatPhoneNumber(), getConfig() and setConfig(). Extending TextifyProvider gives you the shared plumbing.

Artisan commands

  • php artisan textify:test --driver= --to= --message= sends a test message.
  • php artisan textify:table publishes the activity migration.

Examples

Send a one-time password and handle a failed result:

PHP
$response = Textify::via('revesms')->send($user->phone, "Your OTP is {$otp}");

if ($response->isFailed()) {
    report(new RuntimeException($response->getErrorMessage()));
}

Send different messages to different recipients in one call:

PHP
Textify::send([
    ['to' => '01712345678', 'message' => 'Welcome aboard'],
    ['to' => '01887654321', 'message' => 'Your invoice is ready'],
]);

Retry on a second gateway when the first one fails:

PHP
Textify::via('revesms')->fallback('mimsms')->sendWithFallback('01712345678', 'Your OTP is 482913');

Test code that sends SMS without hitting a gateway by selecting the array driver:

.env
TEXTIFY_PROVIDER=array

React to delivery outcomes by listening to the package events:

PHP
use DevWizard\Textify\Events\TextifyFailed;

Event::listen(TextifyFailed::class, function (TextifyFailed $event) {
    Log::warning('SMS failed', ['provider' => $event->provider]);
});

FAQ & Troubleshooting

Messages are not reaching phones. The default provider is log. Set TEXTIFY_PROVIDER to a real gateway and confirm its credentials are in .env.

How do I confirm credentials work? Run php artisan textify:test --driver=revesms --to=01712345678, or call Textify::via('revesms')->getBalance().

Queued messages never send. queue() dispatches a job, so a queue worker must be running (php artisan queue:work). Failed jobs raise TextifyJobFailed.

The notification channel cannot find a number. Define routeNotificationForTextify() on the notifiable, or send to an ad hoc number with Notification::route('textify', '01712345678').

Activity tracking is empty. It is off by default. Set TEXTIFY_ACTIVITY_TRACKING_ENABLED=true and, for the database driver, publish and run the migration with textify:table.

Changelog & Support

Release history is in the CHANGELOG and on the GitHub releases page. Open bugs and feature requests in GitHub issues. Source: DevWizardHQ/laravel-textify. For help wiring SMS into a larger product, the DevWizard team takes project contracts and monthly retainers through the contact page.