Laravel Framework provides many options to send notifications to your users. You can send Emails, Slack messages, Telegram Notifications, and the good old SMS messages. Today, I’ll show you how you can easily send SMS messages in Laravel.

What are Notifications?

Generally speaking, notifications are short informational messages that alert your users about something that happened in your application. You can also use notifications as a mechanism to bring the User back to your application to perform some task. For example, you might send a “Subscription Renevewd” notification once a month, via SMS or email channels to your subscribed users.

Laravel Project Setup

We’ll install a new Laravel project using Composer.

composer create-project --prefer-dist laravel/laravel laravel-sms-notifications

cd laravel-sms-notifications

The above command pulls in the latest version of Laravel and installs it in laravel-sms-notifications folder.

To be able to register users in our app. We will have to pull in Laravel’s UI package. The laravel/ui package contains views related to Login, Registration, Password Reset, and more.

 composer require laravel/ui

Once the installation is completed, use artisan to publish auth related assets to /resources/ folder.

php artisan ui vue --auth

After that, we need to compile these assets. We can do that using npm.

npm install && npm run dev

Next up, we’ll need to set-up a database for our application. I’ve gone ahead and created a laravel-sms database, and I’ll be adding connection details to this database in .env file.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-sms
DB_USERNAME=root
DB_PASSWORD=

Finally, let’s run our migrations to complete the project set up.

php artisan migrate

Now let’s bring up our application by starting the webserver.

php artisan serve

Go ahead and visit http://127.0.0.1:8000. You should see a welcome page similar to this.

Laravel Welcome Page

Set up Vonage SMS Gateway

Laravel SMS channel uses Vonage (previously known as Nexmo) as an SMS service provider. Therefore, we’ll have to create an account with Vonage and set-up our API access before we can start sending SMS messages.

Setting Up Vonage Takes Less than 10 Minutes.

The registration is straightforward and does not even require a Credit Card to begin with. So, that’s quite good. However, you will have to confirm both your email address and phone number before you can start sending SMS. Once you’ve done that, your account will also be credited with a small $3 starting balance!

To leverage Vonage’s service, we need to install their Laravel package. Let’s do that using Composer.

composer require laravel/nexmo-notification-channel

After that, we need to connect our application to our Vonage account. We do that by using the API key, and the Secret provided on the “Getting Started” page.

Add both credentials to the .env file, like so:

NEXMO_KEY=ajsdh7ahs
NEXMO_SECRET=Sud7hsHS5sMA

Next, we have to add sms_from property to our config/services.php file. The sms_from is the phone number from which your SMS messages will be sent from.

'nexmo' => [
    'sms_from' => 'Vonage SMS API',
],

Note: You can also generate a custom phone number or Sender Id in the Vonage dashboard and set that value here instead.

Create Notification Class

In the previous step, we set up the dependencies required to send SMS messages. Now we will use the SMS package in our notification class to send SMS messages to our users.

First, create the WelcomeNotification class using artisan.

php artisan make:notification WelcomeNotification

Next, we’ll define our SMS logic in the WelcomeNotification class. We’ll need to define two things here. Firstly, we’ll specify our notification channel by defining a via() method that returns nexmo. And then, a toNexmo() with logic to send an SMS. This toNexmo() method will be invoked every time we send any notification using the WelcomeNotification class.

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\NexmoMessage;

class WelcomeNotification extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['nexmo'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', url('/'))
                    ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }

    /**
     * Get the Nexmo / SMS representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return NexmoMessage
     */
    public function toNexmo($notifiable)
    {
        return (new NexmoMessage)
                    ->content('Welcome to Codezen Laravel Tutorial!');
    }
}

Set Up User Model for SMS Notifications.

We are now one step closer to sending an SMS message to our User on registration. However, to which number should we send the SMS to?

To fix that issue, we will be asking the User for his phone number during the registration. Therefore, we need to modify our default auth and User set up.

Add a phone_number column to the users table by specifying a new field in database/migrations/create_users_table.php.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('phone_number');
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

After that, re-run migrations. Note that the below command will drop all your existing tables and create new ones.

php artisan migrate:fresh

Next, add phone_number field to the $fillable property of User.php. This will enable us to create a User using the create() method.

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'phone_number'
    ];

Next, We will modify the default User creation logic in the RegisterController and make it work with our newly added field.

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'phone_number' => ['required', 'between:10,13'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'phone_number' => $data['phone_number'],
            'password' => Hash::make($data['password']),
        ]);
    }
}

Next, you will need to define a routeNotificationForNexmo method to User.php. This method should return the user’s phone number which will be picked up by Laravel when we are trying to send a notification.

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

Finally, We will modify the User registration form register.blade.php and add a new phone_number input:

<div class="form-group row">
    <label for="text" class="col-md-4 col-form-label text-md-right">Phone Number</label>

    <div class="col-md-6">
        <input id="text" type="text" class="form-control @error('phone_number') is-invalid @enderror" name="phone_number" value="{{ old('phone_number') }}" required autocomplete="phone_number">

        @error('phone_number')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>
</div>

Now, visit http://127.0.0.1:8000/register, and you should see the modified register page.

Send a Welcome Message to New Users

We can finally start sending SMS messages now. We will hook into the create() method in registerController.php and dispatch a notification just before a User is created.

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        Notification::send(request()->user(), new WelcomeNotification());

        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'phone_number' => $data['phone_number'],
            'password' => Hash::make($data['password']),
        ]);
    }

In the above method, we’re dispatching our custom notification using Laravel’s Notification facade. Don’t forget to add use App\Notifications\WelcomeNotification; at the top of this file.

Now go ahead and register a User. And You should receive a welcome message to your phone number!

Welcome SMS Message
Welcome Message

 

Send an SMS directly.

You can also send an SMS directly to a Phone Number. Use the Nexmo facade and specify a from and to number along with your message.

    Nexmo::message()->send([
        'to'   => '91952342448',
        'from' => 'Vonage SMS API',
        'text' => 'Welcome to the Codezen Application!'

    ]);

That’s it! It is easy to send SMS Messages in Laravel. If you have any doubts, please ask them in the comment section below. Also, the complete source code of this tutorial is available on my GitHub repository.

If you’re implementing notifications in your app, be sure to check out my recent article on Sending Telegram Notifications in Laravel!