Error sending email in django through gmail - python

I am trying to send a mail using django through gmail.
Following is my settings.py code:
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'me#mycompany.com'
EMAIL_HOST_PASSWORD = 'mypassword'
EMAIL_USE_TLS = True
view.py I am using method send_mail():
send_mail(subject, contact_message, emailfrom, emailto)
When I execute the code & enter details in my contact form & hit submit.
I get the below error:
smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server.
Please suggest!

I don't know Gmail, and I don't know Django, but I hope the following explanations will help you.
A quick analysis shows that your situation is kind of odd. There is a simple method to test what capabilities / extension an SMTP server provides: Get a command line telnet client, connect to the server in question and query its capabilities. The following shows how this is done in Linux, but it's basically the same with Windows:
root#spock:~# telnet smtp.gmail.com 587 <-- Type this on the command line
Trying 74.125.71.109... <-- This is output
Connected to gmail-smtp-msa.l.google.com. <-- This is output
Escape character is '^]'. <-- This is output
220 smtp.gmail.com ESMTP s196sm2489285wmb.6 - gsmtp <-- This is output
EHLO localhost.com <-- **YOU** must type this
250-smtp.gmail.com at your service, [46.83.27.246] <-- The following lines are output
250-SIZE 35882577
250-8BITMIME
250-STARTTLS <-- NOTE THIS LINE
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
The key points here are the second command line parameter to the telnet command which designates which port to use, and the EHLO command you type (make sure you really type EHLO and not HELO which is another command).
As you can see from the example, smtp.gmail.com definitely supports the STARTTLS command / extension. I have tested this in a normal environment; my Linux box is behind a NAT router which is the usual setup for private households and small companies. No port forwarding or other special configuration is in place.
So the first thing I would recommend is that you repeat this simple test at your place. Then,
If you get the same result as me, especially if the output you get also contains the line 250-STARTTLS, there is absolutely no explanation what happens here besides errors in Django itself. Are you using the most recent version? I can't help you here, because I never have used it and I don't know anything about it.
If the line 250-STARTTLS is not in the output you get, something completely weird must go on. As my example shows, STARTTLS is supported at least for clients at my place, and there is no reason why it shouldn't be supported for clients at your place.
Exceptions might be China or similar countries where governments try to prevent the usage of encryption. So I could imagine that Google turns off the STARTTLS extension based on geo-blocking when a client from such a country connects. But I really don't know! People who do are encouraged to leave a comment ...
Perhaps you are using a proxy which disturbs the communication between your client (Django) and the SMTP server.
I you still haven't found the problem, you could do the following:
You could try port 25 instead of port 587. I have verified that smtp.gmail.com supports STARTTLS on port 25 as well. With most email clients, it doesn't matter if you use port 25 or port 587. You should be able to make Django use port 25 by saying EMAIL_PORT = 25 in your configuration file.
You could try to use implicit TLS (most often called SSL) instead of the explicit STARTTLS. The port which is usually used for this is 465. To implement this, say EMAIL_PORT = 465, EMAIL_USE_TLS = False and EMAIL_USE_SSL = True in your configuration file.

Related

python 3.9.0 smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server

I am trying to send emails with gmail using the smtp module for an amazon price tracker. A few days ago, it was working perfectly but today it came up with this error:
File "C:\Users\61409\AppData\Local\Programs\Python\Python39\lib\smtplib.py", line 755, in starttls
raise SMTPNotSupportedError(
smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server.
This is the code that originally worked but gives the error:
import smtplib
def send_email():
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.ehlo()
server.login('xxxxxxxx#gmail.com', '*password*')
subject = f'The price of your product has fallen'
body = f'Check the amazon link - {URL}'
msg = f"Subject: {subject}\n\n{body}"
server.sendmail(
'xxxxxxx#gmail.com',
'xxxxxxx#gmail.com',
msg
)
print('The email has been sent')
server.quit()
I have tried making another gmail account and using SSL (importing ssl too) but the other gmail account comes up with the same problem and when using SSL, it comes up with a SMTP AUTH problem (unable to solve this too). I have allowed less secure apps but the same problem still occurs. I have also tried removing the first server.ehlo() and I have also tried using the server.set_debuglevel(1) but both do not work. I have also tried using with stmplib.SMTP(*Host*, *Port*) as server: and I have tried just using SMTP without using SSl and TLS at all but both answers do not work. Most of the answers removed the smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server. but other problems occured such as smtplib.SMTPServerDisconnected: Connection unexpectedly closed which happened numerous times with other answers. I tried researching on solutions to the connection unexpectedly closing but none of those answers worked too.
These are the answers I have tried:
SMTPException: STARTTLS extension not supported by server
smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server
Python 2: SMTPServerDisconnected: Connection unexpectedly closed
Python3 SMTP 'Connection unexpectedly closed'
https://www.reddit.com/r/Python/comments/5grxy8/python_smtplib_connection_unexpectedly_closed/daumi2m/
How to send an email with Python?
How can I fix this problem?, am I missing something?? Will I need to use another module or library to send emails??? I apologise if this is a repeat question with a viable answer. I also apologise if one of the answers I mentioned as not working does actual work except I screwed up the code.
smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server.
The SMTP connection to the server does not seem to offer the STARTTLS extension, at least as seen from the perspective of the client. This extension is announced inside the response to the initial EHLO command of the client:
$ telnet smtp.gmail.com 587
...
Connected to smtp.gmail.com.
Escape character is '^]'.
220 smtp.gmail.com ESMTP h9sm19557267wre.24 - gsmtp
EHLO mail.example.com
250-smtp.gmail.com at your service, ...
250-SIZE 35882577
250-8BITMIME
250-STARTTLS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
...
Given that smtp.gmail.com definitely supports this extension it is likely that there is some man in the middle somewhere in path of the connection, which rewrites the traffic to something like this:
220 smtp.gmail.com ESMTP h9sm19557267wre.24 - gsmtp
EHLO mail.example.com
250-smtp.gmail.com at your service, ...
250-SIZE 35882577
250-8BITMIME
250-XXXXXXXA <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
...
Here the response of the server is changed to no longer show support for STARTTLS, in the hope that the client continues without encryption and thus the mail can be analyzed be the man in the middle. Such man in the middle are typically corporate firewalls like Cisco ASA but can also be ISP or local antivirus products.
A few days ago, it was working perfectly but today it came up with this error:
Check if there were any changes regarding local security products (antivirus) or its settings or if there are changes to your environment (corporate firewall, different network you use ...).
I had the same problem: smtplib working properly and then returning this same error, without any change in the server (outlook).
It just so happens that I had refactored my code, and the function that sent the email was deeper in the modules.
If I used the old way, it worked!
When I turned off the anti-virus (AVG in my case), all worked just fine!
So, for some reason, the code refactoring made the sending procedure to be caught by anti-virus.

Django: Outlook email smtp timeout in production server

i'm trying to send a SMTP email from Django, using my credentials of Outlook. My code works in localhost, but when I upload my code to production server, it doesn't.
If I use my Gmail credential, it also works in production, but it doesn't with Outlook. So, I think Outlook is configured in a different way, but I dont know.
This is my view code:
def send_my_custom_email():
connection = mail.get_connection(
host = 'smtp-mail.outlook.com',
port = 25,
username = 'myemail#outlook.com',
password = 'mypassword' ,
)
connection.open()
email2send = mail.EmailMessage('hello', 'hello', 'myemail#outlook.com', to=['receiveremail'], connection=connection)
email2send.send()
connection.close()
I know that my configuration setting are right because it can send emails from localhost. These are my settings.py:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
I already try to check the Outlook settings, but I couldn't find anything about SMTP use.
My exact questions are:
Outlook need aditional settings in production?
The problem is in my code or in Outlook settings?
Why it works in localhost but it does not in production server?
Outlook.com only allows encrypted SMTP TLS connections on port 587. It does not even listen on port 25, that is why you get a timeout.

How to send authenticated email using Python?

I have a python function to send an email notification. I have included the login call to authenticate with my local SMTP server, however emails are being returned stating '553-mail rejected because your IP is in the PBL'. Further reading on https://www.spamhaus.org/pbl reveals that apparently I am not being prevented from sending email, I am simply required to authenticate first.
I have tried base64 encoding to avoid sending the password as plain text without success.
I have also looked at the Pysasl library, but I am a little unsure how I might use this for authenticating with my SMTP server.
Would anyone have any guidance as to the correct use of either base64 encoding, the pysasl library or if a better method exists for satisfying the correct authentication requirements?
My code is below.
def emailNotify(self,userid):
SMTPserver = 'localhost'
sender = '***' # blanked
username = '***' # blanked
receiver = '***' # blanked
pwd = '***' # blanked
text_subtype = 'plain'
msg = 'requested data was posted to dashboard for '+userid
subject = 'confirmation of POST\'d data for '+userid
try:
msg = MIMEText(msg, text_subtype)
msg['Subject'] = subject
msg['From'] = sender
conn = smtplib.SMTP(SMTPserver)
conn.login(username, pwd)
try:
conn.sendmail(sender, receiver, msg.as_string())
finally:
conn.quit()
except:
print('message sending failed')
Thanks in advance.
You have 2 ways of building a program for sending mail:
build a bullet proof solution:
analyze what server announces as its capabilities
choose the one that better meets your requirement
use that authentication method
actually send the mail
simply that means that you have to implement code for reading and decoding what the server returns (which can be weird) and also all various authentication methods, not speaking of TLS
use a custom connection method adapted to that server
read the documentation of the server to know what it declares to support
test it manually first through a mere telnet connection then in an interactive Python session (idle is enough here, but you can choose your prefered Python shell)
carefully program the way you have just tested - but leave relevant error messages in cases the server capabilities change...
IMHO much simpler...

Errno 10060 A connection attempt failed

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST='smtp.gmail.com'
EMAIL_PORT=465
EMAIL_HOST_USER = 'yogi'
EMAIL_HOST_PASSWORD = '###'
DEFAULT_EMAIL_FROM = 'yogi#gmail.com'
above are the settings for django core mail module. I am using its send_mail to send mails to users. When i try to build the program with the gmail smtp it throws the following error
'Errno 10060 A connection attempt failed because the connected party
did not properly respond after a period of time, or established
connection failed because connected host has failed to respond'.
I am doing this in my company and so it has proxy settings. I have given the proxy credentials in .condarc settings file. But still the connection timeout error. Do i need to set the proxy settings somewhere else or let me know where i am going wrong. ?
As far as I know django does not detect any SMTP proxy settings from anaconda configuration files. You can overcome this by manually building a connection.
Notice that send_mail , has an option parameter for a connection. You get one by calling mail.get_connection now you need to wrap it around sockspi
see Python smtplib proxy support and Python send email behind a proxy server for further details.

Connect to SMTP (SSL or TLS) using Python

I am attempting to connect to the Gmail SMTP mail server and perform tasks as outlined by the skeleton code given to me. Only the use of sockets is allowed (so not the smtplib). I need to: send HELO command, MAIL FROM, RCPT TO, and DATA.
There are many cases of similar problems posted, but they haven't received the proper answer. For example:
Implementing Transport Layer Security in Python - Simple Mail Client
The program is required to connect to smtp.gmail.com over port 587. I've taken two different approaches:
Using STARTTLS:
mailserver = 'smtp.gmail.com'
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((mailserver, 587))
recv = clientSocket.recv(1024)
print recv
if recv[:3] != '220':
print '220 reply not received from server.'
#Send HELO command and print server response
heloCommand = 'HELO Alice\r\n'
clientSocket.send(heloCommand)
recv1 = clientSocket.recv(1024)
print recv1
if recv1[:3] != '250':
print '250 reply not received from server.'
#Send MAIL FROM command and print server response.
command = "STARTTLS\r\n"
clientSocket.send(command)
recvdiscard = clientSocket.recv(1024)
print recvdiscard
clientSocket.send("MAIL From: email\r\n")
recv2 = clientSocket.recv(1024)
print recv2
if recv2[:3] != '250':
print '250 reply not received from server.'
Using SSL:
clientSocketSSL = ssl.wrap_socket(clientSocket)
Then clientSocketSSL replaces all instances of clientSocket. The STARTTLS lines are also removed and import ssl is added to the top.
When using the first method, the MAIL FROM: command isn't returning anything. I'm getting the following output:
250 mx.google.com at your service
220 2.0.0 Ready to start TLS
250 reply not received from server.
When using SSL, I'm getting the same as the linked post:
ssl.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
Am I missing something here? I guess my best option is to use TLS but I have no idea how to go about that... is there something wrong with my MAIL FROM command?
When using SSL, you need to connect to port 465 instead of port 587. If you use STARTTLS, you still need to use ssl.wrap_socket, you just do it later - specifically, after receiving the 220 response to the STARTTLS command. After doing STARTTLS, you're supposed to do HELO again, since the server is supposed to forget anything that happened before the STARTTLS.
In either case, the servers at smtp.google.com ports 465 and 587 still won't return a 250 response to the MAIL command, since they require that you are authenticated before you send mail. You'll get a 530 response instead. You'll need to use the AUTH command with your gmail.com credentials to authenticate before you can use MAIL successfully on those servers.
If you don't want to authenticate, and depending on the details of what you need to do, you could try using port 25 of the server found in gmail.com's MX record. At the moment, the server is gmail-smtp-in.l.google.com and supports STARTTLS.
After STARTTLS, call
clientSocket = ssl.wrap_socket(clientSocket)

Categories