Today I spread shit on Twitter
Hello ici ! Mon précédent article sur le no code m’a donné envie de jouer avec Spreadsheet comme source de données active.
Je n’aime pas tellement Twitter. Pour moi c’est une fosse à fumier au mieux, au pire un déversoir à haine 🤷
Du coup on va rajouter une couche de Nutella sur une pile de caca et on va faire un bot semi-automatique pour poster des trucs fauchés, mais un peu qualifiés sur le Net.
On va faire rentrer tout ça dans mon service GCP préféré Cloudrun, et utiliser le Cloud Scheduler pour planifier des actions.
Accroche-toi à ton Futal, je change de poste, aujourd’hui je suis Head of Community Manager Bot. 🤭🤭
Objectif faire un bot Twitter
Mon idée c’est de scraper des liens qualifiés et de remplir mon tableau une ligne par lien.
le web scraping est la technique permettant d’extraire des informations depuis des pages web.
J’aurais une case qui me permet d’ajouter le contenu de mon choix à mon tweet en plus du lien à ma convenance. Un lien de callback sur chaque ligne pour me permettre de poster instantanément et une case qui me permet de dire si oui ou non l’article peux être autoposté plus tard.
L’idée de l’autopostage, c’est que si je n’ai pas le temps ou l’envie de semi-auto mes postes, je peux ne pas toucher du tout à mon Spreadsheet et mon robot va me planifier tout ça dans la journée plus ou moins random.
On va utiliser Cloudrun en backend pour faire:
- le scrap des liens
- une boucle de callback (un lien clickable dans Speadsheet pour publier directement le tweet depuis la feuille de calcul)
- un comportement d’autopostage qui prendra un tweet préparé au hasard et le publiera
Et enfin une route de clean pour nettoyer Spreadsheet à intervalle régulier pour que la feuille Spreadsheet reste utilisable en semi-auto.
Comprendre ouvrable dans le navigateur dans un délai raisonnable et sans crasher lamentablement.
On avait vu lors du précédent article qu’à partir d’un moment, Spreadsheet a tendance à laguer du cul sévèrement.
quatre routes présentées comme ceci
/scrap -> scraping des articles
/publish_callback -> route post
/auto_post -> route scheduler d'auto post
/clean_shit
CI/CD de gros sale (mais vous avez l’habitude)
#!/bin/bash
function shameful_cicd_function(){
black main.py scraps/* || exit -1
gcloud config set project twitter-pooper
gcloud auth configure-docker europe-west1-docker.pkg.dev
export TF_VAR_cloudrun_image=europe-west1-docker.pkg.dev/twitter-pooper/twitter-pooper/twitter_pooper:$(git rev-parse --short HEAD)
gcloud builds submit --tag "$TF_VAR_cloudrun_image" --timeout="9000"
cd terraform
terraform fmt|| exit -1
terraform apply -auto-approve -var-file=terraform.tfvars
cd ..
}
if [ -z "$(git status --porcelain)" ]; then
# Working directory clean
shameful_cicd_function & disown
echo ""
fi
exit 0
Du coup mon script de git hook prepush moche:
- on fait un coup de black (un linter python très efficace) pour vérifier et corriger la syntaxe du code
- on active le gcloud local avec mon projet Google sobrement intitulé twitter-pooper
- on build le container avec Google Cloud Build en réarrangeant les lettres, ça fait CBD coïncidence ?
- un coup de terraform fmt (ça permet de reformater le code pour le prochain commit. Comme avec l’outil black, on pète une erreur en cas d’erreur de syntaxe terraform)
- et on apply le Terraform en auto-approve comme un saltimbanque.
Ça me permet de coder et deploy en mode prod is the new dev comme un gros cochon et de pouvoir tester des trucs directement à cible, je deploy à chaque fois et je patch au fur et à mesure.
Scraping des liens
La route de scrap devrait être assez simple, mais paradoxalement m’occuper le plus. Pour trouver les sources de données, mettre en place le code de scraping des liens, il faudra y revenir souvent et c’est du custom pour chaque source.
Ce qui me semble important :
- Filtrer et qualifier les liens
- Éviter au maximum les redirections
- Éviter au maximum de reposter les même liens.
Petit challenge rigolo, plus la feuille de calcul est grosse et plus le traitement va cramer de la RAM au chargement des données. Il faudra jouer finement pour éviter au maximum l’inflation de la RAM et le temps de traitement.
C’est là que le clean a tout son sens, même si je peux lire ligne par ligne la feuille de calcul, il ne faut pas dégrader les perfs et exploser les quota d’API Google.
Le publish callback, l’idée c’est de pouvoir choisir et customiser les articles de mon choix, ce n’est pas de faire du masse posting, l’auto post le fera pour moi.
Je veux pouvoir modifier le champ de publication et cliquer sur mon lien de callback pour poster mon tweet depuis ma feuille de calcul.
J’étais parti dans l’idée de scrapper les liens avec du code à la louche, mais entre temps j’ai trouvé un outil avec des quotas gratuits qui fera le taf pour moi.
Article non sponsorisé par Apify, restez bien jusqu’à la fin pour soutenir mon égo :)
Donc je vais pas rentrer dans le détail sur le fonctionnement d'Apify, c’est pas le but, mais en gros:
- on configure un agent de scrap (quelle donnée on veut récupérer, et comment on formate le résultat)
- on schedule notre agent
- Apify formate la donnée sous forme de dataset
- Apify expose une API REST pour requêter cette donnée
Du coup vous avez compris, je delègue les tâches relou de gestion du scrap et j’ai pas besoin de faire tourner du compute sur Google, c’est les quota gratuits d'Apify qui s’en chargent. implémentation:
|
|
Alors tu vois Bobby, avec Apify je configure le truc une fois, et j’en ai plus rien à foutre ensuite !
Du coup que fait ce bout de code ?
- récupération des ids des 50 derniers datasets
- récupération des données pour l’ensembles des ids
- unpack des jeux de données (on a une liste de liste , on la transforme en liste simple)
- filtrage des URLs racine (probablement qu’on peut le faire avec apify mais j’ai eu la flemme)
- on retourne une liste de liens
On prend tout ça, on en fait une route de scrap dans cloudrun et on l’appel de façon planifiée tous les jours avec Cloud Scheduler. Petite astuce au passage, comme j’ai mis une protection basic auth sur mon lien, il faut passer le header qui va bien au Scheduler. C’est ce que fait le code Terraform ici.
|
|
On attrape l’URL de Cloudrun et on y colle la route de scrap Petite astuce, pour l’authentification basic auth, j’ajoute la concaténation de mon user et de son mot de passe en base64 dans un Header authorisation.
Emballé, c’est pesé ! Je vous met une tranche de jambon pour votre chien à punk ?
Call me back, and publish
L’idée du publish callback, c’est de pouvoir customiser dans le Spreadsheet le contenu du tweet et de le publier via un lien cliquable directement dans le Spreadsheet. Ce lien pointera vers une URL de mon cloudrun avec le numéro de ligne de l’article que je veux poster.
Pour des questions de sécurité minimum, je vais mettre un basic auth dessus quand même pour éviter les abus (utilisateur + mot de passe).
Le Cloudrun reçoit le numéro de ligne de ma feuille de calcul, vient lire la ligne dans Spreadsheet, prépare et envoi le tweet. Et ensuite coup classique, suppression dans Spreadsheet.
le format de donnée ressemblera à cette capture dans Spreadsheet
Auto publish, l’usine à scoop
On va partir dans l’idée de faire des posts avec un découpage temporel.
Pour éviter de tout balancer en même temps et de se faire un peu pourrir par twitter, on va poster tranquille 1 article vers 10h tous les jours.
Fonctionnellement ça va être assez simple, on prend les articles scrappés et non tagués du flag no publish, on construit les tweets et on les envoie de façon timée.
Mais là où ça va être marrant, c’est quand va falloir faire une roulette bullshit pour pimenter un peu le jeu, avec des phrases un peu putaclic ou débiles 🤷
Du genre :
- C’est vraiment avant-gardiste, j’aurai dû investir avant que ça devienne mainstream 😱
- Vraiment ? Je suis choqué 😱😱
- Cette astuce incroyable que les DSI vous cache
- Mais c’est incroyable, que quelqu’un en fasse un NFT 😱
- Alors, là je cite Julien Lepers mais oui oui oui.
- Dans le contexte actuel c’est vraiment un move délicat.
- Encore une boulette de Microsoft haha
J’ai dans l’idée de faire une phrase roulette russe : “mange tes morts avec du roquefort”, c’est le côté punk à chien qui revient 🤭
Du véritable travail de journaliste d’investigation Topito en somme.
Rien ne se passe jamais comme prévu
J’ai changé plusieurs fois d’avis sur la manière de m’y prendre donc je fais un update de mon idée première. J’ai consommé pas mal de temps sur Apify pour comprendre la logique et m’approprier le Python SDK. L’authentification de l'API Twitter m’a donné une diarrhée aiguë, et m’a fait perdre mon cool. Sérieusement quatre secrets différents et une bataille débile avec l’interface pour configurer le bouzin, j’ai bien failli lâcher l’affaire.
Et vous verrez, vous verrez, La Rage au fond des cœurs Les cris, les pleurs, la haine et la douleur
(La Rage - les sales majestés)
Le contenu autogénéré est souvent redondant et pas du tout pertinent, donc du coup l’autopublish va fonctionner seulement sur les contenus que j’ai flagué comme publiable. Il fera un publish automatisé tout les jours vers 10h en tapant au hasard dans la liste des posts publiable. Je garde le contenu autogéré puisqu’il peut servir de base pour mes publications.
J’ai vite compris que je ne pouvais pas publier tout le code sans que ça fasse un bloc indigeste dans l’article, alors je vous propose de regarder le code dans github https://github.com/helldrum/spreadsheet_twitter, mais je vais quand même isoler et commenter les parties de codes qui me semblent importants.
Lire et écrire dans Spreadsheet
Pour une fois j’ai lu la doc pour lire et écrire dans Spreadsheet! Mauvaise idée, la doc est ultra pourrie en ce qui concerne l’authentification avec spreadsheet. On demande de faire un token application compliqué et des modifs manuelles, alors que moi je veux juste un service account tout simple :)
J’ai trouvé un article qui m’à sauvé, pour utiliser un service account au lieu de l’application auth.
https://blog.benjames.io/2020/09/13/authorise-your-python-google-drive-api-the-easy-way/
Ben James, you’r the man !
on active l’API sheets.googleapis.com , on créer un service account, on autorise le service account email sur le spreadsheet (en mode clic clic) et c’est parti.
|
|
En modifiant un peu la soupe, vous pouvez utiliser directement le service account et éviter d’utiliser une variable d’environnement avec la clef Json du service account. De cette façon l’autorisation de lecture écriture sera donnée directement à mon Cloudrun via le Service Account associée.
|
|
Vous voyez que j’ai un peu dupliqué et mal rangé le code de Spreadsheet pour la lecture et l’écriture, je n’ai pas trouvé l’API super sympa à utiliser quand on commence à faire des trucs compliqué, comme des formules par exemple. Alors j’ai fait du code de gros débile, si je savais faire du code malin ça se saurait :)
Filtrer et manager les liens
A force de bricoler j’ai fait le postulat que c’était plus simple de persister quelque part les liens que j’avais dèja combiné dans ma feuille de calcul et de supprimer les lignes publiées. Donc on va faire un genre de tampon de persistance dans un bucket gcs, pour ne plus réécrire les liens déjà écrits une fois dans la feuille de calcul.
Les lignes supprimées seront ignorées et on va ajouter à la fin de la feuille les nouveaux liens.
donc nouvelle idée:
Récupération des liens depuis ***Apify***
lecture de mon fichier de persistance
filtres des "nouveaux" liens déjà existants dans la persistance
lecture de la feuille de calcul
ajout des nouveaux liens à la fin de la liste
réécriture de la feuille de calcul
On règle deux problèmes en même temps, les doublons et les lignes supprimées manuellement.
Constriction:
J’ai mis un temps absolument incroyable pour un truc que je pensais tranquille et ça ne marche même pas comme je l’avais pensé au départ.
Par contre, dans le processus, j’ai pas mal appris sur l’API de spreadsheet et sa capacité à en faire un outil de productivité automatisé.
Pourtant dans mes expériences passées, j’ai toujours eu la désagréable impression que les feuilles de calcul étaient un peu cancer et très énervantes.
Le truc qu’il ne faut jamais utiliser de peur d’être maudit. L’outil duquel on martèle que ce n’est pas une base de données et que c’est tout naze, ça scale pas, on ne peut pas faire des requêtes complexes. Je ne mets pas mes données dedans c’est nul le CSV !
Je pense que c’est un peu un héritage de dev qu’on traîne, une sorte de superstition un peu bête de l’outil graphique pas trop à la mode et un peu noob. On le moque un peu du doigt avec le relent un peu puant que ce n’est pas un outil sérieux de dev.
Comme n’importe quel outil un peu sur-utilisé et mal exploité, il peut laisser un goût amer et énerver beaucoup de gens.
Moi ce que j’en pense, c’est que je ne sais pas l’utiliser et en vrai ce n’est pas si grave 🤭🤭
Comme je suis un power user sur Linux (ce n’est pas pour me la péter, mais un peu quand même), je peux scripter et forger des commandes beaucoup plus scalables et efficaces et sur des formats de données plus variés. Un CSV ne va pas forcément être mon ami et un xls (format Windows) va juste me ralentir et me gaver 🤷
Par contre, donnez-moi un CSV en SaaS, où plusieurs personnes peuvent contribuer, qui est auto versionné et pilotable à distance via API et c’est une toute autre histoire 🚀
Mon use case est débile, j’en ai bien conscience. Mais le côté SaaS de spreadsheet rend les échanges de documents et leur traitement automatisé beaucoup plus simple et sécurité.
Imaginez-vous faire la même chose avec un serveur FTP, des documents qu’il faut télécharger, modifier et uploader. Et ensuite une tâche planifiée pourrait faire des trucs automatiques. Ça serait douloureux si plusieurs personnes devaient modifier la feuille de calcul plusieurs fois par jour et partager leurs modifs 🤷 et si le traitement automatique n’est pas synchro, on pète tout et bon courage pour la reconstruction 🤪
Encore une bonne couche de serverless avec ça et la consommation est fortement réduite et l’impact serveur est presque nul, mon cloudrun tourne à la requête et ne reste pas allumé quand il ne fait rien 🙂 Ce qui pour une bêtise pareille est quand même non négligeable 🤭
Encore un gros shot de Google, je crois que je suis accro 🤷 c’est chiant, mais ils sont beaucoup trop forts 😆
J’utilise beaucoup Python aussi, je sais que ça énerve certains d’entre vous 🤭🤭 On peut dire que Python est un langage lent avec quelques autres défauts, mais c’est tellement confortable et rapide de travailler en python pour faire de la glue interservices, de la manipulation de données et des appels web, que vous auriez tord de vous en priver 🙂
N’hésitez pas à me dire ce que vous avez pensé de mon petit bricolage. Le compte Twitter utilisé https://twitter.com/cyberpunkach1 :) À bientôt pour de nouvelles aventures, n’hésitez pas à exprimer votre haine sur Twitter, je ne vous répondrai pas 🙂
Et coucou à Elon Musk pour son rachat de l’oiseau