Support the ongoing development of Laravel.io →
Article Hero Image

Send an SMS in Laravel Using Vonage

30 Jun, 2022 10 min read

Photo by Adem AY on Unsplash

Introduction

In your Laravel applications, there may be times that you want to send SMS messages to your users. You might want to do this to send notifications to your users, or maybe as a form of 2FA (two factor authentication).

To send the messages, you'll typically need to interact with a third-party service's API (such as Vonage or Twilio) that can handle the sending (and sometimes receiving) of your messages. In this guide, we're going to take a look at how to use Vonage (who were previously named Nexmo) to send an SMS message to your users from your Laravel app.

Vonage offers several different APIs that you can use, including:

  • SMS API - for sending and receiving SMS
  • Voice API - for making phone calls
  • Video API - for making video calls
  • Verify API - for adding 2FA functionality and verifying a user's phone number or identity

In this particular guide, we'll be using the SMS API.

Sending SMS Using Vonage

Create a Vonage Account

Before we touch any code in our projects, you'll first need to create a Vonage account. It's super simple and quick to do! After that, you'll be able to grab your API keys.

When you first sign up, you'll likely be given some free credit (I was given €2 EUR) and have some small restrictions placed on your account, such as:

  • All of the SMS messages that you send will have a watermark at the end of the message (which says "[FREE SMS DEMO, TEST MESSAGE]")
  • You'll only be able to send the message to your own phone number

But, this isn't an issue because it can give you a chance to experiment with the API and check whether its right for your project. Once you're ready to use Vonage and lift the restrictions, you can upgrade to a paid account.

Installation

Now that we've created our Vonage account and got our API keys, we can install Laravel's first-party notification channel for Vonage (laravel/vonage-notification-channel) using the following command:

composer require laravel/vonage-notification-channel

We can then head over to our .env file and add our API keys that we got after creating our Vonage account:

VONAGE_KEY=your-vonage-key-here
VONAGE_SECRET=your-vonage-secret-here
VONAGE_SMS_FROM=1234567890

As you can see, we've also added a VONAGE_SMS_FROM field too. This will be the number (or name) that the message will appear as being sent by. If you've bought a phone number from Vonage, you may want to put that number here; or you might want to use your brand/company name here instead. Further down, we'll discuss how you can override this value on a notification-by-notification basis when sending the SMS messages.

Configuring Our Models

Now that we have the notification channel set up, we need to configure our model. In this example, we're going to imagine that we want to send the SMS to our User models and that they have their phone number stored in a phone_number field.

Whenever we send an SMS notification in Laravel, we need to let Laravel know where to grab the recipient's phone number from. At the moment, it has no idea which phone number to use. So, we create a new routeNotificationForVonage method on our User model that returns the phone_number field. For example, we could update our model to look like so:

namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable
{
    use Notifiable;

    // ...
  
    public function routeNotificationForVonage($notification)
    {
        return $this->phone_number;
    }
}

You'll also need to make sure that your model is using the Illuminate\Notifications\Notifiable trait so that we can use the notify method to send the notification later.

We've now specified that whenever we are sending a notification using the Vonage channel that we should send the SMS to the user's phone number that's stored in the phone_number field.

Create the Notification

Now that we've configured our model, we can create a new notification class. For the purpose of this tutorial, we're going to imagine that we want to send an SMS notification to a user once they've registered for our application.

So, we'll start by creating the notification using the following command:

php artisan make:notification SuccessfulRegistration

Running the command should have created a new notification class in the app/Notifications directory. We can then update the class so that it can be used for sending SMS messages:

namespace App\Notifications;

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

class SuccessfulRegistration extends Notification implements ShouldQueue
{
    use Queueable;

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

    /**
     * Get the Vonage / SMS representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\VonageMessage
     */
    public function toVonage($notifiable)
    {
        return (new VonageMessage())
            ->content('You have now registered for My Amazing App!');
    }
}

As you can see, we've specified that the via method returns ['vonage']. We've also added a new toVonage method that returns an instance of Illuminate\Notifications\Messages\VonageMessage with our SMS message content.

You might have also noticed that I've also made sure that the class implements the ShouldQueue interface. This means that if we send the SMS as part of a request, we won't need to wait for the SMS to be sent before we return the response to the user. Instead, the SMS will be dispatched and run by one of our project's queue workers in the background. I've talked about using this approach in the past and how it can speed up your Laravel projects in my 6 Quick & Easy Ways to Speed Up Your Laravel Website article if you're interested in reading more.

Sending the Notification

Now that we've prepared our notification, we can now send it. To do this, we can use the notify method (that we get access to via the Notifiable trait on the User model) like so:

$user->notify(new SuccessfulRegistration());

Your user should now receive an SMS message saying "You have now registered for My Amazing App!".

Taking it Further

Now that we've seen how we can send a simple SMS message to a user, let's take a look at how we could take this a little bit further.

Passing Extra Information to the SMS

You might sometimes want to send extra information in the SMS to the user. As a basic example, let's imagine that we also want to display the browser that the user was using when they signed up. We could grab this information like shown in my Getting the User's Device, Browser & OS in Laravel. We'll then want to update our notification class to accept this information like so:

namespace App\Notifications;

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

class SuccessfulRegistration extends Notification implements ShouldQueue
{
    use Queueable;
  
    public function __construct(private string $browser)
    {
      //
    }

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

    /**
     * Get the Vonage / SMS representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\VonageMessage
     */
    public function toVonage($notifiable)
    {
        return (new VonageMessage())
            ->content('You have now registered for My Amazing App using '.$this->browser.'!');
    }
}

Notice how we've added a constructor to the notification that accepts a $browser parameter as a string.

We can now update our method call to pass this extra information in like so:

use Jenssegers\Agent\Facades\Agent;

$user->notify(new SuccessfulRegistration(Agent::browser()));

In this particular example, we are using the (jenssegers/agent) package to determine the user's browser. For the purpose of the article, we'll make the assumption that the Agent::browser call returns "Firefox". So, our user should now have received an SMS saying: "You have now registered for My Amazing App using Firefox!"

On-demand Vonage SMS Notifications

There may be times that you want to send notifications to someone that doesn't exist in your database. For example, you might want to send an SMS to yourself everytime someone completes a sign up or purchases something from your website. To do this, we can make use of Laravel's "on-demand notifications".

As an example, let's take a look at how we could send a notification to ourselves. First of all, we'll want to create a new config variable. It's important to remember that you should never hard code credentials, emails, or phone numbers in code as it can pose a security risk if your code is ever compromised (whether that be by a disgruntled ex-employee, or a malicious hacker). This is actually a topic that I'll be covering in more detail in my upcoming ebook Battle Ready Laravel if you're interested in reading more about it.

You should choose the best place to put this field depending on what you're using it for, but in this particular example, I'm going to call it admin_sms_number and I'm just going to place it at the bottom of my config/app.php config file:

return [

    // ...

    'admin_sms_number' => env('ADMIN_SMS_NUMBER'),

    // ...
  
];

We'll then want to add the ADMIN_SMS_NUMBER to our .env file:

ADMIN_SMS_NUMBER=1234567890

We can now write our code to send the notification. We're going to imagine that we've followed the guide above to create a new notification that we've called NewUserRegistered and already has the content set up. We'll also assume that the constructor accepts a parameter with the user's email address. So, we can send the notification like so:

use Illuminate\Support\Facades\Notification;
  
Notification::route('vonage', config('app.admin_sms_number'))
    ->notify(new NewUserRegistered($user->email));

The really nice thing about using on-demand notifications like these are that you can send notifications on multiple channels at once. For example, if we added the functionality to our NewUserRegistered class to send emails, we could extend our above code to also send an SMS and email at the same time:

use Illuminate\Support\Facades\Notification;
  
Notification::route('vonage', config('app.admin_sms_number'))
    ->route('mail', config('app.admin_email_address'))
    ->notify(new NewUserRegistered($user->email));

Using a Different "From" Number or Name

By default, all of the messages will be sent using your VONAGE_SMS_FIELD field that you defined in your .env file. However, there may be times when you're creating your SMS messages that you'll want to change the "from" number or name. For example, let's say that you want to override the "from" number when sending out a specific notification. To do this, you can override the "from" number or name inside the notification class using the from method.

Let's say that we want to set our SuccessfulRegistration notification from above to be sent from "My Awesome App". We could update the toVonage method in the class like so:

public function toVonage($notifiable)
{
  return (new VonageMessage())
      ->from('My Awesome App')
      ->content('You have now registered for My Amazing App');
}

Now, when the user receives the SMS, it should show up as being received from "My Awesome App".

Conclusion

Hopefully, this post should have shown you how you can use Vonage to send SMS messages to your users in your Laravel applications. It should have also given you a quick insight into how you can send on-demand SMS notifications, pass extra information to the SMS, and also change the "from" number on a notification-by-notification basis.

If you enjoyed reading this post, I'd love to hear about it. Likewise, if you have any feedback to improve the future ones, I'd also love to hear that too.

If you're interested in getting updated each time I publish a new post, feel free to sign up for my newsletter.

Keep on building awesome stuff! 🚀

Last updated 3 weeks ago.

driesvints, felixramowda liked this article

2
Like this article? Let the author know and give them a clap!
ash-jc-allen (Ash Allen) I'm a freelance Laravel web developer from Preston, UK. I maintain the Ash Allen Design blog and get to work on loads of cool and exciting projects 🚀

Other articles you might like

Article Hero Image November 18th 2024

Laravel Custom Query Builders Over Scopes

Hello 👋 Alright, let's talk about Query Scopes. They're awesome, they make queries much easier to r...

Read article
Article Hero Image November 19th 2024

Access Laravel before and after running Pest tests

How to access the Laravel ecosystem by simulating the beforeAll and afterAll methods in a Pest test....

Read article
Article Hero Image November 11th 2024

🍣 Sushi — Your Eloquent model driver for other data sources

In Laravel projects, we usually store data in databases, create tables, and run migrations. But not...

Read article

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.