DEV Community

Cover image for Criando um bot para WhatsApp que se comunica com o Jira
Emerson Vieira
Emerson Vieira

Posted on

Criando um bot para WhatsApp que se comunica com o Jira

Este projeto faz uso dos seguintes módulos node:

1 - whatsapp-web.js
2 - axios, axios-cookiejar-support e tough-cookie
3 - node-cron
4 - qrcode-terminal

OBS: Crie um projeto node e adicione os módulos acima

Estrutura do Projeto

project ├── services │ └── api.js ├── utils │ └── jiraUtils.js ├── index.js ├── jiraClient.js └── package.json 
Enter fullscreen mode Exit fullscreen mode

Código do Projeto

// api.js const axios = require("axios"); const { wrapper } = require("axios-cookiejar-support"); const { CookieJar } = require("tough-cookie"); const cookieJar = new CookieJar(); axios.defaults.withCredentials = true; axios.defaults.jar = cookieJar; const instance = wrapper( axios.create({ baseURL: process.env.JIRA_REST_API_URL, }) ); module.exports = instance; 
Enter fullscreen mode Exit fullscreen mode

Os módulos axios-cookiejar-support e tough-cookie ajudam a tratar e manipualr cookies.

// jiraClient.js const instance = require("./services/api"); const loginJira = async () => { try { const result = await instance.post("/rest/auth/1/session", { username: process.env.JIRA_USERNAME;, password: process.env.JIRA_PASSWORD, }); if (result.status === 200) { console.log("Login realizado com sucesso"); return true; } } catch (error) { console.log("Erro ao realizar o login:", error.message); } return false; }; const getIssue = async (id) => { const result = await instance.get(`/rest/api/2/issue/${id}`); return result; }; const jiraClient = async (id) => { try { const result = await instance.get("/rest/auth/1/session"); if (result) { console.log("Sessão ativa"); const issue = await getIssue(id); return issue; } } catch (error) { if (error.response.status === 401) { console.log("Não autorizado"); const loginResult = await loginJira(); if (loginResult) { return jiraClient(id); } else { throw error; } } else { console.log("Erro ao obter a sessão:", error); throw error; } } }; module.exports = jiraClient; 
Enter fullscreen mode Exit fullscreen mode
// jiraUtils.js const jiraClient = require(".././jiraClient"); const JIRA_REMINDER_MESSAGE = "Não esquecer de logar as horas no Jira!"; const makeResponseJira = async (id) => { try { const jiraIssue = await jiraClient(id); return `Issue: ${jiraIssue?.data?.key}\nLabel: ${jiraIssue?.data?.fields?.labels[0]}\nAssignee: ${jiraIssue?.data?.fields?.assignee?.name}\nDescription: ${jiraIssue?.data?.fields?.description}`; } catch (error) { if (error.response.status === 404) { return `Issue ${id} não encontrada!`; } if (error.response.status === 401) { return `Verifique suas credenciais!`; } } }; const processMsgReceived = async (msg) => { let response; if (msg.body.startsWith("DEV-")) { response = await makeResponseJira(msg.body); } else if (msg.body.startsWith("!lembrete")) { response = JIRA_REMINDER_MESSAGE; } else { return null; } return response; }; module.exports = processMsgReceived; 
Enter fullscreen mode Exit fullscreen mode

OBS: DEV refere-se ao padrão de nomenclatura das issues do Jira durante os testes
Exemplo de issue: DEV-100

// index.js  const qrcode = require("qrcode-terminal"); const { Client, MessageMedia, LocalAuth } = require("whatsapp-web.js"); const cron = require("node-cron"); const processMsgReceived = require("./utils/jiraUtils"); const GROUP_ID = process.env.WPP_GROUP_ID; const JIRA_LOGO_URL = "https://visuresolutions.com/wp-content/uploads/2022/07/Logo-Jira.png"; const JIRA_REMINDER_MESSAGE = "Não esquecer de logar as horas no Jira!"; const newBotClient = async () => { const client = new Client({ authStrategy: new LocalAuth() }); return client; }; const botJira = async (client) => { client.initialize(); client.on("qr", (qr) => { qrcode.generate(qr, { small: true }); }); client.on("authenticated", () => { console.log("AUTHENTICATED"); }); client.on("ready", async () => { console.log("Client is ready!"); cron.schedule( "0 17 * * *", async () => { // running a task every day 17 hrs const media = await MessageMedia.fromUrl(JIRA_LOGO_URL); let message = JIRA_REMINDER_MESSAGE; client.sendMessage(GROUP_ID, media, { caption: message, }); }, { scheduled: true, timezone: process.env.TIMEZONE || "America/Sao_Paulo", } ); client.on("message", async (message) => { const processedMsg = await processMsgReceived(message); console.log("processedMsg MSG: ", processedMsg); if (processedMsg !== null) { const media = await MessageMedia.fromUrl(JIRA_LOGO_URL); const response = client.sendMessage(message.from, media, { caption: processedMsg, }); return response; } }); }); }; const startBot = async () => { try { const client = await newBotClient(); botJira(client); console.log("Bot started!"); } catch (error) { console.log("ERROR INIT BOT: ", error); } }; startBot(); 
Enter fullscreen mode Exit fullscreen mode

Alguns pontos a serem explicados:

1 - Ao Startar o projeto, será exibido um QR Code no terminal. Você deverá ler o mesmo utilizando a conta do WhatsApp que será o bot.
2 - GROUP_ID refere-se ao grupo do WhatsApp em que o bot será adicionado para responder.
3 - cron.schedule é utilizado para disparar um lembrete todo dia às 17hrs

Link do projeto: https://github.com/mensonones/bot-jira-tutorial

Por hora é isso! Espero que seja útil e qualquer dúvida basta comentar ou entrar em contato comigo. Até a próxima :)

Top comments (0)