sms-gateway-android.png

Qui n'a pas rêvé d'envoyer gratuitement des SMS via Webservices REST ? Il existe sur la toile de nombreuses API pour envoyer des SMS, mais elles sont malheureusement généralement payantes.

Il est désormais possible de construire sa propre Gateway SMS, il vous suffit pour cela de trois ingrédients :

  • Une carte SIM Free à 0 euros avec un forfait illimité de SMS.
  • Un vieux téléphone Android inutilisé.
  • L'application Android SMS Gateway.

L'application Android SMS Gateway possède deux fonctionnalités intéressantes pour un développeur. Elle est en effet capable d'appeler un webservice REST tiers dès qu'un SMS est reçu et elle expose un webservice REST pour permettre l'envoi de SMS à partir d'un applicatif tiers.

gateway-sms.jpg

Voici à titre d'exemple un script Node JS permettant d'envoyer un SMS via un appel HTTP au webservice REST exposé par l'application Android SMS Gateway :

var request = require('request');

function send(phone,message){

     // Set the headers
     var headers = {
        'User-Agent':       'Domogeek/'+config.version,
        'Content-Type':     'application/x-www-form-urlencoded'
     }

     // Configure the request
     var options = {
        url: "http://montelephone:9090/sendsms",
        method: 'GET',
        headers: headers,
        qs: {'phone': phone, 'text': message}
     }

     // Start the request
     request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.info('SMS sended to: %s => %s', phone, message);
        } else {
            console.error('SMS error : %s => %s', error, message);
        }
     });
}

Enfin, voici un exemple de script pour traiter les SMS reçus via un simple script Node JS / Express de quelques lignes :

/**
 * HTTP GET /sms
 * Returns:
 */

app.get('/sms', function (req, resp, next) {

    if (!req.query['phone']){
        resp.json(400, { message: "Missing phone number"});
    }

    var phone = req.query['phone'];
    var message = req.query['text'];
   
    ....
}

Vous voilà désormais prêt à jouer avec votre passerelle de SMS pour superviser vos serveurs pour bien remonter des alertes de votre système domotique. A vous votre API REST de SMS gratuits !

apache-cordova-google-analytics.jpg

Vous souhaitez profiter de la nouvelle API Google Analytics Universal.js pour tracer les événements de votre application cross-platform Cordova / Phonegap  ? Cependant, vous rencontrez des difficultés pour faire fonctionner Google Analytics dans votre application ? Voici la solution pour permettre à Google Analytics de fonctionner correctement avec les contraintes des frameworks de développement mobile Phonegap / Cordova.

Paramétrage du tracker

La première étape consiste à indiquer à Google Analytics que vous souhaitez suivre l'activité d'une application mobile lors de la création du "tracker".

option-app-mobile.jpg

Modification de la librairie Analytics.js

La seconde astuce est de copier la librairie Analytics.js fournie par Google localement au sein de l'application. Il vous faudra ensuite commenter le morceau de code suivant permettant d'empêcher la librairie de fonctionner dans un wrapper Cordova ou PhoneGap.

if("http:"!=a&&"https:"!=a)throw"abort";

Cette petite astuce vous permettra que la librairie Universal s'initialise correctement lors de l'inclusion de la librairie dans votre page.

Désactivation des cookies

La dernière astuce consiste à désactiver l'utilisation de cookie pour identifier l'utilisateur, les pages étant chargées depuis le "file://" il est impossible à Google Analytics de gérer des cookies.

Pour cela le code suivant est à déclarer après réception de l’événement DeviceReady transmis par Cordova dès que celui-ci est initialisé. Cet évènement est nécessaire pour pouvoir utiliser correctement la propriété "device.uuid" qui vous indiquera l'identifiant unique du terminal basé sur les données du matériel accessibles par Cordova / Phonegap.

ga('create', 'UA-XXXXXX-XX', {
 'storage': 'none',
 'clientId':device.uuid
 });

N'oubliez surtout pas d'ajouter les bonnes autorisations au niveau de votre projet pour pouvoir utiliser cette fonctionnalité de Cordova / Phonegap.

Une fois la librairie chargée, il ne vous reste plus qu'à inscrire les informations de version de votre application dans le contexte :

ga('set', {
  'appName': 'myAppName',
  'appId': 'myAppId',
  'appVersion': '1.0',
  'appInstallerId': 'myInstallerId'
});

Ces paramètres vous permettront de créer des filtres intéressants par version depuis l'interface de suivi des indicateurs de Google Analytics.

Pour tracer chaque page vue et chaque événement spécifique, il vous suffira d'appeler les fonctions suivantes :

ga('send', 'screenview', {'screenName': 'Home'});
ga('send', 'event', 'video', 'started');

Enfin, sachez qu'il est désormais possible de tracer les exceptions Javascript de votre application au travers d'un simple "handler" d'erreur, pour cela :

window.onerror = function (errorMsg, url, lineNumber) {
    ga('send', 'exception', {
      'exDescription': 'Error: ' + errorMsg + ' Script: ' + url + ' Line: ' + lineNumber,
      'exFatal': false
    });
}

Vous voilà prêt pour superviser votre application Cordova/Phonegap en production. Si vous souhaitez aller plus loin, sachez qu'il est aussi possible de superviser les temps de chargement et d'ajouter des champs personnalisés dans les indicateurs remontés à Google.

Vous pourrez vérifier que les indicateurs sont correctement collectés par Google au travers de la vue "Temps réel" proposée sur l'interface de suivi Google Analytics.

html5-up.png

Vous êtes à la recherche d'inspirations pour créer un site HTML5 avec un design et une navigation moderne ?

Faites un tour sur html5up.net, ce site met en ligne de superbes thèmes HTML5 RWD sous licence Creative Commons.

Les thèmes proposés se basent sur le framework skelJS qui fournit un système de "grid layout" réactif et minimaliste. Les thèmes fonctionnent sur PC, tablette et smartphone.

html5-up-screen.jpg

La licence Creative Commons utilisée par son auteur vous autorise à modifier les thèmes à votre convenance et de les utiliser pour des usages commerciaux.

Mais attention, les thèmes sont tellement jolis, que le nombre de téléchargements sur la plupart ont dépassé les 100 000. N'oubliez donc pas d'ajouter votre petite couche de personnalisation au niveau du design afin d'éviter d'avoir un site qui ressemble à plusieurs milliers d'autres sur la toile.

rank-human-coder.jpg

Vous êtes développeur et vous recherchez à élargir votre réseau sur Twitter pour alimenter votre veille personnelle ?

HumanCoders a mis en ligne un top 50 des développeurs francophones les plus influents sur la toile.

Vous y trouverez les comptes Twitter de développeurs influents avec des CV incroyables comme Romain Guy par exemple, Guru Android de chez Google.

J'ai eu l'opportunité d'apparaître quelques heures dans ce classement, mais mes 2000 followers ne font plus le poids pour apparaître dans ce top 50. Il ne me manque plus que 400 followers pour revenir au classement ;-)

N'hésitez pas à aller faire un tour sur ce classement, j'ai fait de très belles découvertes !

Enfin, pour ceux qui lisent ce blog et qui ne me suivent toujours pas sur Twitter <Cliquez ici>.

GDG_Nantes_-_OK_Nantes.JPG

Pour les absents de la soirée Google Glass organisée par le GDG Nantes au Stéréolux, voici les slides de présentation technique détaillant le développement d'applications Google Glass.


Les apps Google Glass sont ni plus ni moins que des apps Android compilées avec le SDK 4.0.3 et bénéficiant de quelques API supplémentaires apportées par le GDK Sneak Peek.
Les développeurs Android peuvent rapidement développer des apps Google Glass, il faut préalablement comprendre l'usage de la timeline et des cards.

Si vous souhaitez découvrir les API du GDK, vous pouvez télécharger le GDK via une option du SDK Manager Android sur la version 15 des API Android.

Si vous êtes à Nantes jeudi soir prochain et que vous souhaitez découvrir les possibilités offertes par les Google Glass, alors venez à la soirée Google Glass organisée par le GDG Nantes au Stéréolux.

La soirée se déroulera en deux temps :

1. Conférence :

  • Présentation des nouveaux usages liés aux Glass
  • Retour technique sur l'utilisation du kit de développement et des possibilités offertes.

2. Codelab :

  • Découverte du développement avec plusieurs paires de Google Glass mis à notre disposition. Attention le nombre de place pour le codelab est limité !


2014_03_13_ok_nantes.png

Venez-nombreux, l’événement est gratuit !

Mais n'oubliez pas de vous inscrire au préalable, les places sont limitées.
Pour les chanceux qui auront réussi à obtenir des places, n'hésitez pas à venir discuter avec moi si vous réussissez à me reconnaître.

CodinGame.png

Si vous souhaitez comme moi perdre votre temps en participant au concours de développement Tron Battle, voici un code Java qui vous permettra rapidement de développer votre robot Tron plus rapidement.

L'attribut checkerboard contient le damier avec les valeurs de chaque joueur, il ne vous reste à implémenter la méthode "Play()" avec la bonne logique pour bloquer les autres bots qui participent au concours ;-)

import java.util.Scanner;

/**
 * Tron Player
 *
 * Author : Ludovic Toinel
 */

class Player {
         
    // Constants
    private static final String UP = "UP";
    private static final String DOWN = "DOWN";
    private static final String LEFT = "LEFT";
    private static final String RIGHT = "RIGHT";
    private static final  String[] directions = new String[]{UP,LEFT,DOWN,RIGHT};
    private static final int X = 30;
    private static final int Y = 20;
   
    // checkerboard
    public static int[][] checkerboard = new int[X][Y];
   
    // Number of players
    public static int nbPlayer;
   
    // Id of this player
    public static int idPlayer;
   
    // Current players positions
    public static Position[] players;
   
    /**
     * Play an action
     */

    private static void action(String direction){
        System.out.println(direction);
    }
   
    /**
     * Debug a message
     */

    private static void debug(String message){
         System.err.println(message);
    }

    /**
     * Main player class
     * @param args
     */

    public static void main(String args[]) {
       
        // Init the scanner
        Scanner in = new Scanner(System.in);

        // Init coordinates
        int x0, y0, x1, y1;
 
        // Initialize the checkerBoard
        removePlayer(0);

        // Infinite while ...
        while (true) {
           
            // Count of players
            nbPlayer = in.nextInt();
           
            // Initialize players positions
            if (players == null){
                players = new Position[nbPlayer];
                for(int i = 0; i < nbPlayer; i++){
                    players[i] = new Position(0,0);
                }
            }
           
            // Retrieve my player ID
            idPlayer = in.nextInt();
   
            // For each players
            for (int player = 0; player < nbPlayer; player++){
           
                // Read the coordinates
                x0 = in.nextInt();
                y0 = in.nextInt();
                x1 = in.nextInt();
                y1 = in.nextInt();
               
                // Player has lost
                if (x0 == -1){
                    removePlayer(player);
                    continue;
                }
               
                // Update the checkerboard
                checkerboard[x1][y1] = player;
               
                // Save the current player position
                players[player].update(x1,y1);
            }

            // Play the round
            play();
           
        }
    }

   
    /**
     * Remove the player from the checkerboard
     */

    private static void removePlayer(int id){
        for(int i=0; i<checkerboard.length;i++){
            for (int e = 0; e < checkerboard[i].length;e++){
                if (checkerboard[i][e]  ==  id ) {
                        checkerboard[i][e] = -1;
                }
            }
        }
    }
 
    /**
     * Play a round
     */

    public static void play(){

        // TODO CODE HERE !

        action(LEFT);
       
    }
   
    /**
     * Position class
     */

    public static class Position{
        public int x;
        public int y;
        public boolean me;
       
        /** Constructor */
         public Position(int x, int y){
             this.x = x;
             this.y = y;
         }
         
         /** Update the position */
         public void update(int x, int y){
             this.x = x;
             this.y = y;
         }
         
        /* (non-Javadoc)
         * @see java.lang.Object#equals(java.lang.Object)
         */

        public boolean equals(Position obj) {
                return (obj != null && obj.x == x && obj.y == y);
        }
    }
 }

Dépêchez-vous, il ne vous reste plus que 32 jours avant la fin du concours.

CodinGame.png

Une battle Tron avec des petits programmes fait-main, cela vous dit ?

Développez votre petit programme d'intelligence artificielle dans le langage de votre choix, capable de donner des directions à partir de la position des autres participants sur un plateau de jeu Tron.

Votre programme a au maximum 100 ms pour répondre, le but est de tenir le plus longtemps possible sur le plateau. A chaque fois qu'un joueur perd, il disparaît du plateau laissant ainsi vide les cases qu'il occupait.

tron-battle.jpg

Des combats sont générés aléatoirement entre les joueurs par le serveur pour générer un classement par langage de développement et un classement global.
Toutes les stratégies sont permises ! Mais attention, le code source du programme copié sur la plateforme ne doit pas dépasser les 50 Ko.

Rendez-vous sur Coding Game pour vous inscrire au jeu et que le meilleur développeur gagne !

chart-html5-test.png

Nous sommes dans une pleine phase de transition technologique où le HTML5 commence à être correctement supporté par l'ensemble des navigateurs Web du marché. Cependant, aucun outil de conception d'applications Web digne de ce nom n'a vu le jour pour le moment.

Nous ne voyons que des frameworks apparaître sur le marché : AngularJS, DART, Backbone, Node.js, xxxx.js ....

Qui sera le premier éditeur capable de réaliser un studio aussi puissant que le Flex Designer et capable de générer du HTML5 ?

Adobe serait-il sur le coup ? Ou est-ce Google ? Que fait Microsoft pendant ce temps là ?
Je pense qu'il ne s'agit plus qu'une question de mois avant de voir un IDE digne de ce nom apparaître sur le marché. Nous sommes en pleine phase de transition technologique, phase qui dure déjà depuis bientôt deux années.

Les "Rich Internet Applications" de la première décennie des années 2000 développées en GWT, Flex, RicheFaces, Silverlight ... ont intérêt à bien se tenir sous peine d'une migration forcée en HTML5 / Flat Design / RWD.

Tenez-vous prêts développeurs, apprenez le Javascript ou le DART ... qui sait ! ;-)

w3c-content-security-policy.png

Vous développez des sites Internet ? Connaissez-vous le Content Security Policy (CSP) ?

Le Content Security Policy est un mécanisme de sécurité permettant de limiter l'origine des contenus inclus dans une page Web à certains domaines autorisés.

Cela permet de mieux prémunir un site Web d'une éventuelle faille XSS. À condition bien sûr que la norme soit supportée par tous navigateurs. Pour le moment, le support de cette norme est limité aux dernières versions des navigateurs Web du marché.

content-security-policy.png

La norme CSP est actuellement au statut "Candidate Recommendation", elle est consultable sur le site W3C. Son utilisation est très simple et se base sur un entête HTTP spécifique interprété par les navigateurs qui supportent le CSP :

Content-Security-Policy : default-src 'self'

L'exemple ci-dessus permet de bloquer le chargement de ressources provenant d'un domaine externe au site ayant délivré le contenu HTML.

Différents paramètres peuvent être précisés dans cet entête HTTP afin de protéger seulement certains types de ressources : script-src, object-src, style-src ....

Ceci vous permet de contrôler l'origine de toutes les ressources incluses sur votre site. Pour visualiser les erreurs potentielles de chargement, vous pouvez spécifier un "report-uri". Ce "report-uri" sera utilisé par les navigateurs pour transmettre les potentielles erreurs de chargement de ressources. Indispensable pour un site possédant énormément de contenus d'origines diverses.

De nombreux sites ont adopté un CSP sur leur site, voici l'exemple du CSP complexe utilisé par Facebook  :

content-security-policy:default-src *;script-src https://*.facebook.com http://*.facebook.com https://*.fbcdn.net http://*.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl 'unsafe-inline' 'unsafe-eval' https://*.akamaihd.net http://*.akamaihd.net *.atlassolutions.com https://*.internet.org http://*.internet.org;style-src * 'unsafe-inline';connect-src https://*.facebook.com http://*.facebook.com https://*.fbcdn.net http://*.fbcdn.net *.facebook.net *.spotilocal.com:* https://*.akamaihd.net ws://*.facebook.com:* http://*.akamaihd.net https://fb.scanandcleanlocal.com:* *.atlassolutions.com https://*.internet.org http://*.internet.org http://attachment.fbsbx.com https://attachment.fbsbx.com;

Pour en savoir plus sur cette norme W3C, je vous conseille vivement de lire l'article dédié sur HTML5Rocks et de vous rendre sur la page OWASP spécialisée sur le sujet.

Une fois votre Content Security Policy en place, vous pouvez valider sa syntaxe via l'outil CSP-Tester présent sur GitHub ou bien l'add-on UserCSP disponible pour Firefox.

Enfin, si jamais vous utilisez Wordpress, sachez qu'un plugin CSP pour Wordpress existe et vous permet d'activer le CSP en deux clics sur votre site.