Recevoir gratuitement par SMS les nouvelles de son site : côté serveur Envoyer
Programmation et tuning - Programmation Web
Écrit par Neamar   
Mercredi, 25 Novembre 2009 20:11

Dans le premier article, j'indiquais comment configurer son compte Google pour pouvoir recevoir des notifications par SMS.
Maintenant que cette partie est faite, nous allons pouvoir entrer dans le vif du sujet et commencer à coder ce qui déclenchera l'envoi du rappel par SMS pour vous tenir au courant des mises à jour de votre site.

Je suppose donc que vous avez configuré tout ce qui est décrit dans le premier article "Côté Google", à savoir : un compte Google d'aide, le partage des agendas, et l'ajout des notifications par défaut.

Ok ? Allons-y !

Avant de rentrer dans le vif du sujet, mettons les choses à plat : nous souhaitons juste ajouter des événements dans l'agenda Google. Les événements seront mis avec une date dans le futur de une minute, ce qui déclenchera l'envoi immédiat du SMS de rappel.
Le bon côté des choses, c'est que Google fournit une API toute faite pour manipuler ses données. Le mauvais côté, c'est qu'il s'agit d'une bonne grosse usine à gaz...
Ce qui m'amène à rappeler les conditions :

  • Un serveur web hébergeant PHP 5.2.4 ou supérieur ;
  • Les extensions PHP suivantes : ctype, dom, libxml, spl, standard, openssl (normalement inclues par défaut dans la plupart des configurations, même gratuites).

Et comme on aime bien savoir où on va, voici le plan que je vais suivre :

  1. Télécharger l'API Google ;
  2. Configurer une page du serveur pour utiliser l'API ;
  3. Tester ;
  4. Insertion d'un événement ;
  5. Tester le final.

Rien de bien compliqué, on est parti !

1. Télécharger l'API Google

Rendez-vous sur http://framework.zend.com/download/gdata et téléchargez la dernière version de la librairie. Décompressez le tout, et envoyez l'intégralité du dossier library sur votre FTP (de façon à avoir un chemin du type chemin/vers/library/Zend/, j'insiste sur la présence du library dans l'arborescence.
Et voilà pour la première étape, on a connu pire.

2. Configurer une page du serveur pour utiliser l'API

Comme je le disais (et comme vous avez pu le constater en uploadant les fichiers), l'API est relativement lourde et il ne parait pas utile de l'inclure à chaque fois. Je vous conseille donc de créer une page notifier.php que vous inclurez quand vous souhaiterez communiquer avec Google.

Dans cette page, il va falloir inclure l'ensemble de l'API Google. Pour cela, il faut indiquer au serveur où se trouve la librairie : un peu comme la variable $PATH sous Linux en fait.

 
//1 : régler le chemin vers la librairie Google
$clientLibraryPath = substr(__FILE__,0,strrpos(__FILE__,'/')) . '/library';
set_include_path(get_include_path() . PATH_SEPARATOR . $clientLibraryPath);
 
//2 : charger les librairies
require_once 'Zend/Loader.php';//Adresse connue grâce à l'ajout de la ligne précédente
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
 

ATTENTION, ce code suppose que votre page notifier.php est au même niveau que votre dossier library/. Ajustez le code si nécessaire, mais pensez à utiliser un chemin absolu.

3. Tester

À ce point, Google recommande de tester pour vérifier si votre serveur est vraiment compatible. Collez-donc à la suite de votre code le code suivant (sans le <?php, évidemment) le contenu de cette page.
Vous devriez obtenir le résultat suivant :
Installation de Google API OK
Si ce n'est pas le cas, effectuez les modifications demandées.

4. Insertion d'un événement

Parfait, ne reste plus qu'à insérer un élément. À l'aide de la documentation de Google Calendar, on arrive assez rapidement à créer le code correct que je détaille ici.

4.1. Connexion au compte Google

On touche ici à l'intérêt d'avoir crée un compte helper : il va falloir entrer en clair le mot de passe dans la page. Et pour ce genre de situations, mieux vaut n'offrir au hacker potentiel que votre compte inutile !

 
//3 : connexion
$user='votre@email.fr';
$pass='mdp';
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
 
$client = Zend_Gdata_ClientLogin::getHttpClient($user,$pass,$service);
 

4.2. Insertion de l'élément

Une fois connecté, reste à insérer un élément. On va se servir de la fonction time() qui renvoie le timestamp actuel et de la fonction date() qui permet de formater ce nombre à la manière voulue.
Il faut aussi préciser le fuseau horaire sur lequel on se situe, "+01" en France.

 
//4 : Insertion de l'élément
 
$start=time()+130;
$startDate = date('Y-m-d',$start);//2009-11-23';
$startTime = date('H:i',$start);
 
$tzOffset = '+01';
 
$gdataCal = new Zend_Gdata_Calendar($client);
$newEvent = $gdataCal->newEventEntry();
 
$newEvent->title = $gdataCal->newTitle($notifTitre);
$newEvent->content = $gdataCal->newContent($notifDesc);
 
$when = $gdataCal->newWhen();
$when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
$newEvent->when = array($when);
$event = $gdataCal->insertEvent($newEvent);
 

(Bien évidemment, à vous de régler correctement les variables $notifTitre et $notifDesc qui contiennent respectivement le titre et la description de l'évènement à ajouter.
Précisons que le titre ne doit pas dépasser 60 caractères pour recevoir le SMS valide, et que la description ne sera pas visible dans la notification.
)

Normalement, vous devriez vous demander : pourquoi ce +130 dans le code ?
En fait, il faut ajouter au moins 60 secondes puisque la notification sera déclenchée une minute avant l'évènement : si on mettait la date exacte, le rappel ne serait pas envoyé.
À ces 60 secondes viennent s'ajouter 10 secondes "de latence", qui prennent en compte la possibilité d'un lag du serveur google / de votre serveur / des échanges réseaux : déjà 70 secondes.
Enfin, vous aurez remarqué que la définition de la date se fait sans les secondes : en conséquence, si on en est à 59 secondes de la minute actuelle, on a 59 secondes de retard pour l'évènement... et une nouvelle fois, la notification ne sera pas envoyée car l'évènement n'est pas enregistré assez loin dans le futur. Au final, 60 + 10 + 60 = 130.
J'ajoute que le deuxième 60 n'est pas utile dans tous les cas (en théorie, on pourrait donc faire 130 - date('s')) ; c'est son utilisation qui fait que vous ne recevrez pas instantanément le SMS (latence d'une minute).

5. Tester le final

Je vous conseille d'ajouter tout en haut de votre script la ligne suivante, qui vous permettra de réaliser des tests et aussi de vérifier la cohérence de vos appels :

 
//0 : Avant d'appeler le script, penser à  préciser les variables
//$notifTitre = 'Ttitre';
//$notifDesc='Description';
if(!isset($notifTitre) || !isset($notifDesc))
{
  if(!isset($_GET['test']))
    exit('Paramétres mal spécifiés');
  $notifTitre="(defaut)";
  $notifDesc='';
}
 

Il ne vous reste plus qu'à appeler la page notifier.php?test pour tester votre réalisation... sous 90 secondes, vous devriez recevoir votre SMS. Alors, on dit merci qui ?

Code complet

Pour les fainéants, voici l'intégralité du code :

 
<?php
//0 : Avant d'appeler le script, penser à  préciser les variables
//$notifTitre = 'Ttitre';
//$notifDesc='Description';
if(!isset($notifTitre) || !isset($notifDesc))
{
  if(!isset($_GET['test']))
    exit('Paramétres mal spécifiés');
  $notifTitre="(defaut)";
  $notifDesc='';
}
 
//1 : régler le chemin vers la librairie Google
$clientLibraryPath = substr(__FILE__,0,strrpos(__FILE__,'/')) . '/library';
set_include_path(get_include_path() . PATH_SEPARATOR . $clientLibraryPath);
 
//2 : charger les librairies
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
 
//3 : connexion
$user='votremail.fr';
$pass='mdp';
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
 
$client = Zend_Gdata_ClientLogin::getHttpClient($user,$pass,$service);
 
 
//4 : Insertion de l'élément
 
$start=time() + 60 + 10 + 60 - date('s');
$startDate = date('Y-m-d',$start);//2009-11-23';
$startTime = date('G:i',$start);
 
$tzOffset = '+01';
 
$gdataCal = new Zend_Gdata_Calendar($client);
$newEvent = $gdataCal->newEventEntry();
 
$newEvent->title = $gdataCal->newTitle($notifTitre);
//$newEvent->where = array($gdataCal->newWhere($where));
$newEvent->content = $gdataCal->newContent($notifDesc);
 
$when = $gdataCal->newWhen();
$when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
$newEvent->when = array($when);
 
$event = $gdataCal->insertEvent($newEvent);
 

Je vous laisse connecter cette page avec votre fonction d'ajout d'article / de commentaire : il suffit de régler les deux $notif et d'inclure la page.

Mise à jour le Jeudi, 15 Juillet 2010 08:12
 

Ajouter votre commentaire

Votre nom:
Votre site web:
Sujet:
Commentaire (vous pouvez utiliser de balises HTML ici):
  Code de vérification. Lettres minuscules seulement et sans espace.
Code de vérification:
Commentaires (18)
1Samedi, 19 Juin 2010 11:55
Florian
Salut!

Excellent tutoriel! Très simple et très efficace. Merci beaucoup!

Seulement j'ai un problème : Les évènements s'ajoutent bien dans mon agenda mais il n'y aucun rappel dessus. Alors que quand je passe par "Créer un évènement", le rappel SMS 1 minute avant est bien là.
Comment ajouter un rappel à mon évènement? Existe t-il quelque chose du genre $newEvent -> Reminder = true ?
2Samedi, 19 Juin 2010 12:11
Neamar

Il y a effectivement un mécanisme pour contrôler les rappels, par exemple pour recevoir par SMS une minute avant l'évènement :



 
function setReminder($client, $eventId, $minutes=1)
{
  $gc = new Zend_Gdata_Calendar($client);
  $method = "sms";
  if ($event = getEvent($client, $eventId)) {
    $times = $event->when;
    foreach ($times as $when) {
        $reminder = $gc->newReminder();
        $reminder->setMinutes($minutes);
        $reminder->setMethod($method);
        $when->reminder = array($reminder);
    }
    $eventNew = $event->save();
    return $eventNew;
  } else {
    return null;
  }
}
 


Cependant, si tu as crée un compte dédié pour l'agenda comme je le conseille, il te suffit depuis ton vrai compte gmail d'aller sur les paramètres de l'agenda partagé, et de placer une notification par défaut "SMS - 1 minute avant" : ainsi, tu crées les évènements sans leur associer de rappels et chacune des personnes qui a accès à l'agenda peut contrôler le rappel qu'elle désire : pour Omnilogie, certains ont des SMS, d'autres préfèrent les mails... et les possesseurs d'Android apprécient plus encore les pop-ups !

3Samedi, 19 Juin 2010 13:48
Florian
Merci encore! Ça fonctionne seulement en compte partagé en fait je savais pas.
4Jeudi, 15 Juillet 2010 00:19
dumber
Bonjour, moi ca fonctionnais tres bien et m'etait tres util hors depui aujourd'hui j'ai cette erreur (ce apres 1 jour d'utilisation sans probleme)


Fatal error: Uncaught exception 'Zend_Gdata_App_HttpException' with message 'Expected response code 200, got 400 [Line 1, Column 201, element gd:when] Badly formatted datetime' in /chemin/ZendGdata-1.10.5/library/Zend/Gdata/App.php:700 Stack trace: #0 /chemin/ZendGdata-1.10.5/library/Zend/Gdata.php(219): Zend_Gdata_App->performHttpRequest('POST', 'http://www.goog...', Array, 'performHttpRequest('POST', 'http://www.goog...', Array, 'performHttpRequest('POST', 'http://www.goog...', Array, 'performHttpRequest('POST', 'http://www.goog...', Array, '


une idee ??

merci d'avance
(PS : super tuto)
5Jeudi, 15 Juillet 2010 08:11
Neamar
L'heure doit être sur deux chiffres (avec des zéros initiaux).
J'avais eu le même problème (moins explicite à l'époque ;)), mais j'ai oublié de mettre à jour l'article.

Remplace :
 
$startTime = date('G:i',$start);
 


Par :
 
$startTime = date('H:i',$start);
 
6Jeudi, 15 Juillet 2010 12:30
dumber
Merci pour ta solution Neamar et pour ce super tuto ^^
7Lundi, 19 Juillet 2010 15:31
Anto
Bonjour,
Je voudrais savoir si je peux utiliser cette solution pour mon serveur de jeu qui est hebergé chez un hebergeur de serveurs de jeux.
Est-ce possible ?
Merci de votre réponse.
8Lundi, 19 Juillet 2010 15:43
Neamar
Je ne suis pas sur d'avoir compris ta question...
Si tu peux écrire du PHP, oui tu devrais pouvoir si tu n'es pas en safe_mode sans aucune autorisation vers l'extérieur.

Bref, le plus simple c'est de tester :)
9Lundi, 19 Juillet 2010 15:57
Anto
Bonjour,
Je vais éxpliquer en détails, le fonctionnement de mon serveur:
J'ai créé un serveur de jeu, ce serveur est hebergé par un hebergeur, cet hebergeur loue un serveur dédié.
Donc nous sommes plusieurs a profiter de ça.
Je voulais savoir si en mettant ce truc dans les dossier de mon serveur de jeu, serait-il possible de pouvoir mettre en place ce systéme pour que je puisse recevoir par sms des notifications de mon serveur de jeu, genre reçevoir une notification lorsqu'un joueur est banni sur le serveur, lorsque le serveur se ferme, lorsqu'il y a un bug dessus,...

Bref, je voulais juste savoir ça.
Merci
10Lundi, 19 Juillet 2010 16:35
Neamar
Bien sûr, c'est toujours la même chose. Il suffit de faire une fonction à appeler au bon moment ;)
11Mardi, 20 Juillet 2010 12:50
Anto
Salut,
Est-il possible d'utiliser ce dispositif avec 2 comptes GOOGLE ou + ?
Parce que j'aimerais qu'une personne en + de moi reçoive un sms.
Merci de votre aide.
12Mardi, 20 Juillet 2010 12:52
Neamar
Bien sûr !
Depuis le compte principal, il suffit de partager l'agenda avec toutes les autres personnes qui peuvent en bénéficier.

C'est ce que je fais sur Omnilogie : tous les administrateurs peuvent configurer leurs notifications de cette façon. Il suffit d'ajouter le compte google d'un nouvel admin pour qu'il puisse lui aussi recevoir ses rappels :)
13Mardi, 20 Juillet 2010 13:08
Anto
Mais ce que tu apelles "Compte principal", c'est le lien qui est donné en 1er, pas celui là: www.google.com/calendar ?
14Mardi, 20 Juillet 2010 13:12
Neamar
Le compte principal, c'est le comtpe gmail auquel tu te connectes depuis le script (celui que tu as mis dans $user et $pass).
Avec ce compte, tu te connectes à google.com/calendar, puis dans les options de partage de l'agenda tu ajoutes tout ceux qui peuvent l'utiliser.
15Mardi, 20 Juillet 2010 13:19
Anto
Et je ne voit pas a quoi ça sert de creer un compte sur ça : https://www.google.com/accounts/NewAccount?hl=fr
Peux-tu me l'éxpliquer ?
Autant creer une adresse mail sur google Mail, non ?
Réponse de l'administrateur :
Mardi, 20 Juillet 2010 13:20
Neamar
Un compte Gmail est un compte Google.
16Mardi, 20 Juillet 2010 13:30
Anto
Oui mais je n'ai pas compris l'intérêt de creer un compte sur ce site.
Il nous sert à creer compte pour utiliser l'agenda ?
Oui mais on ne peut pas utiliser l'agenda avec un compte Google (Gmail) ?
Réponse de l'administrateur :
Mardi, 20 Juillet 2010 13:32
Neamar
Oui, il sert à créer un compte pour utiliser l'agenda.
Oui tu peux utiliser un compte Gmail.

Mais je te déconseille d'utiliser ton vrai comtpe, d'abord parce que niveau notification c'est plus compliqué, mais aussi parce que ça t'obligerait à mettre en clair tes login / mdp dans un script.

Maintenant, je t'engage à faire des tests avant de vouloir trop en faire...
17Mardi, 20 Juillet 2010 13:37
Anto
Oui donc, tu me conseillerais d'utiliser quoi comme compte, mon adresse mail actuelle, ou creer un compte chez Gmail et l'utiliser dans le script ?
De +, il éxiste "MD5", ce qui permet de hacker le mot de passe.
Donc pas de soucis.
Réponse de l'administrateur :
Mardi, 20 Juillet 2010 13:39
Neamar
Créer un compte Google.

Et md5 ne va pas hacker ton mot de passe, mais le hasher.
Ensuite, tu en feras quoi ? Il faut bien qu'à un moment ou un autre tu l'envoies aux serveurs de Google...

Et md5 est déconseillé maintenant, l'avenir c'est sha1 !
18Mardi, 20 Juillet 2010 13:43
Anto
Oui je me suis trompé de lettre =S, j'ai mis un C a la place du S,
Donc je peut utiliser le Sha1.
Merci de ton aide