1- Introduction

Nous avons vu dans un ancien tutoriel comment envoyer des SMS. Recevoir des SMS sur son application est tout aussi simple !

Dans ce tutoriel nous allons voir comment faire.

2- Recevoir des SMS, quel intérêt ?

Le SMS est un moyen de communication très accessible et facile à utiliser. Pouvoir déclencher des actions sur votre site depuis votre téléphone peut vous faire gagner du temps et éviter d'avoir à courir apès un cybercafe.

Cela peut également permettre d'ajouter une valeur ajoutée à votre site, en développant divers petits services comme par exemple l'ajout d'article à son blog par SMS.

Dans ce tutoriel nous allons créer un petit service de prévision méteo dans les principales villes françaises, en utilisant l'API Yahoo! Weather. Si un utilisateur mobile nous envoie un SMS du type "Météo Paris", notre application lui renvoie les prévisions méteo de Paris.

Vous trouverez certainement des idées de service beaucoup plus intéressants, le but de cet exemple est juste de montrer comment faire.

3- La différence entre SMS MO & SMS MT

Avant de commencer, deux abbréviations sont souvent utilisées dans le monde du SMS :

MO
  Mobile Originated - sont les messages qui proviennent d'un mobile,
  MO = Un utilisateur mobile envoie un SMS vers notre application.

MT
  Mobile Terminated - sont les messages qui vont vers un mobile,
  MT = Notre application envoie un SMS à un utilisateur mobile.

4- Recevoir les SMS-MO

Le numéro de réception

Avant de recevoir des SMS-MO, il faut tout d'abord avoir accès à un numéro de réception, auquel les utilisateurs mobile peuvent envoyer leur message SMS.

Il est possible d'utiliser les commandes AT, avec un mobile ou modem GSM, mais c'est compliqué et ne permet pas de recevoir un gros volume de SMS.

Il est préférable de louer un numéro court auprès d'un prestataire de services SMS, en général partagé (et donc utilisé avec un mot clef). Dans la suite de ce tutorial, on utilisera un numéro court français de la passerelle de SMS TM4B.

Comment ça fonctionne ?

Quand un utilisateur mobile envoie un SMS à notre numéro court, l'opérateur mobile le transmet à notre prestataire de service qui nous l'envoie ensuite dans le protocole souhaité (SMTP, SMPP ou HTTP). 

Dans ce tutorial, nous utiliserons le protocole HTTP, qui est le plus facile à utiliser. Il faut simplement savoir quels paramètres on reçoit, les récupérer en GET, puis interpréter le texte du SMS.

La requête MO.

Pour notre simple application, 3 paramètres sont utiles:

  • from: Le numéro de téléphone à partir duquel le SMS a été envoyé
  • msg: Le texte du SMS
  • to: Le numéro court auquel le SMS a été envoyé

NB: Il y a plus de paramètres disponibles, mais ils ne sont utiles que dans des applications plus sophistiquées.

5- Interpréter le SMS-MO

Recevoir le SMS-MO

Commençons par vérifier que les paramètres transmis sont les bons, on commence par un script PHP de 2 lignes:

echo "<pre>";
print_r($_GET);

On peut simuler la réception d'un SMS en appelant notre script avec les paramètres suivants: 

?from=33612345678&msg=Météo+Paris&to=31589

Le script renvoie ainsi le résultat suivant...

Array
(
[msg] => Météo Paris
[to] => 31589
[from] => 33612345678
)

Extraire les mots-clefs

A l'exception de quelques services, les mots-clefs ont un rôle important dans les services MO. Dans notre exemple, nous avons 2 mots-clef:

  1. Le mot clef Météo, qui correspond au service météo
  2. La ville
Nos mots-clef sont séparés par un espace.
$Keywords = explode(" ", $_GET[msg]);

En pratique, il faudra améliorer le script, en gérant par exemple les villes avec des espaces.

6- Interroger l'API Yahoo!

Maintenant que nous avons découpé les mots, nous connaissons la ville dont l'utilisateur mobile veut la météo. Il ne reste plus qu'à interroger l'API Yahoo!

Préparer la requête

Selon l'API météo Yahoo!, on récupère la méteo d'une ville en appelant une URL avec un identifiant de ville. On commence donc par paramétrer l'identifiant de ville...

switch(strtoupper($Keywords[1]))
{
case "BORDEAUX": $LocationID = "FRXX0016";
case "LYON": $LocationID = "FRXX0055";
case "PARIS": $LocationID = "FRXX0076";
//...
}

Pour rester simple, notre script gère uniquement Paris, Bordeaux & Lyon. Pour gérer plus de villes, une liste complète des villes françaises est diponible dans la section France Weather du site Yahoo! Weather.

Interroger Yahoo! Weather

Si l'utilisateur a saisi une ville supportée, on interroge l'API Yahoo!

if($LocationID)
{
// Creation de l'URL
$YahooURI = "http://weather.yahooapis.com/forecastrss?p=$LocationID&u=c";

// Interrogation de l'API Yahoo Weather
$YahooResponse = file_get_contents($YahooURI);
// Si allow_url_fopen est off dans votre php.ini, il faut utiliser CURL
}

Analyser la réponse Yahoo! Weather

La réponse de Yahoo est complète et facile à comprendre. Pour notre service de test, on  se contentera d'utiliser leur description en HTML pout éviter d'analyser tout le XML.

if($YahooResponse)
{
preg_match_all("#(.+)<\/description>#Uis", $YahooResponse, $Matches);
$Forecast = trim(strip_tags($Matches[1][1]));
$Forecast = str_replace("\t", "", $Forecast);
while(strstr($Forecast, "\n ")) $Forecast = str_replace("\n ", "\n", $Forecast);
$ForecastArray = explode("\n\n", $Forecast);
$Forecast = "Weather for $Keywords[1]\n".$ForecastArray[0];
}

7 - Envoyer un SMS de réponse

Préparer le SMS-MT

Quelques tests de cas d'erreur...

  1. Si l'utilisateur mobile a oublié de spécifier une ville, on lui indique.
  2. Si l'utilisateur mobile a spécifié une ville non supportée, on lui indique.
  3. Sinon, si tout va bien, on lui donne le temps prévu.
  4. Sinon, si Yahoo! est HS, on s'excuse.
if(!$LocationID)
{
if($Keywords[1]) $OurResponse = "Désolé $Keywords[1] n'est pas supportée! Pour une liste des villes supportées, veuillez visiter http://weather.yahoo.com/regional/FRXX.html.";
else $OurResponse = "Veuillez spécifier une ville.";
}
elseif($Forecast) $OurResponse = $Forecast;
else $OurResponse = "Le service Météo est actuellement indisponible, veuillez re-essayer ultérieurement";

Envoyer le SMS-MT de réponse

Si vous n'avez pas lu le tutorial sur l'envoi SMS:

// Préparation de la requête - Détails ici: http://www.tm4bhelp.com/kb/v-119.php
$Param['username'] = 'username';
$Param['password'] = 'password';
$Param['type'] = 'broadcast';
$Param['msg'] = $OurResponse;
$Param['to'] = $_GET['from'];
$Param['from'] = $_GET['to'];
$Param['route'] = 'GD01';
$Param['version'] = '2.1';
foreach($Param as $Key => $Value) $Request .= $Key.'='.urlencode($Value)."&";

// Appel de l'API SMS
$SP_Response = file_get_contents("http://www.tm4b.com/client/api/http.php?$Request");

// Recuperation broadcastID
if(!strstr($SP_Response, "broadcastID")) echo $SR_Response;
else
{
preg_match("/([^<]*)<\/broadcastID>/i", $SP_Response, $Matches);
echo "BroadcastID = $Matches[1]";
}

8 - Conclusion

Voilà! Vous avez mis en place une application de réception et envoi SMS en PHP.

Beaucoup de choses peuvent être améliorées. On peut par exemple utiliser le composant Yahoo weather d'Arash Hemmat pour parser le XML Yahoo!. On peut également améliorer l'analyse des mots clef, et faire une meilleure utilisation des expressions régulières.

  1. <?php
  2.  
  3. echo "<pre>";
  4. print_r($_GET);
  5.  
  6. /*extraire les mots clef
  7. -----------------------------------------------------------------*/
  8. $Keywords = explode(" ", $_GET[msg]);
  9.  
  10. /*Interroger l'API Yahoo! Weather
  11. -----------------------------------------------------------------*/
  12. //Identification du Location ID
  13. switch(strtoupper($Keywords[1]))
  14. {
  15. case "BORDEAUX": $LocationID = "FRXX0016";
  16. case "LYON": $LocationID = "FRXX0055";
  17. case "PARIS": $LocationID = "FRXX0076";
  18. }
  19.  
  20. //Si la ville est ok, on appelle Yahoo!
  21. if($LocationID)
  22. {
  23. //Creation de l'url
  24. $YahooURI = "http://weather.yahooapis.com/forecastrss?p=$LocationID&u=c";
  25.  
  26. //Appel API Yahoo Weather
  27. $YahooResponse = file_get_contents($YahooURI); #If allow_url_fopen is off in your php.ini, you'll have to use cUrl
  28. }
  29.  
  30. //Si on a une reponse, on l'analyse
  31. if($YahooResponse)
  32. {
  33. preg_match_all("#<description>(.+)<\/description>#Uis", $YahooResponse, $Matches);
  34. $Forecast = trim(strip_tags($Matches[1][1]));
  35. $Forecast = str_replace("\t", "", $Forecast);
  36. while(strstr($Forecast, "\n ")) $Forecast = str_replace("\n ", "\n", $Forecast);
  37. $ForecastArray = explode("\n\n", $Forecast);
  38. $Forecast = "Weather for $Keywords[1]\n".$ForecastArray[0];
  39. }
  40.  
  41. /* SMS de reponse
  42. -----------------------------------------------------------------*/
  43. if(!$LocationID)
  44. {
  45. if($Keywords[1]) $OurResponse = "Sorry, we don't support $Keywords[1]! For supported locations, visit http://weather.yahoo.com/regional/FRXX.html.";
  46. else $OurResponse = "It looks like you forgot to include a location. Please try again with a location.";
  47. }
  48. elseif($Forecast) $OurResponse = $Forecast;
  49. else $OurResponse = "Sorry, but the service is down. Please try again later.";
  50.  
  51.  
  52. /* Envoi du SMS
  53. -----------------------------------------------------------------*/
  54. //Preparation de la requete. Détails @ http://www.tm4bhelp.com/kb/v-119.php
  55. $Param['username'] = 'username';
  56. $Param['password'] = 'password';
  57. $Param['type'] = 'broadcast';
  58. $Param['msg'] = $OurResponse;
  59. $Param['to'] = $_GET[from];
  60. $Param['from'] = $_GET[to];
  61. $Param['route'] = 'GD01';
  62. $Param['version'] = '2.1';
  63. foreach($Param as $Key => $Value) $Request .= $Key.'='.urlencode($Value)."&";
  64.  
  65. //Appel de l'API SMS
  66. $SP_Response = file_get_contents("http://www.tm4b.com/client/api/http.php?$Request");
  67.  
  68. //Recuperation id envoi
  69. if(!strstr($SP_Response, "broadcastID")) echo $SR_Response;
  70. else
  71. {
  72. preg_match("/<broadcastID>([^<]*)<\/broadcastID>/i", $SP_Response, $Matches);
  73. echo "BroadcastID = $Matches[1]";
  74. }
  75. ?>

Tutorial écrit par Walid