Tutorial: Compile un rastreador de contribuciones de GitHub sin servidor mediante Activadores, Functions y Values
Tiempo estimado para completar: 30 minutos
En este tutorial, utilizará Atlas App Services para crear una aplicación sin servidor que monitoree los repositorios de GitHub y haga un seguimiento de las contribuciones.
La aplicación de servicios de aplicaciones que cree tendrá varias características:
Realice un seguimiento de los usuarios que han contribuido a su proyecto en una colección de MongoDB Atlas.
Deje un comentario que dé la bienvenida a los nuevos colaboradores cuando abran una solicitud de extracción o presenten un problema.
Genere y envíe un informe semanal que resuma las contribuciones a su repositorio.
Después de completar este tutorial, sabrá cómo realizar las siguientes tareas:
Escriba y ejecute funciones sin servidor que manejen la lógica de su aplicación.
Automatice las tareas programadas y responda a los datos cambiantes con Atlas Triggers.
Almacena y accede a datos estáticos, como claves API, en Valores.
Conectarse a un servicio externo a través de una API
Requisitos previos
Necesitará lo siguiente antes de poder comenzar este tutorial:
A GitHub repository. The App you build will track contributions to this repository. You can create a new repository for this tutorial or use an existing repo that you have admin access to.
Un clúster de MongoDB Atlas. Si aún no tienes un clúster, regístrate en MongoDB Atlas y crea uno gratis.
Tenga en cuenta también que este tutorial no utiliza el flujo de trabajo de borrador de implementación. Un borrador de implementación es un conjunto de cambios en la aplicación que puede implementar o descartar como una sola unidad. A menos que haya desactivado los borradores de implementación, es posible que deba guardar los cambios en un borrador y luego implementarlos manualmente.
Crear una nueva aplicación
Primero, debes crear una aplicación en App Services.
Para crear la aplicación:
Abra su proyecto Atlas en cloud.mongodb.com.
In the top navigation, click App Services.
Haga clic en Create a New App.
Name the App
github-tracker-tutorial.Seleccione su clúster para vincularlo a la nueva aplicación.
Haga clic en Create App Service.
Bienvenidos nuevos colaboradores de GitHub
Conectaremos la aplicación a tu repositorio de GitHub mediante un webhook. Los webhooks informan a tu aplicación de cualquier evento, como una nueva confirmación o una solicitud de extracción, en tu repositorio. Cada evento ejecuta una función sin servidor que te permite responder a una acción.
Para este tutorial, usaremos la API REST de GitHub para enviar un mensaje de bienvenida a los colaboradores cada vez que abran su primera solicitud de extracción o problema en un repositorio.
Crear un punto final
Los webhooks funcionan enviando una solicitud sobre el evento a una URL controlada por tu aplicación. En tu aplicación, deberás exponer un punto final personalizado con una URL única para recibir y gestionar las solicitudes de webhooks.
Para crear el punto final:
En el menú de navegación de la izquierda, haga clic en HTTPS Endpoints.
Haga clic en Add An Endpoint.
Nombre la ruta del punto final
/greetNewContributors.En Operation Type, copia la URL de devolución de llamada del punto final. La necesitarás para configurar el webhook de GitHub más adelante.
Deje el método HTTP establecido en POST.
Para la autorización, seleccione Require a Secret.
Introduzca un nuevo nombre de secreto y haga clic en Create para crearlo. A continuación, introduzca
tutorialcomo valor del secreto. Esto requiere que todas las solicitudes entrantes incluyan el parámetro de consultasecret=tutorialen la URL de la solicitud.Cree una nueva función Atlas para el punto final y
endpoints/greetNewContributorsllámela.Por ahora, configure un controlador básico que solo responda a las llamadas entrantes sin realizar ninguna otra tarea. Copie el siguiente código en el cuerpo de la función:
exports = async function greetNewContributors(request, response) { return response .setStatusCode(200) .setBody("Successfully received a GitHub webhook event") } Haga clic en Save e implemente el punto final.
Actualice la configuración de autenticación de su función de punto final
Ahora que has creado el endpoint en tu aplicación, necesitas cambiar la configuración de autenticación de la función del endpoint para que se acepte el webhook de GitHub.
Para actualizar la configuración de autenticación de su función:
En el menú de navegación de la izquierda, haga clic en Functions.
Encuentra tu Function endpoint y selecciónalo.
Haga clic en Settings.
En Authentication, cambie el método de autenticación a System.
Haga clic en Save para implementar la función.
Conecte el punto final a un webhook de GitHub
Con tu Function para endpoint lista para usarse, necesitas configurar un webhook en tu repositorio de GitHub que envíe eventos al endpoint.
Para crear el webhook en su repositorio:
Abra la configuración del repositorio y seleccione Webhooks en el menú de navegación izquierdo.
Agregar un webhook nuevo y establecer el Payload URL en la URL del endpoint que acabas de crear, además de un parámetro query
secretestablecido en el valor secreto, como:?secret=tutorial. La URL de la carga útil tendrá un aspecto similar al siguiente, con algunas diferencias que dependerán del modelo de implementación de la aplicación. Tenga en cuenta el?secret=tutorialañadido al final de la URL:https://us-west-2.aws.data.mongodb-api.com/app/<App ID>/endpoint/greetNewContributors?secret=tutorial Establezca el tipo de contenido del webhook como application/json.
Deje Secret vacío. El punto final HTTPS ignora cualquier valor introducido aquí, por lo que añadimos el secreto como parámetro de consulta en la URL de carga útil en los pasos anteriores.
Elija seleccionar eventos individuales y configure el webhook para enviar solo eventos para Issues y Pull requests.
Haga clic en Add webhook para guardar el nuevo webhook.
Para confirmar que el webhook llama correctamente a tu endpoint, revisa los registros de tu aplicación en App Services para ver si hay entradas de Endpoint tipo. Puedes acceder a ellas haciendo clic Logs en en el menú de navegación izquierdo.
También puedes consultar los registros de solicitudes del webhook en GitHub, en Recent Deliveries la sección de la página de configuración del webhook. Cada solicitud exitosa tiene una marca de verificación verde junto a ella.

Obtener un token de acceso de GitHub
El webhook ya está configurado para enviar eventos desde GitHub a tu endpoint. Sin embargo, para responder a los eventos en el endpoint con la API de GitHub, necesitarás un token de acceso. Este tutorial utiliza tokens de acceso personales, pero también puedes configurar una aplicación de GitHub y usar ese token.
Para crear un token de acceso personal:
Abra la configuración de usuario de GitHub (no la configuración de su repositorio) y seleccione Developer settings en el menú de navegación izquierdo.
En el menú de navegación de la izquierda, seleccione Personal access tokens y luego haga clic en Generate new token.
Configure el token con un nombre descriptivo y un tiempo de expiración razonable. Dado que este es un tutorial, considere expirar el token después de 7 días.
Seleccione el alcance
repo.Haga clic en Generate token.
Copia el token en un lugar seguro donde puedas acceder de nuevo. GitHub nunca volverá a mostrarte el token después de este punto.
Almacenar el token como un valor
De vuelta en tu aplicación, agrega un nuevo valor para almacenar el token de acceso personal que acabas de generar. Podrás referenciarlo desde tu punto final sin tener que codificar el token en tus funciones.
Para crear el Valor:
En el menú de navegación de la izquierda, haga clic en Values.
Haga clic en Create New Value.
Nombra el valor
GitHubAccessToken.Deje el tipo establecido en Value.
Pegue el token de acceso personal en la entrada del valor. El valor debe ser un JSON válido, así que asegúrese de incluirlo entre comillas.
Haga clic en Save.
Instalar el cliente de API de GitHub
El punto final interactuará con la API REST de GitHub para dejar comentarios. Puedes escribir y enviar solicitudes HTTP directamente a la API usando el context.http cliente integrado o una biblioteca externa. Sin embargo, en este tutorial usamos Octokit, la biblioteca oficial de Node.js de GitHub, que encapsula la API. Una vez instalada, podrás importar la biblioteca desde cualquier función de tu aplicación.
Para agregar la biblioteca Octokit a su aplicación:
En el menú de navegación de la izquierda, haga clic en Functions.
Seleccione la pestaña Dependencies.
Haga clic en Add Dependency.
Introduzca el nombre del paquete:
@octokit/request.Haga clic en Add.
Espere a que App Services instale el paquete. La instalación debería completarse en unos segundos, pero podría tardar hasta un minuto.
Escribe la lógica del punto final
Ahora que tiene un token de acceso e instaló Octokit, puede actualizar la función del punto final para que realice una acción al recibir eventos. En concreto, la función debe:
Analizar el evento webhook entrante
Registrar la contribución en MongoDB
Añade un comentario a través de la API de GitHub
Envíe una respuesta informativa a GitHub
Para actualizar la función:
En el menú de navegación de la izquierda, haga clic en Functions.
Haga clic en endpoints/greetNewContributors para abrir el editor de funciones del punto final.
Reemplace la función básica con el siguiente código:
funciones/puntos finales/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.` ); }; Haga clic en Save e implemente el punto final.
Prueba el endpoint
El punto final del mensaje de bienvenida ya debería estar completamente configurado. Para comprobar su correcto funcionamiento, abra una nueva incidencia o solicitud de incorporación de cambios en el repositorio. El punto final añadirá un nuevo comentario al hilo la primera vez que lo haga, pero no añadirá un mensaje de bienvenida en los intentos posteriores.

GitHub registra las solicitudes de webhook del repositorio, por lo que también puedes consultar la entrada de registro en GitHub para confirmar que todo funciona correctamente. Cada registro de solicitud incluye un mensaje de respuesta del endpoint.

Tip
Si quieres reiniciar la prueba, elimina el documento con tu nombre de usuario de GitHub de community.contributions. Esto permite que la aplicación olvide que ya has contribuido y te dé la bienvenida en tu próxima contribución.
Generar un informe semanal de la comunidad
Tu aplicación está conectada a GitHub, almacena información sobre las contribuciones y da la bienvenida a nuevos colaboradores. Ahora la ampliaremos para que analice y genere informes automáticamente para tu repositorio.
Especificar qué repositorios deben generar informes
Tu aplicación necesita saber qué repositorios generar informes cada semana. En este tutorial, codificaremos la lista en un valor.
Crea un nuevo valor llamado GitHubProjects que contenga una matriz de objetos. Cada objeto especifica el nombre owner y repo de un repositorio de GitHub. Asegúrate de incluir una entrada para tu repositorio.
[ { "owner": "<GitHub Username>", "repo": "<Repository Name>" } ]
Crear una función que genere informes
Un informe es un documento que resume las contribuciones a un repositorio durante un período de tiempo. Utilizaremos una Function para crear informes on-demand para un repositorio.
Crea una nueva función llamada generateCommunityReport y agrega el siguiente 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, }; };
Genere y guarde informes cada semana
La función que acaba de crear genera un informe para un repositorio bajo demanda. Sin embargo, en este momento, ningún elemento la llama y los informes generados no se guardan en ningún lugar. Para usarla, crearemos un disparador Atlas programado que llame a la función una vez por semana y guarde los informes generados en su clúster vinculado.
Para crear el disparador:
En el menú de navegación de la izquierda, haga clic en Triggers.
Haga clic en Add a Trigger.
Seleccione Scheduled para el tipo de disparador.
Name the Trigger
generateAndSaveCommunityReportsElija el tipo de programación Advanced
Introduzca la siguiente programación cron para que se ejecute una vez a la semana los lunes a las 5 AM UTC:
0 5 * * 1 Crea una nueva función para el disparador y llámala
triggers/generateAndSaveCommunityReports.Haga clic en Add Dependency e instale
moment, que usamos para trabajar con fechas en la Función.Copie el siguiente código en el cuerpo de la función:
funciones/desencadenadores/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(); } Haga clic en Save.
Actualice la configuración de autenticación de su nueva función para que coincida con la función del nuevo punto final mencionada anteriormente en este tutorial.
Enviar notificaciones de informes
Tu aplicación generará y guardará informes automáticamente cada semana. Sin embargo, estos informes no serán muy útiles si nadie los ve. Crearemos un disparador de base de datos que detecta nuevos informes y genera un mensaje con formato que puedes enviar a los usuarios finales.
Para configurar los mensajes:
En el menú de navegación de la izquierda, haga clic en Triggers.
Haga clic en Add a Trigger.
Deje el tipo de disparador establecido en Database.
Nombra el activador
sendCommunityReport.Agregue el disparador a la colección
community.reportsy escuche Insert eventos.Habilite Full Document para incluir cada nuevo documento de informe en el evento de cambio pasado a la función de activación.
Crea una nueva función para el disparador y llámala
triggers/sendCommunityReport.Copie el siguiente código en el cuerpo de la función:
funciones/desencadenadores/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); }; Haga clic en Save e implemente el disparador.
Prueba los activadores de informes
Tu aplicación está configurada para generar, guardar y enviar informes automáticamente cada semana. Para asegurarte de que todo funcione correctamente, puedes ejecutar este flujo de informes manualmente.
Abra el editor de funciones de su disparador programado, triggers/generateAndSaveCommunityReports, y haga clic en el botón Run. Esto debería generar y guardar informes a pedido para cada repositorio que haya indicado en el valor GitHubProjects.
Para confirmar:
Marque
community.reportspara ver los nuevos documentos del informe.Consulte los registros de activación de la base de datos de su aplicación para encontrar el mensaje formateado para cada informe
¿Que sigue?
¡Felicitaciones! Has configurado correctamente un rastreador de contribuciones de GitHub sin servidor y has llegado al final de este tutorial.
Sigue construyendo
Si quieres seguir desarrollando, puedes intentar añadir algunas funcionalidades nuevas al rastreador. Por ejemplo, podrías:
Actualice el punto final para manejar más tipos de eventos de webhook como issue_comment o pull_request_review.
Actualice los informes semanales para incluir más información de la API de GitHub.
Conéctese a un servicio externo como Twilio o SendGrid para enviar el informe por correo electrónico o SMS en lugar de simplemente registrarlo.
Explorar la documentación
Los Servicios de aplicaciones incluyen muchos servicios que pueden potenciar tu aplicación. Consulta el resto de la documentación para obtener más información sobre estos servicios y cómo puedes usarlos.
Envíanos tus comentarios
Trabajamos constantemente para mejorar nuestra documentación y tutoriales. Si tienes alguna sugerencia o tuviste algún problema con este tutorial, haz clic en Give Feedback al final de esta página para calificarlo y enviarnos un comentario.
Comunidades de MongoDB
Para preguntas, debates o soporte técnico general, visite las comunidades de MongoDB en Reddit o Stack Overflow. Estas plataformas son excelentes lugares para conectar con otros usuarios de MongoDB, hacer preguntas y obtener respuestas.
Para mostrar sus proyectos MongoDB, compartir contenido, conocer nuestros programas comunitarios, recibir comentarios de sus pares y conectarse con otros desarrolladores, visite el Foro de la comunidad MongoDB.