Partage d’un code source pour le tracking COLISSIMO

Super Edit :

j’ai des infos de la poste, ils sont en train de mettre en place une API Officielle.
Pour cela il faut avoir un compte Inet-Expeditor et le service sera proposé en janvier 2014.
Il répondra au jolis nom de « colis view ». Je vous conseille de vous rapprocher de votre commercial car l’ancienne API sera supprimée.

« EDIT » Ce code rencontre de petits problèmes actuellement, je vous conseille de vous tourner vers la vieille version en procédurale qui fonctionne .

Les années avançant et les statistiques Google Analytics sont là pour le prouver , la page la plus lue sur le blog est celle concernant un petit code mis en ligne pour faire du tracking de paquet Colissimo.

Je ne pouvais pas le mettre en ligne tel quel, un dépoussiérage me semblais nécessaire, c’est pourquoi j’ai décidé de m’appuyer sur la programmation orientée objet pour refondre ce code.

En faisant une petite recherche sur internet je me suis rendu compte qu’un lyonnais avais déjà effectué cette démarche et quelle était beaucoup plus avancé que ce que j’étais susceptible de vous proposer. Son code est disponible sur GITHUB.

Pour les autres le voici :

/*
 * @author Julien 'delphiki' Villetorte <gdelphiki@gmail.com>
 * http://www.delphiki.com/
 * http://twitter.com/delphiki
 *
 */
class ColissimoAPI{
    private $host = 'http://www.laposte.fr';
    private $page = '/outilsuivi/web/suiviInterMetiers.php';
    private $user_agent = 'Dalvik/1.4.0 (Linux; U; Android 2.3.5; HTC Desire HD Build/GRJ90)';
    private $key ;
    private $method;
    private $code;
    private $image_dir;
    private $param_string;
    private $response;
    private $invalidResponse;
    private $parsedResponse = array();

    /**
     * @access Public
     * @param string $_key
     */
    public function __construct($_key = 'd112dc5c716d443af02b13bf708f73985e7ee943'){
        $this->setKey($_key);
        $this->setImageDir('images/');
    }

    /**
     * @access public
     * @name setImageDir()
     * @param Path of image Directory
     * @throws Exception
     */
    public function setImageDir($_image_dir){
        $this->image_dir = $_image_dir;
        if(substr($this->image_dir, -1) !== '/'){
            $this->image_dir .= '/';
        }
        if(!is_writable($this->image_dir)){
            throw new Exception('Image directory not writable.');
        }
    }

    /**
     * @access public
     * @param string $_key
     * @throws Exception
     */
    public function setKey($_key ){
        if(preg_match('#^[a-zA-Z0-9]{40}$#', $_key) || empty($_key) || ($_key === 'null')){
            $this->key = $_key;
        } else {
            throw new Exception('Invalid key or empty.');
        }
    }

    /**
     * @access public$
     * @name   setUserAgent()
     * @param  string $_user_agent
     */
    public function setUserAgent($_user_agent){
        $this->user_agent = $_user_agent;
    }

    /**
     * @access public
     * @name setReferer()
     * @param string $_referer
     * @throws Exception
     */
    public function setReferer($_referer){
        if(filter_var($_referer, FILTER_VALIDATE_URL)) {
            $this->referer = $_referer;
        } else {
            throw new Exception('Invalid URL');
        }
    }

    /**
     * @access public
     * @name getStatus()
     * @param string $_code
     * @param string $_method
     * @param bool $_plain
     * @return Xml
     * @throws Exception
     */
    public function getStatus($_code, $_method = 'xml', $_plain = false){
        if(!preg_match('#^[0-9]{1}[a-zA-Z]{1}[0-9]{11}#', $_code)) {
            throw new Exception('Invalid code.');
        }
        $this->code = $_code;

        $allowed_methods = array('xml', 'json', 'img');

        if(!in_array($_method, $allowed_methods)){
            throw new Exception('Invalid method.');
        }
        $this->method = $_method;

        $this->param_string = '?key='.urlencode($this->key).'&code='.urlencode($this->code);

        return $this->getResponse(!$_plain);
    }

    /**
     * @access private
     * @name getResponse()  
     * @param bool $_parse
     * @return type
     */
    private function getResponse($_parse = true){
        $ch = curl_init();

        $url = $this->host.$this->page.$this->param_string;

        if($this->method != 'img'){
            $url .= '&method='.$this->method;
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_USERAGENT, $this->user_agent);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FAILONERROR, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
        curl_setopt($ch, CURLOPT_TIMEOUT, 3);
        $data = curl_exec($ch);
        curl_close($ch);

        $this->response = $data;

        return ($_parse || $this->method == 'img') ? $this->parseResponse() : $this->response;
    }

   /**
    * @access private
    * @name parseResponse()
    * @return img, xml, json
    * @throws Exception
    */
    private function parseResponse(){
        switch($this->method){
            default:
                throw new Exception('Invalid method.');
                break;
            case 'img':
                $newImg = imagecreatefromstring($this->response);
                imagepng($newImg, $this->image_dir.$this->code.'.png');

                $this->parsedResponse = array(
                    'code' => $this->code,
                    'image' => $this->image_dir.$this->code.'.png'
                );
                break;
            case 'xml':
                $dom = new DOMDocument('1.0', 'utf-8');
                if(!$dom->loadXML($this->response)){
                    $this->invalidResponse = $this->response;
                    $this->response = null;

                    if($this->invalidResponse != NULL ) {
                        return $this->invalidResponse;
                    } else {
                        throw new Exception("Invalid XML.\n\n" . $this->invalidResponse);
                    }
                }

                $this->parsedResponse['status']     = $dom->getElementsByTagName('status')->item(0)->nodeValue;
                $this->parsedResponse['code']       = $dom->getElementsByTagName('code')->item(0)->nodeValue;
                $this->parsedResponse['client']     = $dom->getElementsByTagName('client')->item(0)->nodeValue;
                $this->parsedResponse['date']       = $dom->getElementsByTagName('date')->item(0)->nodeValue;
                $this->parsedResponse['message']    = $dom->getElementsByTagName('message')->item(0)->nodeValue;
                $this->parsedResponse['gamme']      = $dom->getElementsByTagName('gamme')->item(0)->nodeValue;
                $this->parsedResponse['base_label'] = $dom->getElementsByTagName('base_label')->item(0)->nodeValue;
                $this->parsedResponse['link']       = $dom->getElementsByTagName('link')->item(0)->nodeValue;
                $this->parsedResponse['error']      = $dom->getElementsByTagName('error')->item(0)->nodeValue;

                $this->parsedResponse = array_map('utf8_decode', $this->parsedResponse);

                break;
            case 'json':
                if($this->response === null){
                    $this->invalidResponse = $this->response;
                    $this->response = null;

                    if( $this->invalidResponse != NULL ){
                        return $this->invalidResponse;
                    } else {
                        throw new Exception("Invalid JSON.\n\n".$this->invalidResponse);
                    }
                }

                $this->parsedResponse = json_decode($this->response, true);
                $this->parsedResponse = array_map('utf8_decode', $this->parsedResponse);

                break;
        }
        return $this->parsedResponse;
    }
}

 

Pour l’utiliser rien de plus simple :

try{     $colis = new ColissimoAPI();     $colis->setImageDir('tmp/'); // optionnal, default: images/

    $res = $colis->getStatus('XXXXXXXXXXXXX');
}
catch(Exception $e){
    echo $e->getMessage();
}

N’oubliez pas le « try catch » pour gérer proprement les erreurs.

Bien à vous

Grand maître L


Publié

dans

,

par

Commentaires

11 réponses à “Partage d’un code source pour le tracking COLISSIMO”

  1. Avatar de Thibault
    Thibault

    Alors suite à des entretiens avec laposte, je vais vous poster une nouvelle qui ne fait pas plaisir. Au dessous de 25 000 euros de chiffres d’affaire à laposte, vous n’aurez pas accès à l’api. Il faudra faire le suivi de vos colis à la main. Sympa la poste, ils aiment leurs clients. Vivement qu’un jour le marché soit plus ouvert que ca.

    1. Avatar de klm
      klm

      Tant pis pour eux …
      Tant qu’ils ont pas changé l’url … ça marche toujours ..
      quitte a passer par un proxy aléatoire pour changer d’ip et pas etre blacklisté !

      VOILA UNE CLEF QUI MARCHE !

      http://www.laposte.fr/outilsuivi/web/suiviInterMetiers.php?code=LW994950647FR&key=6b252eb30d3afb15c47cf3fccee3dc17352dc2d6&method=xml

      1. Avatar de klm
        klm

        et quand elle sera plus bonne il suffira de refaire un dump tcp sur son smartphone avec l’apli laposte et Shark sur android !

  2. Avatar de Bauer
    Bauer

    Merci.

    En utilisant ce code j’ai une page blanche.

    quand j’affiche $ch, j’ai « Resource id #2 »

    Même via directement le navigateur l’url
    http://www.laposte.fr/outilsuivi/web/suiviInterMetiers.php?method=xml&key=null&code=xxxxxxxxx&width=190&font=Arial&t=1253811351937

    ne donne rien

  3. Avatar de Bauer
    Bauer

    Bonjour,

    J’ai un message invalid XML depuis moins d’une semaine, avez-vous constaté le même problème ?

    1. Avatar de Grand Maître L

      Il faudrait que tu fasse un var_dump() sur le retour (le xml) et dit moi ce qui s’affiche.

      1. Avatar de Grand Maître L

        Si non dirige toi vers http://www.luc-sanchez.fr/2013/09/partage-dun-code-source-bitbucket/ avec cette classe tu aura plus d’infos en cas de plantages

      2. Avatar de Bauer
        Bauer

        C’est bien le code que j’utilise et le seul message d’erreur vient de la partie « throw new Exception(« Invalid XML.\n\n » . $this->invalidResponse); » et dit « Invalid XML »

        En faisant un var_dump au préalable à cette ligne j’ai la chose suivante:
        object(ColissimoAPI)#1 (11) { [« host »: »ColissimoAPI »:private]=> string(21) « http://www.laposte.fr » [« page »: »ColissimoAPI »:private]=> string(37) « /outilsuivi/web/suiviInterMetiers.php » [« user_agent »: »ColissimoAPI »:private]=> string(65) « Dalvik/1.4.0 (Linux; U; Android 2.3.5; HTC Desire HD Build/GRJ90) » [« key »: »ColissimoAPI »:private]=> string(40) « d112dc5c716d443af02b13bf708f73985e7ee943 » [« method »: »ColissimoAPI »:private]=> string(3) « xml » [« code »: »ColissimoAPI »:private]=> string(13) « 9V04667619407 » [« image_dir »: »ColissimoAPI »:private]=> string(5) « /tmp/ » [« param_string »: »ColissimoAPI »:private]=> string(64) « ?key=d112dc5c716d443af02b13bf708f73985e7ee943&code=9V04667619407 » [« response »: »ColissimoAPI »:private]=> NULL [« invalidResponse »: »ColissimoAPI »:private]=> bool(false) [« parsedResponse »: »ColissimoAPI »:private]=> array(0) { } }

        1. Avatar de Grand Maître L

          Mes investigations me donnent la même chose que toi, je continus de chercher.

          1. Avatar de Bauer
            Bauer

            Bonsoir

            As-tu pu reproduire le problème ?

            Cordialement

          2. Avatar de Grand Maître L

            Bon, j’ai fait des test avec mon ancien code (celui qui est en procédural) et tout fonctionne, je te laisse chercher comment modifier la class proprement, je manque de temps actuellement.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.