I've read a bunch of different questions on the same problem and tried multiple things. For reference, here's the code that I'm trying to run:
user = "enbee"
to = "ncbentley4#gmail.com"
subject = "Test"
message = "Test email"
email = user + "#leadshelperpro.com"
smtpserver = "mail.leadshelperpro.com"
header = 'From: %s\n' % email
header += 'To: %s\n' % to
header += 'Subject: %s\n\n' % subject
m = header + message
server = smtplib.SMTP(smtpserver, 465, None, 30)
server.starttls()
server.login(user, 'password redacted')
server.sendmail(email, to, m)
server.quit()
I have verified that the smtpserver and the port are correct.
This script works when I run it from my local computer so it's not a firewall blocking connection. I've also used telnet to connect to the server and it works correctly.
I have tried using server.ehlo() both before and after server.starttls() (as well as before AND after at the same time).
Nothing I've tried up until this point has worked and I've been on the horn with support for the hosting service I'm using. They've changed some configurations of SMTP but nothing has worked. I'm still convinced it's an outbound connection being blocked but I'm not sure how.
Support from my hosting company helped to show that port 465 only works for SSL connections. Changing the port to 587 and keeping the server.starttls() line fixed the problem.
Related
I would like to use Python's SMTP to send automated emails with a custom domain iCloud+ email address. However, I can't get logged into the SMTP servers. I will always either get "Mailbox does not exist" or "Authentication failed".
From the Apple support pages it seems like you need to use SSL over port 587. Additionally, they want you to generate an "app-specific password" for outside applications. This led me to the following code:
import smtplib, ssl
smtp_server = "smtp.mail.me.com"
port = 587 # For SSL
# Create a secure SSL context
context = ssl.create_default_context()
sender_email = "me#example.com" # Enter your address
receiver_email = "you#example.com" # Enter receiver address
password = "some,password" # app specific password from Apple ID settings
message = """\
To: {to}
From: {sender}
Subject: Hello There
This was sent through Python!
""".format(to=receiver_email, sender=sender_email)
with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
server.login(sender_email, password)
# Send email here
server.sendmail(sender_email, receiver_email, message)
However, this was still giving me a connection error. Only when I changed the last part to use TLS instead would it connect and give me an authentication error. This was taken from this question: SMTP_SSL SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)
try:
server = smtplib.SMTP(smtp_server, port)
server.ehlo() # Can be omitted
server.starttls(context=context) # Secure the connection
server.ehlo() # Can be omitted
server.login(sender_email, password)
# Send email here
server.sendmail(sender_email, receiver_email, message)
except Exception as e:
import traceback
print(traceback.format_exc())
finally:
server.quit()
So how can I use my custom domain address with Apple's iCloud+ service with Python's SMTP?
Just before I was going to ask this question, I solved it!
After reading this reddit post, I figured that all custom domain iCloud+ accounts are actually alias of some sort to the main iCloud account. So, I tried logging into my "main" iCloud account. This worked with the above code and sent the email! However, the from was still not my custom domain email address.
This is a somewhat easy fix though, simply modify the "From: <sender>" line in the email body. I'm not sure if this should be done (since it's technicaly faking who you are) but it seems to work. If any email experts know of better ways to do this please comment/answer though! The following code is what I used:
sender_email = "me#icloud.com" # this is who we actually are
sender = "me#example.com" # this is who we appear to be (i.e. custom domain email)
receiver_email = "you#example.com" # this is to who we have sent the email
message = """\
To: {to}
From: {sender}
Subject: Hello There
This was sent through Python!
""".format(to=receiver_email, sender=sender) # this is what changed, we use an alias instead
# ...
server.sendmail(sender_email, receiver_email, message)
I'm trying to send a basic email with an attached document. The example I have works fine with a google address smtp.google.com, but when I try changing it over to smtp.office365.com, I get this error: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:852).
This is a domain email that runs through the office365 SMTP server as a host for the email service. I've checked with the IT team, and they have turned on SMTP authentication on the account.
Obviously, this has been done before, so I have checked my code against this example, but don't see any obvious differences that could be causing it. I've also doubled checked the smtplib documentation, and smtp.office365.com is a valid, recognized SMTP address.
I've written this out as follows (note the confidential credentials which prevent a minimal reproducible example). I've noted where the error occurs, it's almost like smtplib is not recognizing the office365 SMTP address.
def send_email(self, html_message):
# Create a text/plain message
formatted_date = datetime.datetime.now().strftime('%Y%m%d')
msg_root = MIMEMultipart('related')
msg_root['Subject'] = self.client.client_name + 'Test Forecast'
msg_root['From'] = self.config.get_email_from
recipients = self.client.recipient_email
recipients = recipients.split(', ')
body = MIMEText(html_message, 'html')
msg_root.attach(body)
filename = self.client.city + ', ' + self.client.state
# PDF attachment
if self.client.use_pdf:
filepath = self.config.get_email_pdf_file_path
fp = open(filepath, 'rb')
att = email.mime.application.MIMEApplication(fp.read(), _subtype="pdf")
fp.close()
att.add_header('Content-Disposition', 'attachment', filename=filename + '.pdf')
msg_root.attach(att)
# SSL port config
port = 587
# Create a secure SSL context
context = ssl.create_default_context()
# Connect
with smtplib.SMTP_SSL("smtp.office365.com", port, context=context) as server: # Error on this line
server.ehlo()
server.starttls()
server.login(self.config.get_email_from, self.config.get_email_password)
print("Sending email report...")
# Send email
server.sendmail(self.config.get_email_from, recipients, msg_root.as_string())
print("Your email was sent!")
According to
error: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:852)
You should use 465 port because you are using SSL protocol and 587 port is for TLS protocol.
It appears that because Microsoft uses port 587 for SMTP and the external domain we're using doesn't communicate via SSL, I had to change the port over to 587, remove the SSL argument from the method, and remove the context. With it now using SMTP rather than SSL, starttls was also necessary.
The working version looks like this:
port = 587
# Connect
with smtplib.SMTP("smtp.office365.com", port) as server:
server.ehlo()
server.starttls()
server.ehlo()
server.login(self.config.get_email_from, self.config.get_email_password)
print("Sending email report...")
# Send email
server.sendmail(self.config.get_email_from, recipients, msg_root.as_string())
print("Your email was sent!")
I've seen a lot of other posts with the same issue, I tried all of the following:
allow access to less secure app on gmail
Unlock token on google
make an app specific password
allow IMAP on gmail
Nothing is working, i still get the same error message:
SMTPAuthenticationError: (534, b'5.7.9 Please log in with your web browser and then try again. Learn more at\n5.7.9 https://support.google.com/mail/?p=WebLoginRequired s3sm5978501edm.78 - gsmtp')
This is my code on my python jupiter notebook:
sender_email = "xxx#gmail.com"
receiver_email = "yyy#gmail.com"
password = "xxxxxx"
message = MIMEMultipart("alternative")
message["Subject"] = "new properties for rent"
message["From"] = sender_email
message["To"] = receiver_email
# Create the plain-text and HTML version of your message
text = "Hi, new properties satisfy your search on daft: %s" % dictionary
html = "<html><body>%s</body></html>" % emailBody
# Turn these into plain/html MIMEText objects
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
# Add HTML/plain-text parts to MIMEMultipart message
# The email client will try to render the last part first
message.attach(part1)
message.attach(part2)
# Create secure connection with server and send email
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
server.ehlo()
server.login(sender_email, password)
server.sendmail(
sender_email, receiver_email, message.as_string()
)
There's a couple of reasons for this.
But since you exhausted most of them, and after talking in the comments. It's clear that you were sitting behind some sort of VPN or shared internet connection.
Some times, logging in on your account in a browser from this VPN/Shared connection would solve the problem. If not, the fastest and easiest way around this is to swap to a single-user connection (home wifi, dedicated VPS, something where only a handful of users might be sitting).
Common issues are: You're using Tor, a popular VPN provider, a school/company network.
Here's more information on the topic:
https://support.google.com/websearch/answer/86640?hl=en
I'm trying to send emails using yandex but my function doesn't work. It's just waiting forever there is no error either. Here is my function :
def send_emails(title,msg):
server = smtplib.SMTP('smtp.yandex.com.tr:465')
server.ehlo()
server.starttls()
server.login(yandex_mail,yandex_pass)
message = 'Subject: {}\n\n{}'.format(title,msg)
server.sendmail(yandex_mail,send_to_email,message)
server.quit()
print('E-mails successfully sent!')
send_emails('Test Mail', 'Yes its a test mail!')
i think your problem is here:
server = smtplib.SMTP('smtp.yandex.com.tr:465')
you need to use smtplib.SMTP_SSL because connection is security with SSL docs, also smtplib.SMTP_SSL get many params, first is host and second is port and other params, but you need now only this two, you need to give host and port separately, try this
def send_emails(title,msg):
server = smtplib.SMTP_SSL('smtp.yandex.com.tr', 465)
...
I'm trying to send an email in python. Here is my code.
import smtplib
if __name__ == '__main__':
SERVER = "localhost"
FROM = "sender#example.com"
TO = ["wmh1993#gmail.com"] # must be a list
SUBJECT = "Hello!"
TEXT = "This message was sent with Python's smtplib."
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO[0], message)
server.quit()
print "Message sent!"
This runs without error, but no email is sent to wmh1993#gmail.com.
Questions
One thing I don't understand about this code --- what restrictions do I have when setting the FROM field?
Do I somehow have to say that it was from my computer?
What is in place to prevent me from spoofing someone else's email?
Or am I at liberty to do that?
This runs without error, but no email is sent to wmh1993#gmail.com.
This usually means, the message was transferred to your MTA (mailserver) on 'localhost', but this server could not relay it to gmail. it probably tried to send a bounce message to "sender#example.com" and that failed as well. or it sent the message successfully but it landed in gmails spam folder (the message could trigger spam rules since it is missing a date header)
One thing I don't understand about this code --- what restrictions do I have when setting the FROM field?
it must be a syntactically valid email address
Do I somehow have to say that it was from my computer?
no. but that could be the problem why it was not delivered. is your computer on a home/dynamic/dial-up IP? gmail (and many many many other providers) don't accept mail from such IPs. the HELO of your mailserver might be wrong, DNS settings might be incorrect etc. you need to check the server logs. you probably have to configure your local mailserver to relay the message via a smarthost instead of trying to contact the target server directly.
What is in place to prevent me from spoofing someone else's email?
not much, that's why we have so much spam from forged adresses. things like SPF/DKIM can help a bit, but the SMTP protocol itself doesn't offer protection against spoofing.
Or am I at liberty to do that?
technically yes.
Well, since you don't specify exactly what kind of email server you are using and its settings, there are several things that might be wrong here.
First of all, you need to specify the HOST and the PORT of your server and connect to it.
Example:
HOST = "smtp.gmail.com"
PORT = "587"
SERVER = smtplib.SMTP()
SERVER.connect(HOST, PORT)
Then you need to specify an user and his password to this host.
Example:
USER = "myuser#gmail.com"
PASSWD = "123456"
Some servers require the TLS protocol.
Example:
SERVER.starttls()
Then you need to login.
Example:
SERVER.login(USER,PASSWD)
Only then you are able to send the email with your sendmail.
This example works pretty well in most common servers.
If you are using, as it seems, your own server, there aren't much changes you need to apply. But you need to know what kind of requirements this server has.
The "from" field in the email headers specifies the sender's email address. When using smtplib in Python to send an email, the "from" field can be set using the "from_address" argument in the smtplib.SMTP function. Here's an example:
import smtplib
sender_email = "sender#example.com"
recipient_email = "recipient#example.com"
message = "Subject: Example Email\n\nThis is an example email."
with smtplib.SMTP("smtp.example.com", 587) as smtp:
smtp.ehlo()
smtp.starttls()
smtp.login("sender#example.com", "password")
smtp.sendmail(sender_email, recipient_email, message)
Note that many email servers may reject emails that have a "from" address that doesn't match the login credentials.