Ma Première Application Javascript

Présentation

Dans le cadre de ma formation à Ironhack, je dois réaliser un projet final en javascript qui reprend tous les concepts traités lors des précédentes semaines. Mongo, Express, Vue & Node : tout y passe. À ces fins, je souhaite retranscrire jour après jour la manière dont je vais développer cette application.

mevn-javascript

Ce journal de développement a également pour but de montrer à tous mes lecteurs no-tech qu’il est possible de rapidement se mettre à niveau et de pouvoir développer ses projets. Bien évidemment, il reste pas mal de chemin à parcourir avant de pouvoir maintenir une application grand public, mais réaliser un MVP est dorénavant tout à fait jouable.

Ainsi, lors des deux prochaines semaines, je tâcherais d’éditer quotidiennement cet article afin de vous donner tous les détails de ma démarche.

Pour ce projet, j’ai souhaité réaliser une application de dating.

Problématique

Tinder a frappé un grand coup en imposant un standard sur les applications de rencontre : le swipe. Cependant, des applications ont réussi à se frayer un chemin sans utiliser cette fonctionnalité. Je pense notamment ici à Happn qui s’adosse sur la géolocalisation de ses utilisateurs.

Toutefois un outsider, Bumble, réussit à sortir son épingle du jeu. La feature #1 est la suivante : les filles amorcent les discussions sous 24h après le match sinon la mise en relation est supprimée.

Il est intéressant également de citer Abricot qui réinvente l’agence matrimoniale et qui rencontre un succès conséquent auprès des femmes.

Suite à quelques interviews, j’ai pu détecter, auprès des filles, que les applications (comme Tinder qui n’émettent aucun type de restrictions) ont de moins en moins le vent en poupe. On a tous ce pote qui est capable de liker 300 matchs / seconde :)

En effet, il existe un déséquilibre majeur entre les aspirations des femmes et des hommes sur ce type d’application. Le comportement des hommes est parfois perçu comme déplacé par les femmes.

Données

Aujourd’hui, près d’une parisienne sur deux est célibataire. – source : étude ifop – lci

Les applications de rencontres sont démocratisées chez les jeunes (28% des 18-25 ans) et chez les CSP+ (16,3%) – source : BVA

Les utilisateurs n’hésitent pas à avoir plusieurs applications – source interviews

Une personne sur deux avoue à son entourage sa présence sur une application.  – source : BVA

Il est plus facile de faire venir des hommes sur une application mobile que des femmes. – source : interviews & intuition :)

Réponse

Dans un souhait de rendre l’application plus authentique que le niveau moyen, l’idée est ici de contraindre le swipe grâce à un quizz.

Exemple : Je suis l’utilisateur A, je trouve les photos et la description de l’utilisateur B intéressantes, je like ce profil et l’application m’impose de répondre à un quizz, préalablement édité par B, avec des thèmes comme la musique, les films, les voyages ou encore les livres. Si mon taux de réussite est satisfaisant, B sera notifié que je souhaite rentrer en relation avec.

QCM

Véritable pierre angulaire de ce projet, ce quizz a donc vocation d’augmenter la friction sur la mise en relation. Des questions à choix multiples permettent ici de rendre cette fonctionnalité possible à la fois sur un plan d’expérience utilisateur que sur un plan technologique.

En connectant les API de Spotify, IMDB, Google Places et Books il est possible de traiter des cellules très classiques comme :

  • Musique : quel est ton artiste préféré ? quelle est ta musique du moment ?
  • Cinématographie : quel est le film qui t’a le plus marqué ? qui est ton acteur favori ?
  • Voyages : ta destination de vacances préférée ? ton prochain voyage ?
  • Littérature : quel est ton livre de chevet en ce moment ? l’auteur qui t’a le plus inspiré ?

Seuil

L’utilisateur a toutefois la possibilité de garder un contrôle sur cette friction en déclarant un % de réussite minimum/maximum.

Par exemple, un utilisateur qui souhaite recevoir des notifications uniquement en provenance d’autres utilisateurs qui ont réussi à remplir parfaitement le quizz. À l’inverse, un utilisateur pourrait décider d’être notifié sans une seule réponse juste à son quizz.

L’utilisateur gardant, bien entendu, la possibilité d’accepter ou non la mise en relation.

Si l’utilisateur valide, la messagerie sera activée pour cette connexion. Le concept de l’application permet également de briser la glace plus rapidement grâce au quizz préalablement rempli.

Exemple :

Toi aussi tu es fan de Tarantino ?

Technologies employées

Pour arriver au résultat escompté, voici les ensembles technologiques que je vais utiliser :

  • Database : MongoDB + Mongoose
  • Back : Nodejs + Express
  • Front : Vuejs + Vuerouter
  • Mobile : React + ReactNative (dans un second temps)

Prochaines étapes

Comme précédemment décrit, je vais faire tout mon possible pour vous retranscrire mon parcours du combattant. Mais à cette étape du projet, je suis intéressé d’avoir des beta testeurs qui ont des idées/suggestions à proposer.

Jour #1 : Conception

Une journée sans ouvrir mon éditeur de texte c’est l’objectif que je me suis fixé. J’ai déjà réalisé des mini projets qui avaient été attaqués trop tôt sous un aspect technique. Au détriment de la conception et de l’expérience utilisateur. Aujourd’hui, l’idée était de récupérer un maximum de feedbacks de la part de mes camarades de classe. Cet exercice est obligatoire et vous évite à coup sûr des erreurs bien plus difficiles à rattraper par la suite. Grâce à cette première étape, et à plusieurs interviews dispensés au préalable, j’ai pu affiner quelques détails, notamment sur le parcours utilisateur.

Quand demander telle ou telle information ?

Que faire si l’utilisateur ne souhaite pas donner ses informations ? Son quizz ?

Pour le reste de la journée, je me suis seulement attelé à dessiner mes wireframes. Mais soyons honnête, je vais m’inspirer très fortement de l’application desktop de Tinder.

tinder desktop
Pas la peine de réinventer la roue :)

La seule grande différence résidera donc au like qui enverra vers un formulaire édité par l’utilisateur « swipé ».

Schéma de données

Ce fût de loin la tâche la plus complexe de ma journée. En effet, la schématisation de vos données peut vous faire gagner beaucoup de temps, ou vous en faire perdre beaucoup par la suite.

Voici donc les 4 principaux modèles qui devraient me permettre de faire tourner mon application :

  • User : où seront recensées les id, la bio, les photos etc…
  • Quizz : ce modèle étant relié à l’utilisateur
  • Match : qui représentera la réussite d’un questionnaire, avec ses réponses et les 2 user id concernés
  • Conversation : le modèle qui acceptera tous les messages échangés

Ce dernier étant généré lorsque le modèle Match passera pending à granted (deuxième utilisateur validant la mise en relation).

N’hésitez pas à cette étape du projet de sortir votre stylo et votre feuille de papier.   

Gagner du temps

Pour faciliter la tâche lors de l’élaboration du questionnaire, je souhaite connecter plusieurs API afin de :

  • Proposer un choix exhaustif
  • Sanitizer mes données
  • Construire plus rapidement des QCM car les questions ouvertes sont, dans un premier temps, difficiles à gérer

J’ai donc pris la peine de créer une Google Spreadsheet avec tous mes logins, mot de passes, clés API et documentations associées.

Repo

L’appel du clavier. J’ai pas pu résister à écrire quelques lignes. Ou plutôt exécuter quelques lignes de commande pour générer mon application. Pour ce faire, voici les lignes de commande à taper depuis un dossier commun.

$ express server
$ cd server
$ npm install
$ npm start
$ cd ..
$ vue create client
$ cd client
$ npm install
$ npm run serve

Pour express pas besoin de views. Vous pouvez nettoyer votre dossier. Au niveau de vuejs, il suffit de rajouter vue router et la vie est belle.

express-setup vuejs-setupJe vérifie que sur les ports 3000 et 8080 mes deux environnements fonctionnent.

Même si c’est pas tout à fait ça, voici à quoi devrait ressembler approximativement votre application après ce setup.

Plus ou moins…

Jour #2 : Modèles & Signup

On commence à rentrer dans le vif du sujet. L’objectif du jour était de :

  • Créer mes modèles grâce à Mongoose
  • Générer des seeds (données fausses basées sur le schéma)
  • Monter un sign-up via Facebook

L’objectif est atteint, non sans peine, mais tout est prêt pour démarrer l’application côté base de données.

Modèles & Seeds

Je vais pas détailler ici mes 4 modèles mais plutôt un seul, le modèle User.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
  facebookId: {
    type: String,
    required: true
  },
  status: {
    type: String,
    required: true,
    default: 'pending',
    enum: ['pending', 'granted', 'killed']
  },
  gender: {
    type: String,
    required: true,
    enum: ['1', '2']
  },
  lookingFor: {
    type: String,
    enum: ['1', '2']
  },
  firstName: {
    type: String,
    required: true,
  },
  age: {
    type: Number,
    required: true,
    min: 18,
    max: 99,
  },
  bio: {
    type: String,
    maxlength: 280
  },
  work: {
    type: String,
    maxlength: 70,
  },
  mail: {
    type: String,
  },
  phone: {
    type: String,
    minlength: 10,
    maxlength: 12
  },
  photos: {
    type: String,
  },
  createdAt: {
    type: String,
    default: new Date(),
  },
  updatedAt: {
    type: String,
    default: new Date(),
  }
});

const User = mongoose.model('User', userSchema);
module.exports = User;

Ce modèle est classique mais reprend tous les champs nécessaires pour la suite (enfin, je crois).

Je pense qu’il est cependant important de garder des traces des créations, modifications (cf createdAt & updatedAt).

Le gender et le looking for me permettant de gérer par la suite les différentes orientations sexuelles.

Pour vérifier que tout fonctionne, l’idée est de créer un seed pour bien vérifier que mon application envoie les données souhaitées dans ma base de données (MongoDB). Pour ce faire, voici un script d’exemple :

const mongoose = require('mongoose');
mongoose.connect(process.env.MONGODB_URI);
const User = require('../../models/user.js');

let userDatas = [
  {
    facebookId: '123456789',
    status: 'pending',
    gender: '1',
    lookingFor: '2',
    firstName: 'Vivian',
    age: 29,
    bio: 'Lorem ipsum dolor sit amet',
    work: 'Student @Ironhack',
    mail: 'yolo@yolo.com',
    phone: '0667721671',
    photos: 'https://lh3.googleusercontent.com/-QRfzdXqbRk0/AAAAAAAAAAI/AAAAAAAARKU/0mVuCX8pVhM/s60-p-rw-no/photo.jpg',
  }
]

User.create(userDatas, (err, user) => {
  if (err) {
    throw err;
  }
  else {
    user.forEach(user => {
      console.log(user);
    });
  }
  mongoose.connection.close();
});

TA-DA ! Ça fonctionne !

Le plus dur c’est de faire le premier, après le reste ça roule. C’est une partie qui peut paraître anodine mais pourtant essentielle.

Signup

Bon là par contre, c’est un peu l’enfer. Pour avoir discuté avec plusieurs développeurs, plus ou moins chevronnés, le sign-up / login est toujours une plaie à coder. Même si il est vrai que des initiatives comme Passport ou JWT vous change la vie, ça reste une étape fastidieuse.

Pour mon application, j’ai pris le parti de ne permettre uniquement le login via Facebook. C’était un choix que nous avions fait à l’époque pour le projet MyBetFriend et nous n’avions pas eu à l’époque de retours négatifs. De plus, la quasi totalité des applications de rencontre ont déjà évangélisé cette manière de s’inscrire.

Pour récupérer :

  • Mail
  • Prénom
  • Genre
  • Photos
  • etc…

Facebook fonctionne à la perfection :)

Le conseil que j’aurais à donner pour cette partie, c’est de prendre le temps de créer (avec d’autres développeurs éventuellement) un boilerplate qui sera réutilisé à l’avenir.

Jour #3 : Préparation de l’API

Journée de transition. En ce troisième jour, je ne fus pas à 100% sur le développement de mon application. Cependant, à cette étape du projet, un travail considérable a pointé le bout de son nez : la réalisation de mon API REST.

Cette API a pour vocation de faire communiquer ma partie client (vuejs) avec mon serveur (express).

J’ai pu d’ores et déjà constaté une erreur sur mon signup. En effet, j’ai réalisé ce dernier côté serveur alors qu’il aurait été plus productif de le réaliser côté client d’entrée. Mais bon c’est en faisant qu’on apprend de ses erreurs non ?

Signup & données

Je me suis donc attaché aujourd’hui à transférer mon signup sur ma partie client et a commencé la préparation de mon API. J’ai pu également améliorer la phase d’inscription en faisant matcher les données Facebook avec mon modèle de données. Grâce à cela, je peux dorénavant faire correspondre le prénom de l’utilisateur sur Facebook avec mon modèle de données.

Je pensais (naïvement) qu’il allait être aisé de rapatrier les photos d’un profil sur mon modèle mais ce thread ouvert sur Stackoverflow m’a quelque peu refroidi.

Il faut dorénavant fournir un screencast de son application à Facebook pour avoir la possibilité de récupérer les photos de profil.

Je vais donc devoir attendre d’avoir une application un peu plus précise pour pouvoir soumettre ma review.

Timestamps

Mais j’ai découvert une astuce relativement intéressante sur Mongoose qui me va me permettre de récupérer mes timestamps lors des créations et des modifications de mes données utilisateurs.

Le tout de manière très simple en rajoutant en second argument de mon modèle :

{
  timestamps: true
}

Ce qui donne en sortie :

J’ai également mis à jour mon modèle en remplaçant les 1 et 2 par male et female.

API

Pour en revenir sur l’API, l’idée est d’écrire côté client un fichier api.js qui va interroger mon serveur. Pour protéger ces routes, je vais utiliser mon token généré au signup.

J’utiliserai donc ici le module axios pour me faciliter la vie.

import axios from 'axios'

const mtmt = axios.create({
  baseURL: process.env.API_URL || 'http://localhost:3000/',
});

Demain c’est donc un gros chantier qui m’attend, la réalisation des premières méthodes de mon API pour récupérer toutes les datas nécessaires côté client.

Jour #4 : API & Vuejs – Tome I

Si Google est ton ami, Postman est ton meilleur ami. Surtout quand tu commences à écrire ta première API REST. Effectivement, gérer une application de A à Z commence à devenir complexe. Gérer 4 environnements (front, api, serveur et db) et les faire communiquer entre eux n’est pas plus chose aisée. Surtout lorsque vous commencez à rencontrer des problèmes de type CORS.

CORS

Cross-Origin Resource Sharing… Vous ne connaissiez pas cette acronyme ? Vous en avez de la chance. Le cross origin c’est ce qui va permettre de faire discuter votre front (qui tourne chez moi sur un localhost:8080) avec votre serveur (localhost:3000). Dans un soucis de sécurité, votre navigateur n’accepte pas aisément ce va et vient incessant entre ces deux origines. Heureusement qu’il existe une extension Chrome pour gérer ce genre de soucis.

Ne pas oublier que sur des sites comme Facebook ou encore Github le comportement est parfois hasardeux si l’extension est activée.

Node –inspect

Aka la commande qui te sauve la vie ! Effectuer des console.log(‘tutu’) côté client ça va, mais côté serveur on fait comment pour se déboguer ? Heureusement que cette commande existe et qu’elle vous permet d’ouvrir une interface ad hoc pour pouvoir insérer des points d’arrêts dans votre code côté serveur.

Signup

Encore et toujours la même histoire…

Bon, ils sont bien gentils Facebook, mais réaliser un sign-up correct avec eux c’est quand même pas si évident. Je pense que la prochaine fois ça va partir sur du Firebase direct !

En clair, voici le nouveau chemin pour faire fonctionner tout ce beau monde :

  1. Front : clique sur le sign-up
  2. Facebook : retourne les informations dans mon serveur (id, firstName…)
  3. Serveur : envoie le token et les informations de Facebook via un redirect
  4. Front : utilise les req.params pour faire tourner l’application
  5. Il y’a pas de 5, ça suffit.

Vuejs, les prémices

Sur les conseils de mes professeurs émérites, il est de bon ton de développer le front et l’api en même temps, afin de cadrer au mieux avec les desiderata des futurs utilisateurs. C’est donc ainsi que j’ai commencé à faire avancer mon front.

Je saluerai donc jamais assez les personnes qui vont vivre les repos comme Buefy ou Element. Ces modules permettent de réaliser des composants à la vitesse de l’éclair et ça c’est cool.

 

Par exemple, pour proposer un range d’âge sur mon application, voici le composant récupérer sur Element :

Maintenant que mon sign up est en place, il me reste plus qu’à attaquer ma fonctionnalité quizz qui ne sera pas une mince affaire non plus.

Jour #5 : API & Vuejs – Tome II

‘Va y’en avoir combien des tomes ?!?

Il me reste 9 jours de code et j’ai l’impression que j’avance pas. Je veux pas sortir les violons, mais quand même, ce n’est pas chose aisée. Surtout quand votre IDE (Visual Code) décide de péter un plomb. 2 heures de perdues, merci.

Spotify

Le gros morceau de la journée fût de connecter l’API de Spotify à mon modèle de Quizz. Lors du sign-up je demande à l’utilisateur quel est son groupe préféré.

C’était assez chronophage car je devais récupérer le code, puis le token mais bon c’est très instructif. Autre avantage, je vais pouvoir dupliquer sur mes autres API rapidement ce week-end.

En parallèle de ça, j’apprends aussi React (qui est probablement un peu plus complexe pour un débutant). Je veux pas rentrer dans une guéguerre stérile sur les différents frameworks javascript, mais il faut reconnaître que Vuejs à quelques avantages vis à vis de React.

Syntactic sugar

Vuejs est assez facile à lire et à écrire. Par exemple, pour ma génération d’artistes, voici ce que j’ai pu faire :

<figure class="image is-4by3">
  <img v-if="artist.images[0]" v-bind:src=artist.images[0].url alt="Placeholder image">
  <img v-else src="https://placehold.it/600x600" alt="Placeholder image">
</figure>

Spotify n’a pas d’image pour tout ses artistes. Et si une image manque, c’est toute la requête qui tombe à l’eau. Grâce à Vuejs, en 2 lignes de code, vous pouvez vous prémunir de ce genre de comportement. Et ça c’est cool.

T’as la photo c’est bien, tu l’as pas, placehold.it fera le reste !

Jour #6 : API & Vuejs – Tome III

Autre avantage, je vais pouvoir dupliquer sur mes autres API rapidement ce week-end.

Rien.

N’est.

Rapide.

Je devrais le  savoir quand même ! Il est vrai que j’ai pu transposer ma recherche de musique sur les films relativement rapidement. L’API de TMDB est super bien faite et il existe de nombreux wrappers sur GitHub.

Mais en partageant mon projet à une amie, elle m’a fait une remarque pertinente.

Non mais c’est bien gentil les musiques, les films, mais le trait de caractère c’est quand ?

Spafo. Du coup, j’ai mis de côté les intégrations API pour partir sur un autocomplete très simple : qualité & défaut.

Autocomplete

Quelle joie ce Buefy. Vous pouvez facilement trouver votre bonheur dans la partie Forms Controls.

Source : https://buefy.github.io/#/documentation/autocomplete

<template>
    <section>
        <p class="content"><b>Selected:</b> {{ selected }}</p>
        <b-field label="Find a JS framework">
            <b-autocomplete
                rounded
                v-model="name"
                :data="filteredDataArray"
                placeholder="e.g. jQuery"
                icon="magnify"
                @select="option => selected = option">
                <template slot="empty">No results found</template>
            </b-autocomplete>
        </b-field>
    </section>
</template>

<script>
    export default {
        data() {
            return {
                data: [
                    'Angular',
                    'Angular 2',
                    'Aurelia',
                    'Backbone',
                    'Ember',
                    'jQuery',
                    'Meteor',
                    'Node.js',
                    'Polymer',
                    'React',
                    'RxJS',
                    'Vue.js'
                ],
                name: '',
                selected: null
            }
        },
        computed: {
            filteredDataArray() {
                return this.data.filter((option) => {
                    return option
                        .toString()
                        .toLowerCase()
                        .indexOf(this.name.toLowerCase()) >= 0
                })
            }
        }
    }
</script>

Comme vous le remarquerez, même la partie .js est gérée. Terminé bonsoir.

Demain petite pause, je vais intégrer la landing page et lâcher un peu le duo infernal Express / Mongoose.

Jour #7 : Landing Page

Petit dimanche détente, intégration de ma landing page. OKLM.

Mon premier jet est disponible ici.

Étant donné qu’il faudra fournir une landing page de notre projet, autant le faire maintenant. Je pense que je serai tellement emmerdé par ma mise en production plus tard…

Mais ce n’est pas une excuse pour faire une landing page moisie. J’ai souhaité incorporer de la parallaxe et quelques animations CSS. Pour ce faire j’ai utilisé deux ressources très intéressantes : paroller & animista.

Paroller

Source : https://github.com/tgomilar/paroller.js/

Paroller est un plugin basé sur jQuery qui permet des animations parallaxes très facilement. Alors oui je sais, utiliser jQuery c’est le mal gnia gnia… Mais bon, ça marche, c’est facile, pas la peine de perdre des heures à reproduire la même chose avec du Tween non ?

Ce que j’ai le plus apprécié dans paroller c’est sa facilité de mise en place. Il suffit de déclarer une classe sur la partie qu’on souhaite animer et la suite se gère très bien :

$(".p1, [data-paroller-factor]").paroller({
  factor: 1,              // multiplier for scrolling speed and offset
  type: 'foreground',     // background, foreground
  direction: 'horizontal' // vertical, horizontal
});

Il suffit de gérer ces 3 paramètres et le tour est joué.

Animista

Source : http://animista.net/

Animista c’est le Google des animations css. Il suffit de piocher son animation, copier coller sa classe, ses keyframes et ça marche.

Jour #8 : De la data

Journée relativement productive. Mise à jour du Trello, finalisation du quizz. J’attaque maintenant le gros morceau : l’interface de mise en relation (swipe + quizz + chat). Mais avant cela, deux travaux relativement importants : enregistrer l’utilisateur localement (local storage) et création de faux profils.

Ce n’est pas pour faire semblant d’avoir une croissance exponentielle, non c’est plutôt pour tester tous les cas de figures. Les combinaisons possibles de recherches sont très élevées (âge, âge recherché, sexe et orientation sexuelle).

Enregistrer l’utilisateur localement

J’avais mis ça de côté en pensant que c’était pas trop compliqué à faire par la suite. C’est le cas, mais autant le faire de suite la prochaine fois :)

data: function() {
    return {
      error: null,
      files: [],
      photos: '',
      id: this.$route.query.id,
      firstName: this.$route.query.firstName
    }
  }

Au sign-up, je récupère l’id depuis l’url de callback de Facebook.

Une fois présenté, je suis en mesure de l’envoyer, avec axios, dans mon local storage (developer tools > application > local storage).

NB : j’envoie aussi mon token mais pas au même endroit :)

.then( res => {
        const { data } = res;
        localStorage.setItem('id', obj._id);
        axios.defaults.headers.common['Authorization'] = 'Bearer ' + data.token;
        return data;
      })

C’est pas les lignes de code de l’année mais ça fait le taf.

Par la suite, je récupère facilement l’id comme suit :

        .sendTreshold({
          userId: localStorage.getItem('id'),                
          treshold: this.treshold
        })

Faker.js

La trouvaille. Je pensais devoir scrapper des sites de rencontre pour pouvoir avoir une première base de test. Mais bon, comme vous devez le savoir, le scrapping, c’est pas bien.

Heureusement je suis tombé sur Faker qui est une librairie permettant de générer des quantités phénoménales de données. L’un des énormes avantages, c’est que Faker est capable de rester fidèle à la localité. Ce qui permet, dans mon cas, de mettre uniquement des personnes françaises.

const mongoose = require('mongoose');
mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/mtmt");
const User = require('../../models/user.js');

var faker = require('faker');
faker.locale = "fr";

var file = [];
for (let i = 0; i < 2000; i++) {
  
  let fakeDatas = {
    facebookId: faker.random.number(),
    status: 'granted',
    gender: faker.random.arrayElement(['male', 'female']),
    lookingForGender: faker.random.arrayElement(['male', 'female']),
    lookingForRange: [{'min' : faker.random.number({min:18, max:24}), 'max' : faker.random.number({min:32, max:49})}],
    firstName: faker.name.firstName(),
    age: faker.random.number({min:18, max:49}),
    bio: 'Je suis un faux compte et je le vis bien.',
    work: faker.company.companyName(),
    mail: faker.internet.exampleEmail(),
    phone: faker.phone.phoneNumber(),
    photos: faker.image.avatar(),
  }
  file.push(fakeDatas)
}

User.create(file, (err, user) => {
  if (err) {
    throw err;
  } else {
    user.forEach(user => {
      console.log(user);
    });
  }
  mongoose.connection.close();
});

Extrait :

{ facebookId: '37981',
  status: 'granted',
  gender: 'male',
  lookingForGender: 'female',
  lookingForRange: [ { min: 22, max: 46, _id: 5a9e51b9c932da671f9b1c2b } ],
  firstName: 'Lena',
  age: 48,
  bio: 'Je suis un faux compte et je le vis bien.',
  mail: 'Pauline90@example.net',
  phone: '0689125768',
  photos: 
   [ 'https://s3.amazonaws.com/uifaces/faces/twitter/nfedoroff/128.jpg' ],
  swiped: [],
  _id: 5a9e51b9c932da671f9b1c2c,
  createdAt: 2018-03-06T08:30:49.843Z,
  updatedAt: 2018-03-06T08:30:49.843Z,
  __v: 0 }
{ facebookId: '74494',
  status: 'granted',
  gender: 'male',
  lookingForGender: 'female',
  lookingForRange: [ { min: 19, max: 45, _id: 5a9e51b9c932da671f9b1c2d } ],
  firstName: 'Célia',
  age: 41,
  bio: 'Je suis un faux compte et je le vis bien.',
  mail: 'Lo_Leroux@example.com',
  phone: '+33 614805908',
  photos: 
   [ 'https://s3.amazonaws.com/uifaces/faces/twitter/kianoshp/128.jpg' ],
  swiped: [],
  _id: 5a9e51b9c932da671f9b1c2e,
  createdAt: 2018-03-06T08:30:49.843Z,
  updatedAt: 2018-03-06T08:30:49.843Z,
  __v: 0 }

La vie est belle.

Jour #9 : Vuejs et ses composants

J’ai pu goûter aujourd’hui à la puissance de  Vuejs. Autre force de ce framework c’est la structuration de ses composants et de ses vues.

Pour mon interface de swiper j’ai donc un composant Card et un autre Quizz. Ces deux composants se retrouvant dans une vue Swiper.

  1. Swiper.vue – view
  2. Card.vue – component
  3. Quizz.vue – component

De base, le quizz est désactivé. Je l’active sur le click Like sur la Card.vue. Mais je le referme depuis le composant Quizz.vue grâce à un event : $this.emit(‘hide’)

Ce dernier est récupéré dans Card.vue avec @hide=hideQuizz

Plutôt facile non ?

Dernière petite astuce, utiliser beforeMount() pour charger l’API avant le composant dans le but d’afficher de la data dès que le composant prend vie.

Jour #10 : Like & Dislike + Heroku

Je dois présenter mon projet vendredi. Ça serait pas mal de faire les fonctionnalités annoncées non ? Avec un petit déploiement également ?

Aujourd’hui je me suis donc attaché à coder mes features clés qui Like & Dislike l’utilisateur avec une première mise en production pour pas avoir trop mal vendredi matin.

De toutes façons on fait jamais une MEP un vendredi… Source

Like & Dislike : MongoDB & Vuejs

Pour que l’application cadre avec le souhait de l’utilisateur, il est impérieux de proposer des profils qui cadrent avec le sexe, l’orientation sexuelle et l’âge.

Pour ce faire…

Ma route

router.get('/api/getmatches/:id', function (req, res, next) {
  User.findById(req.params.id, function (err, user) {
    if (err) {
      next (err);
    } else {
      User
      .find({
        gender: user.lookingForGender,
        age: { $gte : user.lookingForRange.min, $lte: user.lookingForRange.max } 
      })
      .limit(100)
      .exec((err, users) => {
        if (err) {
          next(err);
        } else {
          res.json(users)
        }
      })
    }
  })
})

Qui sera améliorée demain bien entendu…

Comme vous le voyez, rien de très compliqué. En fonction de l’id de l’utilisateur, je récupère les informations nécessaires pour lui proposer les matches qui correspondent à ses envies.

Par la suite, je requête la base en entier sur ses critères. Je limite à 100 dans un premier temps, pas besoin de plus pour tester.

Mes méthodes

methods: {
    getMatches() {
      api
        .getMatches(localStorage.getItem("id"))
        .then((users) => {
          this.users = users
        })
        .catch(err => {
          this.error = err;
        })
    },
    increment(){
      this.counter++;
    }
  },
  beforeMount() {
    this.getMatches()
  },

Sur Vuejs il faut conceptualiser plusieurs choses.

L’appel de l’API se fait bien sur la base de l’id de l’utilisateur. C’est donc tout naturel de le récupérer depuis le local storage. 

Ce que j’utilise en revanche c’est une incrémentation pour faire passer les profils les uns après les autres. Il serait peut être intéressant que je filtre l’objet en sortie sur la date d’inscription, pour faire passer en avant les anciens profils. À voir.

Ne pas oublier le beforeMount() et on est bons.

Heroku

Mouairf… Pas très glorieux tout ça. Le déploiement est à mon sens une tâche réellement ingrate. Très difficile à déboguer, vous pouvez passer un temps considérable pour un résultat faible. Bon, il est vrai que vous pourrez toujours crâner auprès de vos petits copains en fin de journée.

Trève de plaisanteries, Heroku est quand même bien pratique et très bien documenté. En plus c’est gratuit.

Jour #11 & #12 : Fin.

Pour les derniers jours impossible de prendre le temps d’écrire. Sur la journée #11 j’ai réalisé pas moins de 20 commits sur mon application. Record battu :)

Quizz

Sur cette journée j’ai tout simplement réussi à mettre en place ma fonctionnalité principale : le quizz.

La plus grande complexité fût de réaliser des faux quizz et des les lier aux faux utilisateurs.

const mongoose = require("mongoose");
mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/mtmt");
const Quizz = require("../../models/quizz.js");
const User = require("../../models/user.js");

var faker = require("faker");
var randomArtists = require("./random/randomArtists");
var randomMovies = require("./random/randomMovies");
var quality = require("./random/quality");
var defect = require("./random/defect");

var users = [];
User.find({})
    .select({
        _id: 1
    })
    .limit(100)
    .exec((err, users) => {
        if (err) {
            next(err);
        } else {
            var file = [];
            for (let i = 0; i < 20000; i++) {
                let fakeDatas = {
                    userId: faker.random.arrayElement(users),
                    treshold: faker.random.number({ min: 0, max: 100 }),
                    music: {
                        answer: faker.random.arrayElement(randomArtists),
                        badResponses: [
                            faker.random.arrayElement(randomArtists),
                            faker.random.arrayElement(randomArtists),
                            faker.random.arrayElement(randomArtists)
                        ]
                    },
                    movie: {
                        answer: faker.random.arrayElement(randomMovies),
                        badResponses: [
                            faker.random.arrayElement(randomMovies),
                            faker.random.arrayElement(randomMovies),
                            faker.random.arrayElement(randomMovies)
                        ]
                    },
                    traits: {
                        "quality.answer": faker.random.arrayElement(quality),
                        "quality.badResponses": [
                            faker.random.arrayElement(quality),
                            faker.random.arrayElement(quality),
                            faker.random.arrayElement(quality)
                        ],
                        "defect.answer": faker.random.arrayElement(defect),
                        "defect.badResponses": [
                            faker.random.arrayElement(defect),
                            faker.random.arrayElement(defect),
                            faker.random.arrayElement(defect)
                        ]
                    }
                };
                file.push(fakeDatas);
            }

            Quizz.create(file, (err, quizz) => {
                if (err) {
                    throw err;
                } else {
                    quizz.forEach(quizz => {
                        console.log(quizz);
                    });
                }
                mongoose.connection.close();
            });
        }
    });

Pour ce faire j’utilise toujours ce bon vieux Faker.js qui fait gagner un temps considérable. Une fois le fichier créé je le pousse en base via Mongoose.

Refacto

Sur la doc de React j’ai trouvé une partie très intéressante : Thinking In React. Je n’ai pas (encore) trouvé son pendant côté Vuejs.

Cette partie  vous explique comment découper une petite application web en composants. C’est très intéressant, car si vous commencez à créer une application avec une architecture bancale, la moindre fonctionnalité va devenir très compliquée à produire.

C’est en ce sens que j’ai souhaité (la veille de mon rendu) « refactoriser » mon interface de swipe.

Ce n’est pas un choix que je regrette car j’ai pu avancer beaucoup plus vite par la suite. Je pense que pour la prochaine application, je vais utiliser beaucoup plus de papier et de feuilles blanches pour conceptualiser l’application.

Toasts

Petite fonctionnalité intéressante, qui plus est pour l’utilisateur final, le toast. C’est d’une facilité enfantine à mettre en place et le résultat est plutôt sympa pour l’utilisateur.

          .then(data => {
            this.$toast.open({
              message: "Bien reçu",
              type: "is-success"
            });
            this.$router.push("/quizz-info");
          })

Vous pouvez rajouter rapidement dans votre retour de données API ce petit bout de code qui avertira l’utilisateur que tout est OK. Le tout avant de le rediriger vers la prochaine page.

It’s a match!

Pour les besoins de la démonstration live, j’ai du mettre insérer un pattern fixe sur les bonnes réponses. J’aurais bien entendu pas fait ça comme ça pour une vraie mise en production. Mais bon j’ai codé ça en quatrième vitesse et ça faisait le taf, donc bon…

router.post("/api/postquizz/", function(req, res, next) {
    Quizz.findById(req.body._id, function(err, quizz) {
        if (err) {
            next(err);
        } else {
            var score = 0;
            if (req.body.musicAnswer === "A") {
                score = 25;
            }
            if (req.body.movieAnswer === "B") {
                score += 25;
            }
            if (req.body.qualityAnswer === "C") {
                score += 25;
            }
            if (req.body.defectAnswer === "A") {
                score += 25;
            }
            if (score > quizz.treshold) {
                Match.create({
                    _quizzId: req.body._id,
                    _userRequester: req.body._userRequester,
                    _userCandidate: req.body._userCandidate,
                    average: score / 100
                });
                res.json({
                    message: "BRAVO"
                });
            } else {
                res.json({
                    message: "NOPE"
                });
            }
        }
    });
});

npm run build

Autre élément important appris lors de ces folles journées du code, l’intérêt de faire passer un build de production assez rapidement. En effet, Vue (et les autres) vont compiler votre code et le distribuer dans un dossier /dist. Le seul petit soucis, c’est que si vous avez fait le barbare comme moi en bougeant des classes css natives vous allez retrouver votre appli tout en désordre. Donc ce qui peut être pas mal c’est de faire un build en fin de journée pour bien vérifier que tout est à sa place.

Ou sinon vous codez correctement et vous faîtes des classes partout.

Conclusion

Voila. http://mtmt.viviansarazin.com/

NB : L’application n’est pas optimale en version mobile

Deux semaines de code, une application. Je pense que la prochaine fois je pourrais faire la même application en une semaine. Mais bon il faut passer par là !

Rétrospectivement, je dirais que j’aurais pu passer un peu plus de temps sur la phase de conception afin de mieux préparer mon API, mes composants toussa toussa.

J’ai aussi perdu pas mal de temps sur le setup, plus précisément sur le signup via Facebook. La prochaine fois je pense que je partirais directement sur du Firebase. Autre possibilité, réaliser un boilerplate MEVN pour gagner du temps.

Remerciements

C’est le moment de sortir les mouchoirs. Faut bien que ça s’arrête quand même !

Pour les profs : Merci Eduardo, Guillaume, Maxence, Mickaël A, Mickaël B, Nizar & Yacine.

Et les autres : Merci Antoine, Charlotte, Karim & Maya.

 

Bien à vous :)

Pour vous inscrire à la newsletter c’est par ici :

InstaPy, créer votre bot Instagram

Une nouvelle catégorie vient de voir le jour sur growthhacking.fr : Screencast. L’objectif est de poster mensuellement du contenu vidéo présentant des hacks pratico-pratiques. Et pour ouvrir le bal, nous avons pensé à faire un tutoriel sur InstaPy qui vous permet de créer facilement un bot Instagram en Python. La partie vraiment sympa c’est que le bot tourne depuis votre IP locale, beaucoup plus complexe pour Instagram de vous coincer du coup.

Bon visionnage !

Pour voir la vidéo vous devez être enregistré sur le forum :

landing-page-checklist

Landing Page Checklist

La première chose qu’on apprend à l’école des pilotes de chasse, c’est la checklist. Durant cet intervalle de temps, avant le décollage, le pilote vérifie le bon état de son avion, la météo, son armement etc… Et c’est l’objectif de cet article, vous proposer une Landing Page Checklist pour vous aider à ne rien oublier. Avec Brice, Julien & Camille de growthhacking.fr nous recevons un flux considérable de landing page à analyser. Bien entendu, nous sommes ravis d’aider nos confrères à propulser les meilleures landing page possibles, toutefois nous avons pu remarquer que beaucoup de points revenaient sans cesse. Grâce à cette checklist (Google Spreadsheets) nous allons pouvoir enfin nous concentrer sur le plus important : votre valeur ajoutée et votre stratégie digitale dans son ensemble.

Lors de nos discussions avec mes comparses du forum, nous avons identifié 5 grands piliers : Marketing, Seo, Mobile & Speed, Tracking & Tags.

Cette checklist a pour but d’évoluer avec vos retours, ainsi n’hésitez pas à apposer vos suggestions en commentaire de l’article ou de la feuille

Marketing

Je faisais allusion à la notion de marketing lors de mon article sur les Facebook Audience Insights il y a de cela quelques mois. Si vous vous lancez dans la création d’une landing page c’est que vous souhaitez vous présenter sur le marché (ou bien pour quoi pas le créer, bonne chance) avec un produit/service doté d’un avantage concurrentiel majeur.

Si c’est pour faire moins bien et plus cher assurez vous d’avoir une grosse équipe de sales.

Proposition de valeur unique

Une proposition de valeur n’est pas un slogan !

C’est un exercice très difficile de pouvoir synthétiser sa valeur ajoutée tout en étant assez intriguant pour inciter à la conversion. L’exercice de proposition de valeur est l’un des plus complexes à mes yeux. Surtout qu’une fois que vous pensez avoir atteint le sommet, il vous reste plus qu’une chose à faire : trouver encore mieux.

C’est toutefois bien ici que vous allez pouvoir réaliser des sauts quantiques sur vos taux de conversion. Un 0,5% de conversion stable est souvent plus intéressant qu’un +5% de trafic. Surtout si il est pas qualifié.

Brice de deux.io en parle à merveille dans son article sur les proposition de valeurs. #mustread

Persona

L’édition de vos personae (oui, au pluriel on met un e, chiant…) est là aussi un exercice indispensable. La persona marketing a pour but de représenter, cibler, un segment marketing. Cet outil est initialement utilisé pour le développement de nouveaux produits/services. Ce qui devrait faire l’affaire pour nous non ?

J’utilise depuis plusieurs temps Xtensio pour ce genre de représentations. Le template User Persona est juste parfait.

J’ai également apprécié l’article de Punchify sur le sujet des Persona Marketing. L’approche Google Analytics est très intéressante.

Content , CTA’s & Features

Cette partie reste relativement subjective. Certaines landing pages sont très laconiques et pourtant convertissent à merveille. Toutefois, si il y’a pas de Call To Action ça va être un peu compliqué de convertir :)

N’oubliez pas toutefois de répondre sur les How & Why de la manière la plus précise possible.

La ressource que j’apprécie beaucoup c’est Landing Folio qui recense des centaines de landing page de très belle facture.

SEO

Je vous vois venir…

Une landing page ça n’a pas vocation à être référencé !

Faîtes ce que vous voulez, mais une landing page avec un contenu de qualité qui reçoit quelques backlinks, peut rapidement atteindre de bons résultats en référencement naturel et ainsi garantir un trafic substantiel. Adios adwords !

Je ne vais pas revenir ici sur les centaines de règles SEO que vous pourrez trouver sur les Internets, l’idée c’est de fournir une checklist avec quelques items majeurs.

H1, Meta & Title

L’excellent blog yakaferci.com va vous donner des explications bien plus détaillées en la matière. Mais dans tous les cas, pensez à renseigner ces éléments. Ça ne prend pas longtemps et ça vous aide à synthétiser votre sujet en quelques caractères. Exercice atroce mais infiniment salutaire.

N’oubliez pas la formule =NBCAR() pour compter la longueur de vos metas.

Search Console, Robots.txt & Sitemap.xml

Là on est un peu plus technique, mais cela me semble important d’écrire quelques mots à ce sujet.

Même si l’usage d’un robots + sitemap est overkill sur une seule et unique page, je vous le conseille de l’intégrer à votre sitemap existant. Vous avez également la possibilité d’indiquer les priorités et les fréquences de crawling de chaque pas dans le sitemap.xml, donc ne vous gênez pas.

Exemple : daily, prority 0.9

En ce qui concerne le search console, c’est à mes yeux indispensable si vous souhaitez agir en SEO.

search console
Search Console

Vous allez ainsi pouvoir voir (entre autres fonctionnalités) quelles requêtes amènent du trafic organic sur votre site. Vous serez en plus averti si des erreurs sont détectées par Google.

Mobile & Speed

Selon les gars sûrs de Smart Insights, l’Internet est consulté dorénavant majoritairement par les devices mobiles. Plus intéressant encore, le mobile supplante le desktop le matin et le soir.

mobile-vs-desktop
Mobile vs Desktop vs Tablet

Source : Mobile Marketing Statistics compilation

En ce sens, vous serez bien urbain de proposer une version responsive ou mobile de votre landing page. Merci d’avance.

Autre point, soyez vigilants au temps de chargement de votre page. Ça paraît rien, mais nous savons tous qu’un site rapide à charger est très agréable. Le coût de l’agréable est quand même un peu élevé pour Amazon si on en croit ce billet

Tracking

Installer Google Analytics ne vous cause pas de problèmes ? Si ?! Bon et bien évitez cette lecture pour tous les autres je vous conseille de jeter un œil sur cette méthode. Là aussi, c’est peut être un peu surdimensionné pour une simple landing page mais si vous en avez des dizaines à gérer au quotidien vous ne serez pas déçu d’avoir lu ceci.

Je conseille également d’installer le Facebook Pixel le plus rapidement possible pour ne pas perdre une miette du trafic que vous avez pu amener sur votre site. Retargeter peut s’annoncer très utile par la suite. Surtout, vous allez pouvoir créer vos conversions personnalisées et ainsi rapprocher votre coût de conversion si vous réalisez des Facebook Ads.

Autre point, l’usage d’Hotjar peut s’avérer efficient si vous avez la discipline suffisante pour analyser régulièrement vos précédentes visites. L’UX vaut de l’or, ne passez pas à côté du parcours client réel.

Dernier point, si vous utilisez un outil de marketing automation comme Hubspot ou Active Campaign (excellent rapport qualité/prix) n’oubliez pas d’insérer le petit .js qui va bien. Ça serait dommage de passer à côté du lead scoring et/ou des scenarii mailing (très chiant ça aussi les « ii »). Sans oublier le lead nutrturing qui vous permettra de convertir plus tard des prospects.

NB : Si vous avez correctement installé Google Tag Manager, cette étape ne devrait pas être complexe. Voir précédent article.

Tags

Votre landing page est trop stylée, le contenu est ouf, vos rankings SEO donnent le vertige, tout naturellement les visiteurs ont envie de partager la bonne nouvelle sur les réseaux sociaux. Et là qu’est-ce qui se passe ? Vous n’avez pas mis les balises Open Graph et l’aperçu de votre site est tout simplement épouvantable. Quand même dommage de passer à côté d’un bon petit referral des familles non ?

Pour plus répéter ce genre d’approximations, je travaille avec Webcode Tools vous allez voir c’est juste fantastique.

Checklist Landing Page : Next Steps?

J’espère que ce format vous sera utile, si maintenant vous souhaitez apporter des commentaires modifications, n’hésitez pas à rejoindre le fil de discussion ouvert à ce sujet sur growthhacking.fr

Un channel sur mon Slack est également ouvert pour en discuter. Pour le rejoindre laisse ton petit mail :)

Maîtrise tes datas dès le premier jour

Le growth-hacking sans datas c’est un peu comme jouer au foot sans ballon : c’est nul. Le growth-hacker vit une relation pour le moins particulière avec la donnée.

« Mes actions auront elles l’impact escompté ? »

« Pourquoi ça chute ici ? »

Tout growth-hacker se sera posé au moins une fois dans la journée des questions analogues.

Mais ne l’oublions pas, un growth-hacker est avant tout conscient de la puissance des processus bien huilés. Les outils arrivent ensuite.

Et c’est l’objectif de cet article : partager toutes les connaissances nécessaires pour mettre en place, dès le premier jour, un processus pour extraire et interpréter de manière sûre vos données. Les outils proposés ici sont uniquement gratuits. Ce ne sont pas forcément les plus performants sur le marché, pour un premier environnement data, ça devrait être suffisant.

Dans une première étape nous allons parler de Google Tag Manager qui est un gestionnaire de balises. C’est ici que nous incorporerons par la suite les différentes balises. En termes d’Analytics nous parcourrons Google Analytics & Mixpanel pour enfin terminer sur l’édition de dashboards via Google Data Studio.

Le lien vers l’infographie

Google Tag Manager

– Kevin* tu peux me mettre ce petit script dans le <head> du site s’il te plaît ?

– Non.

– Ok merci, t’es super !

On a tous eu ce genre d’échange avec son développeur (oui, beaucoup de bon dév’ s’appellent Kevin, c’est comme ça). En réalité si votre développeur ne daigne pas insérer votre misérable script vous n’allez pas pouvoir faire grand-chose.

Il vous reste une seule solution : le conjurer à genoux d’accéder à votre requête.

C’est ainsi que Google, dans sa grâce la plus aboutie, a proposé au monde de l’Internet : Google Tag Manager. GTM permet, en insérant deux petits scripts dans votre application, de piloter l’intégralité de vos balises. Ainsi vous n’aurez qu’à faire insérer dès le début de votre collaboration ces fameux scripts GTM et vous pourrez ajouter, modifier supprimer vos scripts secondaires depuis l’interface.

Fini les passes d’armes avec Kevin. Pfiou !

 

Mais GTM a d’autres côtés tout aussi pratiques.

Si vous voulez en savoir plus sur l’installation vous pouvez vous renseigner sur la documentation officielle : https://developers.google.com/tag-manager/quickstart

Variables

GTM identifie vos variables et vous permet de les communiquer entre différents services.

Par exemple, si votre formulaire renvoie first_name, last_name & email, vous allez pouvoir pousser ces informations à d’autres services tiers.

C’est très simple à réaliser et leur interface de débogage (mon Dieu quel mot affreux…) est vraiment optimale pour vérifier votre Data Layer (données envoyées à GTM).

Environnement

Cette fonctionnalité est vraiment intéressante car elle vous permet de découper votre écosystème en différents modules.

Imaginons que vous ayez :

  • Blog
  • Landing page (x4)
  • Site Web
  • Application

Vous allez pouvoir aisément définir quelles balises déclencher selon les environnements identifiés.

Exemple : sur votre Front pas besoin d’analytics poussé (dans un premier temps) l’usage de KissmetricsMixpanel ou Amplitude serait plus utile sur votre application.

Ainsi vous n’ajoutez pas tout, partout. Ceci vous permettant d’éviter lourdeurs dans le code et surtout des « dépenses » inutiles.

Si vous souhaitez aller plus loin je vous conseille de lire les ressources fournies par Segment  qui est une alternative plus que sérieuse à GTM. Si maintenant vous voulez voir ce qu’on peut faire quand on maîtrise à la perfection sa data regardez du côté de chez hull.io. Indécent.

Analytics

Maintenant que votre Google Tag Manager est en place dans tous vos modules (blog, appli, front etc…), vous allez pouvoir insérer vos analytics. Que la fête commence !

Tracking Plan

Pour que votre environnement soit clair et maintenable, je ne peux que vous conseiller de réaliser un Tracking Plan avec une nomenclature précise.

Pour vous aider, j’ai réalisé une spreadsheet qui comprend 3 onglets.

  1. Questions : L’idée est de pouvoir croiser vos différents modules et les outils d’analyses associés. Qu’est-ce qui est réalisable ? Quels sont mes KPI’s ?
  2. Tracking Plan : Une fois les bonnes questions posées, il vous sera plus aisé de réaliser un tracking plan. Diana Smith de Segment nous résume tout ça.diana h. smith @dianahsmith Tracking Plan. Name Why Properties Location Signed Up Key event for user interest, marketing c...
  3. Nomenclature : Pour que vous puissiez mettre en œuvre votre Tracking Plan il vous faudra nommer vos événements correctement.

Google Analytics

Google nous gratifie une fois de plus d’un bel outil : Google Analytics. Très utile pour identifier des données comme :

  • Source
  • Support
  • Taux de rebond
  • Conversions
  • etc…

Google Analytics devient d’un coup beaucoup moins performant lorsqu’il s’agit de faire de l’analytics user-centric. Il reste néanmoins excellent pour tous les aspects « marketing ».

En effet, Google Analytics fonctionne à la page view alors que d’autres analytics s’attachent à calculer sur l’event.

C’est ainsi que Google Analytics n’est pas le meilleur outil à utiliser pour tous les aspects funnels et autres cohortes de rétention.

Mixpanel

Quand on parle d’analytics user-centric Mixpanel n’est effectivement jamais très loin. Mixpanel est globalement très performant et vous permet d’effectuer dorénavant votre tracking sans recourir à votre Kevin local.

NB : je rédige une MAJ avec Amplitude dans pas longtemps.

Autotrack

Que ce soit sur une application web ou mobile, la fonctionnalité Autotrack développée par Mixpanel vous permettra de créer vos événements personnalisés.

Il vous suffit juste de cliquer sur votre élément et de lui donner un petit nom.

Probablement le petit nom que vous aurez au préalable défini dans votre nomenclature :p

 

Sélecteurs CSS

Autotrack va prendre en compte votre sélecteur CSS et vous indiquer si il a été cliqué ou non. Toutefois, si Kevin n’a pas inséré des id ou tout simplement changé les classes Bootstrap, Mixpanel va compter tout ceci en doublon.

#jesuisbtnlarge

Pas d’inquiétudes voici une solution qui fera très bien l’affaire.

  1. Ouvrir l’inspecteur

  2. Copier le sélecteur CSS

  3. Coller dans Custom Event

Bonus : Si vous devez fusionner plusieurs éléments rajouter une virgule à la fin de votre sélecteur. Vous pourrez ainsi créer des custom events tout en restant en mode free chez Mixpanel.

Si vous souhaitez aller plus loin avec Mixpanel & Google Tag Manager je vous conseille cette vidéo :

Hotjar & Fullstory

Hotjar & Fullstory ne sont pas des analytics communs. Même si vous y trouverez des funnels, ou des diagrammes circulaires (a.k.a. camembert) leur force principale ne réside pas, à mon sens, dans ces représentations.

Leurs fonctionnalités principales sont l’enregistrement vidéo des parcours de vos visiteurs. Ces analytics très sérieux vous permettront de comprendre ce que fait réellement votre utilisateur.

Ces outils sont à mes yeux inévitables pour toutes personnes travaillant de près ou de loin dans l’UX.

Grâce à GTM vous allez pouvoir déclencher par exemple Hotjar sur votre Home et Fullstory sur votre App très facilement et ainsi économiser vos crédits freemium.

Dashboards & reportings

Votre écosystème est en place, vos tracking ne laissent rien passer, la vie est belle. Mais il manque encore quelque chose pour être au summum du kif : la génération de vos dashboards et autres reportings.

Google Spreadsheet

J’ai réalisé une vidéo l’an dernier pour présenter un module complémentaire de Google Spreadsheet qui est plus que pratique.

Le modus operandi est le suivant :

  1. Création de vos requêtes

  2. Planification

  3. Extraction des données

  4. Tableaux croisés dynamiques

  5. Représentation graphique

Avec ça vous n’avez plus à vous soucier de l’actualisation de vos dashboards, Google s’en charge tout seul dans la nuit, comme un grand.

Toutefois attention à ne pas compiler des données échantillonnées dans vos tableaux de bords, ça ferait mauvais genre (En effet, Google Analytics a tendance à échantillonner les datas quand vous faîtes une requête trop importante).

Google Data Studio

Vous avez probablement entendu parler de cette louable initiative de Google de nous fournir encore un outil aussi beau que puissant pour visualiser nos données.

J’ai l’impression que je fais une lettre de motivation à Google…

GDS est très pratique car parfaitement synchronisable avec Google Analytics et aussi et surtout Google Spreadsheet. Grâce à cela vous allez pouvoir rapatrier dans l’interface de visualisation vos données actualisées et calculées.

Dernière fonctionnalité très appréciable, la connexion de bases SQL. Pour que Kevin soit enclin à vous donner les accès, demandez un accès en lecture, ça suffira amplement.

J’ai aussi l’occasion de tester Reeport qui est une alternative plus que solide à Google Data Studio. L’interface est particulièrement fluide et soignée.

Conclusion

La data est votre juge de paix. Sans ces précieuses données vous ne serez pas capables de faire évoluer votre produit.

L’objectif sous-jacent de cet article est donc de vous donner tous les outils, bonnes pratiques, pour que vous déployez dès le premier jour le meilleur système (gratuit) possible. Gagnez du temps et réinvestissez le dans ce qui est probablement le plus important : l’amélioration de votre compréhension utilisateur.

Les features viendront par la suite et Kevin saura quoi coder grâce à vous.

Pour t’inscrire à la newsletter c’est là :

scraper-avec-nodejs

Scraper avec nodejs

Il est temps. Pour 2017, il me semble important de maîtriser un langage de programmation. J’ai essayé plusieurs langages (php ou même ruby) mais mon dévolu se porte aujourd’hui sur le javascript. Plusieurs raisons à cela. Tout d’abord, le javascript peut être utilisé autant en front qu’en back. Ainsi l’apprentissage d’un seul langage peut être profitable partout. Autre point, la communauté js me semble la plus active mais surtout très créative. Enfin, un environnement javascript retient tout particulièrement mon attention par sa puissance : nodejs. Pour vous montrer et démontrer sa puissance, nous allons voir comment coder un scraper avec nodejs.

Introduction

Il serait malvenue de ma part de réaliser ici un réquisitoire pour un langage que je viens à peine de découvrir. J’aurais aussi bien du mal à vous expliquer les tenants et aboutissants de nodejs, mais pour ne pas vous laisser sur votre fin/faim, je vous invite à regarder cette excellente vidéo de Grafikart.

Si vous n’avez jamais écrit du javascript, je vous conseille Sololearn dans un premier temps et Codeacademy par la suite.

Installation

Nodejs a un autre avantage, il est multi-plateforme. Que vous soyez Windows, Mac ou Linux, vous pourrez utiliser nodejs sans problèmes. Pour l’installation, rendez-vous sur nodejs.org et installez le logiciel.

En termes d’éditeur de texte, je vous conseille un IDE qui embarque un terminal. Visual Code Studio fera parfaitement l’affaire, en plus il est gratuit, open-source et tout comme node, multi-plateformes.

Scraper avec nodejs

Je tiens à remercier Gabin Desserprit pour son aide à la rédaction de cet article et à ses nombreuses contributions sur le sujet. En plus, il prend le relais pour le prochain exercice de scraping :)

Enregistrer la page HTML

Le cobaye pour ce test sera le site growthhacking.fr où nous dissertons avec d’autres collègues growth hackers passés maîtres dans l’art de scraper avec nodejs. Pour faire fonctionner ce code, il vous faudra installer axios au préalable. Rien de très compliqué. Placez vous à la racine de votre dossier et exécuter dans votre terminal :

npm install axios
Installation d'Axios

Ce qui est vraiment pratique avec nodejs, c’est l’usage de npm qui vous permet d’installer des paquets et leurs dépendances associées.

Pour les plus curieux, vous pouvez aller faire un tour sur le site de npm

let fs = require('fs');                                         // fs nous sert ici à écrire notre fichier
let axios = require('axios');                                   // axios sert à réaliser une requête http

axios('https://www.growthhacking.fr').then((response) => {      // on demande ici à axios d'aller sur growthhacking.fr, si la réponse est bonne...
    fs.writeFileSync('gh.html', response.data);                 // alors fs enregistre le code html dans le fichier gh.html
}, (error) => {                                                 // si ça marche pas...
    console.log("Error: ", error);                              // merci d'afficher l'erreur dans le terminal :)
});
Enregistrer la page html

Vous pouvez donner le nom que vous voulez à votre fichier. Pour l’exercice je vous propose de l’appeler script.js

Extraction des datas

Normalement, votre code enregistre la page gh.html. La prochaine étape est de parser le fichier et extraire les données.

Nous aurons besoin cette fois-ci de deux autres paquets npm : cheeriojsonframe-cheerio.

npm install cheerio
npm i jsonframe-cheerio --save
Installation de Cheerio & Jsonfrme-cheerio
let fs = require('fs');                                                         // fs nous sert ici à écrire notre fichier
let axios = require('axios');                                                   // axios sert à réaliser une requête http
let cheerio = require('cheerio');                                               // on charge cheerio
let jsonframe = require('jsonframe-cheerio');                                   // et jsonframe-cheerio

axios('https://www.growthhacking.fr').then((response) => {                      // on demande ici à axios d'aller sur growthhacking.fr, si la réponse est bonne...
    fs.writeFileSync('gh.html', response.data);                                 // alors fs enregistre le code html dans le fichier gh.html
    if (response.status === 200) {                                              // si la réponse du serveur est 200 OK
        let $ = cheerio.load(response.data);                                    // on enregistre le contenu html dans une variable $
        jsonframe($);                                                           // cette dernière est placée dans une jsonframe
        var frame = {                                                           // on créé une autre variable frame qui nous permet de construire notre objet
            "post": {
                "selector": "[itemprop=itemListElement]",
                "data": [{
                    "name": "[itemprop=name]",                                  // tous les éléments qui nous intéressent sont décomposés ici
                    "url": {                                                    // pour les retrouver consultez la page gh.html
                        "selector": "[itemprop=url]",                           // et la documentation de jsonframe-cheerio
                        "attr": "content",
                    }
                }]
            }
        };
        var postsList = $('body').scrape(frame);                                // on créé une varibale postsList qui reprend les posts scrapés dans le body
        fs.writeFile('gh.json', JSON.stringify(postsList), function (err) {     // fs.WriteFile nous permet d'enregistrer nos données stockées dans postsList
            if (err) {
                return console.log(err);                                        // y'a un blème ?
            } else {
                console.log("Le fichier est sauvegardé ! #OKLM");               // si tout roule, tu trouveras ce message dans le terminal
            }
        });
    };
});
Scraper avec nodejs

Exécution du script

Votre script semble fonctionner ? Qu’une seule façon de le savoir, l’exécuter !

node script.js
Exécution du script

Si tout fonctionne, vous devriez avoir un message dans votre terminal et votre fichier .json enregistré à la racine de votre dossier.

Le résultat : vous avez réalisé votre premier scraper avec nodejs !

Ce premier script est une première base pour vos prochaines actions. À vous de vous adapter aux prérequis des sites que vous souhaitez aspirer et d’améliorer votre script.

Bonne chasse !

Pour vous inscrire à la newsletter c’est par ici :

Comment j’ai hacké le WebSummit ?

Du 7 au 10 novembre se déroulait à Lisbonne l’un des plus grands rendez-vous web du moment, le WebSummit. Bloomberg nous propose l’analogie suivante : « Davos for geeks ». Et il faut dire qu’ils ne s’étaient pas trompés.

Le WebSummit et ses stars

Lors de mon précédent article sur The Next Web @Amsterdam, j’avais pu remarquer cette tendance à idolâtrer ces nouvelles étoiles montantes du web. Que ce soit CTO (Facebook, Amazon) ou producteurs de contenus (ProductHunt, Reddit) de nouveaux métiers voient leurs popularités s’accroîtrent rapidement, très rapidement. Voire même, peut-être, trop rapidement.

En effet, beaucoup de personnes interrogées au WebSummit ont vécu la même contrariété: les conférences étaient décevantes.

Le storytelling semblait peu sincère et les sujets traités étaient (volontairement?) faibles. Malgré les noms ronflants proposés par l’organisation, je suis resté sur ma faim. Il est possible que mon niveau d’attente fût trop élevé également.

Le WebSummit et son ambiance

Toutefois, une ambiance conviviale s’est vite installée dès le premier jour. Cette atmosphère était très favorable aux échanges. Saluons ici la qualité de l’accueil des Lisboètes qui fût, pour ma part, irréprochable.

Point positif de la conférence, l’exhaustivité des sujets proposés. AI, Gaming, VR, Advertising, Saas, Travel, FinTech, peu de sujets manquaient à l’appel. Cette diversité a eu pour effet d’équilibrer le salon et surtout de rendre juste le nom de cet événement : le sommet du web.

Autre atout du WebSummit la connexion WiFi… Non je déconne, une catastrophe.

Conseil : si vous allez dans un événement de cette envergure, achetez-vous une SIM locale pour pouvoir profiter de la 4G locale…

Le WebSummit et son hack

La veille du salon, j’étais à la recherche d’un hack qui me permettrait d’avoir une matière à exploiter pendant mon séjour, mais surtout pour pouvoir être précis sur le Summit Hacking (je viens de déposer un brevet sur cette appellation donc fais gaffe…).

Car en effet, les salons sont des moments privilégiés pour tout Sales Hacker qui se respecte. La vitesse des contacts est décuplée et un souvenir commun est à mettre au crédit de cette nouvelle relation qui démarre. Sans parler de la démonstration in situ qui est souvent bien plus efficace qu’un Skype.

API publique je t’aime

L’avènement des nouveaux frameworks Js (React, Angular etc.) est une aubaine pour les growth-hackers. Les API étant publiques, il suffit tout simplement d’avoir une connexion Internet et un semblant de logique pour pouvoir recréer des bases de données intéressantes.

Je rappelle à mon (nouveau) lectorat que je ne suis pas un développeur. Intégrateur du dimanche pourquoi pas mais pas dév’ !

Le meilleur apprentissage c’est par l’exemple non ?

Le point de départ

Ce qui m’intéressait c’est d’avoir la liste des attendees. Au total nous étions 55,306 à être passé par la conférence. Beau score.

Donc pour commencer, il faut se rendre sur la page Attendees.

websummit

Cliquer sur F12 (Developer Tools) puis sur l’onglet Network. Cet outil vous permet, entre autres, d’analyser le code HTML & CSS de la page mais aussi et surtout d’intercepter les requêtes client<->serveur.

Si vous souhaitez en savoir plus, je vous conseille cette vidéo de Julien Le Coupanec.

web-summit-lisbon

Rafraîchir la page (F5 ou Ctrl+R) puis scroller de bon cœur et là le miracle se présente !

summit

Vous trouvez une requête qui semble être intéressante : attendees?limit=25&page=2

web-summit

Comme par magie vous avez le résultat des listes chargées.

Mais que se passe-t-il si vous inscrivez 55306 en limite ?

Et bien vous avez la liste des toutes les personnes présentes au salon :)

Ni plus, ni moins !

Enrichir pour mieux cibler

LinkedIn

Grâce aux informations First_name, Last_name & Company, vous allez être capables de retrouver beaucoup de profils sur LinkedIn.

Mon premier conseil est de segmenter votre cible au maximum grâce à Company.

Souvent, quand vous souhaitez toucher tout le monde, vous ne touchez en réalité personne.

Pour cette première étape d’enrichissement j’utilise ce magnifique Add-on qu’est Blockspring. Vous vous souvenez, je ne suis pas dév’. Mais au-delà de tout ça je suis fainéant et j’aime bien aller vite sans faire trop d’efforts.

web-summit-lisboa

J’ai masqué le nom de famille pour ne pas être « trop » vache…

Une fois votre fichier chargé dans Google Spreadsheets :

  • Add-ons
  • Blockspring
  • Authentifications
  • Puis vous cherchez « Retrieve Linkedin Profile URL »
retrieve-linkedin

Vous choisissez «Insert as a formula »

linkedin-profile

Si vous avez agencé votre tableau comme moi, il vous suffira d’inscrire cette formule en colonne D :

=BLOCKSPRING(« get-linkedin-profile-url », « name », concatenate(A2, » « ,B2, » « ,C2))

linkedin-web

Et voilà vous y êtes !
Le taux de retrieve est excellent car pour l’instant c’est + de 85 % qui sont retrouvés. Attention toutefois aux homonymies même si la Company évite bien souvent ce cas.

Il ne vous reste plus qu’à soigner votre profil en indiquant votre présence sur le salon dans la description par exemple et à ajouter les différents attendees pour établir un contact avec eux.

Un script de quelques lignes pourra faire l’affaire une fois les URLs définies.

Email

Maintenant si vous souhaitez avoir les emails de toute urgence, il vous faudra passer par des outils intermédiaires.

Mon préféré pour cette étape bien précise est Voila Norbert

voila-norbert

Simplement en ajoutant les 3 paramètres voulus vous allez pouvoir retrouver les emails des attendees à hauteur de 30 %.

Ce score s’explique car le fichier reprend les volontaires, les étudiants etc. Toutefois je ne pense pas que ceci est une quelconque importance pour vous, car tout le monde sait, les étudiants n’ont pas de thunes.

Ce qui est intéressant c’est la vérification d’email pour éviter de salir vos adresses IP. Même si le risque zéro n’existe pas (trap box) cela vous donne un bel indicateur.

Je vous conseille par la suite d’éditer un drip de mail bien en amont de votre salon avec MixMax en proposant votre lien Calendly pour faciliter la prise de rendez-vous.

Et faîtes-moi plaisir, relancez, relancez, relancez mais aussi et surtout soyez disruptifs, disruptifs, disruptifs !

 

 

PS : Désolé j’ai pas tout dit sur ce hack :) si vous êtes curieux on se prend un expresso ? Je vous expliquerai comment trouver le Twitter Handle, la localisation, la photo de l’attendee et surtout ses intérêts.

PPS : Voici la version English si tu veux…

traction

HappyDriver, la maîtrise de la traction

Depuis mon retour à Toulouse, j’ai été agréablement surpris de la manière dont ce sont organisées les start-up entre elles. Une des initiatives les plus réussies, la création d’At Home, espace communautaire de start-up où cohabite plus de 100 start-upers. L’une d’elles a particulièrement attiré mon attention, et celle de mes confrères : HappyDriver. Ce qui m’a le plus plu en elle c’est sa traction pleinement maîtrisée.

Cette start-up propose un service innovant autour de la réparation/entretien de véhicule. Après avoir contacté HappyDriver, vous recevez un devis comprenant les pièces et la main d’œuvre associée. Une fois accepté, l’équipe récupère votre véhicule et le déplace auprès du garagiste attitré. La réparation faite, HappyDriver ramène votre véhicule, nettoyé à l’intérieur et à l’extérieur. Composante intéressante de leur proposition de valeur, la partie conciergerie (déplacement véhicule + nettoyage) est proposée sous forme de participation libre.

Aujourd’hui l’équipe est débordée car elle bénéficie d’un bouche à oreille très puissant. Mais bon ça reste plutôt agréable d’avoir des problèmes de riches de ce genre non ?

Origine

Au tout début Nicolas & Aurélien, 2 des 3 cofondateurs d’HappyDriver, s’étaient associés pour monter un projet autour du pneu d’occasion : AtoutPneu. Malheureusement pour eux, le terme pneu d’occasion était mal perçue par les consommateurs.

Pour rebondir ils essayèrent de reprendre une société opérant dans ce secteur, mais ce fût également un échec.

Au sortir de cette 2ème expérience, ils décidèrent de monter Le pneu pas cher, avec cette fois-ci une démarche start-up. Bien conseillés par d’autres entrepreneurs toulousains, Nicolas & Aurélien se mirent à étudier le lean start-up et à visionner une multitude de vidéo de The Family.

C’est grâce à cette nouvelle ouverture d’esprit que nos joyeux entrepreneurs décidèrent de pivoter et il faut dire que ça reste bien original la manière dont ils ont trouvé ce pivot :)

Pivot

En discutant avec Nicolas & Aurélien, il ne vous faudra pas longtemps pour vous apercevoir que ces gars sont plein d’idées et qu’ils sont fondamentalement animés d’un esprit disruptif.

On cherchait des clients, alors on déposait des papiers sur les voitures qui avaient des pneus très usés.

Do things that don’t scale qu’ils disaient…

Avec cette démarche ils eurent un client qui déclencha leur stratégie gagnante. Le client en question expliqua qu’il avait besoin d’une solution plus complète. Les pneus c’est bien mais ça fait pas tout. Pour faciliter l’affaire, Nicolas se propose d’amener et ramener le véhicule. Habitué des garages automobiles et de leurs bonnes habitudes, Nicolas décida de nettoyer le véhicule intégralement.

Pour rémunérer ce service, Nicolas proposa une participation libre. Et c’est à l’issue de cette transaction que tout se déclencha. En racontant leur aventure à leurs camarades d’At Home c’est une pluie de demandes qu’ils reçurent.

Success is obvious qu’ils disaient (aussi)…

Ce pivot de type zoom-out est brillant, c’est le moins que l’on puisse dire. Mais qu’est-ce qu’il fait que ça a correctement fonctionné ? A mon sens ce pivot tient sa force dans 3 sous-composantes.

Participation libre

Par sérendipité, Nicolas proposa une participation libre à ce fameux client. Pour lui cela permet de mettre le prospect dans une situation de confiance. Peut être qu’à l’avenir le service pourra se proposer directement dans le devis, mais est-ce que psychologiquement cela ne sera pas un frein ?

En effet, vous êtes capable d’amener votre voiture à votre garagiste. Vous êtes également capable de nettoyer votre voiture.

Pourtant vous ne le faîtes pas forcément. Pourquoi ? Les horaires de travail, la flemme, le manque d’envie etc … tout autant de faits avérés bien assimilés par HappyDriver.

C’est peut être en ça que la participation libre peut faire sauter des verrous psychologiques.

Traction vs Growth

Ce qui est également intéressant dans leur démarche, c’est cette capacité à dissocier instinctivement traction vs growth.

Tous les clients sont encore exploités dans un processus ingénieux mais toujours très artisanal. L’essentiel de leur processus se réalisant via le CRM Base.

Cependant grâce à cette humilité entrepreneuriale (qui fait souvent défaut à beaucoup), c’est un product-market fit solide qui a ici était construit.

Même si dans le tableau Traction vs Growth du légendaire Brian Balfour, on mentionne la rétention en KPI de Traction, dans le cas d’HappyDriver c’est un peu différent. Vous n’amenez pas votre véhicule au garagiste toutes les semaines, encore heureux. Le KPI temporel de rétention d’HappyDriver est élevé (6 mois – 1 an). Le referal est déjà très puissant et les plus gros effets de réseaux sont encore à venir.

Orienté client pour une valeur ajoutée explosive

Là pour le coup c’est du rarement vu. J’ai pu travailler dans quelques start-up mais je n’ai jamais collaboré avec une entreprise qui prenait ses clients avec autant de sérieux et d’attention.

A l’issue de chaque prestation un formulaire est dispensé pour connaître la réelle valeur ajoutée de leur prestation.

Pour eux, hors de question de négliger le moindre détail. Que ça soit venir chercher un véhicule à 6h du matin ou bien le ramener en début de soirée au lieu convenu, HappyDriver se plie en 4 pour vous réaliser le meilleur service possible.

#bouillant

La suite ?

Cadrant plus que correctement avec les préceptes lean start-up, nos chers trublions se concentrent sur une zone précise de Toulouse, très dense en entreprise, pour profiter des effets de réseaux internes.

Côté technologie c’est un chatbot qui semble être la solution idéale pour pouvoir répondre à leur flux de demande de devis.

Adepte de blagues pourries pour finir, je n’ai plus qu’à leur souhaiter bonne route…

#jesors

sdk

Comment générer des hacks avec des SDK ?

La joie des stores ! J’en avais entendu parler, mais s’y confronter c’est tellement plus marrant. J’avais bien travaillé sur quelques lancements, sur de l’ASO par le passé, mais rien de comparable à ce que je vais vous présenter. De la conception en passant par ma première panne serveur, je vais tenter de vous décrire notre parcours avec MyBetFriend et vous dire comment nous nous en sommes sorti avec notamment 3 SDK fabuleux.

Concevoir une application ou l’art de perdre 5 ans d’espérance de vie en autant de semaines

Beer & Pitch

Il fallait bien y aller dans le mobile un jour. Oui, il le fallait. J’avais bien eu quelque idées mais rien de quoi constituer une équipe sur un objectif commun. Comme toute idée valable du IIIème millénaire, celle-ci naquit autour d’une pinte de bière avec un ami. Nous regardâmes un match de foot dans un bar miteux de Paris, et soudain éclair !

Parier ma bière auprès de mon ami selon l’issue du match. Tout deux fascinés par les chiffres, nous nous sommes projetés dans l’agrégation des données statistiques TV en live dans cette hypothétique application mobile.

Ça doit déjà exister… Tu penses que ça plaira ? Mouairf… C’est sympa mais bon…

Il fallut se rendre à l’évidence, mon elevator pitch était nul et donnait autant envie que la vision de Margaret Tatcher nue dans la neige (désolé…).

Face à ce premier échec, je décidais d’appeler l’éditeur de statistiques en question et de lui soumettre mon pitch. Grâce à quelques bottes secrètes je réussis à contacter mon interlocuteur 48h après mon premier coup de fil.

Après avoir pitché mon embryon de projet, je n’entendis qu’un silence pesant. Mais cette fois-ci la réponse fût positive. En fait, ce silence marquât mon premier succès, celui d’avoir attirer l’attention et proposé un service novateur auprès d’un professionnel du secteur.

Il faut être bien évidemment lucide, avec mon fournisseur nous allions commencer une relation commerciale aussi. Mais au vu et au su de son soutien indéfectible, je pense que notre alliance allât plus loin qu’une simple relation tarifée.

Les faisabilités techniques et temporelles scellèrent ma joie et firent naître mon optimisme (naïf) d’entrepreneur digital.

Un pour tous et tous pour un #YOLO

Requinqué par ce premier « succès », je fus à même de monter une équipe de 6 personnes. En l’espace de 2 mois nous étions fixé sur un nom, sur un concept, et surtout sur une finalité à donner à ce projet.

Fondamentalement, nous en avons tous marre de ce bullshit continuel «plus qu’une société, une équipe gnia gnia… » mais typiquement comment les start-up peuvent réaliser de superbes projets sans une équipe de rockstar ? Un grand groupe, avec de l’ancienneté, un réseau, une marque connue, peut se traîner des boulets dans son effectif. Une start-up non. En tout cas si elle le fait, elle finira très rapidement dans le cimetière des start-up.

Il existe plus de start-up mortes que de start-up en activité. Click To Tweet

#instantprofond

Pour en revenir à l’équipe, je dirais qu’il faut retrouver en elle tous les caractéristiques qui permettront de réaliser des 1+1=3.

Avec de la contradiction on améliore ses idées, son travail. Je pense que cette notion est tout de même fondamentale si tant est que vous recherchiez un produit qui s’adresse à autre chose qu’une étroite niche.

Et la conception fût…

J’ai pu remarquer que lorsque vous créiez une application ou quand bien même un service innovant, la majorité des personnes ont tendance à entendre ce qu’elles veulent et à devancer votre effort sacré d’imagination. Infâmes cloportes ! Même si vous pouvez avoir de superbes idées qui viennent à la volée, il va vous être impossible d’avancer sur votre projet. Vous allez déployer toutes les features suggérées par tout votre entourage et votre application ne ressemblera plus à rien.

A vouloir plaire à tout le monde, vous ne séduirez personne et même vous vous aurez un certain dégoût pour vous-même par la suite.

C’est à cette étape bien précise qu’il est de bon aloi d’utiliser Canva (ou Balsamiq) & Invision.

Grâce à ce couple de SAAS gratuit, il vous sera possible de réaliser vous même votre prototype d’application et d’itérer dessus sans même à avoir expliquer vos tenants et aboutissants.

L’UX c’est comme une blague, si tu dois l’expliquer c’est que c’est pas bon

A ce petit jeu là je peux vous garantir qu’avec mon équipe on a pas été tout le temps drôle. Loin de là. Mais mauvaises blagues après mauvaise blagues, nous avons pris le parti de simplifier notre service au maximum et surtout de s’en remettre à une chose pour trancher nos décisions : la data.

Toute le monde n’a pas le même humour. Pourtant nous partageons tous, quelques trucs en commun. Par exemple : les cons, l’air que nous respirons, les gamins qui chialent dans le train (j’en ai un à côté de moi que j’ai envie de massacrer là…), les lois de la physique et les mathématiques. Notre avions donc décidé de choisir ce dernier point pour avoir un juge de paix. C’est assez paradoxal car je connais peu de personnes qui exultent à la vue d’une feuille Excel, mais quand bien même, être data-oriented ne vous fera aucun mal si vous lancez une application.

Exemple de blague tentée : le login uniquement par Facebook. Même si ça n’a pas fait marrer tout le monde au départ, il aura gêné, in fine, 13 % de l’ensemble de nos utilisateurs. Et cette métric nous a été remontée par le premier SDK que je vais vous présenter, MixPanel.

Les SDK c’est trop bien !

MixPanel

Ai-je encore besoin de présenter MixPanel ? Oui ? Bon ok…

MixPanel est à l’application mobile ce que Michael Ange est à la renaissance italienne. (Normalement avec une présentation comme ça et un backlink aussi puissant je devrais gagner un peu de datas gratis…).

Mais arrêtons là les conneries, MixPanel est avant tout un SDK d’Analytics gratuit jusqu’à un certain niveau de consommation. De plus votre développeur n’aura aucun mal à intégrer ce SDK sur iOS & Android.

Fonctionnalités

Les fonctionnalités de MixPanel sont multiples et variées. Vous allez être tout d’abord en mesure de garder la trace de tout vos utilisateurs, définir des profils, intégrer leurs tokens pour déboguer et retrouver ainsi rapidement toutes les informations que vous souhaitez remonter.

De plus vous allez être en mesure d’intégrer des funnels de conversions qui vous montreront les différents points de frictions de votre application. A vous de travailler conjointement avec vos designers et développeurs pour éviter toutes chutes. La bonne interprétation des metrics est souvent à l’origine des hacks.

Autre fonctionnalité, les cohortes de rétentions. C’est peut être là que ça commence à vraiment devenir marrant. En effet, réaliser une application c’est cool, la développer c’est marrant mais générer de la rétention c’est générer de l’amour pour elle. On a plaisir à y aller et surtout à y revenir.

C’est là qu’on (en général) monétise et qu’on génère de la marge nette de manière durable. Difficilement ailleurs.

MixPanel présente aussi d’autres fonctionnalités comme l’A/B testing et les notifcations. Mais ça ça vient plus loin…

Alternative à MixPanel, Amplitude SDK suggéré par Alexandre Jubien de Thinkmobile

OneSignal

Le problème avec les notifications c’est qu’elles ont souvent une fâcheuse tendance à vouloir partir toutes en même temps. Et si votre développeur ne prévoit pas une méthode pour les espacer afin d’éviter un pic de charge trop violent, vous allez avoir un nombre incalculable de notifications non délivrées. Qui plus est difficile de dire à la volée combien sont envoyées, cliquées etc.

C’est à ce niveau précis que OneSignal intervient. Cette fois-ci pas besoin de cirage de chaussures, One Signal est entièrement gratuit.

Le SDK est semble-t’il un petit peu plus complexe à intégrer mais il en vaut la peine.

OneSignal vous permet d’envoyer quasiment toutes vos notifications et de surtout mesurer leurs impacts respectifs. OneSignal intègre parfaitement bien cette notion de reporting.

Cependant les fonctionnalités qui m’auront le plus servi n’auront pas étaient celle-ci.

Segments

OneSignal vous offre la possibilité de générer vos segments d’utilisateurs en fonction de :

  • Nombre de sessions
  • Durée des sessions
  • Première sessions
  • Latitude & Longitude
  • etc.

Grâce à ça vous allez pouvoir envoyer des notifications propres à chaque segments. Manuellement ou automatiquement.

Template & A/B Testing

Là ça devient très puissant. OneSignal va vous permettre d’envoyer automatiquement une notification bien précise lorsqu’un utilisateur rentre dans un segment défini.

Par exemple : nous avons défini dans MyBetFriend un segment « Hardcore users » pour les users dépassant plus de XX sessions. C’est donc à ce moment là que nous lui demandions de nous noter sur le store.

Une fois cette technique mise en place nos reviews 5 étoiles furent régulières.

Et pour bien optimiser ce processus, OneSignal vous propose de réaliser des A/B Tests pour définir le message le plus pertinent.

Que du bonheur !

Branch.io

Dernier SDK pour la route : branch.io

Bon là on frise l’indécence, l’obscène même. Toujours gratuit, ce SDK va vous permettre de générer notamment des deeplinks.

Ces liens (magiques) vont intelligemment comprendre sur quel appareil le lien est ouvert et appliquer un scénario différent.

Exemple : Si vous êtes sur un BlackBerry vous pouvez paramétrer l’ouverture du store BlackBerry bien la redirection vers votre landing page, ou bien votre liste Mailchimp.

Le SDK n’est pas évident à mettre en place, mais les deeplinks sont très puissants pour faciliter le partage. Un bémol toutefois, si vous utilisez un raccourcisseur d’url comme nous, il se peut qu’il soit mal interprété. C’est en ce sens que je vous invite à implémenter un SSL sur votre site et utiliser donc un shorter idoine.

Branch.io propose également un onboarding personnalisé. Même si cette feature nous a un temps intéressé nous l’avons (malheureusement) délaissé au profit d’autres fonctionnalités.

Néanmoins il va sans dire que pour notre V2 nous allons utiliser à fond cette feature.

Toutefois, la feature qui aura été des plus puissantes dans notre cas d’utilisation c’est la feature app banner. Même chose, selon votre device, cette banner s’ajoutera en haut de votre site réagira de différents manières :

  • Ordinateur : La possibilité d’inscrire son numéro de téléphone pour recevoir un deeplink d’installation
  • N’importe quel mobile : L’installation en renvoyant sur le ou les bons stores
  • Un mobile où l’application est déjà installée : L’ouverture de l’application
  • Et un autre mobile où l’application est déjà installée mais non à jour : La mise à jour de l’application

C’est grâce à cette banner que nous avons pu réaliser l’un de nos « hacks » les plus efficaces.

La publicité pour installation d’application étant hors de prix (1€ en moyenne) le fait d’envoyer du trafic uniquement sur notre site (CPC faible sur le foot) eut pour effet d’optimiser notre investissement.

Soit l’internaute téléchargeait l’application, soit il laissait son mail ou soit et bien il générait du trafic sur notre site. Pour ainsi dire nous évitions toutes pertes d’investissements. Si vous êtes en plus l’heureux détenteur d’un blog et/ou d’un site drainant pas mal de visites quotidiennes vous allez pouvoir assister à un bond spectaculaire (je l’espère) de vos installations.

SDK Bonus, Launchkit.io

Dernier SDK et pas des moindres, Launchkit. Récemment acheté par Google, ce SDK nous a permis de gagner énormément de temps sur :

  • Génération des images iOS (apparemment plus besoin maintenant…)
  • Onboarding
  • Review monitor

Ils ont récemment déployé sur git l’ensemble de leurs codes. A voir ce qu’ils vont réaliser par la suite avec Google.

En espérant que cet article t’a plu, on peut se retrouver sur les Internets ici. On discutera de pannes serveurs et d’AdminSys, tu verras c’est rigolo :

The Next Web @Amsterdam

Du 26 au 27 mai s’est déroulé à Amsterdam une conférence que j’aurais tendance à qualifier de sensationnelle. The Next Web réunit chaque année les plus grands pontes du web à Amsterdam Je tiens à préciser à mes lecteurs que je ne suis pas un expert des conférences web mais quand dans la même après-midi vous avez Ryan Holiday & Werner Vogels qui présentent leurs dernières trouvailles, nous sommes en droit de dire que ça commence à envoyer du bois.

Jour 1

tesla3

Comme un symbole. Les startups bougent vite et font preuve d’une efficience à toute épreuve. Comme un totem, il était de bon aloi de déposer une carte de visite pour aller faire un tour avec. Je suis pas (encore) journaliste chez Turbo mais j’apprécie le côté Dolerean avec ces portes old-school/futuriste.

Il m’aura pas fallu longtemps pour être à l’aise. J’ai eu le plaisir de rencontrer Drew Lawrence Chief of Staff @Full Contact. J’ai pu très simplement lui parler et lui montrer mon template Excel qui utilise son API. Le premier mot qui lui est venu fût…. « Awesome ! » Oui Drew est américain. Il a vainement tenté de me débaucher mais je lui ai dit que si j’avais pas la Tesla garée à l’entrée c’était même pas la peine d’y penser. Il m’a gentiment proposé de poursuivre ma visite, vraiment étrange.
 fullcontact

Bon c’est bien sympa Amsterdam quand il fait beau mais bon je suis pas venu pour couper les tulipes, en avant pour la première conférence. Quoi de mieux que Meghan Keaney Anderson VP @Hubspot pour se mettre en selle.

seo-hubspot

Son intervention était, comme beaucoup de fois avec Hubspot, brillante. Cette charmante jeune fille nous a parlé du futur du SEO et il est vrai qu’il nous faut déjà penser à la suite des événements. En effet, la recherche évolue et donc mécaniquement sa stratégie. Meghan a eu la politesse de rappeler à son auditoire que la recherche vocale prend de plus en plus de poids et que cette tendance ne semble pas s’essouffler. Cortana, Alexa et autre Siri deviennent de plus en plus efficaces.

Maintenant que je suis en jambes, allons voir ce qui se passe dans le bâtiment principal.

julie-zhou

Ah bon Rammstein joue ici ?

Non non c’est la VP Facebook

Oh pardon…

La sensation était vous l’aurez compris particulière. Nous étions entassés comme dans un concert de rock à écouter Julie Zhou VP Product Design @Facebook à comprendre comment Facebook concevait et itérait pour ses produits et plus particulièrement pour le Facebook Live. La chose qui m’aura le plus frappé c’est donc ce système de beta-test. Les employés de Facebook sont investis dans leur vie privée pour tester en situation « réelle » les produits Facebook. Et lorsque vous avez des centaines d’employés et bien vous remontez une masse d’informations provenant de situations hétérogènes. Pratique pour lancer un nouveau produit non ?

julie-ben-hayoun

Et puis là c’est la claque, « Le Grand Bombardment ». Connaissiez-vous Nelly Ben Hayoun ? Si oui, je vais porter plainte contre vous car vous me l’aviez jamais dit. Sa présentation était d’une telle énergie que j’ai été littéralement été bouche bée. Ses travaux sur le design sont juste fabuleux et demeurent pour moi (désormais) une source inépuisable d’inspiration. Merci à toi Julie.

Le reste de la journée j’ai tenté de m’intéresser aux startups invitées. Je vous avoue avoir été particulièrement navré par les présentations des unes et des autres. Il est vrai que la plupart était très early stage, mais quand bien même il faut à un moment donner mouiller le maillot.

Quelques jours auparavant la conférence j’ai eu plaisir à recevoir ce mail :

garyvee

Ça fait toujours plaisir:) A l’heure où j’écris ces lignes, je n’ai pas eu l’occasion de lire ne serait-ce qu’une page du livre mais je suis sûr que de superbes idées y sont présentes. Merci Gary et bonne continuation :)

Jour 2

Deuxième jour. On reprend pas les mêmes mais on recommence. Pour commencer de bon matin, une superbe présentation de Jon Troutman designer @Canary.

jon-headshot

Son intervention était basée sur le parallèle entre la relation amoureuse et le design d’un produit. Et je peux vous dire qu’après réflexion, cette métaphore est loin d’être grotesque. Pour une aventure d’un soir ou un engagement advitam eternam, la stratégie employée n’est pas tout à fait la même. Autre point, comme dans toutes les relations vous avez des moments où il est impérieux de discuter, d’écouter et de comprendre ce qu’on vous dit. La leçon est donc la suivante : que ce soit en itération produit ou bien en couple, il faut toujours écouter son partenaire.

Sur cette deuxième journée le niveau des jeunes start-ups invitées fût drôlement meilleur. On a pu tout voir, des data-scientists en blouse blanche, à des costards verts + chaussures lumineuses, on peut dire qu’il y a eu un effort sales de fait.

Il faut croire que j’en avais pas eu assez avec ma première journée, je décide de suivre l’intervention de Bill Buxton, primer researcher @Microsoft.

Je pourrais réaliser un article de 2,000 mots uniquement sur ses 20 minutes d’intervention mais bon si il fallait isoler quelque chose, je pense que cette image parle d’elle même.

bill-bbuxton

Bill a exprimé très sobrement qu’est ce qui faisait qu’un produit s’envolait ou non, c’est potentiellement cette dimension (réelle) d’écosystème. En effet, comme vous le constaterez, 3 règles semblent tenir à cœur à Bill.

Selon lui il ne suffit pas que votre produit/service soit bon, il faut aussi qu’il rendre meilleur les autres produits/services attenants. Ne serait-ce pas ce que Slack a réussi à faire ? Créer un SaaS qui rend meilleur tous les autres SaaS. Bon, ça fait un peu seigneur des anneaux désolé, mais je trouve cette dimension pour le moins intéressante.

Pour s’en remettre il a fallu que je me restaure.

frites

Quelques échanges informels avec d’autres participants, un repos bien mérité dans les jardins du lieu et il était temps de lancer le dernier sprint.

Qui de mieux que Docteur Werner Vogels CTO @Amazon en charge du Machine Learning, pour en prendre plein la figure ? A ce niveau là on peut parler d’indécence. Notre Docteur a eu la gentillesse de nous partager brièvement son modèle de Machine Learning utilisé.

Amazon n’est pas leader par hasard. Et à mon avis cette notion arbitraire de l’aléa n’est pas du goût de Herr Vogels. Pour la réussite de ce genre d’outil une boucle itérative est à mettre en place. Pas une grande nouvelle mais ce que j’ai particulièrement apprécié c’est cette méthode de validation.

Afficher l'image d'origine

Peu de temps après l’ami Werner s’est transformé en développeur évangéliste en nous exposant la solution Amazon ML. J’ai là aussi pas eu le temps d’étudier cette solution de plus près, mais il y a fort à parier que Growth Hacking & Machine Learning auront tendance à fusionner et à offrir des résultats substantiels dès lors que l’exécution sera soignée.

Ce que je peux retenir aussi de cette conférence c’est la qualité des présentateurs. Position difficile de passer après de telles pointures mais je peux dire que cette fonction aura parfaitement été remplie par Boris. Les blagues n’ont pas cessées mais je me dois de vous en partager une :

Savez-vous ce qu'est une Shitistics ? C'est une statistique de merde impossible à expliquer. Click To Tweet

Effectivement, ce n’est pas aussi fin qu’un calembours de Jean Marie Bigard, surtout sorti de son contexte, mais je pense que ma future devise avant une réunion sera « No Shitistics Allowed ».

Dernier intervenant sur lequel je souhaitais écrire quelques lignes, Ryan Holliday. Il n’est même plus la peine de présenter qui est Ryan mais mon excitation s’est rapidement transformée en déception. Ryan a tenté de nous faire énormément de parallèle avec la philosophie antique (Épicure par exemple) et l’entrepreneuriat mais son effet ne s’est pas avéré parlant. En effet, en 2016 on ne lit plus ses slides Ryan, on sait lire, merci. Ryan n’en demeure pas moins fantastique par ses livres et sa disponibilité auprès de son public pour signer des autographes, beau geste.

Mais je le concède cela doit être sacrément difficile de passer derrière Casey :)

C’est sur cette note que j’ai dû quitter la conférence et m’enquérir de prendre mon Thalys.

Une chose est sûre, cette conférence m’aura permis d’ouvrir mon esprit sur d’autres aspects et de me donner du grain à moudre pour mes prochains itérations.

Je veux des leads !

Finies les inepties sur Facebook, aujourd’hui on va parler B2B et Leads. Les metrics c’est bien, mais quand se transforme en Résultat Net c’est mieux. Car c’est bien de ce rapport, Chiffre d’Affaires versus Charges, que nous devons constamment perfectionner pour garder sa start-up à flots. Avec les techniques que je vais vous présenter ci-dessous, vous allez ainsi pouvoir économiser votre Coût d’Acquisition Client et prospecter bien tranquillement depuis votre canapé.

Profile Hopper

L’extension Profile Hopper est une visionneuse Linkedin très puissante. Après avoir installé l’extension Chrome, vous allez pouvoir visionner de manière automatique les personnes qui répondent à votre recherche (poste, ville, entreprise etc…).

Notification Linkedin

Première étape, la visite d’un profil Linkedin déclenche une notification chez la personne visitée. Si votre intitulé de poste et votre nom d’entreprise est cohérent avec l’activité de vos leads, vous pouvez déjà vous attendre à générer du flux entrant.

Mon conseil est d’inscrire votre site internet en intitulé de poste. Facilitez la recherche de la personne sans qu’elle ait besoin de chercher votre site dans Google. Là encore diminuez toute friction éventuelle ;)

Twitter

Vous avez visité des profils, ils visitent votre site, votre profil en retour et vous êtes prêts à dégainer votre arme favorite : le téléphone. Et bien attendez encore un peu ! Vous pouvez faire quelque chose de très pratique, un mass follow des comptes Twitter visités.

Cette action est réalisable grâce à une feature très intéressante de Profile Hopper, l’export .csv de vos visites. Vous allez pouvoir sortir des données très intéressantes comme :

  • Prénom & Nom
  • Poste & Industrie
  • Localité
  • Actuel & anciens employeurs
  • École
  • Nombre de relation & Degré de connexion
  • Email présent sur le profil (en mode payant recherche approfondie)
  • Twitter
  • Sites web
  • Lien du profil
  • Photo de profil

Je réalise cette opération directement via Blockspring pour centraliser toutes mes actions. Ainsi je follow les comptes Twitter afin de multiplier les notifications auprès de mon lead.

Vous pouvez aussi faire des choses assez amusantes comme une recherche inversée de la photo de profil sur Google Images afin de voir où cette photo se situe sur le web.

Cold Email

Si après les notifications Linkedin & Twitter votre lead ne vous a toujours pas contacté il est temps de dégainer votre email. En version gratuite vous aurez accès uniquement aux mails trouvés sur le profil. Pour trouver les autres, je vous conseille l’utilisation de Voila Norbert ou bien Email Hunter.

Followup

Si vous vous êtes frottés au cold mailing vous savez que le premier mail ne génère pas la majorité de vos ventes. Après si vous avez un template magique à partager je suis preneur :)

C’est pour cela que je vous conseille l’utilisation de Mix Max, Reply App ou bien de Rebump afin d’automatiser vos relances.

Pour toutes ces actions sur Linkedin je vous conseille de passer en version premium. Vous risquez d’être bloqué sinon

Anygrowth, la machine à Leads

Tout ce petit processus peut vite devenir fastidieux si vous n’êtes pas organisé. De plus si vous manipulez des milliers de leads cela va vite devenir très compliqué. C’est pour cela que je vous conseille l’utilisation d’Anyleads pour votre génération de leads, crée par la société Anygrowth.

 

Anyleads centralise la quasi intégralité des actions citées au dessus. Vous installez votre extension et vous accrochez la ceinture ça va piquer !

Vous effectuez votre recherche et les leads vont venir à vous comme par magie. De plus, la génération de mail n’est pas du guess mais bel et bien du mail sonnant et trébuchant. Pour une précédente opération, j’ai pu retirer un pourcentage de 36% sur une cible très complexe car elle n’était pas rattachée à une entreprise en particulier.

Templates & Follow-ups

Une des features que j’apprécie par dessus tout, c’est la possibilité de réaliser ses templates en spinnant les attributs comme {{first name}}, {{company}} etc…

Vous allez même pouvoir éditer vos templates de follow-ups et ça c’est vraiment beaucoup de temps de gagné.

Tracking

Autre feature brillante, la possibilité d’installer directement sur son site une iframe de conversion afin de suivre l’activité de votre prospect sur votre site.

Autant éviter les follow-ups sur un lead qui ne demande qu’a être contacté par téléphone :)

 

Cet article vous a plu ? Il vous reste plus qu’à le partager :)

Des #Leads comme si il en pleuvait ! Click To Tweet

Cet article est amené à être amélioré au fur et à mesure des nouveaux outils et techniques qui verront le jour. N’hésitez pas à me contacter pour le faire évoluer.

Et en bonus un blog que j’aime beaucoup Sales Hacking pour éclater son pipe ;)