Artigo original: Send Emails Using Python
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:
- Configurar o servidor SMTP e conectar-se à sua conta.
- Criar o objecto da mensagem
MIMEMultiparte adicionar-lhe os cabeçalhos apropriados paraFrom,Toe para o campoSubject. - Adicionar o corpo da mensagem.
- 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.comCada 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!