Envoyer un SMS depuis Gmail via Freemobile

Si vous avez un peu suivie l'actualité de FreeMobile de ces derniers jours, vous savez certainement que Free a ajouté une option qui permet de recevoir des sms gratuitement sur votre ligne freemobile en appelant une simple URL.

Pour mes besoins, j'ai pondu un petit script Google qui vous permettra de faire la liaison entre Gmail et ce nouveau service. Autrement dit, à chaque fois que vous recevrez un mail correspondant à un libellé précis, vous recevrez automatiquement un SMS sur votre mobile.

Mais pourquoi ?

Pourquoi s’embêter à recevoir des alertes par sms alors qu'on peut les recevoir direct par mail ?

-vous n'avez pas de forfait internet (forfait 2€ de Free)
-vous n'avez pas de "smartphone" (téléphone de boulot, téléphone de secours, ...)
-domotique via SMS
-etc ...

Comment activer votre service de notifications SMS ?

image-2-300x265

Le principe est simple, activez l'option gratuite dans votre espace abonné, rendez-vous dans vos options et activez les "Notifications par SMS". Vous obtiendrez alors une clé d'identification au service, notez là dans un coin car elle est nécessaire au bon fonctionnement de l'envoi.

Comment ça marche ?

Voici le fonctionnement de base (explications venant de freemobile)

L'envoi du SMS se fait en appelant le lien suivant : https://smsapi.free-mobile.fr/sendmsg
avec les paramètres suivants :

    user :  votre login
    pass :  votre clé d'identification générée automatiquement par notre service
    msg :  le contenu du SMS encodé sous forme d'url (Percent-encoding)

Exemple : Envoyer le message "Hello World !" sur votre mobile :

https://smsapi.free-mobile.fr/sendmsg?user=18579358&pass=wUxxnu1DdRMF9k&msg=Hello%20World%20!

Vous pouvez également, si vous le préférez, envoyer les paramètres en POST.
Dans ce cas, le contenu du message n'a pas besoin d'être encodé.

Le code de retour HTTP indique le succès ou non de l'opération :

    200 : Le SMS a été envoyé sur votre mobile.
    400 : Un des paramètres obligatoires est manquant.
    402 : Trop de SMS ont été envoyés en trop peu de temps.
    403 : Le service n'est pas activé sur l'espace abonné, ou login / clé incorrect.
    500 : Erreur côté serveur. Veuillez réessayer ultérieurement.

Recevoir un SMS pour chaque nouveau mail correspondant à un libellé précis

Voici mon script, je vous donne les détails et la mise en place après.

//############################################################//
//                                                            //
//   Freemobile AutoSMS via Gmail Label (V1.2)                //
//                                                            //
//   Script by CHAUVIN Julien for webinventif.com             //
//   Docs: https://developers.google.com/apps-script/         //
//                                                            //
//############################################################//

// -----------------------------------------------------
// Globals
// -----------------------------------------------------
LABEL_SMS = 'SMS Perso';
LABEL_SMS_LU = 'SMS Perso lu';
FREE_PASS = 'votre_clé_de_notification';
FREE_USER = 'votre_identifiant_freemobile';
THREAD_SINGLE_ALERT = false;//recevoir une seule alerte par "conversation" ou à chaque nouveau mail (même dans la même conversation)
LIMIT = 10;

// -----------------------------------------------------
// ReturnFreeUrl(message)
// Retourne l'url du service SMS remplie et formatée
// -----------------------------------------------------
function ReturnFreeUrl(message) {
    message = message.replace(/(\r\n|\n|\r)/gm," ");//les sauts de lignes ne passent pas en GET, alors on nettoie
    return "https://smsapi.free-mobile.fr/sendmsg?user="+FREE_USER+"&pass="+FREE_PASS+"&msg="+encodeURIComponent(message.substring(0,480));
}

// -----------------------------------------------------
// EnvoiSMS()
// Envoi un SMS pour chaque message non lu correspondant
// au label défini dans LABEL_SMS et réattribue le label
// LABEL_SMS_LU
// -----------------------------------------------------
function EnvoiSMS() {
    var label = GmailApp.getUserLabelByName(LABEL_SMS);
    var compt = label.getUnreadCount();
    var singleAlert = 1;
    if (compt != 0){
        var labelLu = GmailApp.getUserLabelByName(LABEL_SMS_LU);
        var threads = label.getThreads();
        var maxMails = LIMIT;
        if(!maxMails) maxMails = threads.length;
        for (i = 0; i < maxMails; i++){
            if(THREAD_SINGLE_ALERT) singleAlert = threads[i].getMessageCount();
            if(threads[i].isUnread()){
                var mailBody = threads[i].getMessages()[Number(singleAlert-1)];// get last message of the thread
                var mailTitle = mailBody.getSubject();
                var message = '[M]'+mailTitle+' || '+mailBody.getPlainBody();
                var mailUrl = ReturnFreeUrl(message);
                var response = UrlFetchApp.fetch(mailUrl);
                threads[i].addLabel(labelLu);
                threads[i].removeLabel(label);
            }
        }
    }
}
 

Donc en gros ce script sera exécuté chaque minute (ou plus, voir la suite), il va chercher tous les mails non lu ayant le libellé défini dans LABEL_SMS, les envoie par SMS et change le label par celui défini dans LABEL_SMS_LU (pour éviter qu'ils ne soient envoyés à appel du script). Donc indiquez vos libellés et vos identifiants dans la section "Globals" du script.

Update du 16/06/2014 (V1.1): Ajout d'une verif "if (compt != 0)" pour empêcher une erreur du script
Update du 17/06/2014 (V1.2): Ajout d'une option qui permet de choisir si l'on reçoit une notification SMS à chaque nouveau message d'une conversation (mails empilés) ou juste lors du 1er message de la pile. En mettant THREAD_SINGLE_ALERT sur true, vous recevrez donc un sms a chaque nouveau mail qui s'ajoute à la conversation (avec le contenu du dernier message de la pile)

Ok mais je fais comment pour activer ce script ?

Ce script est un "Google Apps Script", et pour qu'il soit pris en compte, il va falloir l'ajouter dans votre Google drive de la manière suivante:

  1. Créez ou ouvrez une feuille de calcul dans votre drive
  2. Allez dans le menu "outils" puis "éditeur de scripts"
  3. Choisissez "Projet vide" et collez le script dans la nouvelle fenêtre
  4. Enregistrez le script et ajoutez un déclencheur
  5. Dans le nouveau déclencheur, choisissez d’exécuter la fonction "EnvoiSMS" dans le menu déroulant, puis "En fonction du temps", "Minuteur" et "chaque minute" .... Et "enregistrer"
  6. Une alerte d’autorisation va apparaitre, cliquez sur "Continuer"
  7. Dans la nouvelle fenêtre, cliquez sur "J'accepte"
  8. C'est enfin fini !

Étape par étape en images:
image-3-150x150 - image-4-150x150 - image-5-150x150

image-6-150x150 - image-7-150x150 - image-8-150x150

image-9-150x150 - image-10-150x150 - image-11-150x150

Et voilà !

PS: si quelqu'un arrive à envoyer les données en POST dans le script (j'ai toujours eu des erreurs 400), ça permettrait de pouvoir garder les sauts de lignes dans le sms.

-----

Articles relatifs

  • wx

    Ce script est une excellente idée ! Par contre chez moi je n’arrive pas à le faire fonctionner :
    « TypeError: Impossible d’appeler la méthode « getUnreadCount » de null. (ligne 36, fichier « Code ») »

  • wx

    @wx
    Désolé, c’était juste une histoire de labels. Merci !

  • Pingback: Le petit journal du web — juin 2014 #1()

  • coubi64

    wx :
    @wx
    Désolé, c’était juste une histoire de labels. Merci !

    J’ai le même souci que toi. Peux tu préciser comment tu as résolu le souci?

  • Julien

    Il faut peut être créer le label avant de lancer le script

  • coubi64

    Pb résolu: il faut créer des labels (lu et non lu) qui correspondent à « LABEL_SMS » et « LABEL_SMS_LU », ce que je n’avais pas compris…. Je pensais qu’il fallait y mettre ce qu’on trouve dans l’objet du message, le mot clé déclencheur….

  • Marion

    Jusqu’à maintenant, j’utilisais un script dans google drive qui insérait un évènement dans google agenda. L’envoi des SMS était ensuite réalisé par google agenda. Ton script permet donc de simplifier le processus en évitant de passer par google agenda. C’est une très bonne idée.
    Malheureusement, j’ai parfois des mails qui sont réceptionnés et que je ne reçoit jamais en SMS. Ils ont le libellé SMS Perso mais n’obtiennent jamais le libellé SMS Perso Lu, comme si le script avait échoué. Une idée sur la cause de ces échecs ?

  • Marion

    Quelques précisions sur le problème :
    Échec de la récupération du texte brut du corps d’un message. (ligne 49, fichier « Code »)
    la ligne 49 étant :
    var message = ‘[M]’+mailTitle+’ || ‘+mailBody.getPlainBody();
    Est-ce que cet échec peut être lié au nombre de caractères de l’objet du mail ou de sont contenu ?

  • Jean-Christophe

    Ce script est terrible et fait le boulot comme il faut, si ce n’est que je n’arrive pas à l’adapter pour que la sélection se fasse non pas sur un mais 2 labels :

    var label = GmailApp.getUserLabelByName(LABEL_SMS);

    n’accepte qu’un seul label à priori…

    Alors j’ai bien tenté une incursion avec :

    var threads = GmailApp.search(‘label:_OFF label: »SMS envoyé »)

    …qui fonctionne bien mais la manipulation threads et des labels n’est pas du tout la même, et je bloque.

    A ton avis quelle est la meilleure solution pour gérer non pas un mais deux labels ?

    Merci d’avance

  • Jean-Christophe

    Depuis mon précédent message j’ai bien avancé, et j’ai même trouvé une solution à ma question. En fait je me rends compte maintenant que ma question n’était pas correctement formulée, dans la mesure ou je n’avais pas vraiment intégré la notion de Classe GmailLabel.

  • ledijonnais2

    Bonjour coubi64, comment fait-on pour créer des labels ?
    Merci

  • ledijonnais2

    J’ai ce message quand j’utilise le script

    TypeError: Impossible d’appeler la méthode « getUnreadCount » de null. (ligne 37, fichier « Code »)

    Merci

  • thomtom

    Bonjour.
    Pourriez vous détailler plus le problème de LABEL ?
    J’ai beau chercher j’ai toujours la même erreur « Impossible d’appeler la méthode « getUnreadCount » de null. (ligne 36″.
    Merci d’avance.

  • Julien

    @thomtom
    Il faut créer et attribuer le label manuellement d’abord 😉

  • thomtom

    @Julien
    Merci Pour ta réponde Julien.
    J’ai fais comme ca,
    J’ai carrément intégré le label dans la focntion :

    var monlabel= »SMS Perso »;
    var monlabellu= »SMS Perso lu »;
    var label = GmailApp.getUserLabelByName(monlabel);

    Mais tjr la même erreur.

  • thomtom
  • Julien

    @thomtom En gros tu as shunté la condition getUnreadCount ?

  • Patrick

    pour résoudre l’erreur « Impossible d’appeler la méthode « getUnreadCount » de null. (ligne 36″,
    modifier la ligne :
    if (compt != 0){
    par :
    if ((compt != null)&&(compt != 0)){

  • Salut
    merci pour l’info sms via Gmail et le script d’alerte 🙂

    Je cherche le N. de téléphone utilisé par Gmail pour l’envoit de sms.
    @ceux qui ont testé avez-vous noté un numéro « Gmail » sur les sms reçus SVP ? À moins qu’il y a plusieurs N. ?
    C’est pour pouvoir l’utiliser sur AndroidLost.

  • correction : je voulais dire le N. de téléphone utilisé par les notifications FreeMobile :}
    celui qu’utilise Gmail aussi si vous le connaissez.

  • Julien

    C’est tout simplement le numéro de téléphone du compte freemobile (donc notre propre numéro) 😉

  • Ah oué ? Merci pour l’info Julien
    hmm j’obtiens une page blanche en envoyant un sms via l’URL. Syntaxe : …/sendmsg?user=CODE&pass=KEY&msg=MESSAGE%20ENCODED

  • vincent

    Bonjour,

    Super l’appli, mais je recois toujours un mail avec une erreur a ligne 46 « if(threads[i].isUnread()){ »
    Avez vous une idée du probléme?
    Merci.

  • fr

    Je confirme que le POST ne marche pas :
    $ wget –no-check-certificate –post-data= »msg=Hello world » « https://famille.miradou.com/sendmsg.php?user=xxxxxxxx&pass=yyyyyyyyyyyyyy »
    […]
    requête HTTP transmise, en attente de la réponse… 400 Bad Request

  • Freecoteur

    Bonjour,

    J’ai testé ce script et il semble fonctionner correctement.
    Cependant je crois comprendre que la limite du corps du mail et de 480 caractères (soit 3 SMS standard).

    Le plus important serait d’ajouter dans le SMS, le nom de l’expéditeur du mail reçu dans gmail ! Est-ce possible ?

  • Freecoteur

    Bonjour,

    Comment faire pour lire le nom de l’expéditeur de l’email dans le sms reçu ?

  • Julien

    @Freecoteur En regardant la doc de l’API Gmail (https://developers.google.com/apps-script/reference/gmail/) il semble que l’on puisse accéder à l’expéditeur via getFrom() (https://developers.google.com/apps-script/reference/gmail/gmail-message#getFrom%28%29)

  • joeleymard

    Bonjour,
    Peut-on adapter le script pour détecter si une caméra ip est en fonctionnement ?
    J’explique : il s’agit de détecter les coupures d’électricité dans une résidence secondaire en interrogeant toutes les 5 ou 10 minutes la caméra ip : si on reçoit la demande de nom d’utilisateur et de mot de passe, c’est qu’elle fonctionne ; sinon, c’est qu’elle est éteinte soit en raison d’une coupure électrique, soit par malveillance.

  • Julien

    @joeleymard
    Tu fais un petit script (php ou autre) qui ping l’ip de ta camera toutes les x secondes et si ça ne répond pas, tu charges l’url d’appel du sms.

  • kenneddy

    Bonjour,

    Je n’arrive pas à résoudre cette erreur :

    TypeError: Cannot call method « replace » of undefined. (line 25, file « Code »)

    « replaceText » ne fonctionne pas mieux…

    D’avance, merci !

  • skyrail02

    super idée.
    Mais est-ce que l’api freemobile prendrait aussi en charge l’envoi de sms, via gmail, une url, ou une passerelle imap, vers n’importe qu’elle ligne mobile, en utilisant ma ligne freemobile?

  • Joël Eymard

    Bonjour,

    J’ai l’erreur suivante :
    Type MIME non valide. (ligne 48, fichier « Code »)

    La ligne 48 est celle-ci :
    var message = ‘[M]’+mailTitle+’ || ‘+mailBody.getPlainBody();

    Merci d’avance de votre aide !

  • Julien Gaignerot

    Merci beaucoup. Ce script très utile fonctionne parfaitement chez moi.

    Bien Cordialement,
    Julien

  • moranche

    Bonjour,
    je n’ai pas compris l’utilisation de la fonction ReturnFreeUrl(message)
    si je la déclenche, il y a des erreurs

  • moranche

    il y a aussi cette erreur générée par le code de la fonction EnvoiSMS()
    TypeError: Impossible d’appeler la méthode « isUnread » de undefined. (ligne 46, fichier « Code »)

    ca n’empeche pas l’envoi mais on la recoit si on demande une notification de l’execution du script

  • sam

    Merci pour ce script très utile. Par contre je ne reçois pas le dernier message d’une conversation, mais toujours le premier, encore et encore, à chaque fois qu’un nouveau message arrive. Une suggestion ?

  • Gilles

    Ta méthode de script SMS est vraiment intéressante. Mais n’ayant pas de connaissance sur les scripts, je ne comprend pas ce que tu veux dire en disant de créer et attribuer le label manuellement d’abord. Peux tu m’éclairer ?

  • Laurent Aru

    Parfait ton script ! Beau boulot, ça marche super bien (du moins pour mon usage)
    Qu’elle inventivité !!
    Félicitations !

  • ironman72

    Bonjour, je ne m’en sors pas malgré vos informations j’ai toujours TypeError: Impossible d’appeler la méthode « getUnreadCount » de null. (ligne 40, fichier «  »)

  • ça marche chez moi , quand les Labels sont bien configurés , avec la fonction  » « recherche  » dans les paramètres des filtres , pour le transfère vers SMS Perso et SMS Perso lu .
    Aujourd’hui , j’ai reçu pour la première fois ,  » une notification failure  » des services google . , bien que mes alertes me soient bien parvenues .
    «  » TypeError: Cannot call method « isUnread » of undefined. (line 46, file « Code ») «  »
    C ‘est google qui déconne ? ? OU c’est la mise à jour de mes filtres ( avec l’ option recherche ..) qui à déclenché cette notification ?
    ( quand j’ ai effectué la mise à jour du filtre de gmail , la recherche m’ a fait ressortir 20 ou 30 Alertes mail des mois précédents ; anciens mails auto supprimés qui devaient se trouver dans la corbeille …. Ils sont revenus dans le dossier Label SMS Perso ….)

  • ldl

    avec l’adresse de l’expéditeur:
    LABEL_SMS = ‘votre libellé mail reçu sms à envoyer’;
    LABEL_SMS_LU = ‘votre libellé mails sms déjà envoyé’;
    FREE_PASS = ‘votre mot de passe donné par free’;
    FREE_USER = ‘votre identifiant’;
    THREAD_SINGLE_ALERT = false;//recevoir une seule alerte par « conversation » ou à chaque nouveau mail (même dans la même conversation)
    LIMIT = 10;
    // —————————————————–
    // ReturnFreeUrl(message)
    // Retourne l’url du service SMS remplie et formatée
    // —————————————————–
    function ReturnFreeUrl(message) {
    message = message.replace(/(rn|n|r)/gm, » « );//les sauts de lignes ne passent pas en GET, alors on nettoie
    return « https://smsapi.freemobile.fr/sendmsguser= »+FREE_USER+ »&pass= »+FREE_PASS+ »&msg= »+encodeURIComponent(message.substring(0,480));
    }
    // —————————————————–
    // EnvoiSMS()
    // Envoi un SMS pour chaque message non lu correspondant
    // au label défini dans LABEL_SMS et réattribue le label
    // LABEL_SMS_LU
    // —————————————————–
    function EnvoiSMS() {
    var label = GmailApp.getUserLabelByName(LABEL_SMS);
    var compt = label.getUnreadCount();
    var singleAlert = 1;
    if (compt != 0){
    var labelLu = GmailApp.getUserLabelByName(LABEL_SMS_LU);
    var threads = label.getThreads();
    var maxMails = LIMIT;
    if(!maxMails) maxMails = threads.length;
    for (i = 0; i < maxMails; i++){
    if(THREAD_SINGLE_ALERT) singleAlert = threads[i].getMessageCount();
    if(threads[i].isUnread()){
    var mailBody = threads[i].getMessages()[Number(singleAlert-1)];// get last message of the thread
    var mailTitle = mailBody.getSubject();
    var mailsender = mailBody.getFrom()
    var message = ''+mailsender+'|'+mailTitle+'|'+mailBody.getPlainBody();
    var mailUrl = ReturnFreeUrl(message);
    var response = UrlFetchApp.fetch(mailUrl);
    threads[i].addLabel(labelLu);
    threads[i].removeLabel(label);
    }
    }
    }
    }

  • ldl

    cette fonction ne peut être déclenchée de façon indépendante elle est utilisée lors de l’envoi du sms à l’intérieur de la fonction Envoi SMS

  • GOOD

    Bonjour, je n’arrive pas à faire fonctionner ce script… Je pense que j’ai des soucis avec la dénomination exacte du « LABEL ». Que dois-je indiquer : l’adresse de l’expéditeur ? (en l’occurence Free dans mon cas), ou seulement une partie (le début) de l’adresse, ou encore l’Objet du mail ?…

    Ci-dessous, voici le type de mail que je reçois de Free :

    « —–Message d’origine—–

    De : telephonie.freebox@mevo.freetelecom.fr
    [mailto:telephonie.freebox@mevo.freetelecom.fr]

    Envoyé : jeudi 22 octobre 2015 13:40

    À : djoq—@gmail.com

    Objet : [FREEBOX] 09——–: Nouveau message de: 06——–

    Nouveau Message :

    Pour : 09——–

    De : 06——–

    Le
    : 2015-10-22 13:39:26

    Duree : 9
    secondes »
    Merci pour votre réponse
    Jack

  • ldl

    le label c par exemple boite de réception oui dossier perso ect…

  • Defdef

    Excellent!
    Je l’utilise avec ma montre chinoise 2G 😉

  • legolass73

    Bonjour, ce script est super, sauf que j’aimerai savoir comment fait ton pour ajouté a se script l’option pour faire en sorte qu’il soit marqué comme lu dans gmail et ou qu’il soit deplace dans dossier

  • Dans GMAIL , il faut paramétrer des filtres avec des mots clés , comme ALERTE , ou autre et qui sont des mots qui se trouvent dans l’intitulé ( ou dans le contenu ) du mail d’ alerte que tu vas filtrer . Un filtre dans le dossier ( LABEL ) SMS LU et un filtre dans celui SMS .
    Moi j’ ai mis les mêmes mots clés dans les deux .
    Compte tenu que dans le script GMAIL il y a une temporisation minimale de 1 Minute , le SMS arrive sur le phone entre 0 et 60 secondes .
    Google m ‘envoi toujours régulièrement un rapport d ‘erreur , toujours la fameuse ligne 46 , comme indiqué plus haut .( mais ça marche )
    Je m ‘en sert pour une centrale d ‘ALARME de chez Casto , et pour un NAS Synologi . Alerte DDOS ect….