DEV Community

Thales Bruno
Thales Bruno

Posted on • Updated on

Criando um Bot do Telegram com Node.js

Olá, pessoal. Este é meu primeiro artigo aqui no Dev.to e nele vamos aprender a fazer um Bot do Telegram que monitora serviços web através de requisições HTTP.

GitHub logo thalesbruno / telegram-bot

node.js telegram bot

As tecnologias utilizadas aqui foram o Node.js, o Telegraf, que é um framework para construir Bots do Telegram em Node, o Axios, um cliente HTTP em Javascript, e o Docker para dar um toque mais profissional, rs. Tem também o próprio Telegram, naturalmente, onde vamos iniciar a criação do Bot e vê-lo funcionando.

Acho que um bom ponto de partida é entrar no Telegram e criar nosso Bot. Poucas coisas na vida são mais fáceis que isso: basta procurar pela conta BotFather:

BotFather

Ao iniciar uma conversa com o Pai dos Bots, são exibidos os comandos disponíveis para interagir com ele. Digitamos ou clicamos em /newbot, definimos um nome e em seguida um username, que deve obrigatoriamente terminar em 'bot'. Feito isso, nosso Bot estará criado e o BotFather disponibilizará um token de acesso que usaremos daqui pra frente para comandar nosso Bot. O BotFather nos aconselha a manter o token em segurança, já que ele pode ser usado por qualquer um para controlar nosso Bot.

Bot Criado

Vamos agora ao Node.js. Primeiro, criamos um diretório raiz pro projeto e dentro dele o /src onde ficará o código Javascript:

mkdir -p telegram-bot/src
cd telegram-bot
Enter fullscreen mode Exit fullscreen mode

Então, inicializamos o projeto...

npm init -y
Enter fullscreen mode Exit fullscreen mode

...e instalamos o módulo Telegraf

npm install telegraf
Enter fullscreen mode Exit fullscreen mode

Agora as primeiras linhas de código. Criamos um arquivo index.js em ./telegram-bot/src que será o entrypoint do projeto:

const Telegraf = require('telegraf')

const bot = new Telegraf(process.env.BOT_TOKEN)

bot.start((ctx) => ctx.reply("Hello world"))

bot.launch()
Enter fullscreen mode Exit fullscreen mode

Nele, primeiro importamos o módulo Telegraf, então instanciamos um objeto bot, passando um único argumento, process.env.BOT_TOKEN (falaremos dele no próximo parágrafo). Em seguida, criamos nossa primeira "rota", bot.start(), aqui estabelecemos o que o Bot fará ao receber o comando /start (isso acontece ao iniciarmos pela primeira vez uma conversa com ele ou, após isso, digitarmos /start no chat). Nesta versão inicial de nosso código, ele apenas responderá com um "Hello world". Por fim, na última linha temos bot.launch() que inicializa o Bot.

Sobre o process.env.BOT_TOKEN, process.env retorna um objeto contendo as variáveis de ambiente do usuário, e destas estamos pegando a que nos interessa: a BOT_TOKEN. Mas para que isso funcione, precisamos criar a variável de ambiente BOT_TOKEN e atribuir a ela o token que o BotFather nos passou. Neste momento vamos apenas exportar nossa variável no terminal (Linux/MacOS) e, depois, quando subirmos nosso projeto em uma imagem Docker, vamos usar uma solução mais elegante.

Então, no terminal basta executar:

export BOT_TOKEN=<O_TOKEN_QUE_O_BOTFATHER_NOS_PASSOU>
Enter fullscreen mode Exit fullscreen mode

Nosso Bot já está pronto para ser executado! No diretório raiz, rodamos:

node src/index.js
Enter fullscreen mode Exit fullscreen mode

No Telegram, já podemos interagir com nosso Bot:

Bot start

O que precisamos implementar agora é uma rota status que chamará um módulo responsável por fazer a requisição ao serviço, retornando seu status que, por sua vez, gerará uma resposta de nosso Bot.

Vamos instalar o axios, que é um módulo cliente HTTP.

npm install axios
Enter fullscreen mode Exit fullscreen mode

Novo arquivosrc/status.js, bem simplezinho, checando o status da página inicial do Google:

const axios = require('axios')

const status = async () => {
    try {
        return await axios.get('https://www.google.com/', { timeout: 30000 })
    } catch(error) {
        return error
    }
}

module.exports = status
Enter fullscreen mode Exit fullscreen mode

No arquivo principal do projeto, src/index.js, vamos importar o módulo status e criar a rota que o chamará:

const status = require('./status')

...

bot.command('status', async (ctx) => {

    try {
        const response = await status()

        if (response.status == 200) {
            await ctx.reply(`Google service: ✅`)
        } else {
            await ctx.reply(`Google service: ❌`)
        }

    } catch(error) {
        console.error(error)
    }
})
Enter fullscreen mode Exit fullscreen mode

Projeto salvo, rodamos novamente o node src/index.js e vamos lá falar com nosso Bot:

Bot status

Prontinho! Se o serviço Google tiver fora do ar, o que é meio difícil, ele vai responder com o ❌.

Vamos fazer um ajuste no package.json para rodarmos nossa aplicação com npm start:

...

"scripts": {
    "start": "node src/index.js"
  }

...
Enter fullscreen mode Exit fullscreen mode

Agora pra finalizar, vamos subir nosso projeto em Docker (e docker-compose)! Primeiro criamos um Dockerfile pra será o build de nossa imagem e depois um docker-compose.yml que subirá o serviço. São provavelmente os exemplos mais simples de Dockerfile e docker-compose que vocês verão por aí:

Dockerfile

FROM node:12.7.0-alpine

WORKDIR /app
COPY . .
RUN ["npm", "install"]

ENV BOT_TOKEN=<PUT_YOUR_TELEGRAM_TOKEN_BOT_HERE>

ENTRYPOINT ["npm", "start"]
Enter fullscreen mode Exit fullscreen mode

docker-compose.yml

version: '3'
services:
  bot:
    build: .
Enter fullscreen mode Exit fullscreen mode

(Sim, é só isso). Lembrando que os dois arquivos devem estar na raiz do projeto, no Dockerfile colocamos ali em ENV BOT_TOKEN o mesmo token que já vínhamos usando.

Agora vamos colocar nosso Bot no ar novamente, mas dessa vez usando docker-compose:

docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

O -d é pra ele subir em background, liberando o promp do terminal. Pra parar o serviço é docker-compose down. Se fizer alguma modificação no código, é só rodar docker-compose up -d --build que ele subirá construindo uma nova imagem.

Com o Bot no ar em Docker, podemos ir no Telegram novamente e continuar interagindo com nosso Bot!

Docker bot

Essa é uma versão bem simples e genérica, só pra ilustrar a implementação e o funcionamento. Pro artigo não ficar ainda maior, abstraí algumas explicações de códigos e comandos, mas coloquei os links com as referências de cada tecnologia. Qualquer dúvida é só dar um alô!

Discussion (10)

Collapse
alanqueiroz profile image
Alan Queiroz

Thales, o artigo ficou excelente!

Continue escrevendo, o texto está escrito de uma forma simples, clara e bem objetiva.

Collapse
thalesbruno profile image
Thales Bruno Author

Obrigado, Alan!

Collapse
alpha19i profile image
Camilo Italo

Eu não estou conseguindo, não entendi esse export por terminal

Collapse
thalesbruno profile image
Thales Bruno Author

Oi, Camilo. Qual é o seu SO?

Collapse
alpha19i profile image
Camilo Italo

Windows

Thread Thread
thalesbruno profile image
Thales Bruno Author

Ah, sim. Então, nesse comando ali a variável de ambiente é criada e exportada para ficar acessível pela aplicação. Porém, esse é um comando que só vai funcionar no Linux ou MacOS. No seu caso é preciso ver como setar variáveis de ambiente no Windows. Talvez esse artigo ajude, eu sinceramente nunca fiz isso no Windows, não tenho experiência com o SO.

Agora, para FINS DE TESTE, você também pode passar o token diretamente como parâmetro:
const bot = new Telegraf("o token aqui como string").

Thread Thread
alpha19i profile image
Camilo Italo

Já tinha conseguido fazer, mas obrigado

Thread Thread
thalesbruno profile image
Thales Bruno Author

Massa :))

Collapse
rafaelms87 profile image
Rafael Menezes

Primeiro post? Pode continuar ... Didática muito boa... Obrigado por compartilhar conhecimento

Collapse
thalesbruno profile image
Thales Bruno Author

Muito obrigado pelo feedback!! Que bom que gostou :)