Quem sou eu

Minha foto

Formado em Computação, desenvolvedor web, interessado em tecnologia, metaleiro e um gamer inveterado.

Pesquisar

segunda-feira, 26 de setembro de 2011

Enviando emails no Django através de um pool de contas autenticadas

Recentemente passei por um problema com relação ao envio de emails. O cliente possuia as constas hospedadas em um servidor de emails que limitava o envio diário. Logo, com todos os contatos, logs de erros, logs de controle, etc sendo enviados por uma mesma conta, tinha dias que excedia tal limite.

Para que isso não voltasse a ocorrer, a idéia era ter uma lista de possíveis conexões, para que em caso de falha de autenticação ou limite, utilizasse a outra. Logo veio o problema. No settings.py apenas há espaço para uma autenticação de email.

Então foi que fiz o seguinte:

send_email_by_pool.py ( na raiz do projeto )


import random
import smtplib
from django.conf import settings
from django.core.mail import send_mail, get_connection

def send_mail_by_pool(subject, message, from_email=None, recipient_list=None, fail_silently=False,
auth_user=None, auth_password=None, connection=None):
"""
Seleciona a conexao atual usando um pool de conexoes
"""
global _valid_connections

ret = 0
while _valid_connections and ret == 0:
try:
connection = connection or choose_connection()
from_email = from_email or connection.username

auth_user = auth_user or connection.username
auth_password = auth_password or connection.password

ret = send_mail(subject, message, from_email, recipient_list, fail_silently, auth_user, auth_password, connection)

except (smtplib.SMTPAuthenticationError, smtplib.SMTPSenderRefused):
if not connection:
raise

_valid_connections.remove(connection._pool_name)

return ret

_valid_connections = settings.EMAIL_CONNECTIONS.keys()
def choose_connection():
global _valid_connections
chosen = random.choice(_valid_connections)
conn_settings = settings.EMAIL_CONNECTIONS[chosen]
connection = get_connection(**conn_settings)
connection._pool_name = chosen
return connection

no settings.py:



EMAIL_CONNECTIONS = {
'default': {
'backend': 'django.core.mail.backends.smtp.EmailBackend',
'host': 'smtp.seu_servidor.com.br',
'username': 'seu_email@ seu_servidor.com.br',
'password': 'sua_senha',
'use_tls': False, # para o caso de usar TLS, colocar True
'fail_silently': False,
},
'second': {
'backend': 'django.core.mail.backends.smtp.EmailBackend',
'host': 'smtp.seu_servidor.com.br',
'username': 'seu_email2@ seu_servidor.com.br',
'password': 'sua_senha2',
'use_tls': False, # para o caso de usar TLS, colocar True
'fail_silently': False,
},
}

E na sua view:


from send_email_by_pool import *

subject = "Testando envio"
message = "oi"
from_email = None
recipient_list = ['zejuniortdr@gmail.com',]
fail_silently = False
auth_user = None
auth_password = None 
connection = None

ret = send_mail_by_pool(subject, message, from_email, recipient_list, fail_silently, auth_user, auth_password, connection)



Desta forma, o envio ocorrerá passando por tantas contas quantas forem necessárias até enviar, desde que haja uma conta autorizada e que não tenha excedido o limite.

hasta!