Skip to main content

Como criar um bot do Slack com Zapier e JavaScript para buscar assuntos em alta no Reddit

Escrito por
blog hero webinar

30 de agosto de 2022

0 minutos de leitura

O Reddit é um ótimo lugar para ficar por dentro das novidades sobre desenvolvimento web. Se você é como eu, provavelmente acompanha subreddits como r/node ou r/javascript. Recentemente, encontrei uma ótima maneira de criar uma integração entre o Reddit e o Zapier usando apenas meus conhecimentos de JavaScript — assim, posso compartilhar as publicações em alta do Reddit no canal da minha equipe.

Neste artigo, você vai aprender:

  • Como criar uma integração de bot do Slack.

  • Como criar fluxos de trabalho com gatilhos e ações no Zapier para publicar mensagens em um canal do Slack.

  • Como usar uma chave da API do Reddit para acessar publicações com tokens de acesso e de atualização nativos do Reddit.

  • Como acessar publicações do Reddit pelo endpoint JSON anônimo.

  • Como escrever código JavaScript (compatível com o Node.js versão 10, que está no fim da vida útil) para buscar informações do Reddit usando o cliente HTTP node-fetch.

O que você pode fazer com um bot do Slack?

Este tutorial ensina a escrever um bot do Slack em JavaScript, mas o amplo ecossistema de APIs do Zapier permite conectar muitas outras fontes de informação à API do bot do Slack. Embora este tutorial se concentre em JavaScript, você também pode criar uma aplicação de bot do Slack em Node.js com os webhooks HTTP do Zapier, hospedando suas aplicações Node.js na nuvem.

Criando uma integração entre o Reddit e o Zapier para acompanhar novos assuntos em alta

O que é o Zapier?

O Zapier é uma plataforma de automação que permite integrar diferentes plataformas, conectá-las e criar um fluxo de trabalho. Ela é usada principalmente com APIs e integrações nativas disponíveis no marketplace do Zapier. Mas seu grande diferencial é fornecer dados brutos de entrada e saída dos pontos de integração e permitir que você personalize o fluxo de trabalho usando código.

Para facilitar a integração do bot do Slack, vamos usar o Zapier, que já tem integração nativa com o Slack. Isso significa que não precisamos hospedar o bot em um servidor dedicado nem criar mais uma integração separada de bot do Slack.

Com a integração do bot do Slack ao Zapier configurada, os próximos passos são:

  1. Definir uma programação para a integração. Pode ser recorrente, para que a tarefa do Zapier seja executada e inicie o processamento.

  2. Definir uma tarefa de código JavaScript personalizado no Zapier para buscar os assuntos em alta que nos interessam no endpoint JSON do Reddit.

  3. Formatar os assuntos em alta como preferirmos e enviá-los a um canal do Slack pela integração nativa de bot do Slack incluída no Zapier.

Na interface de fluxo de trabalho do Zapier, o processo completo fica assim:

Fluxo de trabalho do Zapier mostrando um acionador de programação semanal, duas ações em JavaScript e uma etapa de mensagem em um canal do Slack

Gatilho: Toda semana, em Schedule by Zapier

Começamos configurando uma programação recorrente para o fluxo de trabalho do Zapier. Escolhi executá-lo toda segunda-feira às 8h UTC:

Gatilho de agendamento do Zapier configurado para ser executado toda segunda-feira às 8h, com os botões Atualizar campos e Continuar visíveis.

Como automatizar mensagens no Slack?

Neste tutorial de bot do Slack, escolhemos uma programação periódica acionada pelo Zapier. No entanto, a plataforma de API do Zapier oferece muitos outros gatilhos para automatizar ações no Slack. Alguns exemplos são menções no Twitter, atualizações no Google Sheets, mudanças em eventos do Google Calendar, atualizações de feeds RSS e muito mais — tudo isso pode ser integrado à automação do bot do Slack em JavaScript. Você pode até automatizar as notificações de segurança do Snyk para acompanhar vulnerabilidades da sua equipe!

Ação: Executar JavaScript em Code by Zapier

Agora que definimos o gatilho baseado em horário para iniciar o fluxo de trabalho, podemos criar ações para executar tarefas. A integração do Zapier permite conectar os dados processados por essas tarefas e encaminhá-los para a próxima ação da sequência.

Escolha o tipo de ação Run JavaScript in Code by Zapier. Na configuração de Event, selecione Run JavaScript. A configuração inicial deve ficar assim:

Configuração de um fluxo de trabalho no Zapier mostrando o evento “Run Javascript” selecionado em Code by Zapier, com um botão Continue e seções de ação concluídas.

Em seguida, expanda a configuração Setup up action, onde vamos adicionar o código JavaScript necessário para buscar informações do endpoint da API do Reddit sobre os assuntos em alta.

Como usar uma chave da API do Reddit

Há várias maneiras de buscar novidades no Reddit. Vamos abordar duas formas de receber atualizações sobre discussões interessantes:

  1. Usar uma chave da API do Reddit, o que exige criar uma conta de usuário no Reddit.

  2. Usar um endpoint público da API do Reddit.

Se você precisa apenas de acesso de leitura a subreddits e publicações em alta, use o fluxo de trabalho mais simples, sem a API oAuth do Reddit — e vá para a segunda parte deste capítulo sobre acesso à API do Reddit.

Como se cadastrar para obter uma chave da API do Reddit

Acesse as preferências de aplicativos da API do Reddit e clique no botão Create an app na parte inferior da tela. Em seguida, informe os dados do seu caso de uso da API. Defina o tipo de aplicativo como webapp e informe um URI de redirecionamento para processar os tokens de acesso.

Crie um formulário de aplicativo com campos para nome, descrição, URL sobre, URI de redirecionamento e opções para aplicativo web, aplicativo instalado ou script.

Você receberá seu ClientID e ClientSecret, que poderá usar para fazer chamadas à API. Se não souber como consultar a API do Reddit e seguir o fluxo oAuth do Reddit, confira outros tutoriais para começar, como este sobre raspagem de dados do Reddit.

Leia os termos de acesso à API do Reddit para conhecer as regras e condições que você precisa cumprir.

Exemplo de API do Reddit em JavaScript

Vamos nos concentrar em buscar discussões interessantes do Reddit usando JavaScript. Para isso, precisaremos das credenciais ClientID e ClientSecret mencionadas acima, além do valor refresh_token, disponível se você optar por criar um token de acesso oAuth permanente do Reddit.

Veja um bom exemplo de chave da API do Reddit que consulta publicações de subreddits usando código JavaScript nativo. Substitua o texto ABCD abaixo pelas credenciais do Reddit mencionadas acima para que o trecho de código funcione corretamente:

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 trecho de código JavaScript usa o refresh_token para consultar a API do Reddit e solicitar um access_token. Depois de obter o token de acesso à API do Reddit, podemos criar uma nova solicitação HTTP para buscar publicações em alta enviadas ao subreddit r/node. Por fim, percorremos os dados de todas as publicações e criamos uma mensagem para a próxima ação.

Dois pontos importantes sobre o trecho de código anterior:

  1. A API correta e atualizada para consultar os dados do Reddit usa o parâmetro de consulta t, definido em params2. Porém, alguns tutoriais e guias desatualizados ainda mencionam o uso de time.

  2. Outro ponto interessante: como o Zapier nos limita a uma versão antiga do node-fetch, executada em uma versão do Node.js que já chegou ao fim da vida útil (Node.js v10), você pode usar diretamente o objeto URL para fazer solicitações 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 outras operações de API, consulte a página completa e atualizada da documentação da API do Reddit, que lista todos os endpoints disponíveis para contas, histórico, moderação de subreddits e outros recursos do Reddit.

Consultando informações do Reddit pelo endpoint JSON público

Antes de continuar com a outra ação JavaScript do Zapier, veja rapidamente como consultar a API do Reddit sem autenticação oAuth nem qualquer outro tipo de chave de API.

O Reddit disponibiliza as informações de discussões dos subreddits em formato JSON por meio do endpoint público e sem autenticação a seguir:

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

Você também pode solicitar as publicações Top deste subreddit e definir um período para a consulta acrescentando os seguintes parâmetros:

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

A resposta JSON do Reddit será semelhante a esta:

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

Como formatar a resposta JavaScript da ação do Zapier

Independentemente de como você obteve e formatou os dados JSON do Reddit, será preciso prepará-los para a próxima integração do bot do Slack. Você pode fazer isso na própria ação JavaScript anterior do Zapier ou criar uma ação separada para reutilizá-la caso o método de formatação do Reddit mude.

O trecho de código é simples e mostra como receber dados em uma ação JavaScript do Zapier usando a variável inputData e também fornecê-los como saída:

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

A representação em array não é estritamente necessária, mas permite informar ao Zapier que ele deve repetir várias vezes as ações seguintes, usando cada carga (ou conjunto de valores do objeto) do array.

Veja a captura de tela a seguir como referência:

Ação Run Javascript in Code do Zapier mostrando a entrada de mensagem mapeada e o código JavaScript que registra uma mensagem do Slack e retorna um objeto de saída.

Enviar mensagem para um canal no Slack

Chegamos à última etapa para criar a automação do Reddit com um bot do Slack: publicar em um canal do Slack a mensagem processada nas etapas anteriores.

Para isso, autentique o Zapier como um aplicativo de integração geral no Slack e conceda a ele acesso para listar seus canais e outras permissões, como publicar mensagens.

Adicione uma nova ação do Zapier e selecione Slack em Application. No campo Event, escolha Send Channel Message. Em seguida, vá até Choose Account e, de preferência, selecione sua conta do Slack para que as mensagens sejam enviadas pelo seu perfil. Caso contrário, você pode usar a conta de integração do Slack como usuário geral.

Neste ponto, a configuração deve estar assim:

Fluxo de trabalho do Zapier com ações JavaScript seguidas de uma ação do Slack configurada para enviar uma mensagem a um canal

Em seguida, acesse Set up action e informe os seguintes dados:

  • O canal em que a mensagem será publicada (indicado pela opção Channel na interface)

  • A opção Message Text, que deve vir preenchida com o campo Message da ação anterior do Zapier

A configuração deve ficar parecida com esta:

Tela de configuração do Zapier com campos para enviar uma mensagem a um canal do Slack, incluindo texto da mensagem, nome do bot, URL da imagem e opções de link.

Por fim, você pode executar um teste manual do fluxo de trabalho do Zapier, que deve ficar assim:

Tela de revisão do Zapier exibindo dados de mensagens do Slack com links para publicações do Reddit em Node.js e os botões Retestar e revisar e Publicar Zap

Depois de revisar e testar o fluxo de trabalho do Zapier, clique no botão Publish Zap. Isso ativará o fluxo e iniciará a automação de acordo com a programação recorrente definida como gatilho.

Como conectar a API do Slack a outras APIs?

Com o Zapier, você pode criar APIs de bot do Slack que vão além do envio de mensagens para um canal. Veja algumas ideias de automação com bots do Slack em JavaScript usando o Zapier: enviar uma mensagem quando uma linha do Google Sheets for atualizada, compartilhar no Slack eventos do Google Calendar que estão próximos, publicar no Slack novas menções do Twitter ou até atualizar seu status no Slack durante eventos do Google Calendar ou com base em outras atividades conectadas às APIs do Zapier.

Você criou uma integração entre o Reddit e o Zapier!

Hoje, aprendemos a criar um bot do Slack que envia automaticamente mensagens para um canal com as principais novidades em alta no Reddit, usando um endpoint JSON público ou uma chave da API oAuth do Reddit.

Para finalizar, se você está criando uma integração de bot do Slack baseada em código JavaScript, siga as práticas de segurança para JavaScript relevantes e entenda os riscos associados. Assim, você evita expor sua empresa a problemas de segurança.

Publicado em: