Artigo original: How to Build a Bot and Automate your Everyday Work

Muitos trabalhos tem tarefas repetitivas que você pode automatizar, liberando um pouco do seu precioso tempo. Isso faz com que a automação seja um habilidade essencial a ser adquirida.

Um pequeno grupo de engenheiros de automação e especialistas de domínio qualificados podem automatizar muitas das tarefas entediantes de um time inteiro.

Neste artigo, exploraremos o básico sobre a automação do fluxo de trabalho usando o Python - uma linguagem de programação muito poderosa e fácil de aprender. Usaremos o Python para escrever um script de automação fácil e útil que limpará uma pasta específica e colocará cada arquivo em sua pasta respectiva.

Nosso objetivo não é escrever um código perfeito ou criar uma arquitetura ideal no começo.
Também não criaremos nada "ilegal". Em vez disso, veremos como criar um script que limpará uma pasta específica e todos os seus arquivos automaticamente.

Tabela de conteúdos

  1. Áreas de automação e onde começar
  2. Considerações éticas da automação
  3. Criação de um script de limpeza de diretórios
  4. Um guia completo sobre a criação de bots e a automação do trabalho diário

Áreas da automação e onde começar

Vamos começar definindo que tipos de automação existem.

A arte da automação se aplica na maioria dos setores. Para iniciantes, ela pode ajudar com tarefas como extrair endereços de e-mail de vários documentos para que você possa enviar e-mails em massa. Também pode ser usada para uma tarefa mais complexa, como otimizar os fluxos de trabalho e processos internos dentro de uma grande empresa.

Logicamente, passar de pequenos scripts pessoais para uma grande infraestrutura de automação que substitui as pessoas reais é um processo de aprendizado e aperfeiçoamento. Assim, vamos ver como você pode começar essa jornada.

Automação simples

A automação simples é uma porta de entrada simples e rápida. Ela pode estar relacionada a pequenos processos independentes, como um projeto de limpeza e a reestruturação de arquivos dentro de uma pasta, ou ser parte do fluxo de trabalho, como redimensionar automaticamente arquivos já salvos.

Automações de API pública

As automações de API pública são a forma mais comum de automação, pois podemos acessar a maioria das funcionalidades usando uma requisição HTTP para uma API hoje em dia. Por exemplo, se você quiser automatizar a irrigação do seu jardim inteligente de fabricação própria.

Para fazer isso, você precisar ver o clima do dia de hoje para saber se precisa de água ou se uma chuva está por vir.

Engenharia reversa da API

A automação baseada em engenharia reversa da API é a mais comum nos bots atuais. Na seção "Bot Impostor" do gráfico presente na seção "Considerações Éticas" abaixo, veremos um pouco a respeito.

Fazendo a engenharia reversa de uma API, entendemos o fluxo da aplicação do usuário, como, por exemplo, ao fazer login em um jogo on-line de navegador.

Entendendo o login e o processo de autenticação, podemos duplicar esse comportamento com o nosso próprio script. Então, podemos criar nossa própria interface para trabalhar com o aplicativo, mesmo que os criadores não a forneçam.

Seja qual for a sua intenção, sempre considere o fato de ela ser legal ou não.

Você não quer se meter em problemas, quer?

Considerações éticas

Uma pessoa no GitHub entrou em contato comigo uma vez e me falou o seguinte:

"Curtidas e engajamentos são a moeda digital e você está desvalorizando essa moeda."

Isso ficou na minha mente e me fez questionar se eu fiz a ferramenta exatamente com esse propósito.

O fato dessas interações e engajamentos poderem ser automatizados e "falsificados" mais e mais nos leva a um sistema da mídia social distorcido e quebrado.

Pessoas que produzem um conteúdo bom e de valor são invisíveis para empresas de publicidade e para outras pessoas se elas não usam bots e outros sistemas de engajamento.

Um amigo meu fez uma comparação com os "Noves Círculos do Inferno" de Dante, onde, a cada passo para se tornar um influencer, você fica menos e menos consciente sobre o nível de distorção do sistema atual como um todo.

Eu gostaria de compartilhar essa comparação com você aqui, já que eu penso que é uma representação muita precisa do que eu testemunhei enquanto eu trabalhava ativamente com influencers com o InstaPy.

Nível 1: Limbo - Se você não usa bots de modo algum
Nível 2: Flerte - Quando você curte e segue manualmente quantas pessoas você puder para que elas o sigam de volta/curtam suas postagens
Nível 3: Conspiração - quando você entra em um grupo do Telegram para curtir e comentar em 10 fotos para que as próximas 10 pessoas curtam e comentem a sua foto
Nível 4: Infidelidade - Quando você usa um assistente virtual de baixo custo para curtir e seguir em seu nome
Nível 5: Luxúria - Quando você usa um bot para dar curtidas mas não recebe nenhuma curtida de volta (mas você não paga para isso - por exemplo, uma extensão do Chrome)
Nível 6: Promiscuidade - Quando você usa um bot para dar mais de 50 curtidas e recebe mais de 50 curtidas (mas não paga nada por isso - por exemplo, uma extensão do Chrome)
Nível 7: Avareza ou ganância extrema - Quando você usa um bot para curtir/comentar/seguir entre 200-700 fotos, ignorando a chance de ser banido
Nível 8: Prostituição - Quando você paga por um serviço terceirizado desconhecido para engajar com curtidas/seguidores de modo recíproco e automatizado para você, mas usam a sua conta para curtir/seguir de volta
Nível 9: Fraude / Heresia - Quando você compra seguidores e curtidas e tenta se vender para as marcas como um influencer

O uso de bots nas redes sociais é tão prevalente que se você não usar um bot, ficará preso no Nível 1, o Limbo, sem crescimento de seguidores e com baixo engajamento em relação aos seus pares.

Na teoria econômica, isso é conhecido como dilema do prisioneiro e jogo de soma zero. Se eu não uso um bot e você usa um bot, você vence. Se você não usa um bot e eu uso o bot, eu venço. Se nenhum dos dois usa um bot, todo mundo vence. Como não há nenhum incentivo para que não se use um bot, todo mundo usa um bot. Então, ninguém vence.

Esteja ciente disso e nunca se esqueça das implicações que essa ferramenta tem nas mídias sociais.
spectrum-bot-intent-ebook
Fonte: SignalSciences.com

Queremos evitar lidar com as implicações éticas e continuar trabalhando nesse projeto de automação. É por isso que vamos criar scripts simples de limpeza de diretório, que nos ajudarão a organizar suas pastas bagunçadas.

Criação de um script de limpeza de diretórios

Queremos ver um script bem simples. Ele limpará automaticamente um diretório, movendo seus arquivos para outras pastas de acordo com o tipo de extensão.

Então, o que queremos fazer é isso:

directory_clean_img

Configuração do parser de argumentos

Já que estamos trabalhando com operações funcionais do sistema, como mover arquivos, precisamos importar a biblioteca os. Além disso, queremos que o usuário tenha algum controle sobre qual pasta ele limpará. Usaremos a biblioteca  argparse para isso.

import os
import argparse

Depois de importarmos as duas bibliotecas, vamos primeiro preparar o parser (algo como "analisador", em português) de argumentos. Certifique-se de dar uma descrição e um texto de ajuda para cada argumento adicionado para dar um auxílio de grande valor ao usuário quando ele digitar --help.

Nosso argumento se chamará --path. O traço duplo em frente ao nome diz à biblioteca que esse é um argumento opcional. Por padrão, usaremos o diretório atual. Então, coloque o valor padrão como ".".

parser = argparse.ArgumentParser(
    description="Limpa o diretório e coloca os arquivos em pastas correspondentes."
)

parser.add_argument(
    "--path",
    type=str,
    default=".",
    help="Caminho do diretório a ser limpo",
)

# Analisar os argumentos dados pelo usuário e extração do caminho
args = parser.parse_args()
path = args.path

print(f"Limpando o diretório {path}")

Assim terminamos a sessão do parser de argumentos - é bem simples e legível, certo?

Vamos executar o nosso script e verificar se há erros.

python directory_clean.py --path ./test 

=> Limpando o diretório ./test

Assim que é executado, podemos ver o nome do diretório recebendo um print na máquina. Perfeito.
Agora, vamos usar a biblioteca os para obter os arquivos de um determinado caminho.

Obtenção de uma lista de arquivos da pasta

Usando o método os.listdir(path) e providenciando um caminho válido, pegamos uma lista de todos os arquivos e pastas dentro do diretório.

Depois de listar todos os elementos da pasta, queremos diferenciar arquivos e pastas, já que não queremos limpar as pastas, apenas os arquivos.

Nesse caso, usaremos uma compreensão de lista do Python (em inglês, list comprehension) para interagir por todos os elementos e colocá-los em novas listas, caso atendam aos requisitos de serem arquivos ou pastas.

# Obter todos os arquivos de um diretório específico
dir_content = os.listdir(path)

# Criar um caminho relativo ao caminho do arquivo e ao nome do documento
path_dir_content = [os.path.join(path, doc) for doc in dir_content]

# Filtrar o conteúdo do diretório em uma lista de pastas e documentos
docs = [doc for doc in path_dir_content if os.path.isfile(doc)]
folders = [folder for folder in path_dir_content if os.path.isdir(folder)]

# Contador para acompanhar a quantidade de arquivos movidos 
# e uma lista das pastas já criadas para evitar a criação de várias pastas de mesmo conteúdo
moved = 0
created_folders = []

print(f"Limpando {len(docs)} de {len(dir_content)} elementos.")

Como sempre, precisamos nos certificar de que nossos usuários tenham um feedback. Por isso, adicione um print de declaração, que dá ao usuário uma indicação sobre quantos arquivos serão movidos.

python directory_clean.py --path ./test 

=> Limpando o diretório ./test
=> Limpando 60 de 60 elementos.

Depois de executar novamente o script em Python, podemos ver que a pasta /test que eu criei contém 60 arquivos que serão movidos.

Criação de uma pasta para qualquer extensão de arquivos

O próximo passo – e, também, o mais importante – é criar uma pasta para cada extensão de arquivo. Queremos fazer isso passando por todos os arquivos filtrados. Se eles tiverem alguma extensão que não tenha uma pasta, ela será criada.

A biblioteca os nos ajudará com boas funcionalidades, como dividir os tipos de arquivos e dar a eles um caminho para determinado documento, extraindo o próprio caminho e o nome do documento.

# Percorrer todos os arquivos e movê-los para as pastas correspondentes
for doc in docs:
    # Separar os nomes das extensões de arquivo
    full_doc_path, filetype = os.path.splitext(doc)
    doc_path = os.path.dirname(full_doc_path)
    doc_name = os.path.basename(full_doc_path)

	print(filetype)
    print(full_doc_path)
    print(doc_path)
    print(doc_name)
    
    break

O break da declaração ao fim do código acima garante que o nosso terminal não receba spams se o nosso diretório tiver dezenas de arquivos.

Assim que fizermos isso, executamos o nosso script e teremos uma saída semelhante a esta:

python directory_clean.py --path ./test 

=> ...
=> .pdf
=> ./test/test17
=> ./test
=> test17

Podemos ver que a implementação acima divide os tipos de arquivos e, então, os extrai as partes do caminho completo.

Já que, agora, temos o tipos de arquivos, podemos ver se a pasta com o nome do tipo de arquivo já existe.

Antes de fazermos isso, porém, queremos ter certeza garantir  que alguns arquivos não serão verificados. Se usarmos o diretório atual "." como um caminho, precisamos evitar mover o script do Python. Uma condição simples resolve isso.

Também não moveremos arquivos ocultos. Por isso, vamos incluir todos os arquivos que começam com um ponto. O arquivo .DS_Store  no macOS é um exemplo de arquivo oculto.

	# Ignorar este arquivo quando estiver no diretório
    if doc_name == "directory_clean" or doc_name.startswith('.'):
        continue

    # Obter o nome da subpasta e criar a pasta se ela não existir
    subfolder_path = os.path.join(path, filetype[1:].lower())

    if subfolder_path not in folders:
    	# Criar a pasta

Assim que tivermos resolvido a questão do script em Python e dos arquivos ocultos, poderemos criar as pastas no sistema.

Além de verificarmos se a pasta já está lá quando lermos o conteúdo do diretório, para começar, precisaremos de um modo de rastrear as pastas que já criamos. Essa é a razão pela qual declaramos a lista created_folders = [] . Ela servirá como uma memória para rastrear o nome das pastas.

Para criar uma nova pasta, a biblioteca os providenciará um método chamado os.mkdir(folder_path), que recebe um caminho e cria uma pasta com o nome dado lá.

Esse método pode nos lançar uma exceção, dizendo que aquela pasta já existe. Então, vamos nos certificar de pegar esse erro.

if subfolder_path not in folders and subfolder_path not in created_folders:
        try:
            os.mkdir(subfolder_path)
            created_folders.append(subfolder_path)
            print(f"A pasta {subfolder_path} foi criada.")
        except FileExistsError as err:
            print(f"A pasta já existe em {subfolder_path}... {err}")

Depois de configurar a criação da pasta, vamos executar novamente o script.

python directory_clean.py --path ./test 

=> ...
=> A pasta ./test/pdf foi criada.

Na primeira execução, podemos ver uma lista de registros nos dizendo que a pasta com aquele tipo de extensão de arquivo específico já foi criada.

Movimentação de cada tipo de arquivo para a subpasta certa

O último passo agora é mover os arquivos para as suas pastas principais.

Algo importante de se entender quando se trabalha com operações de os é que, às vezes, algumas delas não podem ser desfeitas. Isso é, por exemplo, o caso da exclusão. Portanto, faz sentido, primeiramente, apenas registrar em log o comportamento que nosso script teria se o executássemos.

É por isso que o método os.rename(...) foi mencionado aqui.

# Obter o novo caminho da pasta e mover o arquivo
    new_doc_path = os.path.join(subfolder_path, doc_name) + filetype
    # os.rename(doc, new_doc_path)
    moved += 1
    
    print(f"Arquivo {doc} movido para {new_doc_path}")

Depois de executar o nosso script e de ver o registro correto, podemos remover a hashtag do comentário na linha do nosso método os.rename() e testar o processo do arquivo uma última vez.

# Obter o novo caminho da pasta e mover o arquivo
    new_doc_path = os.path.join(subfolder_path, doc_name) + filetype
    os.rename(doc, new_doc_path)
    moved += 1

    print(f"Arquivo {doc} movido para {new_doc_path}")

print(f"Renomeados {moved} de {len(docs)} arquivos.")
python directory_clean.py --path ./test 

=> ...
=> Arquivo ./test/test17.pdf movido para ./test/pdf/test17.pdf
=> ...
=> Renomeados 60 de 60 arquivos.

Essa última execução agora moverá todos os arquivos para suas pastas apropriadas e nosso diretório será limpo sem a necessidade de ações manuais.

No próximo passo, podemos usar o script que criamos acima e, por exemplo, agendar uma execução toda segunda-feira para limpar a nossa pasta de Downloads para dar uma estruturação melhor aos nossos arquivos e diretórios.

Exatamente por isso, estamos criando um acompanhamento dentro do nosso curso na Udemy de Criação de bots e automação do fluxo de trabalho.

Um guia completo para criação de bots e automação do seu trabalho diário

Felix e eu criamos um curso em vídeo on-line ensinando como criar seus próprios bots baseado no que aprendemos construindo o InstaPy e o Travian-Bot. Na verdade, ele foi obrigado a removê-lo por ser muito eficiente.

Inscreva-se e comece a aprender.

Se você tem alguma dúvida ou feedback, sinta-se à vontade para entrar em contato pelo Twitter ou na sessão de discussão do curso.