Skip to content

Latest commit

History

26 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Criando um BOT para Telegram

Utilizaremos o módulo node-telegram-bot-api para essa tarefa.

Primeira coisa que precisamos fazer é instalar esse módulo:


npm i -S node-telegram-bot-api

E depois iniciar um arquivo index.js com as seguintes linhas:

constTelegramBot=require(`node-telegram-bot-api`)constTOKEN=`SEU TOKEN`constbot=newTelegramBot(TOKEN,{polling: true})

Mas onde pego esse TOKEN ?

Click nesse manolo -> @BotFather <- para incicar o chat com o Bot gerenciador de Bots. <3

@BotFather

Bom como você deve ter percebido ele é auto-explicativo, entao vamos criar nosso bot.

Após executar o comando /newbot siga suas instruções:

Escolhendo o nome do bot

Depois coloque o TOKEN no nosso código:

constTelegramBot=require(`node-telegram-bot-api`)constTOKEN=`275399831:AAHvjSOiGLxgXmff9wgdECdrZXfMtvnKURw`constbot=newTelegramBot(TOKEN,{polling: true})

ps: ñ precisa se preocupar pois jah revoguei o TOKEN antes de publicar

Depois disso precisamos entender o conceito de como esse BOT funcionara', para isso vamos ver o código mais simples possível que interaja com o BOT.

bot.on('message',(msg)=>console.log('msg',msg))

Enviando essa mensagem para o BOT iremos ter o seguinte retorno no console:

{message_id: 2,from: {id: 77586615,first_name: 'Suissa Refatoreitor',last_name: 'Tabajara',username: 'osuissa'},chat: {id: 77586615,first_name: 'Suissa Refatoreitor',last_name: 'Tabajara',username: 'osuissa',type: 'private'},date: 1492093704,text: 'oi'}}

Logo percebemos que além dos dados basicos:

  • message_id: identificador dessa mensagem
  • date: data no formato timestamp
  • text: texto recebido pelo BOT

Também possuimos 2 outros objetos:

  • from: dados de quem enviou a mensagem
  • chat: dados do chat aberto entre você e o BOT

Facilmente podemos inferir que o chat.id é igual ao from.id, logo o Telegram cria essa ligação entre você e chat que você abriu.

Guarde bem essa informação pois sera muito útil no futuro.

Analisando esse retorno podemos montar o seguinte Schema para esse resultado:

constfrom={id: Number,first_name: String,last_name: String,username: String}constchat={id: Number,first_name: String,last_name: String,username: String,type: String}constSchema={message_id: Number,
from,
chat,date: Number,text: String}

Logo mais voltaremos nesse assunto dos Schemas.

Para dar continuidade ao nosso BOT iremos utilizar eventos específicos para que ele não pegue TUDO que vier, mas sim apenas o que desejemos.

Vejamos quais sao esses eventos:

  • message
  • text
  • audio
  • document
  • photo
  • sticker
  • video
  • voice
  • contact
  • location

Esses serão os eventos que utilizaremos por hora, existem muitos outros como você pode conferir na documentação, o link esta abaixo.

fonte: Node.js Telegram Bot API - Usage - Events

onText

Como você viu acima, possuímos o evento text e como sabemos a função on sempre é utilizada para ouvir um evento, por isso o nome da função ja é onText.

O melhor dela é que possamos passar, como primeiro parametro, uma RegEx para que o BOT execute o callback apenas se o texto enviado pelo usuario "caiba" nessa RegEx.

Utilizaremos o exemplo mais simples que encontramos por aí:

bot.onText(/\/echo(.*)/,(msg,match)=>{console.log(`echo msg: `,msg)console.log(`echo match: `,match)})/**echo msg: { message_id: 7, from:  { id: 77586615, first_name: 'Suissa Refatoreitor', last_name: 'Tabajara', username: 'osuissa' }, chat:  { id: 77586615, first_name: 'Suissa Refatoreitor', last_name: 'Tabajara', username: 'osuissa', type: 'private' }, date: 1492101864, text: '/echo blz mein?', entities: [ { type: 'bot_command', offset: 0, length: 5 } ] }echo match: [ '/echo blz mein?', 'blz mein?', index: 0, input: '/echo blz mein?' ]*/

O retorno da msg jah conhecemos, porém ele possui uma propriedade nova: entities.

Não entrarei nesse escopo agora, entao vamos continuar com o echo.

O que nos interessa nesse retorno é o seguinte objeto: match.

['/echo blz mein?','blz mein?',index: 0,input: '/echo blz mein?']

Como podemos ver ele é um array que contém o resultado do match testando a mensagem que o BOT recebeu com a RegEx que você definiu no onText.

Caso você não conheça essa funcao veja como ela funciona executando o seguinte código no Terminal, executando node antes.

>'/echo blz mein?'.match(/\/echo(.*)/)['/echo blz mein?','blz mein?',index: 0,input: '/echo blz mein?']

Logo conseguimos entender que:

  • na posiçao 0: temos o valor total do texto
  • na posiçao 1: o texto sem a RegEx
  • na posiçao 2: o índice onde foi encontrada a RegEx
  • na posiçao 3: a entrada

Agora vamos fazer o BOT enviar como mensagem o mesmo texto recebido no chat, para isso iremos utilizar a função bot.sendMessage.

Sua assinatura é bem simples:

  • primeiro: o ID do chat onde foi recebido o texto
  • segundo: o texto a ser enviado pelo BOT
bot.sendMessage(id,text)

E essa função irah retornar uma Promise, entao sabemos o que fazer né?

constlogErrorEcho=(msg)=>(err)=>console.log(msg,err)constlogSuccessEcho=(msg,match)=>(data)=>console.log(`Success: `,data)constsendEcho=(msg,match)=>bot.sendMessage(msg.chat.id,match[1]).then(logSuccessEcho(msg,match)).catch(logErrorEcho(`Error: `))bot.onText(/\/echo(.*)/,sendEcho)

Exemplo do echo

Funcionalidades

Funcionalidade - Busca no Google

google it

Para criarmos um comando para fazer uma busca usaremos o axios, primeira vez que usarei ele, sempre usei request/request-promise; com ele iremos fazer uma requisição GET em https://www.google.com.br/search?q=nomadev e parsear seu HTML, com cheerio para retirarmos as informaçoes necessarias.

Sim isso é um crawler!

nomadev no Google

Porém quando requisitamos nomadev ao Google e pegamos o atributo href:

print screen

http.get(URL_BASE+match[1]).then((response)=>{const$=cheerio.load(response.data)$(`.r a`).each((i,elem)=>{if(i===1)returnfalseconsturl=$(elem).attr(`href`)console.log(`url`,url)}).catch(function(error){console.log(error);});

Recebemos o seguinte valor: /url?q=http://nomadev.com.br/&sa=U&ved=0ahUKEwiC96G_xKbTAhVFhZAKHQKoALwQFggVMAA&usg=AFQjCNFAoCxThw2mWS4Xvg-PlvnwG0EWdQ


Depois de analisar outras buscas percebi que a url desejada sempre vem adicionada de /url?q= e &sa=U&ved=0ahUKEwiC96G_xKbTAhVFhZAKHQKoALwQFggVMAA&usg=AFQjCNFAoCxThw2mWS4Xvg-PlvnwG0EWdQ logo preciso executar um replace em cada parte para retirar o indesejado:

http.get(URL_BASE+match[1]).then((response)=>{const$=cheerio.load(response.data)$(`.r a`).each((i,elem)=>{if(i===1)returnfalseconsturl=$(elem).attr(`href`).replace(`/url?q=`,``).replace(/\&sa(.*)/,``)console.log(`url`,url)}).catch(function(error){console.log(error);});

Prontinho! A possuimos a url desejada e podemos enviar ela como mensagem pelo BOT.

constTelegramBot=require(`node-telegram-bot-api`)consthttp=require(`axios`)constcheerio=require(`cheerio`)constTOKENS=require(`./token`)constbot=newTelegramBot(TOKENS.TELEGRAM,{polling: true})constURL_BASE=`https://www.google.com.br/search?q=`constlog=(msg)=>(result)=>console.log(msg,result)constsendGoogle=(msg,match)=>{http.get(`${URL_BASE}${match[1]}`).then((response)=>{const$=cheerio.load(response.data)$(`.r a`).each((i,elem)=>{if(i===1)returnfalseconsturl=$(elem).attr(`href`).replace(`/url?q=`,``).replace(/\&sa(.*)/,``)bot.sendMessage(msg.chat.id,url,{parse_mode: 'Markdown'}).then(log(`${url} delivered!`)).catch(log(`Error: `))});}).catch(function(error){console.log(error);});}bot.onText(/\/google(.*)/,sendGoogle)

Resultado:


http://nomadev.com.br/ delivered! { message_id: 52,
from: { id: 275399831,
first_name: 'meu_exemplo_de_bot',
username: 'meu_exemplo_de_bot' },
chat: { id: 77586615,
first_name: 'Suissa Refatoreitor',
last_name: 'Tabajara',
username: 'osuissa',
type: 'private' },
date: 1492262538,
text: 'http://nomadev.com.br/',
entities: [ { type: 'url', offset: 0, length: 22 } ] }


Refatorando Funcionalidade - Busca no Google


Vamos refatorar para funções puras!


constTelegramBot=require(`node-telegram-bot-api`)consthttp=require(`axios`)constcheerio=require(`cheerio`)constTOKENS=require(`./token`)constbot=newTelegramBot(TOKENS.TELEGRAM,{polling: true})constURL_BASE=`https://www.google.com.br/search?q=`constlog=(msg)=>(result)=>console.log(msg,result)constgetURLFrom=(elem,$)=>$(elem).attr(`href`).replace(`/url?q=`,``).replace(/\&sa(.*)/,``)constsendLinkFromGoogle=($,msg)=>(i,a)=>(!i) ? bot.sendMessage(msg.chat.id,getURLFrom(a,$),{parse_mode: 'Markdown'}).then(log(`${getURLFrom(a,$)} delivered!`)).catch(log(`Error: `))
: falseconstsendLink=(msg)=>(response)=>{const$=cheerio.load(response.data)return$(`.r a`).each(sendLinkFromGoogle($,msg))}constsendGoogle=(msg,match)=>http.get(`${URL_BASE}${match[1]}`).then(sendLink(msg)).catch(log(`Error: `))bot.onText(/\/google(.*)/,sendGoogle)

Bora testar o comando: /google github suissa


github do suissa

DESAFIO - Busca

Caso você queira treinar e contribuir com esse projeto crie um bot para alguma das seguintes buscas:

  • Wikipedia
  • mdn.io
  • DuckDuckGo
  • redtube
  • npm
  • caniuse
  • http.cat

E envie para a pasta src/ o arquivo com o nome: desafioBusca.${seu_github_user}.js



Depois irei ensinar a mordularizar e utilizaremos todas as buscas no mesmo BOT!




TERMINA AQUI POR HORA!!!!

// Logo + falar sobre os parse_mode MD e HTML { parse_mode: 'Markdown' }

Erros

409 - onflict: terminated by other long poll or webhook

Esse erro acontece qnd outro BOT com o mesmo TOKEN esta rodando.

body: {ok: false,error_code: 409,description: 'Conflict: terminated by other long poll or webhook'}

About

Exemplo de como criar um BOT para o melhor app de mensagens do mundo: Telegram.

Topics

Resources

Stars

67 stars

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages