Hoe een GitHub-bot te bouwen met PhantomJS, React en Serverless framework

Hoe een GitHub-bot te bouwen met PhantomJS, React en Serverless framework

Deze tutorial gaat over het bouwen van een eenvoudige serverloze bot die een grafiek retourneert met de beste GitHub-repositorybijdragers voor een geselecteerde periode. Het is relevant voor degenen die enige ervaring hebben met React, JavaScript, TypeScript, Node.js, Amazon Web Services (AWS) en het Serverless-framework.

Je kunt de code op Github bekijken.

Services en tools die we zullen gebruiken

Laten we, voordat we met coderen beginnen, een kort overzicht geven van de AWS-services en -tools die we zullen gebruiken.

Om de beste repository-bijdragers op te halen, zullen we GitHub stats API gebruiken, de verbazingwekkende Nivo om gegevens weer te geven, Storybook om te controleren hoe onze grafiek eruitziet en aanvoelt, PhantomJS om HTML om te zetten in een afbeelding en Serverless framework om te communiceren met AWS.

Laten we beginnen

Ik zal TypeScript gebruiken. Als u de voorkeur geeft aan ES6, moet u Babel configureren.

Eerst moet u een bestand aanmaken tsconfig.jsonin de root van uw repository. Opties om op te letten zijn onder meer:

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

Vervolgens maken we een eenvoudige API om statistieken van GitHub op te vragen. Je kunt de bestandsstructuur volgen vanuit de GitHub-repo of je eigen gebruiken. Bijvoorbeeld:

Om toegang te krijgen tot de GitHub API, moet je een persoonlijk toegangstoken maken.

Deze module verzendt eenvoudig het verzoek met het verstrekte token en haalt de gegevens op.

De grafieken weergeven

Om de gegevens weer te geven, gebruiken we Nivo en Storybook. Een eenvoudig onderdeel kan er als volgt uitzien:

Stel eerst Storybooks in door de volgende opdracht uit te voeren in de hoofdmap:

npm i -g @storybook/cligetstorybook

Kopieer de .storybook-map naar de root-repository en vervang alle bestaande bestanden. Het bevat de Webpack- en Storybook-configuratie. Maak een storiesmap en plaats een voorbeeldverhaal voor uw component:

Start npm run storybooken open localhost in de browser. U zou het volgende resultaat moeten zien:

Probeer te spelen met de opties en testgegevens. Storybook zal de look onmiddellijk veranderen.

HTML omzetten in PNG

Gewoonlijk staan ​​chatsystemen zoals Facebook Messenger en Slack gebruikers niet toe om HTML-kaarten in het dialoogvenster in te voegen, dus de volgende stap is het bouwen van een helper die HTML omzet in een PNG-afbeelding.

Met behulp van een eenvoudig script met de jsdom-bibliotheek kunnen we browsergedrag nabootsen en HTML serialiseren, als volgt:

createDomForChartgeeft een nieuw exemplaar van jsdom terug, en de diagramfunctie roept gewoon aan dom.serialize()wanneer het renderen van componenten is voltooid.

Met PhantomJS kunnen we markup omzetten in een afbeelding met behulp van dit eenvoudige script:

We gaan screenshot.jsnaar het phantomjsuitvoerbare pad - samen met een HTML-string, breedte en hoogte - en krijgen de buffer terug met de gerenderde afbeelding.

Het valt je misschien op dat ik twee PhantomJS-binaire bestanden heb gebruikt (voor OS X en Linux). We hebben de Linux-versie verder nodig in een AWS-omgeving. U kunt ze downloaden van PhantomJS.org of bestanden uit de repository gebruiken.

Alles vastbinden

Laten we nu lambda maken om verzoeken af ​​te handelen. Ik raad aan om PNG-renderinglogica in een aparte service te plaatsen. Omdat PhantomJS binair ongeveer 50 mb groot is, vertraagt ​​het de implementatie als je iets in de API verandert. Je kunt deze lambda ook hergebruiken voor andere doeleinden.

We beginnen met het maken van webpack.config.ts(om de broncode te bundelen) en serverless.base.js(om de serverloze basisconfiguratie te definiëren) in de hoofdmap.

Als je meer wilt weten over het gebruik van serverloze JavaScript-configuraties, kun je erover lezen in mijn vorige artikel.

U moet de namen voor implementatie en image-bucket als volgt wijzigen:

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}'},

Dit komt doordat de naam van de bucket wereldwijd uniek moet zijn.

HTML omzetten in PNG-service

Allereerst maken we een handler die een URL van de gegenereerde afbeelding retourneert. De handler moet de aanvraagtekst valideren en verwerken:

… En als alles in orde is, moet het de afbeelding genereren en in een S3-bucket plaatsen.

Laten we maken webpack.config.tsom bronbestanden te bundelen. We zullen de copy-webpack-pluginen webpack-permissions-plugingebruiken om PhantomJS-binaire bestanden in een bundel op te nemen - en machtigingen geven voor uitvoering. Dit vereist dat we de deploy-opdracht uitvoeren met sudo, aangezien Webpack standaard geen machtigingen heeft om bestandssysteemrechten te wijzigen.

De laatste stap zal het serverless.jsbestand gebruiken om onze handler te koppelen aan een API Gateway-gebeurtenis.

Nu moeten we dezelfde stappen uitvoeren voor de stats-handler, maar we hoeven geen wijzigingen aan te brengen in webpack.config.ts.

Het enige verschil is een extra toestemming om lambda aan te roepen:

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

De Slack-bot instellen

De laatste stap is het maken van een service die berichtgebeurtenissen voor de bot afhandelt. Om het simpel te houden, behandelen we alleen de genoemde evenementen. Laten we de basisgebeurtenishandler opzetten.

We moeten een verificatiegebeurtenis van Slack afhandelen en reageren met 200 status- en uitdagingsparameters:

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

Om een ​​Slack-gebeurtenis correct af te handelen, moet het eindpunt binnen 3000 milliseconden (3 seconden) antwoorden, dus we zullen onmiddellijk moeten reageren en asynchroon een vervolgbericht moeten verzenden met behulp van de postMessage API.

In de bovenstaande code hebben we de berichttekst geparseerd om een ​​repositorynaam te extraheren en een lambda voor afbeeldingsstatistieken opgeroepen om een ​​afbeeldings-URL op te halen en een bericht terug te sturen naar Slack. Je kunt de volledige code van de handler hier vinden.

Code voor serverless.js en Webpack-configuraties zou vergelijkbaar zijn met de stats-service, dus als je problemen hebt met het instellen, bekijk dan de volledige broncode.

Een Slack-app maken

Laten we nu een nieuwe Slack-app maken. Ga naar de Slack API, maak een nieuw account aan (als je dat nog niet hebt gedaan), maak een nieuwe app en voeg de botscope toe in de scopes-sectie.

Ga naar het gedeelte "OAuth en machtigingen" in de zijbalk.

Voeg het gebruikersbereik van de bot toe.

Vervolgens kunt u de app voor uw organisatie installeren en toegang krijgen tot tokens.

Implementatie van de services

U moet een serverloze framework-versie hoger dan 1.26 installeren omdat eerdere versies geen JavaScript-configuratiebestanden ondersteunen. En ik raad aan om slx te installeren om de implementatie van meerdere services te vereenvoudigen.

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.

Please clap if you enjoyed the article! And if you’d like to chat or connect, you can find me on Twitter, GitHub and Linkedin.