So I'm trying to send an email in Iron Python 2.7, and nothing has worked for me. So I combined a bunch of different bits of code I got to try and workaround my issue. Basically, I need to send a zip file without using localhost because I'm assuming the client computer won't have localhost.
Here is my code:
# Send an email
def sendEmail():
# Set standard variables
send_to = ["*******#live.com"]
send_from = "********#outlook.com"
subject = "New Game Info"
text = "Some new info for you. This is an automated message."
assert isinstance(send_to, list)
msg = MIMEMultipart(
From=send_from,
To=COMMASPACE.join(send_to),
Date=formatdate(localtime=True),
Subject=subject
)
print "Created MIME..."
msg.attach(MIMEText(text))
print "Attached message..."
with open("TempLog.zip", "rb") as fil:
msg.attach(MIMEApplication(
fil.read(),
Content_Disposition='attachment; filename="%s"' % "TempLog.zip"
))
print "Attached file..."
server = smtplib.SMTP()
server.connect("smtp-mail.outlook.com", 587)
server.starttls()
server.login("*********#outlook.com", "*****")
server.sendmail("********#outlook.com", send_to, msg.as_string())
server.close()
So as you can see, I have put print statements everywhere to locate the issue. It gets up to "Attached file...," but no further.
I appreciate any help with this issue.
I would suggest using a try/catch block to figure out what the problem really is.
With your current code:
try:
server = smtplib.SMTP()
server.connect("smtp-mail.outlook.com", 587)
server.starttls()
server.login("*********#outlook.com", "*****")
server.sendmail("********#outlook.com", send_to, msg.as_string())
server.close()
except SMTPException, err:
print "ERROR: Unable to send mail - %s" %(err)
except Exception, err:
print "Some other error - %s" %(err)
And for an example that I would suggest putting your host options in the SMTP initialization instead of doing so in connect(). You can modify this example to utilize starttls() as you need.
try:
smtp = smtplib.SMTP(host, port)
smtp.sendmail(sender, receivers, message)
print "Successfully sent email to '%s'" %(receivers)
except SMTPException, err:
print "ERROR: Unable to send mail - %s" %(err)
except Exception, err:
print "Some other error - %s" %(err)
I'm the maintainer of yagmail, a package that tries to make it really easy to send emails.
Maybe you can try this:
import yagmail
yag = yagmail.SMTP(send_from, password, host = 'smtp-mail.outlook.com')
yag.send(send_to, subject = subject, contents = [text, "TempLog.zip"])
This should automatically have "text" as body, and when you give it the location of TempLog.zip, it will automatically detect it is a zip file and attach it.
You might have to install it:
pip install yagmail # Python 2
pip3 install yagmail # Python 3
If something does not work (or when it does), please let me know! I will certainly try to help more.
Related
I'm getting a "aborted (disconnected)" when sending multiple emails with smtplib (python 3.6) and I can't find much information online. I'm pretty sure the error is coming from the server and not my code but I'd like to know how to fix this or at least get a clue of what to google to get more information because I am clueless as to how I am going to fix this.
This is the function I'm using the send one e-mail: ( I am calling this function five times and I'm getting the error ).
import smtplib
def enviar_um_mail(to, subject, body):
#source: https://stackabuse.com/how-to-send-emails-with-gmail-using-python/
user = '<mail here>'
password = '<passwrd here>'
sent_from = user
to = 'somemail#somedomain.org'
email_text = 'text of e-mail here'
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(user, password)
server.sendmail(sent_from, to, email_text)
server.close()
print ('Email sent!')
except Exception as e:
print ('Something went wrong...')
print(e)
When calling this function five times the python shell shows:
Email sent!
Email sent!
Email sent!
Email sent!
Email sent!aborted (disconnected)
I'm using python smtplib to send emails. They arrive to the destination, but the "To" field is missing.
In Gmail the "To" field is empty, but in thunderbird says "undisclosed-recipients". I have made some google search, but I didn't find anything.
I don't see any error on the code that explains this, but I was following some code snippets from another question of Stack Overflow, so may be I'm missing something.
This is the code for the mail sender:
def connect_and_send(send_from, send_to, carbon_copy, msg):
confp = ConfigParser()
confp.read("config/mail.ini")
server = str(confp.get('mail', 'host'))
port = str(confp.get('mail', 'port'))
user = str(confp.get('mail', 'username'))
password= str(confp.get('mail', 'password'))
smtp = smtplib.SMTP_SSL()
smtp.connect(server, port)
smtp.login(
user,
password
)
send_to.append(carbon_copy)
smtp.sendmail(send_from, send_to, msg.as_string())
def send_mail(send_from, send_to, carbon_copy, subject, text, signature, files=None):
assert isinstance(send_to, list)
if ARGS.debug:
print "MAIL to:", send_to
print "MAIL from:", send_from
print "MAIL subject", subject
print "with {0} files attached".format(len(files))
msg = MIMEMultipart('alternative')
msg["Subject"] = subject
msg["From"] = send_from
msg["Date"] = formatdate(localtime=True)
msg["To"] = COMMASPACE.join(send_to)
msg.attach(MIMEText(text+"\n"+signature))
for f in files or []:
part = MIMEBase('image', "png")
part.set_payload(f[1].read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="{0}.png"'.format(f[0]))
msg.attach(part)
if ARGS.debug and not ARGS.force_send:
print msg.as_string()
else:
connect_and_send(send_from, send_to, carbon_copy, msg.as_string())
You can try yagmail (full disclose: I'm the developer).
The full code would be:
import yagmail
yag = yagmail.SMTP(send_from, host = host, port = port)
if files is None:
files = []
yag.send(send_to, subject, contents = [text, signature] + files, bcc = carbon_copy)
Note that files will be smartly attached already! (given they are local path to filenames)
I would also suggest to use the keyring of yagmail to prevent from having to store the password locally.
You can get yagmail from pip:
pip install yagmail # python 2
pip3 install yagmail # python 3
Also, since it looks like you're making use of some quite specific mail needs, I'm sure you can benefit from yagmail and it should pay off to read the github documentation. Feel free to raise issues/requests.
I am trying to send an email using SMTP via python.
This is my code:
import smtplib
from email.mime.text import MIMEText
textfile='msg.txt'
you='ashwin#gmail.com'
me='ashwin#gmail.com'
fp = open(textfile, 'rb')
msg = MIMEText(fp.read())
fp.close()
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
print "reached before s"
s = smtplib.SMTP('127.0.0.1',8000)
print "reached after s"
s.sendmail(me, [you], msg.as_string())
s.quit()
when I try and execute this code, "reached before s" is printed and then goes into an infinite loop or so, i.e. "reached after s" is not printed and the program is still running.
This is code for the server:
import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
HandlerClass = SimpleHTTPRequestHandler
ServerClass = BaseHTTPServer.HTTPServer
Protocol = "HTTP/1.0"
if sys.argv[1:]:
port = int(sys.argv[1])
else:
port = 8000
server_address = ('127.0.0.1', port)
HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
httpd.serve_forever()
can someone figure out what is wrong?
I believe yagmail (disclaimer: I'm the maintainer) can be of great help to you.
Its goal is to make it easy to send emails with attachments.
import yagmail
yag = yagmail.SMTP('ashwin#gmail.com', 'yourpassword')
yag.send(to = 'ashwin#gmail.com', subject ='The contents of msg.txt', contents = 'msg.txt')
That's only three lines indeed.
Note that yagmail contents will try to load the string passed. If it cannot, it will send as text, if it can load it, it will attach it.
If you pass a list of strings, it will try to load each string as a file (or, again, just display the text).
Install with pip install yagmail or pip3 install yagmail for Python 3.
More info at github.
Here is a different approach that creates an email sender class with all the error handling taken care of:
import getpass
import smtplib
class EmailBot(object):
# Gets the username and password and sets up the Gmail connection
def __init__(self):
self.username = \
raw_input('Please enter your Gmail address and hit Enter: ')
self.password = \
getpass.getpass('Please enter the password for this email account and hit Enter: ')
self.server = 'smtp.gmail.com'
self.port = 587
print 'Connecting to the server. Please wait a moment...'
try:
self.session = smtplib.SMTP(self.server, self.port)
self.session.ehlo() # Identifying ourself to the server
self.session.starttls() # Puts the SMTP connection in TLS mode. All SMTP commands that follow will be encrypted
self.session.ehlo()
except smtplib.socket.gaierror:
print 'Error connecting. Please try running the program again later.'
sys.exit() # The program will cleanly exit in such an error
try:
self.session.login(self.username, self.password)
del self.password
except smtplib.SMTPAuthenticationError:
print 'Invalid username (%s) and/or password. Please try running the program again later.'\
% self.username
sys.exit() # program will cleanly exit in such an error
def send_message(self, subject, body):
try:
headers = ['From: ' + self.username, 'Subject: ' + subject,
'To: ' + self.username, 'MIME-Version: 1.0',
'Content-Type: text/html']
headers = '\r\n'.join(headers)
self.session.sendmail(self.username, self.username, headers + '''\r\r''' + body)
except smtplib.socket.timeout:
print 'Socket error while sending message. Please try running the program again later.'
sys.exit() # Program cleanly exits
except:
print "Couldn't send message. Please try running the program again later."
sys.exit() # Program cleanly exits
All you need to do is create an EmailBot instance and call the send_message method on it, with the appropriate details as inputs.
I need to send email using SMTP SSL/Port 465 with my bluehost email.I can't find working code in google i try more than 5 codes. So, please any have working code for sending email using SMTP SSL/port 465 ?
Jut to clarify the solution from dave here is how i got mine to work with my SSL server (i'm not using gmail but still same). Mine emails if a specific file is not there (for internal purposes, that is a bad thing)
import smtplib
import os.path
from email.mime.text import MIMEText
if (os.path.isfile("filename")):
print "file exists, all went well"
else:
print "file not exists, emailing"
msg = MIMEText("WARNING, FILE DOES NOT EXISTS, THAT MEANS UPDATES MAY DID NOT HAVE BEEN RUN")
msg['Subject'] = "WARNING WARNING ON FIRE FIRE FIRE!"
#put your host and port here
s = smtplib.SMTP_SSL('host:port')
s.login('email','serverpassword')
s.sendmail('from','to', msg.as_string())
s.quit()
print "done"
For SSL port 465, you need to use SMTP_SSL, rather than just SMTP.
See here for more info.
https://docs.python.org/2/library/smtplib.html
You should never post a question like this. Please let us know what you have done, any tries? Any written code etc.
Anyways I hope this helps
import smtplib
fromaddr = 'uremail#gmail.com'
toaddrs = 'toaddress#ymail.com'
msg = "I was bored!"
# Credentials
password = 'password'
# The actual mail send
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(fromaddr,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
print "done"
I have this simple script that I use to send myself email with a status on a server. It runs, and it gives me no errors, but I do not receive any email, and there is no email in the sent folder at Google. But if I copy and paste every line by line into python in a shell, it does send email and works. There are no errors anywhere. I even get accepted status from Google.
UPDATE: I might have cut to much code out of the sample, and the i variable was accidentally taken out. I have added it again. When I copy paste each line into python cmd line, the script works. When I just run the script, it reports no errors, but does not send the email.
import smtplib
i = 0
try:
text = "This is remarkable"
fromaddr = "<gmail address>"
toaddr = "<email address>"
msg = """\
From: <gmail address>
To: <email address>
Subject: Message number %i
%s
""" % (i, text)
server = smtplib.SMTP("smtp.gmail.com:587")
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.login("<email>", "<password>")
ret = server.sendmail(fromaddr, toaddr, msg)
print "returned : ", ret
print "message sent"
i += 1
except:
print "Now some crazy **** happened"
i is not defined. You would see a NameError if you hadn't wrapped try and a bare except around everything. You should have as little as possible in the try block, at least. Also you can catch the specific error as e. This will print the error also so that you can understand what is the problem.
So the code should be:
import smtplib
i = 1
text = "This is remarkable"
fromaddr = "<gmail address>"
toaddr = "<email address>"
msg = """\
From: <gmail address>
To: <email address>
Subject: Message number %i
%s""" % (i, text)
try:
server = smtplib.SMTP("smtp.gmail.com:587")
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.login("<email>", "<password>")
ret = server.sendmail(fromaddr, toaddr, msg)
except Exception as e:
print 'some error occured'
print e
else:
print "returned : ", ret
print "message sent"
i += 1
Your counter variable i is undefined. A try-except is not a loop. You should be more conservative with what you put inside a try block. Only wrap statements that you think could throw an exception that you need to catch. Certainly your msg string should be built outside the exception handler, since it shouldn't fail and if it does your code is wrong. The calls to the mail server could be wrapped:
server = smtplib.SMTP(host="smtp.gmail.com", port="587")
server.set_debuglevel(1)
try:
server.ehlo()
server.starttls()
server.login("<email>", "<password>")
server.sendmail(fromaddr, toaddr, msg)
print "message sent"
except smtplib.SMTPException as e:
print "Something went wrong: %s" %str(e)
finally:
server.close()
In this way you've reduced the amount of code in the try-except block.
When catching exceptions take care not to catch more than you expect. We can define what type of exceptions we expect and then take appropriate action. Here we simply print it. The finally: block will be executed even if an unknown exception is thrown, one that we don't catch. Typically we close a server connection or a file handler here, since an exception thrown in the try block could leave the server connection open. Creating the server instance outside of the try block is necessary here otherwise we are trying to access a variable that would be out of scope if an exception is thrown.
The smtplib.SMTP methods all throw different variants of smtplib.SMTPException so you should look at the definition of the methods and then only catch the right exception type. They all inherit from smtplib.SMTPException so we can catch that type if we are lazy.
I would suspect the very sensitive SPAM filtering systems which Google has, as you are able to get the alerts when you run the code line by line without any issues.
May be introducing a delay by using time.sleep at some places could give the SPAM filter a feel that the disposition of an email is more human than automated.
Adding to that I would also suggest using an alternate SMTP server by any other provider too and I am sure that you would have already check your spam folder....