DEV Community

Flávio Filipe
Flávio Filipe

Posted on

Bot para Twitter com Node.JS (Erros e acertos)

Resumo

Este artigo tem o intuito de apresentar o meu processo de desenvolvimento do Surta Não Bot, apresentando tanto a criação quanto os problemas enfrentados.
A biblioteca utilizada para fazer a conexão com twitter foi a Twit

Motivação

Após o lançamento da música de um amigo tive a ideia de criar um bot para o Twitter para divuga-lo. A proposta seria monitorar algumas hashtags específicas e comentar uma chamada para a música. O mesmo comportamento seria aplicado para quando o perfil fosse mencionado nos comentários.

Problema

Após feito, testado e enviado para o servidor de "produção" não levou muito tempo para que a conta fosse suspensa e marcada como span. Isso aconteceu por não ter lido as Regras e políticas do twitter.
Em uma de suas clausulas é alertado que será considerado span "se uma conta estiver tweetando para não seguidores de forma repetida e não solicitada ou se estiver envolvida em padrões de comportamento abusivo".
Abaixo apresento as etapas de criação do bot.

Etapa 1 - Credenciais no Twitter

Twitter Developers

Após criar um novo perfil no twitter (ou utilizar um existente) é necessário criar um novo app no Twitter Developers.
Nesta etapa será preciso informar o intuito do bot e fazer a descrição em inglês. Caso tenha dificuldade com o idioma, recorra ao bom e velho Google Tradutor.

Etapa 2 - Criação do projeto

  • Criei uma pasta chamada surta-nao-bot
  • Foi necessário baixar duas bibliotecas: Twit e dotenv. A primeira será utilizada para conectar a API do Twitter e a segunda para carregar as variáveis de ambiente do arquivo .env. Segue o comando para instalar ambas:
npm i twit
npm i dotenv
Enter fullscreen mode Exit fullscreen mode
  • Neste primeiro momento será necessário criar três arquivos: bot.js, config.js e .env.

.env

Dentro deste arquivo insira os códigos de acesso gerado no Twitter Developers

consumer_key=
consumer_secret=
access_token=
access_token_secret=
Enter fullscreen mode Exit fullscreen mode

config.js

Aqui será carregado as chaves de acesso criadas anteriormente para ser utilizada no projeto

require('dotenv').config();

module.exports = {
    consumer_key:process.env.consumer_key,
    consumer_secret:process.env.consumer_secret,
    access_token:process.env.access_token,
    access_token_secret:process.env.access_token_secret
}
Enter fullscreen mode Exit fullscreen mode

bot.js

Este é o arquivo onde terá o core do nosso bot. Para testar vamos criar um código simples onde será pesquisado no twitter posts com a hastag "javascript"

const config = require('./config');
const twit = require('twit')
const Twit = twit(config);

function searchTweets(params){

    Twit.get('search/tweets', params, (err, data, response) => {
        let tweets = data.statuses;
        if(!err) {
            for(let dat of tweets){
                let retweetId = dat.id_str;
                console.log(retweetId);
            }
        }else{
            console.log(err);
        }
    })
}

console.log('Aqui!')
searchTweets({q: '#javascript'}) 
Enter fullscreen mode Exit fullscreen mode

Execute o arquivo bot.js

node bot.js
Enter fullscreen mode Exit fullscreen mode

Caso tudo ocorra bem até aqui, podemos prosseguir para a próxima etapa.
Caso dê algum erro confira as mensagens que serão exibidas no console. Um dos principais motivos poderá ser as chaves de acesso do Twitter.

Etapa 3 - Respondendo Tweets quando mencionado

Seguindo a documentação do Twit, usaremos o Twit.stream para "escutar" um filtro. Neste caso, será feito um filtro no @ da conta, para quando for mecionado possa responder o tweet. Veja o código a baixo do arquivo bot.js:

const config = require('./config');
const twit = require('twit')
const Twit = twit(config);

//Setting up a user stream
var stream = Twit.stream('statuses/filter', { track: '@surtanao_bb' });

stream.on('tweet', tweetEvent);

function tweetEvent(tweet) {
    // console.log(tweet)
    var reply_to = tweet.in_reply_to_screen_name;
    var text = tweet.text;
    var from = tweet.user.screen_name;
    var nameID = tweet.id_str;
    // params just to see what is going on with the tweets
    var params = { reply_to, text, from, nameID };
    console.log(params);

    let new_tweet = "It's me!!";
    if (from !== 'surtanao_bb') {
        new_tweet = 'Surta não @'+from+'!!! Ouça agora a nova música de Wander Luiz: https://bit.ly/SurtaNao';
    }

    var tweet = {
        status: new_tweet,
        in_reply_to_status_id: nameID
    }

    Twit.post('statuses/update', tweet, (err) => {
        if (err) {
            console.log("Something went wrong!", err);
        } else {
            console.log("It worked!");
        }
    });
}
Enter fullscreen mode Exit fullscreen mode

No código a cima nós declaramos na variável stream com o filtro que queremos fazer, neste caso com o perfil @surtanao_bb

Logo a baixo no trecho stream.on('tweet', tweetEvent); é onde as coisas acontecem. A varíavel stream agora é uma instancia do Twit Stream, por isso possui o método on que recebe o evento que será "escutado" no primeiro parâmetro e a função que será executada no segundo, que recebe cada tweet encontrado.

O método tweetEvent recebe por parâmetero um objeto com os dados do tweet e logo no inicio colhe algumas informações, como o usuário que fez a postagem, o texto e o ID. Um pouco mais a baixo é motado a mensagem de resposta para enfim fazer a postagem utilizando o método post do Twit. Caso ocorra algum erro será exibido no console, se não, será impressa a mensagem "It worked!".

Para que funcione é necessário conceder permissão ao app, dentro do Twitter Developers, para ler e escrever mensagens. Eu apliquei a última opção "Read + Write + Direct Messages". Basta acessar seu app, na tela inicial acessar a opção "App permissions".

Bom, até este momento o bot deverá executar com sucesso!
Após este passo decidi inserir as opções de monitorar hashtags específicas para responder automaticamente, o que não deu muito certo, pois pouco tempo depois a conta foi identificada como span. Confira o commit da atualização caso queira ver o resultado.

Etapa 4 - Deploy na Heroku

Para fazer o deploy será necessário ter uma conta na Heroku e criar um novo app e ter instalado o heroku-cli.

Após configurado, dentro da pasta surta-nao-bot será necessário adicionar um novo remote para o heroku, isso permitirá fazer o deploy utilizando o git.

heroku git:remote -a nome-do-app-heroku
Enter fullscreen mode Exit fullscreen mode

Ao exececutar o comando a cima será criado um novo origin do repositório. Você poderá conferir com o comando a baixo:

git remote -v
Enter fullscreen mode Exit fullscreen mode

Para que o Heroku consiga executar a aplicação será necessário criar o arquivo Procfile na raiz do projeto. A principio criei este arquivo com o código a baixo:

worker: node bot.js
Enter fullscreen mode Exit fullscreen mode

Além disso fiz a alteração no arquivo package.json para executar o comando npm start no arquivo bot.js. Segue o trecho de dentro do arquivo package.json:

...
"scripts": {
    "start": "node bot.js"
  },
...
Enter fullscreen mode Exit fullscreen mode

E fiz o deploy utilizando o git

git push heroku master
Enter fullscreen mode Exit fullscreen mode

Antes de enviar para o servidor da Heroku já havia enviado para o github, por isso foi necessário criar o arquivo .gitignore para que não fosse enviado o arquivo .env com as credenciais de acesso. Por isso, ao fazer o push na heroku será necessário criar as variáveis de ambiente dentro da própria plataforma. Segue a baixo o código do .gitignore.

.env
node_modules
.vscode
package-lock.json
Enter fullscreen mode Exit fullscreen mode

Variáveis de ambiente na Heroku

  • Acesse o app e abra as configurações no menu settings
  • Dentro da sessão Config Vars crie as variáveis que estão no arquivo .env do projeto, sendo a key o nome da variável e o value as chave de acesso.

Problema 2

Até aí tudo bem, o código executou na heroku e o bot já estava funcionado. Porém ao acompanhar o arquivo de logs da Heroku com o comando heroku logs -a percebi que após 60seg o bot era finalizado. Pensei que fosse a opção gratuita da plataforma até encontrar a solução.
Em vários tutoriais os passos executados a cima pareciam funcionar, porém para que este tivesse sucesso eu precisei adicionar uma nova linha ao Procfile informando a web. Aparentemente todo app da heroku precisa ter algo do tipo, foi o que funcionou para mim. Segue o código do arquivo Procfile final:

web: echo "whatever"
worker: node bot.js
Enter fullscreen mode Exit fullscreen mode

Pronto! Agora sim o bot estará funcionando na heroku sem parar. Para fazer o deploy faça o push:

git push heroku master
Enter fullscreen mode Exit fullscreen mode

Testando

Para fazer o teste utilize uma outra conta e faça uma postagem mencionando o perfil do seu bot. Acompanhe os logs do servidor com heroku logs --tail.

Melhorias

Algumas melhorias foram feitas, como criar mensagens aleatórias para que seja exibidas nas respostas e a remoção da pesquisa pelas tags.

Coisas como likes e retweets poderão ser exploradas dentro da documentação do Twit

Para acompanhar as atualizações do bot confira o repositório no Github.

Top comments (0)