Tutorial: Crie um rastreador de contribuições do GitHub sem servidor usando gatilhos, funções e valores
Tempo estimado para conclusão: 30 minutos
Neste tutorial, você usará o Atlas App Services para criar uma aplicação sem servidor que monitora repositórios do Github e rastreia contribuições.
O App Services App que você construir terá várias funcionalidades:
Acompanhe os usuários que contribuíram para o seu projeto em uma collection do MongoDB Atlas.
Deixe um comentário que dão as boas-vindas a novos colaboradores quando eles abrem uma pull query ou arquivam um problema.
Gere e envie um relatório semanal que resume as contribuições para seu repositório.
Após concluir este tutorial, você saberá como realizar as seguintes tarefas:
Escreva e execute funções sem servidor que lidam com a lógica do seu aplicativo.
Automatize tarefas agendadas e responda às alterações de dados com o Realm trigger.
Armazene e acesse dados estáticos, como chaves de API, em Valores.
Conecte-se a um serviço externo por meio de uma API
Pré-requisitos
Você precisa do seguinte antes de iniciar este tutorial:
Um repositório do Github. O aplicativo que você construir rastreará as contribuições para esse repositório. Você pode criar um novo repositório para este tutorial ou usar um repositório existente ao qual você tem acesso de administrador.
Um cluster MongoDB Atlas . Se você ainda não tiver um cluster, inscreva-se no MongoDB Atlas e crie um gratuitamente.
Observe também que este tutorial não utiliza o fluxo de trabalho esquema de implantação . Um esquema de implantação é uma collection de alterações de aplicativos que você pode implantar ou descartar como uma única unidade. A menos que você tenha desativado o esquema de implantação, talvez seja necessário salvar as alterações em um esquema e, em seguida, implementá-los manualmente.
Criar um novo aplicativo
Primeiro, você precisa criar um aplicativo no App Services.
Para criar o aplicativo:
Abra seu projeto Atlas em cloud.mongodb.com.
Na navegação superior, clique em App Services.
Clique em Create a New App.
Dê um nome ao aplicativo
github-tracker-tutorial
.Selecione seu cluster para vinculá-lo à nova aplicação.
Clique em Create App Service.
Dê as boas-vindas aos novos colaboradores do Github
Conectaremos o aplicativo ao seu repositório do Github usando um webhook de repositório do Github. Os webhooks avisam seu aplicativo sempre que algum evento, como uma nova solicitação de commit ou pull, acontece em seu repositório. Cada evento executa uma função sem servidor onde você pode fazer algo em resposta.
Para este tutorial, usaremos a API REST do Github para enviar uma mensagem de boas-vindas aos colaboradores sempre que eles abrirem sua primeira solicitação pull ou problema em um repositório.
Criar um ponto de extremidade
Os webhooks funcionam enviando uma solicitação sobre o evento para uma URL que sua aplicação controla. Em sua aplicação, você precisará expor um ponto de conexão personalizado com uma URL exclusiva para receber e lidar com as solicitações de webhook.
Para criar o ponto de conexão:
No menu de navegação esquerdo, clique em HTTPS Endpoints.
Clique em Add An Endpoint.
Nomeie a rota do ponto de conexão
/greetNewContributors
.Em Operation Type, copie a URL da chamada de resposta do endpoint. Você precisará dele para configurar o webhook do GitHub mais tarde.
Deixe o método HTTP definido como POST.
Para autorização, escolha Require a Secret.
Insira um novo nome de segredo e clique em Create para criar um novo segredo. Em seguida, insira
tutorial
como o valor secreto. Isso exige que todas as solicitações recebidas incluam o parâmetro de querysecret=tutorial
na URL da solicitação.Crie uma nova Função de Realm para o ponto final e nomeie-a
endpoints/greetNewContributors
.Por enquanto, configure um manipulador básico que responda apenas às chamadas recebidas sem fazer outros trabalhos. Copie o seguinte código no corpo da Função:
exports = async function greetNewContributors(request, response) { return response .setStatusCode(200) .setBody("Successfully received a GitHub webhook event") } Clique Save e implemente o endpoint.
Atualize as configurações de autenticação da função do Endpoint
Agora que você criou o endpoint em seu aplicativo, é necessário alterar as configurações de autenticação da função do endpoint para que o webhook do Github seja aceito.
Para atualizar as configurações de autenticação da sua função:
No menu de navegação esquerdo, clique em Functions.
Encontre sua função de endpoint e selecione-a.
Clique em Settings.
Em Authentication, altere o método de autenticação para System.
Clique em Save para implantar a função.
Conecte o endpoint a um webhook do GitHub
Com sua função de endpoint pronta para Go, você precisa configurar um webhook em seu repositório GitHub que envie evento para o endpoint.
Para criar o webhook em seu repositório:
Abra as configurações do repositório e selecione Webhooks no menu de navegação esquerdo.
Adicione um novo webhook e defina o Payload URL para a URL do ponto de conexão que você acabou de criar, além de um parâmetro de query
secret
definido para o valor secreto, como:?secret=tutorial
. Seu URL de carga útil será semelhante ao seguinte, com algumas diferenças dependendo do modelo de sistema do seu aplicativo. Observe o?secret=tutorial
anexado ao final da URL:https://us-west-2.aws.data.mongodb-api.com/app/<App ID>/endpoint/greetNewContributors?secret=tutorial Defina o tipo de conteúdo do webhook como application/json.
Deixe o Secret vazio. Qualquer valor inserido aqui é ignorado pelo ponto de conexão HTTPS, e é por isso que anexamos o segredo como um parâmetro de query na URL de carga nas etapas anteriores.
Escolha selecionar eventos individuais e configurar o webhook para enviar apenas eventos para Issues e Pull requests.
Clique em Add webhook para salvar o novo webhook.
Para confirmar se o webhook chama seu endpoint com êxito, verifique se há entradas com o tipo Endpoint
nos aplicação do aplicativo no App Services. Você pode acessá-la clicando em Logs no menu de navegação esquerdo.
Você também pode verificar os registros de solicitações do webhook no Github em Recent Deliveries na página de configurações do webhook. Cada solicitação bem-sucedida tem uma marca de seleção verde ao lado.

Obter um token de acesso ao Github
O webhook agora está configurado para enviar evento do Github para o seu endpoint. No entanto, para responder aos eventos no endpoint com a API do GitHub, você precisará de um token de acesso. Este tutorial usa tokens de acesso pessoal, mas você também pode configurar um aplicativo GitHub e usar esse token.
Para criar um token de acesso pessoal:
Abra suas configurações de usuário do Github (não as configurações do repositório) e selecione Developer settings no menu de navegação esquerdo.
No menu de navegação esquerdo, selecione Personal access tokens e clique em Generate new token.
Configure o token com um nome descritivo e um tempo de expiração razoável. Como este é um tutorial, considere expirar o token após 7 dias.
Selecione o escopo
repo
.Clique em Generate token.
Copie o token em algum lugar seguro onde você possa acessá-lo novamente. O Github nunca mais mostrará o token a você após esse ponto.
Armazenar o token como um valor
De volta à sua aplicação, adicione um novo valor para manter o token de acesso pessoal que você acabou de gerar. Você poderá referenciar o valor a partir do seu endpoint sem codificar o token em suas funções.
Para criar o valor:
No menu de navegação esquerdo, clique em Values.
Clique em Create New Value.
Nomeie o valor
GitHubAccessToken
.Deixe o tipo definido como Value.
Cole o token de acesso pessoal na entrada do Valor. O valor deve ser JSON válido, portanto, certifique-se de ter aspas.
Clique em Save.
Instalar o cliente da API Github
O endpoint interagirá com a API REST do Github para deixar comentários. Você pode escrever e enviar solicitações HTTP diretamente para a API usando o cliente context.http
integrado ou uma biblioteca externa. No entanto, neste tutorial usamos a biblioteca oficial do Node.js do Github chamada Octokit que envolve a API. Depois de instalada, você poderá importar a biblioteca de qualquer função em seu aplicativo.
Para adicionar a biblioteca OctoKit ao seu aplicativo:
No menu de navegação esquerdo, clique em Functions.
Selecione a guia Dependencies.
Clique em Add Dependency.
Insira o nome do pacote:
@octokit/request
.Clique em Add.
Aguarde até que o App Services instale o pacote. A instalação deve ser concluída em alguns segundos, mas pode levar até um minuto.
Grave a lógica do endpoint
Agora que você tem um token de acesso e instalou o OctoKit, pode atualizar a função do endpoint para fazer algo quando ele receber eventos. Especificamente, a função deve:
Analisar o evento de webhook recebido
Registrar a contribuição no MongoDB
Adicionar um comentário por meio da API do GitHub
Envie uma resposta informativa de volta ao GitHub
Para atualizar a função:
No menu de navegação esquerdo, clique em Functions.
Clique em endpoints/greetNewContributors para abrir o editor de função do endpoint.
Substitua a função básica pelo seguinte código:
functions/endpoints/greetNewContributors.jsexports = async function greetNewContributors(request, response) { // Parse the webhook event from the incoming request. const event = JSON.parse(request.body.text()); // Don't do anything unless this is a new issue or pull request if (event.action !== "opened") { return response.setStatusCode(200); } // Get data from the GitHub webhook event. // Based on the webhook configuration the event will be one of the following: // - issues: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#issues // - pull_request: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#pull_request const sender = event.sender; const repo = event.repository; const contribution = event.issue || event.pull_request; const contribution_url = event.issue ? event.issue.url : event.pull_request.issue_url; const issue_number = contribution.number; // Record this contribution in the user's contributor document. // If this user hasn't contributed to the repo before, create a document for them. const atlas = context.services.get("mongodb-atlas"); const contributors = atlas.db("community").collection("contributors"); const contributor = await contributors.findOneAndUpdate( // Look up the user by their GitHub login { login: sender.login }, // Add this issue or pull request to their list of contributions { $push: { contributions: { date: new Date(), type: event.issue ? "issue" : "pull_request", url: contribution_url, }, }, }, // If they haven't contributed before, add them to the database { upsert: true, returnNewDocument: true } ); // Send a welcome message to first time contributors on their issue or pull request const isFirstTimeContributor = contributor.contributions.length === 1; if (isFirstTimeContributor) { const octokit = require("@octokit/request"); await octokit.request( "POST /repos/{owner}/{repo}/issues/{issue_number}/comments", { headers: { authorization: `token ${context.values.get("GitHubAccessToken")}`, }, owner: repo.owner.login, repo: repo.name, issue_number: issue_number, body: `Hi there ${sender.login} 👋 Thanks for your first contribution!`, } ); } // Configure the HTTP response sent back to GitHub return response .setStatusCode(200) .setHeader("Content-Type", "application/json") .setBody( isFirstTimeContributor ? `This is ${sender.login}'s first contribution!` : `${sender.login} has contributed before.` ); }; Clique Save e implemente o endpoint.
Testar o Endpoint
O endpoint da mensagem de boas-vindas agora deve estar totalmente configurado. Para testar se funciona corretamente, abra um novo issue ou pull query no repositório. O endpoint adicionará um novo comentário ao thread na primeira vez que você fizer isso, mas não adicionará uma mensagem de boas-vindas nas tentativas subsequentes.

Github registra as solicitações de webhook do repositório, então você também pode verificar a entrada de registro no Github para confirmar se tudo está funcionando corretamente. Cada registro de solicitação inclui uma mensagem de resposta do endpoint.

Dica
Se você quiser redefinir o teste, exclua o documento com seu nome de usuário do Github de community.contributions
. Isso permite que o aplicativo "esqueça" que você contribui antes e o receberá em sua próxima contribuição.
Gerar um relatório semanal da comunidade
Seu aplicativo está conectado ao Github, armazena informações sobre contribuições e recebe novos colaboradores. Agora vamos estenda-lo para analisar e gerar relatórios automaticamente para seu repositório.
Especifique quais repositórios devem gerar relatórios
Sua aplicação precisa saber quais repositórios deve gerar relatórios para cada semana. Para este tutorial, codificaremos a lista em um valor.
Crie um novo valor chamado GitHubProjects
que contenha uma array de objetos. Cada objeto especifica o nome owner
e repo
de um repositório Github. Certifique-se de incluir uma entrada para o seu repositório.
[ { "owner": "<GitHub Username>", "repo": "<Repository Name>" } ]
Criar uma função que gere relatórios
Um relatório é um documento que resume as contribuições para um repositório por algum período de tempo. Usaremos uma função para criar relatórios sob demanda para um repositório.
Crie uma nova função denominada generateCommunityReport
e adicione o seguinte código:
exports = async function generateCommunityReport({ owner, repo, startDate }) { // Look up issues and pull requests that had activity const octokit = require("@octokit/request"); const { data: issuesWithActivity } = await octokit.request( "GET /repos/{owner}/{repo}/issues", { headers: { authorization: `token ${context.values.get("GitHubAccessToken")}`, }, owner: owner, repo: repo, since: startDate, } ); // Look up users that contributed to the repo const atlas = context.services.get("mongodb-atlas"); const contributors = atlas.db("community").collection("contributors"); const allContributors = await contributors .find({ contributions: { $elemMatch: { date: { $gt: new Date(startDate) }, owner: owner, repo: repo, }, }, }) .toArray(); // Keep track of users who made their first contribution const newContributors = allContributors.filter((c) => { new Date(c.contributions[0].date) > new Date(startDate); }); // Return a report with the data return { owner, repo, startDate, issuesWithActivity, allContributors, newContributors, }; };
Gerar e salvar relatórios toda semana
A função que você acabou de criar cria um relatório para um repositório sob demanda. No entanto, neste ponto, nada chama a função e os relatórios gerados não são salvos em nenhum lugar. Para realmente usá-lo, criaremos um Realm trigger agendado que chama a função uma vez por semana e salva os relatórios gerados no cluster vinculado.
Para criar o trigger:
No menu de navegação esquerdo, clique em Triggers.
Clique em Add a Trigger.
Escolha Scheduled para o tipo de trigger.
Nomear o trigger
generateAndSaveCommunityReports
Escolha o tipo de agendamento Advanced
Insira a seguinte programação cron para executar uma vez por semana na segunda-feira às 5h UTC:
0 5 * * 1 Crie uma nova função para o trigger e nomeie-a
triggers/generateAndSaveCommunityReports
.Clique em Add Dependency e instale
moment
, que usamos para trabalhar com datas na função.Copie o seguinte código no corpo da função:
functions/triggers/generateAndSaveCommunityReports.jsexports = async function generateAndSaveCommunityReports() { const projects = context.values.get("GitHubProjects"); const lastMonday = getLastMonday(); // e.g. "2022-02-21T05:00:00.000Z" // Generate a report for every tracked repo const reportsForLastWeek = await Promise.all( // Call the `generateCommunityReport` function for each project projects.map(async (project) => { return context.functions.execute("generateCommunityReport", { owner: project.owner, repo: project.repo, startDate: lastMonday, }); }) ); // Save the generated reports in Atlas const atlas = context.services.get("mongodb-atlas"); const reports = atlas.db("community").collection("reports"); return await reports.insertMany(reportsForLastWeek); }; // Get an ISO string for last Monday at 5AM UTC function getLastMonday() { const moment = require("moment"); return moment(new Date().setUTCHours(5, 0, 0, 0)) .utc() .day(1 - 7) .toISOString(); } Clique em Save.
Atualize as configurações de autenticação da sua nova função para corresponder à função do novo endpoint como mostrado anteriormente neste tutorial.
Enviar notificações de relatório
Sua aplicação agora gerará e salvará relatórios automaticamente toda semana. No entanto, os relatórios não serão muito úteis se alguém os ver. Criaremos um Database Tools que escuta novos relatórios e cria uma mensagem formatada que você pode enviar aos usuários finais.
Para configurar as mensagens:
No menu de navegação esquerdo, clique em Triggers.
Clique em Add a Trigger.
Deixe o tipo de trigger definido como Database.
Nomeie o gatilho como
sendCommunityReport
.Adicione o trigger à collection
community.reports
e escute evento Insert .Habilite Full Document para incluir cada novo documento de relatório nos eventos de alteração enviados para a função de gatilho.
Crie uma nova função para o trigger e nomeie-a
triggers/sendCommunityReport
.Copie o seguinte código no corpo da função:
functions/triggers/sendCommunityReport.jsexports = async function sendCommunityReport(changeEvent) { // Pull out the report document from the database change event const report = changeEvent.fullDocument; // Format values from the report to include in the message const projectName = `${report.owner}/${report.repo}`; const moment = require("moment"); const formattedDate = moment(report.startDate).utc().format("MMMM Do, YYYY"); const numIssuesWithActivity = report.issuesWithActivity.length; const numContributors = report.allContributors.length; const numNewContributors = report.newContributors.length; // Create a message string that describes the data in the report const message = [ `# Community contributions to ${projectName} since ${formattedDate}`, `Last week, there was activity on ${numIssuesWithActivity} issues and pull requests.`, `We had ${numContributors} people contribute, including ${numNewContributors} first time contributors.`, ].join("\n"); // For this tutorial we'll just log the message, but you could use a // service to send it as an email or push notification instead. console.log(message); }; Clique Save e implante o trigger.
Testar os Atlas Triggers de relatório
Sua aplicação está configurada para gerar, salvar e enviar relatórios automaticamente toda semana. Para garantir que tudo funcione, você pode executar esse fluxo de relatórios manualmente.
Abra o editor de função do seu trigger agendado, triggers/generateAndSaveCommunityReports
, e clique no botão Run . Isso deve gerar e salvar relatórios on-demand para cada repositório que você listou no Valor GitHubProjects
.
Para confirmar:
Verifique
community.reports
para os novos documentos do relatório.Verifique os registros de Database Tools do reconhecimento de data center do seu aplicativo para encontrar a mensagem formatada para cada relatório
O que vem a seguir?
Parabéns! Você configurou com sucesso um rastreador de contribuição do Github sem servidor e chegou ao final deste tutorial.
Continue construindo
Se você quiser continuar desenvolvendo, pode tentar adicionar alguns novos recursos ao rastreador. Por exemplo, você pode:
Atualize o endpoint para lidar com mais tipos de evento de webhook, como emitir_comment ou pull_request_review.
Atualize os relatórios semanais para incluir mais informações da API do Github.
Conecte-se a um serviço externo como Twilio ou SendGrid para enviar o relatório por e-mail ou SMS, em vez de apenas registrá-lo.
Explore a documentação
O App Services inclui muitos serviços que podem melhorar seu aplicativo. Confira o restante da documentação para saber mais sobre esses serviços e como você pode usá-los.
Dê-nos feedback
Estamos sempre trabalhando para melhorar nossos Docs e tutoriais. Se você tiver uma sugestão ou tiver problemas com este tutorial, clique em Give Feedback na parte inferior desta página para avaliar o tutorial e enviar-nos um comentário.
Comunidades do MongoDB
Para perguntas, discussões ou suporte técnico geral, visite as comunidades MongoDB no Reddit ou no Stack Overflow. Essas plataformas são ótimos lugares para se conectar com outros usuários MongoDB , fazer perguntas e obter respostas.
Para mostrar seus projetos do MongoDB, compartilhar conteúdo, saber mais sobre nossos programas de comunidade, obter feedback de pares e conectar-se com outros desenvolvedores, visite a MongoDB Community Federation.