Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django send_mail through gmail very slow

When I try send through ./manage.py shell it takes several minutes to send a single email. When I try to send a user verification email after a form submission in a browser the browser times out with a 504, but the email is eventually sent. What could be going on?

settings.py

...
EMAIL_HOST = 'smtp.gmail.com'                                                   
EMAIL_HOST_USER = '[email protected]'                                      
EMAIL_PORT = 587                                                                
EMAIL_USE_TLS = True                                                            
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER                                            
EMAIL_HOST_PASSWORD = os.environ.get('PASSWORD')   
...

views.py

class SignUpView(CreateView):                                                   
    model = User                                                                
    template_name = 'eventMap/register.html'                                    
    form_class = RegistrationForm                                               
    success_url="/"                                                             

    def form_valid(self, form):                                                 
                form.save()                                                     
                username = form.cleaned_data['username']                        
                email = form.cleaned_data['email']                              
                salt = hashlib.sha1(str(random.random())).hexdigest()[:5]          
                activation_key = hashlib.sha1(salt+email).hexdigest()           
                key_expires = datetime.datetime.today() + datetime.timedelta(2) 

                #Get user by username                                           
                user=User.objects.get(username=username)                        

                # Create and save user profile                                  
                new_profile = UserProfile(user=user, activation_key=activation_key,
                        key_expires=key_expires)                                
                new_profile.save()                                              

                # Send email with activation key                                
                email_subject = 'Account confirmation'                          
                email_body = "Hey %s, thanks for signing up. To activate your account, click this link within \
                48hours http://mywebsite.com/accounts/confirm/%s" % (username, activation_key)

                send_mail(email_subject, email_body, '[email protected]',  
                        ['[email protected]'], fail_silently=False)   

                return super(SignUpView, self).form_valid(form) 

I came across this post about something similar but the logs don't mention anything about an unqualified hostname etc /var/log/mail.log

Jul 27 16:26:04 django postfix/qmgr[5975]: CAF7C1226F2: from=<>, size=3063, nrcpt=1 (queue active)
Jul 27 16:26:34 django postfix/smtp[12874]: connect to example.com[2606:2800:220:1:248:1893:25c8:1946]:25: Connection timed out
Jul 27 16:27:04 django postfix/smtp[12874]: connect to example.com[93.184.216.34]:25: Connection timed out
Jul 27 16:27:04 django postfix/smtp[12874]: CAF7C1226F2: to=<[email protected]>, relay=none, delay=368178, delays=368118/0.02/60/0, dsn=4.4.1, status=deferred (connect to example.com[93.184.216.34]:25: Connection timed out)
like image 355
Chuie Avatar asked Jul 27 '15 21:07

Chuie


People also ask

How do I use Django to send an email from Gmail?

send_mail() method is imported from django. The send_mail() method handles the transmission of Emails. There are some important parameters of send_mail(), which we have defined here: subject: Contains the subject part of the Email. message: Contains the Email body.

How do I send multiple emails in Django?

How to send multiple mass emails django. We need to create a Tuple of messages and send them using send mass mail. In this tutorial, we create a project which sends email using Django. We fill the data in the form and send it using Django Email.

How do I send an email using Django?

In most cases, you can send email using django. core. mail. send_mail() .


1 Answers

I had a similar case where the delay and timeout were caused by the system trying to connect to gmail over IPv6.

This thread was useful in uncovering the mystery.

TLDR:

On the host machine try using telnet to connect to gmail.

telnet smtp.gmail.com 587

If it first attempts to connect over IPv6 (and blocks for a few minutes) followed by a successful connection on IPv4, then this is likely your problem.

The solution:

import socket
EMAIL_HOST = socket.gethostbyname('smtp.gmail.com')

This ensures that python will connect to gmail over IPv4 from the beginning.

Better solution:

Figure out why your host can't connect to gmail over IPv6 and fix that issue. Perhaps adjusting firewall rules to reject packets instead of dropping them.

like image 169
C-o-r-E Avatar answered Sep 19 '22 06:09

C-o-r-E