Sådan oprettes en GitHub-bot med PhantomJS, React og Serverless framework

Sådan oprettes en GitHub-bot med PhantomJS, React og Serverless framework

Denne tutorial handler om at opbygge en simpel serverløs bot, der returnerer et diagram med de bedste GitHub-arkivbidragere i en valgt periode. Det er relevant for dem, der har en vis erfaring med React, JavaScript, TypeScript, Node.js, Amazon Web Services (AWS) og Serverless framework.

Du kan tjekke koden på Github.

Tjenester og værktøjer, vi bruger

Før vi hopper ind i kodning, lad os lave et hurtigt overblik over AWS-tjenester og værktøjer, som vi bruger.

For at hente topbidragbidragere bruger vi GitHub stats API, den fantastiske Nivo til at vise data, Storybook til at kontrollere, hvordan vores diagram ser ud og føles, PhantomJS til at gøre HTML til et billede og Serverfri ramme til at interagere med AWS.

Lad os komme igang

Jeg bruger TypeScript. Hvis du foretrækker ES6, skal du konfigurere Babel.

Først skal du oprette tsconfig.jsoni roden til dit arkiv. Muligheder at være opmærksomme på inkluderer:

"module": "commonjs","target": "es5","lib": ["es6", "esnext.asynciterable"],"moduleResolution": "node","jsx": "react"

Derefter opretter vi en simpel API til forespørgsel om statistik fra GitHub. Du kan følge filstrukturen fra GitHub repo eller bruge din egen. For eksempel:

For at få adgang til GitHub API skal du oprette et personligt adgangstoken.

Dette modul sender simpelthen anmodningen med det medfølgende token og henter dataene.

Visning af kortene

For at få vist dataene bruger vi Nivo og Storybook. En simpel komponent kan se sådan ud:

Først skal du oprette Storybooks ved at køre følgende kommando i rodmappen:

npm i -g @storybook/cligetstorybook

Kopier .storybook-mappen til rodlageret, og udskift alle eksisterende filer. Den indeholder konfigurationen af ​​Webpack og Storybook. Opret en storiesmappe og læg en prøvehistorie til din komponent:

Kør npm run storybookog åbn localhost i browseren. Du skal se følgende resultat:

Prøv at lege med mulighederne og testdata. Storybook ændrer udseendet med det samme.

Sådan omdannes HTML til PNG

Normalt tillader chat-systemer som Facebook Messenger og Slack ikke brugere at indsætte HTML-kort i dialogen, så det næste trin vil være at opbygge en hjælper, der gengiver HTML til et PNG-billede.

Ved hjælp af et simpelt script med jsdom-bibliotek kan vi efterligne browseropførsel og serialisere HTML som denne:

createDomForChartreturnerer en ny forekomst af jsdom, og kortfunktionen kalder simpelthen, dom.serialize()når komponentgengivelse er færdig.

Med PhantomJS kan vi gøre markering til et billede ved hjælp af dette enkle script:

Vi går screenshot.jsind i den phantomjseksekverbare sti - sammen med en HTML-streng, bredde og højde - og får buffer tilbage med det gengivne billede.

Du bemærker muligvis, at jeg har brugt to PhantomJS-binære filer (til OS X og Linux). Vi har brug for Linux-versionen yderligere i et AWS-miljø. Du kan downloade dem fra PhantomJS.org eller bruge filer fra arkivet.

Binde alt sammen

Lad os nu oprette lambda til at håndtere anmodninger. Jeg anbefaler at sætte PNG-gengivelseslogik i en separat tjeneste. Da PhantomJS binær er ca. 50 mb i størrelse, sænker den implementeringen, hvis du ændrer noget i API'en. Du kan også genbruge denne lambda til andre formål.

Vi starter med at oprette webpack.config.ts(for at samle kildekode) og serverless.base.js(for at definere basisserverløs konfiguration) i rodmappen.

Hvis du vil vide mere om brugstilfælde af serverløse JavaScript-konfigurationer, kan du læse om det i min tidligere artikel.

Du bliver nødt til at ændre implementerings- og billedspandnavne på denne måde:

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

Dette skyldes, at skovlens navn skal være globalt unikt.

Drejning af HTML til PNG-tjeneste

Først og fremmest opretter vi en handler, der returnerer en URL til det genererede billede. Handleren skal validere og behandle anmodningsorganet:

... og hvis alt er ok, skal det generere billedet og lægge det i en S3-spand.

Lad os oprette for webpack.config.tsat samle kildefiler. Vi bruger copy-webpack-pluginog webpack-permissions-plugintil at inkludere PhantomJS-binære filer i en pakke - og give tilladelse til udførelse. Dette kræver, at vi kører implementeringskommandoen med sudo, da Webpack ikke har tilladelse til at ændre filsystemrettigheder som standard.

Det sidste trin vil være at bruge serverless.jsfilen til at binde vores handler med en API Gateway-begivenhed.

Nu skal vi udføre de samme trin for statistikhåndtering, men vi behøver ikke foretage nogen ændringer til webpack.config.ts.

Den eneste forskel er en yderligere tilladelse til at påberåbe sig lambda:

iamRoleStatements: [ ...baseConfig.provider.iamRoleStatements,{ Effect: 'Allow', Action: ['lambda:InvokeFunction'], Resource: ['*']}]

Opsætning af Slack-bot

Det sidste trin vil være at oprette en tjeneste, der håndterer meddelelsesbegivenheder for bot. For at holde det enkelt håndterer vi kun nævne begivenheder. Lad os oprette den grundlæggende begivenhedshåndterer.

Vi er nødt til at håndtere en verifikationshændelse fra Slack og svare med 200 status- og udfordringsparametre:

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

For at håndtere en Slack-begivenhed korrekt skal slutpunktet svare inden for 3000 millisekunder (3 sekunder), så vi bliver nødt til straks at svare og asynkront sende en opfølgende besked ved hjælp af postMessage API.

I koden ovenfor analyserede vi meddelelsesteksten for at udtrække et lagernavn og kaldte en billedstatistik lambda for at hente en billed-URL og sende en besked tilbage til Slack. Du kan finde den fulde kode for handler her.

Kode til serverless.js og Webpack-konfigurationer svarer til statistiktjenesten, så hvis du har problemer med at konfigurere den, skal du se på den fulde kildekode.

Oprettelse af en Slack-app

Lad os nu oprette en ny Slack-app. Gå til Slack API, opret en ny konto (hvis du ikke allerede har gjort det), opret en ny app, og tilføj bot-omfanget i rækkevidden.

Gå til afsnittet "OAuth & Permissions" i sidepanelet.

Tilføj bot-brugeromfanget.

Derefter kan du installere appen i din organisation og få adgang til tokens.

Implementering af tjenesterne

Du bliver nødt til at installere en serverløs rammeversion, der er større end 1,26, fordi tidligere versioner ikke understøtter JavaScript-konfigurationsfiler. Og jeg anbefaler at installere slx for at forenkle implementeringen af ​​flere tjenester.

npm install -g serverlessnpm install -g serviceless

Copy the GitHub and Slack bot tokens, and set them to GITHUB_TOKEN and SLACK_TOKEN environment variables accordingly. Run the following command in the terminal:

sudo GITHUB_TOKEN= SLACK_TOKEN= slx deploy all

As mentioned above, we need sudo to set execute permissions to PhantomJS binaries.

Be patient! Deployment may take a while. At the end you should see a similar output:

Deployment completed successfuly
[app/html-to-png] [completed]:Service Informationservice: html-to-pngstage: devregion: us-east-1stack: html-to-png-devapi keys: Noneendpoints: Nonefunctions: renderToPng: html-to-png-dev-renderToPngServerless: Removing old service versions...[app/slack] [completed]:Service Informationservice: git-stats-slackstage: devregion: us-east-1stack: git-stats-slack-devapi keys: Noneendpoints: POST - //xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/stats/slack/event-handlerfunctions: eventHandler: git-stats-slack-dev-eventHandlerServerless: Removing old service versions...[app/stats] [completed]:Service Informationservice: git-statsstage: devregion: us-east-1stack: git-stats-devapi keys: Noneendpoints: GET - //xxxxxx.execute-api.us-east-1.amazonaws.com/dev/stats/contributors/{owner}/{repo}functions: getContributorStatsImage: git-stats-dev-getContributorStatsImageServerless: Removing old service versions...

The last step will be to subscribe our endpoint to bot mention events.

Select the “Event Subscription” section in the Slack API navigation.

Then paste the event handler URL that you can find in the deploy command output.

Time to play around a bit! Here are some examples of rendered images:

serverless/serverless

facebook/react

plouc/nivo

That’s it!

I hope you found this article helpful. I’d love to see in the comments other types of stats you would like to see in the service.

Venligst klapp, hvis du nød artiklen! Og hvis du gerne vil chatte eller oprette forbindelse, kan du finde mig på Twitter, GitHub og Linkedin.