Lego IT guy par bnilsen

Comment construire un bot GitHub avec les frameworks PhantomJS, React et Serverless

Ce tutoriel concerne la création d’un bot Serverless simple qui renvoie un graphique avec les meilleurs contributeurs au référentiel GitHub pour une période donnée. Cela concerne tout ceux qui ont une expérience de React, de JavaScript, de TypeScript, de Node.js, d'Amazon Web Services (AWS) et du framework Serverless.

Vous pouvez vérifier le code sur Github.

Services et outils que nous utiliserons

Avant de passer au codage, décrivons rapidement les services et les outils AWS que nous allons utiliser.

Pour récupérer les meilleurs contributeurs au référentiel, nous utiliserons l'API de statistiques GitHub, l'incroyable Nivo pour afficher les données, Storybook pour vérifier l'aspect et le rendu de notre graphique, PhantomJS pour convertir le HTML en image et le framework Serverless pour interagir avec AWS.

Commençons

Je vais utiliser TypeScript. Si vous préférez ES6, vous devrez configurer Babel.

Vous devez d’abord créer tsconfig.json à la racine de votre référentiel. Options à faire attention à inclure:

"module": "commonjs",
"cible": "es5",
"lib": ["es6", "esnext.asynciterable"],
"moduleResolution": "noeud",
"jsx": "réagir"

Ensuite, nous allons créer une API simple pour interroger les statistiques de GitHub. Vous pouvez suivre la structure du fichier depuis le dépôt GitHub ou utiliser le vôtre. Par exemple:

Pour accéder à l'API GitHub, vous devez créer un jeton d'accès personnel.

Ce module envoie simplement la requête avec le jeton fourni et récupère les données.

Affichage des graphiques

Pour afficher les données, nous utiliserons Nivo et Storybook. Un composant simple peut ressembler à ceci:

Commencez par installer Storybooks en exécutant la commande suivante dans le dossier racine:

npm i -g @ storybook / cli
getstorybook

Copiez le dossier .storybook dans le référentiel racine et remplacez tous les fichiers existants. Il contient la configuration Webpack et Storybook. Créez un dossier d'histoires et insérez un exemple d'histoire pour votre composant:

Exécutez npm run storybook et ouvrez localhost dans le navigateur. Vous devriez voir le résultat suivant:

Essayez de jouer avec les options et les données de test. Storybook va changer le look immédiatement.

Conversion de HTML en PNG

En règle générale, les systèmes de discussion tels que Facebook Messenger et Slack ne permettent pas aux utilisateurs d'insérer des cartes HTML dans la boîte de dialogue. La prochaine étape consiste donc à créer un utilitaire permettant de rendre le code HTML au format PNG.

En utilisant un script simple avec la bibliothèque jsdom, nous pouvons imiter le comportement du navigateur et sérialiser HTML, comme ceci:

createDomForChart renvoie une nouvelle instance de jsdom, et la fonction de graphique appelle simplement dom.serialize () lorsque le rendu du composant est terminé.

Avec PhantomJS, nous pouvons transformer le marquage en une image en utilisant ce script simple:

Nous passons screenshot.js dans le chemin d’exécutable de phantomjs - avec une chaîne HTML, largeur et hauteur - et récupérons le tampon avec l’image rendue.

Vous remarquerez peut-être que j’utilise deux fichiers binaires PhantomJS (pour OS X et Linux). Nous aurons besoin de la version Linux plus avant dans un environnement AWS. Vous pouvez les télécharger à partir de PhantomJS.org ou utiliser des fichiers du référentiel.

Tout attacher

Maintenant, créons lambda pour gérer les requêtes. Je recommande de placer la logique de rendu PNG dans un service séparé. Étant donné que la taille du fichier binaire PhantomJS est d’environ 50 Mo, elle ralentit le déploiement si vous modifiez quoi que ce soit dans l’API. En outre, vous pouvez réutiliser ce lambda à d’autres fins.

Nous allons commencer par créer webpack.config.ts (pour regrouper le code source) et serverless.base.js (pour définir la configuration de base sans serveur) dans le dossier racine.

Si vous voulez en savoir plus sur les cas d'utilisation de configurations JavaScript sans serveur, vous en saurez plus à ce sujet dans mon article précédent.

Vous devrez modifier les noms de compartiment de déploiement et d’image, comme suit:

deploymentBucket: {
    nom: 'com.github-stats .... deploys'
},
environnement: {
    BUCKET: 'com.github-stats .... images',
    GITHUB_TOKEN: '$ {env: GITHUB_TOKEN}',
    SLACK_TOKEN: '$ {env: SLACK_TOKEN},
    STAGE: '$ {self: provider.stage}'
},

En effet, le nom du compartiment doit être unique au monde.

Passage de HTML au service PNG

Tout d’abord, nous allons créer un gestionnaire qui renverra une URL de l’image générée. Le gestionnaire doit valider et traiter le corps de la demande:

… Et si tout va bien, il devrait générer l'image et la placer dans un seau S3.

Créons webpack.config.ts pour regrouper les fichiers source. Nous allons utiliser les plug-in copy-webpack-plugin et webpack-permissions-plug-in pour inclure les fichiers binaires PhantomJS dans un paquet - et donner des autorisations d'exécution. Pour cela, nous devons exécuter la commande deploy avec sudo car Webpack n’est pas autorisé à modifier les droits du système de fichiers par défaut.

La dernière étape consistera à utiliser le fichier serverless.js pour lier notre gestionnaire à un événement API Gateway.

Maintenant, nous devons suivre les mêmes étapes pour le gestionnaire de statistiques, mais nous n’avons pas à modifier Webpack.config.ts.

La seule différence est une autorisation supplémentaire d'invoquer lambda:

iamRoleStatements: [... baseConfig.provider.iamRoleStatements,
{
    Effet: 'Autoriser',
    Action: ['lambda: InvokeFunction'],
    Ressource: ['*']
}]

Mise en place du bot Slack

La dernière étape consistera à créer un service qui gérera les événements de message pour le bot. Pour rester simple, nous ne traiterons que les événements mentionnés. Configurons le gestionnaire d’événements de base.

Nous devons gérer un événement de vérification de Slack et répondre avec 200 paramètres d'état et de défi:

rappel (null, {
   body: JSON.stringify ({
     challenge: (slackEvent as VerificationEvent) .challenge
   }),
   statusCode: 200
});

Pour gérer correctement un événement Slack, le point de terminaison doit répondre dans un délai de 3 000 millisecondes (3 secondes). Nous devons donc répondre immédiatement et envoyer un message de suivi de manière asynchrone à l'aide de l'API postMessage.

Dans le code ci-dessus, nous avons analysé le texte du message afin d'extraire un nom de référentiel, puis appelé une image stats lambda afin de récupérer une URL d'image et de renvoyer un message à Slack. Vous pouvez trouver le code complet du gestionnaire ici.

Le code pour les configurations serverless.js et Webpack serait similaire au service de statistiques. Par conséquent, si vous rencontrez des problèmes pour le configurer, consultez le code source complet.

Créer une application Slack

Créons maintenant une nouvelle application Slack. Accédez à l'API Slack, créez un nouveau compte (si vous ne l'avez pas déjà fait), créez une nouvelle application et ajoutez la portée du bot dans la section des étendues.

Allez à la section «OAuth & Permissions» dans la barre latérale.

Ajoutez la portée de l'utilisateur bot.

Ensuite, vous pourrez installer l'application dans votre organisation et accéder à des jetons.

Déploiement des services

Vous devrez installer une version d'infrastructure sans serveur supérieure à 1,26 car les versions antérieures ne prennent pas en charge les fichiers de configuration JavaScript. Et je recommande d'installer slx pour simplifier le déploiement de plusieurs services.

npm install -g sans serveur
npm install -g sans service

Copiez les jetons bot GitHub et Slack et définissez-les en conséquence sur les variables d'environnement GITHUB_TOKEN et SLACK_TOKEN. Exécutez la commande suivante dans le terminal:

sudo GITHUB_TOKEN =  SLACK_TOKEN =  slx déploie tout

Comme mentionné ci-dessus, nous avons besoin de sudo pour définir les autorisations d'exécution sur les fichiers binaires PhantomJS.

Sois patient! Le déploiement peut prendre un certain temps. À la fin, vous devriez voir une sortie similaire:

Déploiement terminé avec succès
[app / html-to-png] [terminé]:
Des informations de service
service: html-to-png
étape: dev
région: us-east-1
pile: html-to-png-dev
clés api:
   Aucun
points finaux:
   Aucun
les fonctions:
   renderToPng: html-to-png-dev-renderToPng
Serverless: Suppression des anciennes versions de service ...
[app / slack] [terminé]:
Des informations de service
service: git-stats-slack
étape: dev
région: us-east-1
pile: git-stats-slack-dev
clés api:
   Aucun
points finaux:
   POST - https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/stats/slack/event-handler
les fonctions:
   eventHandler: git-stats-slack-dev-eventHandler
Serverless: Suppression des anciennes versions de service ...
[app / stats] [terminé]:
Des informations de service
service: git-stats
étape: dev
région: us-east-1
pile: git-stats-dev
clés api:
   Aucun
points finaux:
   GET - https://xxxxxx.execute-api.us-east-1.amazonaws.com/dev/stats/contributors/{owner}/{repo}
les fonctions:
   getContributorStatsImage: git-stats-dev-getContributorStatsImage
Serverless: Suppression des anciennes versions de service ...

La dernière étape consistera à abonner nos événements aux événements mentionnés.

Sélectionnez la section «Inscription à un événement» dans la navigation de l'API Slack.

Collez ensuite l'URL du gestionnaire d'événements que vous pouvez trouver dans le résultat de la commande de déploiement.

Il est temps de jouer un peu! Voici quelques exemples d'images rendues:

sans serveur / sans serveur

facebook / réagir

plouc / nivo

C'est tout!

J'espère que vous avez trouvé cet article utile. J'adorerais voir dans les commentaires d'autres types de statistiques que vous aimeriez voir dans le service.

S'il vous plaît applaudir si vous avez aimé l'article! Et si vous souhaitez discuter ou vous connecter, vous pouvez me trouver sur Twitter, GitHub et Linkedin.