Como eu criei um robô do Deschamps para colocar a newsletter no Twitter
Sou inscrito na Newsletter do Deschamps há pouco mais de um ano e sempre achei as notícias incríveis, mas por ser um ávido usuário leitor do Twitter, eu pensei: "E se as notícias diárias viessem parar aqui na rede social do passarinho?"
E decidi que faria em Python, pois seria um desafio mais bacana tendo em vista que sou Dev Frontend.
- O primeiro passo foi criar um e-mail para receber as newsletters. Inicialmente cogitei o Gmail por ser o mais tradicional, mas vi que algumas pessoas tiveram problemas com o excesso de segurança da Google, então optei pela Aol, pois teria menos empecilhos de segurança durante o acesso.
- Criei a conta e me cadastrei na newsletter.
- Descobri uma biblioteca chamada
imap_tools
que permitia que eu acessasse a conta, então fiz algo mais ou menos assim:
from imap_tools import AND, MailBox
# conexão ao e-mail
mailbox = MailBox(getenv('IMAP')).login(getenv('MAIL'), getenv('PASS'), initial_folder='INBOX')
# leitura da caixa de entrada
read_mail(mailbox) if mailbox.uids()
# leitura do html do email
# limpeza do asterisco usado para negrito
# transformação da notícia em itens de uma lista
posts = []
for msg in mailbox.fetch(AND(from_='[email protected]')):
posts = msg.text.replace('*', '').split('\r\n\r\n')
- Observe que usei o
getenv
da bibliotecadotenv
para acessar as variáveis de ambiente e não expor as senhas.
- Na sequência criei uma conta no Twitter e fiz o cadastro na Developer Platform do Twitter.
- Foi preciso criar um "Development App" e um "Project".
- Descobri então que há uma biblioteca que ajuda muito chamada
tweepy
, ela faz praticamente tudo, desde a conexão até os tweets. Resumindo, ficou algo assim:
from tweepy import OAuthHandler, API
# conexão ao Twitter
auth = OAuthHandler(getenv('API_KEY'),
getenv('API_KEY_SECRET'))
auth.set_access_token(getenv('ACCESS_TOKEN'),
getenv('ACCESS_TOKEN_SECRET'))
api = API(auth)
# iteração pelos posts (aqui parametrizado como tweet_list)
# string dividida em lista de strings com máximo de 280 caracteres
for tweet in tweet_list:
each_tweet = wrap(tweet_decoded, 280, break_long_words=False)
post_tweet(api, each_tweet)
def post_tweet(api, each_tweet):
original_tweet = []
for i, chunk in zip(range(len(each_tweet)), each_tweet):
original_tweet.extend([chunk])
print([chunk])
if i == 0:
# básico para tweetar
original_tweet[i] = api.update_status(chunk)
else:
# usado para aninhar ao mesmo tweet
original_tweet[i] = api.update_status(chunk,
in_reply_to_status_id=original_tweet[i - 1].id,
auto_populate_reply_metadata=True)
# espera de 1 segundo para resposta ao mesmo tweet
sleep(1)
# espera de 10 minutos para outro tweet
sleep(600)
- Após pronto, excessivamente testado e corrigido quase 200 vezes, era o momento de automatizar tudo para poder chamá-lo de robô, então criei essa Action:
on:
- cron: "0 14 * * 1-5" # Aciona de segunda a sexta às 14:00 GMT
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: pip install -r requirements.txt
- name: Execute Python script # Run the app.py
env:
IMAP: ${{ secrets.IMAP }}
MAIL: ${{ secrets.MAIL }}
PASS: ${{ secrets.PASS }}
API_KEY: ${{ secrets.API_KEY }}
API_KEY_SECRET: ${{ secrets.API_KEY_SECRET }}
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
ACCESS_TOKEN_SECRET: ${{ secrets.ACCESS_TOKEN_SECRET }}
BEARER_TOKEN: ${{ secrets.BEARER_TOKEN }}
run: python app.py
- Para as variáveis de ambiente (as senhas e chaves) serem lidas pelo Workflow do GitHub foi necessário adicioná-las em
settings/environments
no repositório.
Então, todos os dias da semana o robozinho "acorda", verifica o e-mail, separa o grande bloco de notícias em uma lista com uma notícia cada e vai tweetando-as (essa palavra existe?) a cada 10 minutos.
Procurei ser bem direto aqui e não exibi o código todo para que o post não ficasse tão grande, você pode acessar o código completo em Bot-Deschamps-Newsletter e acessar o perfil dele em @BotDeschamps.
Para a imagem eu apenas copiei o cabelo do Deschamps e colei no emotion de robô. Eu diria que essa imagem expressa o meu amadorismo no campo do design.
Disclaimer: Esse projeto não tem autorização legal do Filipe Deschamps ou equipe. Caso eles me peçam para tirar do ar, eu o farei.