Tweemol: publicando automaticamente no Twitter
7/25/2020
Saudações! Sempre que possível, gosto de me desafiar a fazer coisas que nunca fiz e continuar aprendendo sempre. Recentemente (levemente inspirado por um vídeo do Filipe Deschamps), resolvi desenvolver um robô (bot) para, todos os dias, escolher uma molécula na Wikipédia, encontrar informações sobre ela, a estrutura química, e publicar um tweet sobre isso. No momento em que escrevo, este projeto está funcionando e mora no Twitter @Tweemol (segue ele lá hehe). Além disso, o código é open-source está disponível no GitHub.
Verapamil, sold under various trade names, is a medication used for the treatment of high blood pressure, angina (chest pain from not enough blood flow to the heart), and supraventricular tachycardia.
— Tweemol (@tweemol) July 18, 2020
Know more: https://t.co/edylwYnoNW pic.twitter.com/zwGlehCyUF
Neste post, vou explicar como desenvolvi isso e como você pode fazer o seu também. De preferência, aventure-se com APIs diferentes das que usei, ou escolha publicar em outra rede. Isso vai evitar que você apenas siga um tutorial e realmente desenvolva o seu projeto. Antes de tudo, quero adiantar que este projeto é relativamente grande. Tem MUITA coisa que precisamos discutir em detalhes aqui. Recomendo ler uma vez e partir para o seu projeto, consultando novamente no momento sentir que não está avançando mais. Então vamos lá.
Escolhendo tecnologias
Se você esta desenvolvendo um projeto real que vai para produção (momento em que o projeto já está funcionando com usuários reais, diferente do estágio de desenvolvimento), o ideal é escolher a tecnologia baseado nas especificidades do negócio, na necessidade de performance, produtividade da equipe, maturidade da tecnologia, suporte, facilidade de contratar profissionais, dentre diversos outros fatores. Ao desenvolver um projeto para estudo, no entanto, a coisa muda um pouco de figura: nesse caso, eu já recomendo escolher tecnologias que não estejam na sua zona de conforto, ou que sejam novas, para garantir que você esteja aprendendo algo.
Quando desenvolvi este projeto, eu ainda não tinha muito costume com o Node.js e queria me aprofundar um pouco. Isso me fez escolher essa tecnologia. Mais tarde, escolhi Python para desenvolver outro projeto (que posso trazer aqui em breve) pelo mesmo motivo.
Planejamento: como as coisas vão funcionar
Antes de abrir o Visual Studio Code (ou o editor que você preferir) e começar a escrever um monte de coisa, é importante parar um pouco e planejar como o seu robô vai se comportar. Pense bem: como desenvolver um robô que nem você sabe como funciona? Isto dito, vamos começar nosso planejamento definindo bem o que nosso robô vai fazer.
O que o robô vai fazer?
Eu decidi que queria um robô capaz de publicar, todos os dias, às 10h da manhã, um tweet contendo algumas informações sobre uma molécula, sua estrutura química e um link para saber mais. Como um robô faria isso? O primeiro passo para responder essa pergunta é com outra pergunta: como eu faria isso?
O que eu faria?
Bom... Como químico da área de fármacos, eu simplesmente abriria a Wikipédia, procuraria alguma dessas listas e escolheria uma molécula aleatoriamente que eu ainda não tivesse escolhido (para facilitar, manteria uma lista das moléculas que já publiquei, pra não ter que percorrer todo meu Twitter). Daí eu faria um resumo daquele texto na Wikipédia para caber num Tweet, adicionaria um link, a própria estrutura presente na Wikipédia e pronto. Se a Wikipédia não tivesse uma estrutura disponível, eu pesquisaria rapidamente o nome do fármaco no Google Images e pegaria a estrutura. Caso o resultado não fosse satisfatório, como bom Químico Computacional, eu procuraria pelo código SMILES para gerar eu mesmo uma estrutura usando o ChemSketch ou outro software. Feito.
O que um robô deveria fazer?
Ótimo. Podemos elencar esse meu algoritmo. Nosso robô precisa:
- Escolher aleatoriamente uma molécula em alguma lista da Wikipédia que ainda não tenha sido escolhida
- Salvar isso em uma nova lista das moléculas que já foram escolhidas
- Extrair o texto da página escolhida
- Resumir o texto de maneira inteligente (!!!!) para que caiba num Tweet
- Obter a estrutura química, se disponível.
- Caso indisponível, procurar pelo SMILES para desenhar a estrutura, (computacionalmente, é mais fácil desenhar uma estrutura química que encontrar um bom resultado no Google, já que não temos o recurso bater-o-olho-e-escolher-a-melhor-opção)
- Caso também indisponível, pesquisar no Google Images.
- Publicar tudo isso no Twitter.
A parte de repetir isso todos os dias será uma tarefa cron no servidor, não é exatamente responsabilidade do nosso robô.
Mas você pode estar se perguntando agora. Pera lá... Resumir texto? Pesquisar no Google? Publicar no Twitter? Como raios um robô vai fazer isso? Bom, vamos lá.
Como o robô vai fazer o que o robô tem que fazer?
Agora sabemos bem o que o robô precisa fazer. Tá na hora de partir para o como. Ainda estamos no planejamento. Sem códigos. Sem fonte monospaced (uma vezinha só, vai). Mas aqui a coisa começa a ficar interessante. Se sentir que está muito rápido, é porque é pra ser assim. Só vamos ver como implementar isso bem mais tarde. Relaxe e prepare-se para uma chuva de links!
-
Escolher moléculas Baseado na lista da Wikipédia que elenquei acima, eu fiz um script para extrair os nomes das moléculas que nosso robô poderá trabalhar. O resultado foi este JSON com mais de 5000 moléculas (não me lembro o número exato agora). Basta escolher uma molécula aleatória nesse JSON e procurá-la na Wikipédia.
-
Obtendo dados da Wikipédia A Wikimedia Foundation (organização que desenvolve a Wikipédia) disponibiliza a API Media Wiki que, dentre outras coisas, permite navegar na Wikipédia de maneira programática (de dentro de um programa). Caso não tivéssemos acesso a uma API, poderíamos usar web scraping (e aqui vai um link da Wikipédia bem no momento que falamos nela kkkkk).
-
Resumir o Texto Hmmm, vou manter o suspense por agora.
-
Obter a estrutura química Vamos dar uma rápida analisada em como a Wikipédia funciona. Acompanhe comigo a página sobre o Paracetamol, droga muito conhecida no Brasil no tratamento sintomático de dores de cabeça e febre.
Observe que, à direita, há uma caixa de informações químicas sobre o fármaco. Muitas páginas da Wikipédia e todos (ao menos quase todos) os fármacos contêm essa caixa. Ela é chamada, de maneira geral, de Infobox. Para o nosso caso, duas Infoboxes são esperadas: a Chembox (compostos químicos em geral) e a Drugbox (específica para fármacos). Essas Infoboxes trazem, normalmente, um parâmetro do tipo image*contendo a imagem principal. Voltaremos a isso mais tarde. -
Obter a estrutura química, Pt. 2: pesquisar no Google Eu sei, pode parecer trivial. Ou impossível. A verdade é que não é nenhum dos dois. O Google nos permite criar um motor de busca personalizado (Custom Search Engine) e fornece gratuitamente uma Custom Search API para fazermos nossas pesquisas. Voltaremos a isso em detalhes mais tarde.
-
Publicar no Twitter Adivinhem. O Twitter também nos fornece uma API através da qual podemos publicar em uma conta. Entretanto, é necessário se aplicar para uma conta de desenvolvedor antes de colocar as mãos na sua Chave de API. Faça isso aqui. Aqui vai a primeira coisa que eu não gostaria de escrever: eu sugiro enfaticamente que você leia atentamente (sério!) todos os termos relacionados à utilização do Twitter como desenvolvedor. Existem diversos limites (muito mais rígidos para robôs que para humanos) que, caso transgredidos, podem (e, acredite, vão) resultar no bloqueio da sua conta. Se usar de maneira responsável, nada de ruim vai acontecer. Enquanto sua aplicação é analisada, comprometa-se a ler a documentação da API do Twitter. Outros desenvolvedores podem discordar, mas, particularmente, achei terrível de ler. Isso não significa que todas as informações não estejam lá. É só que tem informação demais. Procure. Leia. Copiar o meu código não vai te ensinar tanto quanto eu aprendi lendo a API e fazendo funcionar.
-
Resumir o Texto Para resumir o texto, na verdade não vamos implementar nenhum algoritmo de NLP (Processamento de Linguagem Natural). Você pode fazer isso, mas eu vou usar um que já foi implementado (quem sabe em breve eu não implemente o meu rsrsrs). Essa API será fornecida por nós pelo Algorithmia. O Algorithmia não é exatamente gratuito, mas fornece uma quantidade mensal de créditos gratuitos que será mais que o suficiente para nossa aplicação. Acesse o site, clique em Try It For Free e crie sua conta. Dentro do Dashboard, à esquerda, clique em Algorithms e mergulhe na enorme lista de algoritmos disponíveis. Atente-se que cada um consome uma quantidade diferente de créditos todos consomem, no mínimo, um crédito por chamada. Além disso, cada algoritmo pode definir sua cobrança. Você pode testá-los dentro da interface. Este aqui foi o que se saiu melhor (e só consome 1 crédito por requisição). O próprio Algorithmia também fornece outros algoritmos, como o do Google Translate, que você pode implementar se quiser (mais tarde vamos falar sobre isso também). Clique no ícone de perfil e em Manage API Keys e garanta já a sua.
Ok... Temos um planejamento. Vamos à parte mais bonita de todas... Mentira. Mais um passo antes.
Configurando o Ambiente
Bom... Vamos usar Node.js, então precisamos dele instalado. Instale para seu sistema operacional favorito, obviamente o Linux (brincadeira, pode usar o que você quiser). Instale a versão LTS ou, caso goste de viver perigosamente, a versão Current. Se estiver usando Linux, recomendo dar uma olhada nas opções de instalação via package manager. Usaremos diversas dependências, mas, a menos que você esteja copiando um tutorial (o que, obviamente, você não está fazendo), ninguém instala todas as dependências antes de começar a escrever o código.
Isso só pode significar uma coisa...
Coding time
Quem diria! A primeira coisa que precisamos fazer é escolher uma molécula. Como já disse, estou usando este JSON. A estratégia aqui será simples como gerar um número aleatório para escolher uma posição do array e salvar isso nas moléculas já postadas (um JSON análogo). Vamo lá então.
Escolhendo uma molécula
Começaremos criando o ponto de entrada da nossa aplicação (index.js) e também o diretório src/, onde vamos armazenar a maior parte do código.
Num primeiro momento, criaremos um arquivo chooseMolecule.js dentro de src/. O código desse arquivo é o que segue.
const { molecules } = require('../all_molecules.json');
const { posted_array } = require('../posted_molecules.json');
const chooseMolecule = () => {
let moleculeOfTheDay;
do {
const rand = Math.floor(Math.random() * molecules.length);
moleculeOfTheDay = molecules[rand];
}
while (posted_array.indexOf(moleculeOfTheDay) > -1);
return moleculeOfTheDay;
}
const savePostedMolecule = (posted) => {
posted_array.push(posted);
// Salvar o JSON em seguida.
}
// Exportamos tudo
exports.chooseMolecule = chooseMolecule;
exports.saveServer = savePostedMolecule;
Vamos, no index.js, fazer alguma coisa também.
const { chooseMolecule, savePostedMolecule } = require('./src/chooseMolecule');
class Main {
constructor(){}
async start(){
const molecule = chooseMolecule();
await savePostedMolecule(molecule);
}
}
// O que estamos fazendo aqui é criar uma função anônima assíncrona e invocando a mesma, permitindo assim o uso do await que, no Node.js, só é permitido em funções assíncronas (diferente do Deno).
(async () => {
const mainInstance = new Main();
await mainInstance.start();
})();
Obtendo informações da Wikipédia
