quarta-feira, 10 de setembro de 2025

📧💸 Automação em Python: Assistente Inteligente de E-mails de Cobrança 📧💸

Resumo rápido: um script em Python que lê uma planilha com clientes, gera faturas em PDF, envia e-mails personalizados via Outlook e registra tudo num log. Ideal para reduzir tempo com cobranças e manter histórico para auditoria.


Por que isso ajuda sua empresa? 🤔

  • Evita retrabalho manual (copiar/colar e-mails).

  • Mantém linguagem padronizada e profissional.

  • Gera prova de envio (PDF + log).

  • Ajuda a acelerar recebimentos e reduzir inadimplência.


O que você precisa ter antes de rodar 🛠️

  1. Windows com Microsoft Outlook instalado (automatização usa Outlook).

  2. Python 3.8+ instalado.

  3. Bibliotecas: pandas, openpyxl, pywin32, fpdf.
    Instale com:

    pip install pandas openpyxl pywin32 fpdf
  4. Uma planilha Excel (clientes.xlsx) com estas colunas (exatas):
    Cliente | Email | Valor | Vencimento | Pago
    Exemplo:

    ClienteEmailValorVencimentoPago
    Acme Ltdacliente@acme.com1500.02025-08-10Não
    Bento SAfinanceiro@bento.br320.52025-09-01Sim

Código completo (salve como assistente_cobranca.py) 💻

# assistente_cobranca.py import os # 1 import pandas as pd # 2 import win32com.client as win32 # 3 from datetime import datetime # 4 from fpdf import FPDF # 5 import unicodedata # 6 # Configurações EXCEL_INPUT = "clientes.xlsx" # 7 LOG_FILE = "log_cobrancas.xlsx" # 8 PASTA_FATURAS = "faturas" # 9 os.makedirs(PASTA_FATURAS, exist_ok=True) # 10 def nome_arquivo_seguro(texto): # 11 nf = unicodedata.normalize('NFKD', texto).encode('ASCII', 'ignore').decode() # 12 nf = "".join(c for c in nf if c.isalnum() or c in (' ', '-', '_')).strip() # 13 nf = nf.replace(" ", "_") # 14 return nf.lower() + ".pdf" # 15 def gerar_pdf(cliente, valor, vencimento, pasta=PASTA_FATURAS): # 16 nome = nome_arquivo_seguro(f"fatura_{cliente}") # 17 caminho = os.path.join(pasta, nome) # 18 pdf = FPDF() # 19 pdf.add_page() # 20 pdf.set_font("Arial", size=12) # 21 pdf.cell(0, 10, txt=f"Fatura - {cliente}", ln=1, align="C") # 22 pdf.ln(5) # 23 pdf.cell(0, 10, txt=f"Valor: R$ {valor:,.2f}", ln=1) # 24 pdf.cell(0, 10, txt=f"Vencimento: {vencimento.strftime('%d/%m/%Y')}", ln=1)# 25 pdf.output(caminho) # 26 return caminho # 27 def enviar_emails(): # 28 df = pd.read_excel(EXCEL_INPUT, engine="openpyxl") # 29 outlook = win32.Dispatch("Outlook.Application") # 30 enviados = [] # 31 for idx, row in df.iterrows(): # 32 cliente = str(row.get("Cliente", "")).strip() # 33 email = str(row.get("Email", "")).strip() # 34 valor = float(row.get("Valor", 0)) # 35 venc = pd.to_datetime(row.get("Vencimento")) # 36 pago = str(row.get("Pago", "")).strip().lower() # 37 dias_atraso = (datetime.now() - venc.to_pydatetime()).days # 38 if not email or pago in ("sim", "s", "yes", "true"): # 39 continue # 40 if dias_atraso <= 0: # 41 continue # 42 if dias_atraso < 10: # 43 mensagem = f"Olá {cliente},\n\nSua fatura venceu em {venc:%d/%m/%Y}. Pode regularizar, por favor?\n\nObrigado!" # 44 elif dias_atraso < 30: # 45 mensagem = f"Olá {cliente},\n\nSua fatura de R$ {valor:,.2f} está em aberto há {dias_atraso} dias. Precisamos regularizar.\n\nAtt." # 46 else: # 47 mensagem = f"Atenção {cliente},\n\nSua fatura está vencida há {dias_atraso} dias. Entre em contato para evitar medidas.\n\nAt.te." # 48 fatura = gerar_pdf(cliente, valor, venc) # 49 mail = outlook.CreateItem(0) # 50 mail.To = email # 51 mail.Subject = f"Cobrança - {cliente} - R$ {valor:,.2f}" # 52 mail.Body = mensagem # 53 mail.Attachments.Add(os.path.abspath(fatura)) # 54 try: mail.Send() # 55 enviados.append({"Cliente": cliente, "Email": email, "Valor": valor, "Vencimento": venc, "DiasAtraso": dias_atraso, "Fatura": fatura, "EnviadoEm": datetime.now()}) # 56 print(f"E-mail enviado para {cliente} -> {email}") # 57 except Exception as e: print(f"Falha ao enviar para {cliente}: {e}") # 58 if enviados: # 59 df_log = pd.DataFrame(enviados) # 60 if os.path.exists(LOG_FILE): # 61 df_antigo = pd.read_excel(LOG_FILE, engine="openpyxl") # 62 df_novo = pd.concat([df_antigo, df_log], ignore_index=True) # 63 df_novo.to_excel(LOG_FILE, index=False) # 64 else: df_log.to_excel(LOG_FILE, index=False) # 65 if __name__ == "__main__": # 66 enviar_emails() # 67

Explicação linha por linha (linguagem simples) 🧾🔍

Vou explicar cada linha numerada acima. Se preferir, copie o código e acompanhe.

1 import os

  • Importa o módulo que ajuda a trabalhar com pastas e arquivos (criar pasta, juntar caminhos).

2 import pandas as pd

  • Importa o pandas, usado para ler e escrever planilhas Excel e manipular tabelas de dados.

3 import win32com.client as win32

  • Importa a biblioteca que permite controlar o Outlook no Windows (enviar e-mails automaticamente).

4 from datetime import datetime

  • Traz a classe datetime para calcular datas e horas (ex.: quantos dias de atraso).

5 from fpdf import FPDF

  • Importa o gerador de PDF simples, usado para criar a fatura em PDF.

6 import unicodedata

  • Usado para “limpar” nomes (tirar acentos) e gerar nomes de arquivos seguros.

7 EXCEL_INPUT = "clientes.xlsx"

  • Nome do arquivo Excel que o script vai ler (coloque sua planilha com este nome ou altere aqui).

8 LOG_FILE = "log_cobrancas.xlsx"

  • Nome do arquivo onde vamos guardar o registro dos e-mails enviados.

9 PASTA_FATURAS = "faturas"

  • Pasta onde os PDFs das faturas serão salvos.

10 os.makedirs(PASTA_FATURAS, exist_ok=True)

  • Cria a pasta faturas se ela não existir (não dá erro se já existir).

11 def nome_arquivo_seguro(texto):

  • Início de uma função que transforma texto (nome do cliente) em nome de arquivo seguro.

12 nf = unicodedata.normalize('NFKD', texto).encode('ASCII', 'ignore').decode()

  • Remove acentos e caracteres especiais (transforma 'José' em 'Jose').

13 nf = "".join(c for c in nf if c.isalnum() or c in (' ', '-', '_')).strip()

  • Mantém só letras, números, espaços, traço e underline — elimina outros símbolos.

14 nf = nf.replace(" ", "_")

  • Substitui espaços por underscore para formar nomes de arquivo amigáveis.

15 return nf.lower() + ".pdf"

  • Retorna o nome final em minúsculas com extensão .pdf.

16 def gerar_pdf(cliente, valor, vencimento, pasta=PASTA_FATURAS):

  • Inicia a função que cria o PDF da fatura para um cliente.

17 nome = nome_arquivo_seguro(f"fatura_{cliente}")

  • Cria um nome seguro para o PDF, usando o nome do cliente.

18 caminho = os.path.join(pasta, nome)

  • Monta o caminho completo do arquivo (pasta + nome do arquivo).

19 pdf = FPDF()

  • Cria um objeto PDF vazio para começar a escrever.

20 pdf.add_page()

  • Adiciona a primeira página ao PDF.

21 pdf.set_font("Arial", size=12)

  • Define a fonte (tipo e tamanho) para escrever no PDF.

22 pdf.cell(0, 10, txt=f"Fatura - {cliente}", ln=1, align="C")

  • Escreve o título da fatura (centralizado).

23 pdf.ln(5)

  • Pula uma linha para dar espaço.

24 pdf.cell(0, 10, txt=f"Valor: R$ {valor:,.2f}", ln=1)

  • Escreve o valor formatado com duas casas decimais.

25 pdf.cell(0, 10, txt=f"Vencimento: {vencimento.strftime('%d/%m/%Y')}", ln=1)

  • Escreve a data de vencimento no formato dia/mês/ano.

26 pdf.output(caminho)

  • Salva o arquivo PDF no disco no caminho criado.

27 return caminho

  • Retorna o caminho do PDF gerado (para anexar no e-mail).

28 def enviar_emails():

  • Início da função principal que faz a leitura da planilha, gera PDFs e envia e-mails.

29 df = pd.read_excel(EXCEL_INPUT, engine="openpyxl")

  • Lê a planilha clientes.xlsx para uma tabela (df = data frame).

30 outlook = win32.Dispatch("Outlook.Application")

  • Conecta ao Outlook para poder criar e enviar e-mails.

31 enviados = []

  • Lista vazia para registrar (na memória) os envios bem sucedidos.

32 for idx, row in df.iterrows():

  • Começa a percorrer cada linha da planilha (cada cliente).

33 cliente = str(row.get("Cliente", "")).strip()

  • Pega o nome do cliente da linha; transforma em texto e limpa espaços extras.

34 email = str(row.get("Email", "")).strip()

  • Pega o e-mail do cliente.

35 valor = float(row.get("Valor", 0))

  • Lê o valor (número) da fatura; se não tiver, usa 0.

36 venc = pd.to_datetime(row.get("Vencimento"))

  • Converte a data de vencimento para um objeto de data do pandas.

37 pago = str(row.get("Pago", "")).strip().lower()

  • Verifica na coluna "Pago" se a fatura já foi quitada (texto em minúsculo).

38 dias_atraso = (datetime.now() - venc.to_pydatetime()).days

  • Calcula quantos dias se passaram desde o vencimento (dias de atraso).

39 if not email or pago in ("sim", "s", "yes", "true"):

  • Se não tiver e-mail ou se a fatura estiver marcada como paga, pula este cliente.

40 continue

  • Pula para o próximo cliente na planilha.

41 if dias_atraso <= 0:

  • Se não há atraso (vencimento futuro ou hoje), pula também.

42 continue

  • Pula para o próximo registro.

43 if dias_atraso < 10:

  • Se o atraso for menor que 10 dias — mensagem mais suave.

44 mensagem = f"... (texto educado) ..."

  • Define o texto do e-mail para esse caso (você verá no código real).

45 elif dias_atraso < 30:

  • Se atraso entre 10 e 29 dias — mensagem mais direta.

46 mensagem = f"... (texto intermediário) ..."

  • Texto correspondente ao caso.

47 else:

  • Se 30 dias ou mais — mensagem mais firme.

48 mensagem = f"... (texto firme) ..."

  • Texto final para atraso crítico.

49 fatura = gerar_pdf(cliente, valor, venc)

  • Chama a função para criar o PDF da fatura e guarda o caminho do arquivo.

50 mail = outlook.CreateItem(0)

  • Cria uma nova mensagem de e-mail no Outlook.

51 mail.To = email

  • Define o destinatário.

52 mail.Subject = f"Cobrança - {cliente} - R$ {valor:,.2f}"

  • Define o assunto do e-mail (útil para organização).

53 mail.Body = mensagem

  • Coloca o texto no corpo do e-mail.

54 mail.Attachments.Add(os.path.abspath(fatura))

  • Anexa o PDF que acabamos de gerar.

55 mail.Send()

  • Envia o e-mail (pode abrir aviso de segurança no Outlook em alguns PCs).

56 enviados.append({...})

  • Se deu certo, guardamos dados sobre esse envio (cliente, data, arquivo).

57 print(f"E-mail enviado para {cliente} -> {email}")

  • Imprime no terminal que o e-mail foi enviado (útil para acompanhar execução).

58 except Exception as e: / print(f"Falha...")

  • Se der erro no envio, registra na tela qual foi o problema (não para todo o script).

59 if enviados:

  • Depois de terminar a varredura, se houver envios bem sucedidos, vamos gravar no log.

60 df_log = pd.DataFrame(enviados)

  • Converte a lista de envios em uma tabela (para salvar no Excel).

61 if os.path.exists(LOG_FILE):

  • Se o arquivo de log já existe, vamos anexar ao que já tem.

62 df_antigo = pd.read_excel(LOG_FILE, engine="openpyxl")

  • Lê o log antigo.

63 df_novo = pd.concat([df_antigo, df_log], ignore_index=True)

  • Junta o antigo com os novos registros.

64 df_novo.to_excel(LOG_FILE, index=False)

  • Salva tudo de volta no arquivo de log (completo).

65 else: df_log.to_excel(LOG_FILE, index=False)

  • Se não havia log, cria um novo com os envios.

66 if __name__ == "__main__":

  • Padrão Python: se você rodar este arquivo diretamente, executa o que vem a seguir.

67 enviar_emails()

  • Chama a função principal para começar o processo.


Como usar — passo a passo simples ✅

  1. Coloque assistente_cobranca.py e clientes.xlsx na mesma pasta.

  2. Abra o terminal (Prompt) nessa pasta.

  3. Instale dependências: pip install pandas openpyxl pywin32 fpdf

  4. Rode: python assistente_cobranca.py

  5. Observe no terminal as mensagens de sucesso/erro. Verifique a pasta faturas/ e o arquivo log_cobrancas.xlsx.


Dicas importantes e boas práticas ⚠️

  • Teste primeiro com 1 ou 2 e-mails (coloque seu próprio e-mail) antes de rodar em toda base.

  • Outlook pode mostrar um alerta de segurança; algumas empresas bloqueiam automações — consulte o time de TI.

  • Não use para spam: envie apenas cobranças válidas e respeite regras de comunicação.

  • Mantenha backup da planilha original antes de rodar.


Variações e melhorias que você pode pedir depois 🔧

  • Enviar em lotes (por ex. 50 por vez).

  • Integração com SMTP (para quem não usa Outlook).

  • HTML no corpo do e-mail (assinatura com logo).

  • Interface simples em Tkinter para selecionar arquivo e rodar com 1 botão.

  • Agendamento diário (via Agendador de Tarefas do Windows).


Precisa de suporte contábil? 📞 

Sou contador e ajudo profissionais e empresas com:

  • Abertura e registro de empresas no Simples Nacional;

  • Acompanhamento mensal da contabilidade;

  • Tributação e planejamento tributário.

Nenhum comentário:

Postar um comentário