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
Bom como você deve ter percebido ele é auto-explicativo, entao vamos criar nosso bot.
Após executar o comando /newbot siga suas instruções:
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:
messagetextaudiodocumentphotostickervideovoicecontactlocation
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
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)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!
Porém quando requisitamos nomadev ao Google e pegamos o atributo href:
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 } ] }
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
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' }
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'}






