Artigo original: https://www.freecodecamp.org/news/send-emails-using-code-4fcea9df63f/

Tradução em português continental (europeu)

Como um exercício de aprendizagem, recentemente eu fui a fundo no Python 3 para ver como é que conseguiria enviar uma certa quantidade de e-mails. Poderão haver métodos mais simples de fazer isto em ambiente de produção. No entanto, este método resultou para mim.

Portanto, este é o cenário: temos os nomes e endereços de e-mail de um grupo de contactos. Vamos querer enviar uma mensagem para cada um desses contactos, enquanto adicionamos "Querido [nome]" ao topo da mensagem.

Por uma questão de simplicidade, guardaremos os detalhes dos contactos em um ficheiro em vez de em uma base de dados. Também poderemos guardar o template da mensagem que desejamos enviar num ficheiro.

O módulo smtplib do Python é basicamente tudo o que precisamos para enviar e-mails simples, sem linha de assunto ou outra informação adicional. Mas, para e-mails reais, precisamos de linhas de assunto e muitas outras informações - talvez até imagens e anexos.

É aqui que o módulo de e-mail do Python nos é útil. Atenção que não é possível enviar mensagens de e-mail usando exclusivamente o módulo de email. Precisamos de uma combinação do email e do smtplib.

É aconselhável ver a documentação oficial completa de ambos os módulos.

Aqui estão os quatro passos básicos para enviar e-mails usando Python:

  1. Configurar o servidor SMTP e conectar-se à sua conta.
  2. Criar o objecto da mensagem MIMEMultipart e adicionar-lhe os cabeçalhos apropriados para From, To e para o campo Subject.
  3. Adicionar o corpo da mensagem.
  4. Enviar a mensagem usando o servidor SMTP.

Agora, vou guiá-lo por todo o processo.

Vamos dizer que temos o ficheiro de contactos mycontacts.txt como o seguinte:

user@computer ~ $ cat mycontacts.txt
john johndoe@example.com
katie katie2016@example.com

Cada linha representa um único contacto. Temos o nome seguido do endereço de e-mail. Estamos a guardar tudo em letras minúsculas. Vamos deixar para a lógica do programa, converter qualquer campo para letras maiúsculas ou para início de frase se necessário. Tudo isto é muito fácil em Python.

De seguida, temos o template da mensagem no ficheiro message.txt.

user@computer ~ $ cat message.txt 

Querido ${PERSON_NAME}, 

Isto é uma mensagem de teste.
Tenha um bom fim-de-semana.

Cumprimentos.

Reparou na palavra “${PERSON_NAME}”? Isto é um template string em Python. Template strings podem ser trocadas facilmente com outras strings; neste exemplo, ${PERSON_NAME} vai ser trocado pelo nome da pessoa,  como veremos de seguida.

Agora, vamos começar com o código em Python. Primeiro, precisamos de ler os contactos do ficheiro mycontacts.txt. Vamos também generalizar isto na sua própria função.

# Function to read the contacts from a given contact file and return a
# list of names and email addresses
def get_contacts(filename):
names = []
emails = []
with open(filename, mode='r', encoding='utf-8') as contacts_file:
for a_contact in contacts_file:
names.append(a_contact.split()[0])
emails.append(a_contact.split()[1])
return names, emails

view rawread_contacts.py, hospedado com ❤ no GitHub

A função get_contacts() recebe um nome de um ficheiro como argumento. Ela abrirá o ficheiro, lerá cada linha (ou seja, cada contacto), dividirá no nome e no e-mail e depois vai acrescentá-los em duas listas separadas. Finalmente, a função retorna as duas listas.

Também precisamos de uma função para ler o ficheiro do template (como o message.txt) e retornar um objecto Template feito com os seus conteúdos.

from string import Template
def read_template(filename):
with open(filename, 'r', encoding='utf-8') as template_file:
template_file_content = template_file.read()
return Template(template_file_content)

view rawread_template.py, hospedado com ❤ no GitHub

Tal como a função anterior, esta também recebe o nome do ficheiro como argumento.

Para enviar o e-mail, vamos ter de usar o SMTP (Simple Mail Transfer Protocol). Como mencionado anteriormente, o Python fornece bibliotecas para gerir esta tarefa.

# import the smtplib module. It should be included in Python by default
import smtplib
# set up the SMTP server
s = smtplib.SMTP(host='your_host_address_here', port=your_port_here)
s.starttls()
s.login(MY_ADDRESS, PASSWORD)

view rawsetup_smtp.py, hospedado com ❤ no GitHub

No código acima, vamos importar a smtplib e então criar a instância SMTP que vai encapsular a ligação SMTP. Ela recebe como parâmetro o endereço do host e o número da porta. Ambos dependem inteiramente nas definições de SMTP do nosso provedor de e-mail particular. No caso do Outlook, por exemplo, a linha 4 de cima seria:

s = smtplib.SMTP(host='smtp-mail.outlook.com', port=587)

Aqui, deverá ser utilizado o endereço do host e o número da porta do nosso fornecedor de e-mail para que tudo funcione.

MY_ADDRESS e PASSWORD acima, são duas variáveis que mantêm o endereço de e-mail completo e a password da conta que estamos a utilizar.

Agora, será um bom momento para extrair a informação de contacto e o template da mensagem usando as funções que definimos acima.

names, emails = get_contacts('mycontacts.txt')  # lê contactos
message_template = read_template('message.txt')

Agora, para cada um dos contactos, vamos enviar um e-mail separado.

# import necessary packages
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# For each contact, send the email:
for name, email in zip(names, emails):
msg = MIMEMultipart() # create a message
# add in the actual person name to the message template
message = message_template.substitute(PERSON_NAME=name.title())
# setup the parameters of the message
msg['From']=MY_ADDRESS
msg['To']=email
msg['Subject']="This is TEST"
# add in the message body
msg.attach(MIMEText(message, 'plain'))
# send the message via the server set up earlier.
s.send_message(msg)
del msg

view rawsend_email.py, hospedado com❤ no GitHub

Para cada name e email (do ficheiro de contactos), vamos criar um objecto MIMEMultipart, configurando os headers do tipo conteúdo From, To, Subject como um dicionário de palavras-chave. Depois, vamos anexar o corpo da mensagem ao objecto MIMEMultipart como simples texto. Será relevante ler a documentação para encontrar mais informação sobre outros tipos de MIME que é possível experimentar.

Também, de notar na linha 10 (do código acima), que estamos a substituir ${PERSON_NAME} com o nome que está a ser extraído do ficheiro de contactos usando o mecanismo de templates em Python.

Neste caso em particular,  estamos a eliminar o objecto MIMEMultipart e a recriá-lo de cada vez que iterarmos através do ciclo for.

Assim que isto está feito, poderemos enviar mensagens usando a útil função do objecto SMTP send_message(), a qual criámos anteriormente.

Aqui está o código completo:

E aqui estamos! Acredito que o código agora é suficientemente claro.

Fique à vontade para copiar o código e alterá-lo como for necessário.

Para além da documentação oficial do Python, também quero mencionar este recurso (em inglês), que me ajudou imenso.

Feliz programação :)

Este post foi originalmente publicado aqui (em inglês). Obrigado pela leitura!