PRANK

Il fait un bot Twitter, ça tourne mal.

François Eoche

+

François Eoche

Web cabinetmaker

  • Développement Web, Web mobile et hybride
  • UX Front-End Developer chez OVH depuis septembre 2017
  • Il paraît qu'on me voit à RennesJS des fois aussi

ATTENTION

La présentation qui va suivre vous montrera bien des aspects de développement, mais ceux-ci ne seront finalement que du code un peu moisi. Ici, on parle majoritairement du principe de faire des bots sans grand intérêt pour Twitter.

 

Egalement, de l'humour (pas très bon) sera présent dans ces slides. Si vous n'êtes pas familier avec le concept, demandez conseil à votre pharmacien.

Bien qu'inspirée en partie de faits réels, les personnages et les situations de ce récit étant purement fictifs, toute ressemblance avec des personnes ou des situations existantes ou ayant existé ne saurait être que fortuite.

Lorem ipsum dolor sit amet, consectetur adipiscing elit e que s'apelerio Quézac.

Jour 0

Le jour où tout a commencé

J'aime bien les bots

In Peace

Jour 1

Ok, bah on y va?

Make a bot out of you

  • Une base en NodeJS
  • Utilise la libraire ntwitter, relayant l'API Twitter
  • Il faut créer une application sur apps.twitter.com
  • Très peu de configuration (4 clés Twitter API)
const twitterAPI = new Twitter({
  consumer_key,
  consumer_secret,
  access_token_key,
  access_token_secret
});

ntwitter - Les possibilités

  • get()
    • une liste de favoris, une liste de tweets
  • post()
    • un tweet, évidemment
  • stream()
    • avec un filtre (sur un/des utilisateur(s), des mots/hashtags, ...)

Étape 1 - Espionnage industriel

Étape 2 - On rabote !

  • Enlever le retweet, ne garder que les réponses
  • De même, on enlève le like automatique
  • Et on change les critères de recherche
KEYWORDS: [
    /digita(l|ux)/gmi,
    /#?transfo(rmation)?\s?digi(tal)?/gmi, 
    /campagnes?\s?digital/gmi, 
    /fractures?\sdigitale/gmi
],
EXCEPTIONS : [/(?:(?:dispositif|empreinte|affichage)s?\s|num[ée]rique.*?|num[ée]riser.*?|[_./#\-"]|@.*?|
\spas\s)([dD]igita(?:l(?:es)?|ux|lis(?:er|ations?)?))|([dD]igita(?:l(?:es)?|ux|lis(?:er|ations?)?))\s
(?:(?:dash|native|nomad|deluxe|transformation)|.*?numérique|.*?num[ée]riser)|Digital/]

// Digital, digital native, empreintes digitales, ... (et numérique, hein)

Test #01 - Le test foufou

  • Façon bruteforce: Réponse à tous les tweets avec digital
  • ~ 15 réponses/sec., 200 tweets en 1min

Test #02 - Le test moins foufou

  • Répondre aux tweets francophones uniquement (lang_fr)
  • ± 2 tweets/min, la machine est en route !

Et là ! (C'est le drame)

  • Action POST de tweet désormais impossible (403)

Jour 2

L'échec n'est pas une option

Étape 4 - Concertation, réflexion, action

  • Moins de tweets du bot (objectif : 1-2 tweets/heure)
  • Il faut choisir les tweets auquel le bot répond
  • Comment? En faisant des probas !
    • Popularité (en followers) du compte
    • Fréquence de tweet avec le mot-clé dissident

Un machine learning de l'extrême...

// Tweet contains text (how dumb)
tweet.text && 

// Tweet is in french (Twitter language detection)
tweet.lang === `fr` && 

// Tweet is in french for sure (external library detection)
lngDetector.detect(tweet.text) === `french` && 

// Tweet is not a Retweet
!containsRegExp(tweet.text, [/RT\s\@/]) && 

// Tweet has not been already answered
!recordedTweets.includes(tweet.text) &&

// Tweet does not contain any of the excluded terms
!containsRegExp(tweet.text, data.KEYWORDS)

===> TWEET !

+ un peu de maths...

P = \min(\max(\frac{n}{100-8.6\log{f}},1),100)

P : probabilité de répondre au tweet

n : nombre de tweets de suite avec mot-clé

f : nombre de followers

Et, ben...ça marche !

Jour 3

Y'a plus qu'à appliquer !

Appli #02 - ꜰᴇБᴏᴄʜᴇ

  • Tweete toutes les 3 heures un tweet à la con construit aléatoirement avec le contenu de tous mes tweets perso (@feoche)
  • Il se base sur le principe des chaînes de Markov afin d'avoir des tweets "plausibles" syntaxiquement :

+

Appli #02 - ꜰᴇБᴏᴄʜᴇ

Appli #03 - HuggyLesBonsTuyaux

  • Stream des tweets d'une liste de comptes Twitter de bons plans

 

  • Identifie les promotions

 

  • Évite les doublons de promotion

Appli #03 - HuggyLesBonsTuyaux

Éviter les tweets dupliqués, ça se fait aussi avec :

"LEGO Star Wars - Millenium Falcon" VS  "Lego faucon millenium Star Wars"   = 0.710 // 71%
"Lego faucon millenium Star Wars"   VS  "LEGO Star Wars - Millenium Falcon" = 0.667 // 66.7%
"Toto va à la mer Star wars"        VS  "Lego faucon millenium Star Wars"   = 0.654 // 65.4%
  • Le même prix affiché
  • La plus longue sous-chaîne en commun entre deux Tweets
  • La distance de Damerau-Levenshtein (proba de similarité)

 

  • Un mélange des trois "à ma sauce"

Appli #03 - HuggyLesBonsTuyaux

🅰️ Micro casque Xbox One à 20€ au lieu de 49€ !  dlbs.fr/cxb69 #bonplan

🅱️ Casque Xbox One à 20e chez leclerc hmstr.biz/TO5Qe (passe à ce prix dans le panier)

🅰️ micro casque xbox one 20€ au lieu de 49€

🅱️ casque xbox one 20€ chez leclerc passe ce prix dans le panier

simplifyAndComparePrices()

Appli #03 - HuggyLesBonsTuyaux

🅰️ ["casque", "micro", "lieu", "xbox", "one", "20€", "au", "de", "49€"]

       4 mots en commun avec 🅱️ sur 9 mots = 44% de ressemblance

🅱️ ["leclerc", "casque", "panier", "passe", "chez", "dans", "prix", "xbox", "one", "20€", "ce", "le"]

       4 mots en commun avec 🅰️ sur 12 mots = 33% de ressemblance

🅰️ micro casque xbox one 20€ au lieu de 49€

🅱️ casque xbox one 20€ chez leclerc passe ce prix dans le panier

splitOrderAndCompare()

Appli #03 - HuggyLesBonsTuyaux

Doublon !

 0.623, donc 62.3% de similitude

🅰️ micro casque xbox one 20€ au lieu de 49€

🅱️ casque xbox one 20€ chez leclerc passe ce prix dans le panier

damerau_levenshtein(🅰️,🅱️)

Appli #03 - HuggyLesBonsTuyaux

Ça marche, mais ça n'est pas parfait (beaucoup de "coup de bol" au niveaux des doublons, quelques faux-positifs)

Améliorations :

  • Analyse sémantique des tweets afin de récupérer les parties importantes quelque soit le format du tweet
    • Application du Natural Language Processing
"Elle semble se nourrir essentiellement de plancton, et de hotdog."

=> [{"elle":["PRO:per"]},{"semble":["VER"]},{"se":["PRO:per"]},{"nourrir":["VER"]},{"essentiellement":["ADV"]},
{"de":["PRE","NOM","ART:def"]},{"plancton":["NOM"]},{"et":["CON"]},{"de":["PRE","NOM","ART:def"]},
{"hotdog":["UNK"]}]

Appli #04 - BreizhTéo

  • À la manière de Tweetéo France, tweete tous les 3h la météo de la Bretagne en se basant sur les données Météo France
  • L'objectif est de lancer un hook de tweet tous les 3h plutôt que de laisser un process tourner avec un timeout

Idées (pour plus tard/un jour/jamais)

  • Un bot sur la présence d'allergies

 

 

  • Un bot qui tweet des bottes

 

  • Un bot qui répond à des bots?

Jour 4

Ok, mais l'hébergement d'un bot?

Un bot Twitter en Node

  • Le bot est lancé avec un simple :
   npm start

 

  • 1 bot = une instance de Node qui tourne (potentiellement)

 

  • Plus il ya de bots à gérer, plus il faut de terminaux pour les accueillir

L'hébergement Node (en mode radin%)

J'ai retenu ces options (gratos) :

  • Heroku (0€, moins cher que gratuit)
    • Host d'un bot, obligé de relancer la tâche Node tous les 15 min
  • OpenShift
    • On peut avoir plusieurs comptes avec plusieurs conteneurs Node, mais c'est devenu payant entre temps...
  • Au final, la solution était chez moi, avec le fameux : "Raspberry-qui-traîne-et-que-tu-sais-pas-quoi-en-faire" ! (et PM2 !)

PM2, manager de processus Node 

  • Gère les processus en parallèle, module et optimise l'utilisation de la mémoire et du processeur
  • La configuration est super simple (et complète), un fichier d’écosystème avec les bonnes variables (clés) et En Avant Guingamp!
  • Fait tourner 24/7 les processus, qui se relancent si erreur il y a (peut même se lancer au branchement du Raspberry!)
  • On peut voir les logs de toutes les tâches en temps réel et en parallèle, et il y a même une vue de monitoring en CLI :D

PM2, manager de processus Node 

En résumé :

  • C'est facile à faire
  • Faut avoir une/des idée(s)
  • Faut pas trop tweeter d'un coup
  • Faut un hébergement qui tient la route
  • et il faut s'amuser à faire ça !

Merci.

PRANK, Il fait un bot Twitter, ça tourne mal.

By François Eoche

PRANK, Il fait un bot Twitter, ça tourne mal.

  • 1,700