À un moment donné, dans le workflow de votre application, vous devrez peut-être transmettre des informations importantes à vos utilisateurs. À cette fin, grâce aux progrès des technologies Web, vous pouvez utiliser des notifications push. Cependant, la plupart de ces services exigent que vos utilisateurs disposent d'une connexion Internet et malheureusement, ce n'est pas toujours le cas. Heureusement, nous pouvons surmonter ce problème en utilisant un système de notification qui ne dépend pas d'Internet.
Dans ce tutoriel, vous découvrirez comment utiliser L'API Programmable SMS de Twilio pour créer un portail de notification SMS à l'aide de Laravel. À la fin de ce tutoriel, vous aurez développé un portail de notification SMS personnalisé permettant d'avertir vos utilisateurs via un tableau de bord par SMS.
Conditions préalables
Pour suivre ce tutoriel, vous avez besoin des éléments ci-dessous :
- Connaissances de base en Laravel
- Laravel installé sur votre machine locale
- Composer installé globalement
- MySQL configuré sur votre machine locale
- Compte Twilio
Configuration du projet
En premier lieu, nous devons créer un nouveau projet Laravel, soit avec le programme d'installation Laravel, soit avec Composer. Dans ce tutoriel, nous allons utiliser le programme d'installation Laravel. Si vous ne l'avez pas installé, consultez la documentation Laravel pour savoir comment procéder. Pour générer un nouveau projet Laravel, exécutez la commande suivante dans votre terminal :
$ laravel new sms-portal
Ensuite, remplacez votre répertoire de travail par sms-portal
et installez le SDK Twilio via Composer :
$ cd sms-portal
$ composer require twilio/sdk
Si Composer n'est pas installé sur votre PC, installez-le selon les instructions indiquées ici.
Après avoir installé le SDK PHP Twilio, nous devons obtenir nos identifiants Twilio à partir du tableau de bord Twilio. Rendez-vous sur votre tableau de bord et récupérez les éléments account_sid
et auth_token
.
Accédez maintenant à la section réservée au numéro de téléphone pour obtenir votre numéro de téléphone compatible avec les SMS.
L'étape suivante consiste à mettre à jour le fichier .env
avec nos identifiants Twilio. Ouvrez le fichier .env
situé à la racine du répertoire du projet et ajoutez ces valeurs :
TWILIO_SID="INSERT YOUR TWILIO SID HERE"
TWILIO_AUTH_TOKEN="INSERT YOUR TWILIO TOKEN HERE"
TWILIO_NUMBER="INSERT YOUR TWILIO NUMBER IN [E.164] FORMAT"
Configuration d'une base de données
Maintenant que nous avons un projet de base de Laravel avec le SDK Twilio, créons notre base de données. Si vous utilisez une application GUI comme phpMyAdmin pour gérer votre base de données, créez une base de données nommée sms_portal
et ignorez cette section. Si ce n'est pas le cas, si vous n'avez pas d'outil équivalent et si MySQL n'est pas installé, téléchargez MySQL depuis le site officiel pour votre système d’exploitation.
Lancez le terminal et exécutez cette commande pour vous connecter à MySQL :
$ mysql -u {your_user_name}
REMARQUE : ajoutez l'indicateur -p
si vous avez un mot de passe pour votre instance MySQL.
Une fois la connexion établie, exécutez la commande suivante pour créer une nouvelle base de données :
mysql> create database sms_portal;
mysql> exit;
Ensuite, nous allons modifier la configuration de notre base de données en conséquence dans le fichier .env
à la racine du dossier de ce projet.
DB_DATABASE=sms_portal
DB_USERNAME=root
DB_PASSWORD=
Création d'une migration
Maintenant que nous avons une base de données, nous allons créer une migration de base de données. Pour ce faire, il suffit d'exécuter cette commande dans notre terminal :
$ php artisan make:migration create_users_phone_number_table
Cela génère un fichier de migration {current_time_stamp}_create_users_phone_number_table
dans le répertoire /database/migrations
.
Maintenant, ouvrez le dossier du projet dans votre éditeur de texte/IDE favori pour commencer à apporter les modifications nécessaires. Ouvrez le fichier de migration que nous venons de créer. Le contenu doit être identique à celui-ci :
Nous devons ajouter au tableau la colonne phone_number
. Pour ce faire, modifiez la méthode up()
comme suit :
public function up() {
Schema::create('users_phone_number', function (Blueprint $table) {
$table->increments('id');
$table->string('phone_number');
$table->timestamps();
});
}
Notre fichier de migration est maintenant prêt à être migré. Pour effectuer la migration, il suffit d'exécuter la commande suivante dans le terminal :
$ php artisan migrate
La sortie doit ressembler à ce qui suit :
Création de l'interface utilisateur
À ce stade, nous avons configuré le projet. Il est temps de construire une interface utilisateur simple pour ajouter des données à notre base de données et pour envoyer des notifications SMS.
Ouvrez /resources/views/welcome.blade.php
et apportez les modifications suivantes au bloc <head>
.
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SMS Portal With Twilio</title>
<!-- Bootstrap styles CDN -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
Nous avons simplement supprimé le style initial de la page et ajouté Bootstrap à l'aide de BootstrapCDN pour simplifier le style. Nous allons ensuite créer deux formulaires sur la page. Un formulaire pour enregistrer le numéro de téléphone des utilisateurs, et l'autre pour envoyer des messages de notification personnalisés aux utilisateurs sélectionnés. Apportez les modifications suivantes au bloc body
.
<body>
<div class="container">
<div class="jumbotron">
<div class="row">
<div class="col">
<div class="card">
<div class="card-header">
Add Phone Number
</div>
<div class="card-body">
<form>
<div class="form-group">
<label>Enter Phone Number</label>
<input type="tel" class="form-control" placeholder="Enter Phone Number">
</div>
<button type="submit" class="btn btn-primary">Register User</button>
</form>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-header">
Send SMS message
</div>
<div class="card-body">
<form>
<div class="form-group">
<label>Select users to notify</label>
<select multiple class="form-control">
@foreach ($users as $user)
<option>{{$user->phone_number}}</option>
@endforeach
</select>
</div>
<div class="form-group">
<label>Notification Message</label>
<textarea class="form-control" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">Send Notification</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
Si vous examinez de plus près le code ci-dessus, vous remarquerez que nous avons ceci :
<select multiple class="form-control">
@foreach ($users as $user)
<option>{{$user->phone_number}}</option>
@endforeach
</select>
Ce fragment de code permet de générer un champ d'option pour chaque numéro de téléphone utilisateur disponible renvoyé avec cette vue. Nous mettrons en œuvre cette fonctionnalité par la suite.
Stockage du numéro de téléphone des utilisateurs
Premièrement, créons un modèle exploitable pour interroger et insérer des enregistrements dans la base de données. Lancez le terminal dans le répertoire du projet et exécutez cette commande :
$ php artisan make:model UsersPhoneNumber
Ouvrez le fichier créé dans app/UsersPhoneNumber.php
et ajoutez le code ci-dessous :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UsersPhoneNumber extends Model
{
protected $table= "users_phone_number";
protected $fillable = [
'phone_number'
];
}
REMARQUE : voici quelques points à prendre en compte :
- L'ajout de
protected $table= "users_phone_number";
indique à Eloquent le nom de la table à utiliser. Sans ce paramètre, le nom au pluriel de la classe sera utilisé comme nom de table. - L'ajout de
protected $fillable
indique à Eloquent de rendre le champ attribuable en masse (pour en savoir plus, cliquez sur le lien ci-dessus).
L'étape suivante consiste à créer le contrôleur où nous allons mettre en œuvre la logique nécessaire pour le routage de chaque requête. Une fois de plus, lancez le terminal et exécutez la commande ci-dessous :
$ php artisan make:controller HomeController
Cela génère un fichier de contrôleur dans app/Http/Controllers/HomeController.php
avec le contenu indiqué ci-dessous :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
//
}
Création de la méthode d'enregistrement de numéro de téléphone
Nous allons créer une fonction qui instancie un nouveau modèle UsersPhoneNumber
avec les données transmises par le corps de la requête :
<?php
/**
* Store a new user phone number.
*
* @param Request $request
* @return Response
*/
public function storePhoneNumber(Request $request)
{
//run validation on data sent in
$validatedData = $request->validate([
'phone_number' => 'required|unique:users_phone_number|numeric'
]);
$user_phone_number_model = new UsersPhoneNumber($request->all());
$user_phone_number_model->save();
return back()->with(['success'=>"{$request->phone_number} registered"]);
}
Avec le code ci-dessus, nous exécutons une validation des données transmises par le corps $request
avant de créer une nouvelle instance de UsersPhoneNumber
. Après avoir enregistré le numéro de téléphone des utilisateurs, nous sommes redirigés vers la page d'accueil avec un message de succès qui s'affiche rapidement (flash) dans la session.
Renvoi d'une vue avec les numéros de téléphone des utilisateurs
Nous devons maintenant renvoyer une vue avec les données des numéros de téléphone enregistrés. Nous allons écrire une fonction simple dans le HomeController qui interroge la table users_phone_number
et renvoie les résultats de la requête dans la vue :
<?php
/**
* Show the forms with users phone number details.
*
* @return Response
*/
public function show()
{
$users = UsersPhoneNumber::all(); //query db with model
return view('welcome', compact("users")); //return view with data
}
REMARQUE : compact() est une fonction PHP qui permet de créer un tableau avec des noms de variables et leurs valeurs.
Envoi de messages avec Programmable SMS de Twilio
Prochaine étape : mettre en œuvre l'envoi de SMS à l'aide de la bibliothèque Programmable SMS de Twilio. Créez une fonction privée dans le HomeController servant de fonction d'aide à l'envoi de messages :
<?php
/**
* Sends sms to user using Twilio's programmable sms client
* @param String $message Body of sms
* @param Number $recipients string or array of phone number of recepient
*/
private function sendMessage($message, $recipients)
{
$account_sid = getenv("TWILIO_SID");
$auth_token = getenv("TWILIO_AUTH_TOKEN");
$twilio_number = getenv("TWILIO_NUMBER");
$client = new Client($account_sid, $auth_token);
$client->messages->create($recipients,
['from' => $twilio_number, 'body' => $message] );
}
La fonction reçoit deux paramètres : $message
et $recipients
. Nous récupérons ensuite nos identifiants Twilio stockés dans les variables d'environnement à l'aide de la fonction PHP getenv() intégrée, après quoi nous instancions un nouveau client Twilio avec les identifiants. Nous pouvons maintenant envoyer le SMS en appelant :
$client->messages->create($recipients, [
'from' => $twilio_number,
'body' => $message
]);
La fonction messages->create()
de Twilio assimile deux paramètres d'un récepteur du message et un tableau avec les propriétés from
et body
, où from
correspond à votre numéro de téléphone Twilio actif.
Envoi d'une notification utilisateur après l'enregistrement
À présent, nous avons terminé la fonction sendMessage()
que nous utiliserons pour envoyer des messages aux utilisateurs. Nous allons mettre à jour la fonction storePhoneNumber()
de sorte à avertir les utilisateurs une fois qu'ils ont été enregistrés avec succès. Pour ce faire, apportez les modifications suivantes à la fonction storePhoneNumber()
:
<?php
/**
* Store a new user phone number.
*
* @param Request $request
* @return Response
*/
public function storePhoneNumber(Request $request)
{
//run validation on data sent in
$validatedData = $request->validate([
'phone_number' => 'required|unique:users_phone_number|numeric',
]);
$user_phone_number_model = new UsersPhoneNumber($request->all());
$user_phone_number_model->save();
$this->sendMessage('User registration successful!!', $request->phone_number);
return back()->with(['success' => "{$request->phone_number} registered"]);
}
Super ! Maintenant, chaque fois que le numéro de téléphone d'un utilisateur est ajouté à notre base de données, nous pouvons envoyer à ce dernier un message de notification l'informant de l'action qui a été effectuée.
Envoi de notifications personnalisées
Ensuite, nous allons écrire une fonction permettant d'envoyer des messages personnalisés à certains utilisateurs. Ajoutez le code ci-dessous à HomeController
:
<?php
/**
* Send message to a selected users
*/
public function sendCustomMessage(Request $request)
{
$validatedData = $request->validate([
'users' => 'required|array',
'body' => 'required',
]);
$recipients = $validatedData["users"];
// iterate over the array of recipients and send a twilio request for each
foreach ($recipients as $recipient) {
$this->sendMessage($validatedData["body"], $recipient);
}
return back()->with(['success' => "Messages on their way!"]);
}
Cette fonction transmet les données validées du corps $request
vers la variable $validatedData
, ce qui nous permet d'effectuer une itération sur le tableau de $validatedData[users]
et d'envoyer à chaque utilisateur le message reçu à partir de $validatedData["body"]
. Ensuite, nous redirigeons vers la page d'accueil avec un message qui s'affiche rapidement dans la session.
Création du routage
Nous avons créé les fonctions de contrôleur. Ajoutons maintenant des routes à l'application. Ouvrez routes/web.php
et apportez les modifications suivantes :
<?php
Route::get('/', 'HomeController@show');
Route::post('/', 'HomeController@storePhoneNumber');
Route::post('/custom', 'HomeController@sendCustomMessage');
Mise à jour du champ de formulaire avec les routes
Ensuite, accédez à resources/views/welcome.blade.php
et apportez les modifications suivantes au champ de formulaire :
//add the method attribute to the Register User form
// also add the name attributes to the input field
<form method="POST">
@csrf
<div class="form-group">
<label>Enter Phone Number</label>
<input type="tel" class="form-control" name="phone_number" placeholder="Enter Phone Number">
</div>
<button type="submit" class="btn btn-primary">Register User</button>
</form>
et
//add the method and action attributes to the Send custom message form
// also add the name attributes to the input fields
<form method="POST" action="/custom">
@csrf
<div class="form-group">
<label>Select users to notify</label>
<select name="users[]" multiple class="form-control">
@foreach ($users as $user)
<option>{{$user->phone_number}}</option>
@endforeach
</select>
</div>
<div class="form-group">
<label>Notification Message</label>
<textarea name="body" class="form-control" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">Send Notification</button>
</form>
Test du code
Regroupons l'ensemble du code que nous avons créé jusqu'à présent. À ce stade, HomeController.php
devrait ressembler à ceci :
<?php
namespace App\Http\Controllers;
use App\UsersPhoneNumber;
use Illuminate\Http\Request;
use Twilio\Rest\Client;
class HomeController extends Controller
{
/**
* Show the forms with users phone number details.
*
* @return Response
*/
public function show()
{
$users = UsersPhoneNumber::all();
return view('welcome', compact("users"));
}
/**
* Store a new user phone number.
*
* @param Request $request
* @return Response
*/
public function storePhoneNumber(Request $request)
{
//run validation on data sent in
$validatedData = $request->validate([
'phone_number' => 'required|unique:users_phone_number|numeric',
]);
$user_phone_number_model = new UsersPhoneNumber($request->all());
$user_phone_number_model->save();
$this->sendMessage('User registration successful!!', $request->phone_number);
return back()->with(['success' => "{$request->phone_number} registered"]);
}
/**
* Send message to a selected users
*/
public function sendCustomMessage(Request $request)
{
$validatedData = $request->validate([
'users' => 'required|array',
'body' => 'required',
]);
$recipients = $validatedData["users"];
// iterate over the array of recipients and send a twilio request for each
foreach ($recipients as $recipient) {
$this->sendMessage($validatedData["body"], $recipient);
}
return back()->with(['success' => "Messages on their way!"]);
}
/**
* Sends sms to user using Twilio's programmable sms client
* @param String $message Body of sms
* @param Number $recipients Number of recipient
*/
private function sendMessage($message, $recipients)
{
$account_sid = getenv("TWILIO_SID");
$auth_token = getenv("TWILIO_AUTH_TOKEN");
$twilio_number = getenv("TWILIO_NUMBER");
$client = new Client($account_sid, $auth_token);
$client->messages->create($recipients, ['from' => $twilio_number, 'body' => $message]);
}
}
et de notre côté, welcome.blade.php
devrait ressembler à ceci :
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SMS Portal With Twilio</title>
<!-- Styles -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="jumbotron">
@if (session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="row">
<div class="col">
<div class="card">
<div class="card-header">
Add Phone Number
</div>
<div class="card-body">
<form method="POST">
@csrf
<div class="form-group">
<label>Enter Phone Number</label>
<input type="tel" class="form-control" name="phone_number" placeholder="Enter Phone Number">
</div>
<button type="submit" class="btn btn-primary">Register User</button>
</form>
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-header">
Send SMS message
</div>
<div class="card-body">
<form method="POST" action="/custom">
@csrf
<div class="form-group">
<label>Select users to notify</label>
<select name="users[]" multiple class="form-control">
@foreach ($users as $user)
<option>{{$user->phone_number}}</option>
@endforeach
</select>
</div>
<div class="form-group">
<label>Notification Message</label>
<textarea name="body" class="form-control" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">Send Notification</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Si votre code est identique, vous pouvez continuer. Si ce n'est pas le cas, vérifiez le code pour savoir ce qui manque.
Exécution de l'application
Ouvrez votre terminal, accédez au répertoire du projet et exécutez la commande suivante :
$ php artisan serve
Cela mettra en service votre application Laravel sur un port localhost, généralement le port 8000
. Ouvrez le lien localhost qui s'imprime après avoir exécuté la commande dans votre navigateur. La page d'accueil devrait ressembler à ceci :
Enregistrez un nouveau numéro de téléphone. Si tout se passe bien, vous devriez recevoir sous peu un SMS vous informant de votre enregistrement.
Vous pouvez aussi tester l'envoi de notifications personnalisées en sélectionnant un ou plusieurs utilisateurs dans le champ correspondant et en saisissant le texte à envoyer aux utilisateurs sélectionnés dans la zone de texte. Lorsque vous avez terminé, cliquez sur le bouton d'envoi de notification pour recevoir un SMS contenant le message de notification personnalisé.
Conclusion
Maintenant que vous avez terminé ce tutoriel, vous devriez être en mesure d'intégrer les SMS programmables Twilio dans votre application Laravel et d'envoyer des messages de notification par SMS. Si vous souhaitez consulter le code source complet de ce tutoriel, rendez-vous sur Github.
Pour aller plus loin, permettez à vos utilisateurs d'effectuer des actions à partir des notifications qui leur sont envoyées par SMS.
Je serais ravi de répondre à toutes vos questions concernant ce tutoriel. Vous pouvez me contacter via les canaux suivants :
- Adresse e-mail : brian.iyoha@gmail.com
- Twitter : thecodearcher
- GitHub :thecodearcher