Skip to main content

Cómo crear un bot de Slack con Zapier y JavaScript para obtener temas populares de Reddit

Escrito por
blog hero webinar

30 de agosto de 2022

0 minutos de lectura

Reddit es un buen lugar para estar al tanto de las noticias sobre desarrollo web y, si eres como yo, probablemente sigues subreddits como r/node o r/javascript. Hace poco encontré una excelente manera de crear una integración de Reddit con Zapier usando solo mis conocimientos de JavaScript, para compartir las publicaciones populares de Reddit en el canal de mi equipo.

En este artículo aprenderás:

  • Cómo crear una integración de bot de Slack.

  • Cómo crear flujos de trabajo con activadores y acciones en Zapier para publicar mensajes en un canal de Slack.

  • Cómo usar una clave de API de Reddit para acceder a publicaciones con tokens de acceso y actualización nativos de Reddit.

  • Cómo acceder a publicaciones de Reddit mediante el endpoint JSON anónimo.

  • Cómo escribir código JavaScript (compatible con Node.js versión 10, que ya llegó al fin de su vida útil) para obtener información de Reddit con el cliente HTTP node-fetch.

¿Qué puedes hacer con un bot de Slack?

Este tutorial te enseña a escribir un bot de Slack en JavaScript, pero el amplio ecosistema de API de Zapier te permite conectar muchas otras fuentes de información a la API de bots de Slack. Aunque este tutorial se centra en JavaScript, también puedes escribir una aplicación de bot de Slack con Node.js y los webhooks HTTP de Zapier, si alojas tus aplicaciones de Node.js en la nube.

Crear una integración de Reddit con Zapier para procesar nuevos temas populares

¿Qué es Zapier?

Zapier es una plataforma de automatización que te permite integrarte con muchas otras plataformas para conectarlas y crear un flujo de trabajo. Se usa principalmente para API e integraciones nativas cuando están disponibles en el marketplace de Zapier, pero destaca aún más porque proporciona datos de entrada y salida sin procesar desde los puntos de integración y te permite personalizar el proceso del flujo de trabajo con código.

Para facilitar la integración del bot de Slack, usaremos Zapier, que ya tiene una integración nativa con Slack. Esto significa que no necesitamos alojar nuestro bot en un servidor dedicado ni crear otra integración de bot de Slack por separado.

Como ya tenemos la integración del bot de Slack con Zapier, los siguientes pasos serán:

  1. Definir un horario para que se ejecute la integración. Puede ser un horario recurrente en el que se active la tarea de Zapier y comience a procesar.

  2. Definir una tarea de código JavaScript personalizada en Zapier para obtener los temas populares que nos interesan desde el endpoint JSON de Reddit.

  3. Dar el formato que queramos a los temas populares y enviarlos a un canal de Slack mediante la integración nativa de Slack que Zapier incluye.

En la interfaz de usuario del flujo de trabajo de Zapier, el proceso completo se ve así:

Flujo de trabajo de Zapier que muestra un activador de programación semanal, dos acciones de JavaScript y un paso para enviar un mensaje a un canal de Slack

El activador: cada semana en Schedule by Zapier

Empezamos por configurar el horario recurrente para el flujo de trabajo de Zapier. En concreto, elegí ejecutarlo todos los lunes a las 8 a. m. UTC:

Activador de programación de Zapier configurado para ejecutarse todos los lunes a las 8 a. m.; se ven los botones Refresh fields y Continue.

¿Cómo automatizar los mensajes de Slack?

En este tutorial de bot de Slack, elegimos un horario oportuno activado por Zapier. Sin embargo, la plataforma de API de Zapier tiene muchos otros activadores que pueden impulsar las automatizaciones de Slack. Algunos ejemplos son las menciones en Twitter, las actualizaciones de Google Sheets, los cambios en eventos de Google Calendar, las actualizaciones de fuentes RSS y otros que puedes conectar a la automatización de bots de Slack en JavaScript. ¡Incluso puedes automatizar las notificaciones de seguridad de Snyk para que tu equipo haga seguimiento de las vulnerabilidades!

Acción: ejecutar JavaScript en Code by Zapier

Ahora que definimos el activador basado en la hora que iniciará el flujo de trabajo, podemos comenzar a crear acciones para realizar algunas tareas. La integración de Zapier nos permite conectar los datos procesados por estas tareas y pasarlos a la siguiente acción de la cadena.

Elige el tipo de acción Run JavaScript in Code by Zapier. En la configuración de Event, selecciona Run JavaScript. La configuración inicial debería verse así:

Configuración de un flujo de trabajo de Zapier con el evento «Run Javascript» seleccionado en Code by Zapier, un botón Continue y secciones de acciones completadas.

Luego, expande la configuración Setup up action, donde agregaremos el código JavaScript pertinente que obtiene información del endpoint de la API de Reddit para nuestros temas populares.

Cómo usar una clave de API de Reddit

Hay varias maneras de obtener noticias de Reddit. Veremos dos formas de recibir actualizaciones sobre hilos interesantes de Reddit:

  1. Usar una clave de API de Reddit, que requiere registrarse con una cuenta de usuario de Reddit.

  2. Usar un endpoint de API de Reddit disponible públicamente.

Si solo necesitas acceso de lectura a subreddits y publicaciones populares, usa el flujo de trabajo más sencillo, que no requiere el flujo de trabajo de la API OAuth de Reddit, y pasa a la segunda parte de este capítulo sobre el acceso a la API de Reddit.

Registrarse para obtener una clave de API de Reddit

Primero, ve a las preferencias de aplicaciones de la API de Reddit y haz clic en el botón Create an app en la parte inferior de la pantalla. Luego, ingresa la información correspondiente al caso de uso de tu API. Deberás establecer el tipo de aplicación como webapp y proporcionar un URI de redirección para procesar los tokens de acceso.

Crea un formulario de aplicación con campos para el nombre, la descripción, la URL de información, el URI de redireccionamiento y opciones para aplicación web, aplicación instalada o script.

Luego recibirás tu ClientID y ClientSecret, con los que podrás realizar llamadas a la API. Si no sabes cómo consultar la API de Reddit ni completar el flujo de trabajo OAuth de Reddit, revisa otros tutoriales para empezar, como este sobre cómo extraer datos de Reddit.

Es importante que leas las condiciones de acceso a la API de Reddit para familiarizarte con las reglas y condiciones que debes cumplir.

Ejemplo de API de Reddit en JavaScript

Nos centraremos en obtener hilos interesantes de Reddit con JavaScript. Para ello, necesitaremos las credenciales ClientID y ClientSecret mencionadas anteriormente, además del valor refresh_token, que existe si elegiste crear un token de acceso OAuth permanente de Reddit.

A continuación, encontrarás un buen ejemplo de una clave de API de Reddit que consulta publicaciones de subreddits con código JavaScript nativo. Reemplaza el texto ABCD a continuación por las credenciales de Reddit mencionadas anteriormente para que el fragmento de código funcione correctamente:

js
  // start -- get access token
   const clientId = ‘ABCD’;
   const clientSecret = ABCD’;

   const dataSecrets = `${clientId}:${clientSecret}`;
   const text = Buffer.from(dataSecrets).toString("base64");

   var url = new URL('https://www.reddit.com/api/v1/access_token');
   var params = {grant_type: 'refresh_token', refresh_token: ‘ABCD'};

   url.search = new URLSearchParams(params).toString();

    const settings = {
        method: 'POST',
        headers: {
            'User-Agent': 'query-api 1.0',
            'Accept': 'application/json',
            'Authorization': `Basic ${text}`,
        },
        credentials: 'omit'
    };

    const res = await fetch(url.href, settings);
    const body = await res.json();
    const accessToken = body.access_token;

    // -----------------------------------------------------
    // make reddit api request
    const params2 = {'limit': 3, 't': 'week'};
    const url2 = new URL('https://oauth.reddit.com/r/node/top');
    url2.search = new URLSearchParams(params2).toString();

    const settings2 = {
        method: 'GET',
        headers: {
            'User-Agent': 'query-api 1.0',
            'Accept': 'application/json',
            'Authorization': `Bearer ${accessToken}`,
        },
        credentials: 'omit'
    };

    const res2 = await fetch(url2.href, settings2);
    const body2 = await res2.json();

    let data = [];
    let message = `Top Node.js posts this week:\n\n`;

    const topPosts = body2.data.children;
    topPosts.forEach((post) => {
        data.push({
          link: post.data.url,
          redditLink: post.data.permalink,
          text: post.data.title,
          score: post.data.score,
          replies: post.data.num_comments
        });

        const text = post.data.title;
        const redditLink = post.data.permalink;

        message = message + `<https://reddit.com${redditLink}|${text}> \n`;
    });

    return {id: 1, message: message};

Este fragmento de código JavaScript para la API de Reddit usa el refresh_token para consultar la API de Reddit y solicitar un access_token. Una vez que obtenemos el token de acceso a la API de Reddit, podemos crear una nueva solicitud HTTP para obtener publicaciones populares de Reddit enviadas al subreddit r/node. Por último, recorremos todos los datos de las publicaciones y creamos una cadena de mensaje que se pasará a la siguiente acción.

Dos observaciones importantes sobre el fragmento de código anterior:

  1. Ten en cuenta que la forma correcta y actualizada de consultar los datos de Reddit es usar el parámetro de consulta t, que se utiliza en params2. Sin embargo, algunos tutoriales y guías desactualizados todavía mencionan el uso de time.

  2. Otro dato interesante es que, como Zapier nos limita a una versión antigua de node-fetch, que se ejecuta en una versión de Node.js que ya llegó al fin de su vida útil (Node.js v10), puedes usar directamente el objeto URL para realizar solicitudes HTTP:

    js const url2 = new URL('https://oauth.reddit.com/r/node/top'); const res2 = await fetch(url2, settings2);

js
    const url2 = new URL('https://oauth.reddit.com/r/node/top');
    const res2 = await fetch(url2, settings2);

Para otras operaciones de la API, puedes consultar la página completa y actualizada de la documentación de la API de Reddit, que incluye todos los endpoints disponibles para cuentas de Reddit, historial, moderación de subreddits y otras funciones.

Consultar información de Reddit con el endpoint JSON público

Antes de continuar con la otra acción de JavaScript en Zapier, veamos rápidamente cómo consultar una API de Reddit sin autenticarse con OAuth ni usar ningún otro tipo de clave de API.

Reddit ofrece la información de los hilos de los subreddits en formato JSON a través del siguiente endpoint, que es público y no requiere autenticación:

sh
https://www.reddit.com/r/node/top.json

Incluso puedes solicitar las publicaciones Top de este subreddit y especificar un período agregando los siguientes parámetros de consulta:

sh
https://www.reddit.com/r/node/top.json?limit=1&t=month

La respuesta JSON de Reddit será similar a la siguiente:

json
{
  "kind": "Listing",
  "data": {
    "after": "t3_vuyxes",
    "dist": 1,
    "modhash": "6v201d03619751a685b19dcf05febbf88ed6d115afa5d16b78",
    "geo_filter": "",
    "children": [
      {
        "kind": "t3",
        "data": {
          "approved_at_utc": null,
          "subreddit": "node",
          "selftext": "",
          "author_fullname": "t2_7eb9a4k5",
          "saved": false,
          "mod_reason_title": null,
          "gilded": 0,
          "clicked": false,
          "title": "Deno in 2022",
          "link_flair_richtext": [],
          "subreddit_name_prefixed": "r/node",
          "hidden": false,
          "pwls": 6,
          "link_flair_css_class": null,
          "downs": 0,
          "top_awarded_type": null,
          "hide_score": false,
          "name": "t3_vuyxes",
          "quarantine": false,
          "link_flair_text_color": "dark",
          "upvote_ratio": 0.92,
          "author_flair_background_color": null,
          "subreddit_type": "public",
          "ups": 745,
          "total_awards_received": 0,
          "media_embed": {},
          "author_flair_template_id": null,
          "is_original_content": false,
          "user_reports": [],
          "secure_media": null,
          "is_reddit_media_domain": true,
          "is_meta": false,
          "category": null,
          "secure_media_embed": {},
          "link_flair_text": null,
          "can_mod_post": false,
          "score": 745,
          "approved_by": null,
          "is_created_from_ads_ui": false,
          "author_premium": false,
          "thumbnail": "",
          "edited": false,
          "author_flair_css_class": null,
          "author_flair_richtext": [],
          "gildings": {},
          "content_categories": null,
          "is_self": false,
          "mod_note": null,
          "created": 1657363081,
          "link_flair_type": "text",
          "wls": 6,
          "removed_by_category": null,
          "banned_by": null,
          "author_flair_type": "text",
          "domain": "i.redd.it",
          "allow_live_comments": true,
          "selftext_html": null,
          "likes": null,
          "suggested_sort": null,
          "banned_at_utc": null,
          "url_overridden_by_dest": "https://i.redd.it/hjv8r84ttia91.jpg",
          "view_count": null,
          "archived": false,
          "no_follow": false,
          "is_crosspostable": true,
          "pinned": false,
          "over_18": false,
          "all_awardings": [],
          "awarders": [],
          "media_only": false,
          "can_gild": true,
          "spoiler": false,
          "locked": false,
          "author_flair_text": null,
          "treatment_tags": [],
          "visited": false,
          "removed_by": null,
          "num_reports": null,
          "distinguished": null,
          "subreddit_id": "t5_2reca",
          "author_is_blocked": false,
          "mod_reason_by": null,
          "removal_reason": null,
          "link_flair_background_color": "",
          "id": "vuyxes",
          "is_robot_indexable": true,
          "report_reasons": null,
          "author": "m_ax__",
          "discussion_type": null,
          "num_comments": 184,
          "send_replies": true,
          "whitelist_status": "all_ads",
          "contest_mode": false,
          "mod_reports": [],
          "author_patreon_flair": false,
          "author_flair_text_color": null,
          "permalink": "/r/node/comments/vuyxes/deno_in_2022/",
          "parent_whitelist_status": "all_ads",
          "stickied": false,
          "url": "https://i.redd.it/hjv8r84ttia91.jpg",
          "subreddit_subscribers": 215851,
          "created_utc": 1657363081,
          "num_crossposts": 0,
          "media": null,
          "is_video": false
        }
      }
    ],
    "before": null
  }
}

Dar formato a la respuesta de JavaScript de la acción de Zapier

Independientemente de cómo hayas obtenido y dado formato a los datos JSON de Reddit, tendremos que prepararlos para que pueda usarlos la siguiente integración del bot de Slack. Puedes hacerlo en la acción de JavaScript anterior de Zapier o ejecutarlo como una acción independiente de Zapier para poder reutilizarla si cambia el método de formato de Reddit.

El fragmento de código es bastante sencillo y muestra cómo aceptar datos de entrada en una acción de JavaScript de Zapier mediante la variable inputData y también proporcionarlos como salida:

js
const slackMessage = inputData.message
output = [{id: 123, message: slackMessage}];

La representación en forma de arreglo no es estrictamente necesaria, pero le permite a Zapier saber que debe repetir varias veces las acciones posteriores, con cada carga útil (o valor de objeto) del arreglo.

La siguiente captura de pantalla sirve como referencia:

Acción Ejecutar JavaScript en Code de Zapier que muestra la entrada del mensaje asignada y código JavaScript que registra un mensaje de Slack y devuelve un objeto de salida.

Enviar mensaje al canal en Slack

Por fin llegamos al último paso para crear la automatización de Reddit con un bot de Slack: publicar en un canal de Slack el mensaje que procesamos en los pasos anteriores.

Para hacerlo, asegúrate de haber autenticado Zapier como una aplicación de integración general en Slack y de haberle dado permiso para ver tus canales de Slack y realizar otras acciones, como publicar mensajes.

Agrega una nueva acción de Zapier y selecciona Slack en la opción Application. En el campo Event, selecciona Send Channel Message. Luego, ve a la opción Choose Account y, de preferencia, ingresa tu cuenta de Slack para que los mensajes provengan de tu perfil de usuario. Si no, puedes usar la cuenta de integración de Slack como usuario general.

En este punto, debería verse así:

Flujo de trabajo de Zapier que muestra acciones de JavaScript seguidas de una acción de Slack configurada para enviar un mensaje a un canal

Luego, ve a Set up action e ingresa la siguiente información:

  • El canal donde se publicará el mensaje (indicado como la opción Channel en la interfaz de usuario)

  • La opción Message Text, que debería tener el campo Message de la acción anterior de Zapier completado de antemano

La configuración debería verse similar a la siguiente:

Pantalla de configuración de Zapier que muestra campos para enviar un mensaje a un canal de Slack, como el texto del mensaje, el nombre del bot, la URL de la imagen y las opciones de enlace.

Por último, puedes iniciar manualmente una prueba de ejecución de este flujo de trabajo de Zapier, que debería verse así:

Pantalla de revisión de Zapier que muestra datos de mensajes de Slack con enlaces a publicaciones de Reddit en Node.js y los botones «Volver a probar y revisar» y «Publicar Zap»

Después de revisar y probar el flujo de trabajo de Zapier, haz clic en el botón Publish Zap para activar el flujo de trabajo y comenzar la automatización según el horario recurrente que configuramos como activador.

¿Cómo conectar la API de Slack con otras API?

Con Zapier puedes crear API para bots de Slack que hagan mucho más que enviar mensajes a un canal. Aquí tienes algunas ideas para bots de Slack en JavaScript que puedes crear con Zapier: enviar un mensaje de Slack cuando se actualice una fila de Google Sheets, enviar los próximos eventos de Google Calendar a un canal de Slack, compartir nuevas menciones de Twitter en Slack o incluso actualizar tu estado de Slack durante eventos de Google Calendar o según otras actividades que puedas conectar con las API de Zapier.

¡Creaste una integración de Reddit con Zapier!

Hoy aprendimos a crear un bot de Slack que envía automáticamente a un canal un mensaje con las principales noticias populares de Reddit mediante un endpoint JSON de acceso público o una clave de API OAuth de Reddit.

Para terminar, si estás creando una integración de bot de Slack que funciona con código JavaScript, asegúrate de seguir las prácticas de seguridad de JavaScript pertinentes y comprender los riesgos asociados para no poner en peligro tu empresa con problemas de seguridad.

Publicado en: