Browsing Category

Hors catégorie

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 :

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

Une autre checklist un peu plus détaillée et plus orientée front-end.

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

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. Cliquez pour tweeter

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.