Send an SMS in Laravel Using Vonage
Tags: webdev, laravel, php
Published: 2022-06-30 11:29:27

## 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](https://www.vonage.co.uk/) or [Twilio](https://www.twilio.com/)) 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](https://www.vonage.co.uk/communications-apis/). 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](https://github.com/laravel/vonage-notification-channel) (`laravel/vonage-notification-channel`) using the following command:

```text
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:

```text
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:

```php
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:

```text
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:

```php
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](https://ashallendesign.co.uk/blog/6-quick-and-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:

```php
$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](https://ashallendesign.co.uk/blog/getting-the-user-device-browser-and-os-in-laravel). We'll then want to update our notification class to accept this information like so:

```php
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:

```php
use Jenssegers\Agent\Facades\Agent;

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

In this particular example, we are using the ([jenssegers/agent](https://github.com/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](https://battle-ready-laravel.com/) 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:

```php
return [

    // ...

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

    // ...
  
];
```

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

```php
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:

```php
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:

```php
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:

```php
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](https://ashallendesign.co.uk).

Keep on building awesome stuff! 🚀