Python Email script trouble - python

I have a script that will be running nightly. I want it to send me an email when it fails to complete. I wrote a short test script to learn how to send an email with Python. In my IDE it runs without error messages but no email. I'm running from one of our servers (not the email server) which doesn't have any email restrictions.
I tried it in the Python shell so I can read any messages:
I tried sending to my gmail account and it get this error:
SMTPRecipientsRefused: {'blahblahblah#gmail.com': (550, '5.7.1 Unable to relay')}
Any ideas??
More info:
I modified the code found here to work with our email.
def send_email(user, recipient, subject, body):
import smtplib
FROM = user
TO = recipient if type(recipient) is list else [recipient]
SUBJECT = subject
TEXT = body
# Prepare actual message
message = """\From: %s\nTo: %s\nSubject: %s\n\n%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
try:
server = smtplib.SMTP("workemailserver.com")
server.sendmail(FROM, TO, message)
server.close()
print 'successfully sent the mail'
except:
print "failed to send mail"
With this I can send an email to my coworkers, but not myself. No biggie because I can use a coworkers email as the sender. Our "email server" relays the messages to office365, so that's why I cant send to my gmail.
My problem is basically solved. But I was never able to get the "simpler" code on top to work when I had tried sending to coworkers?

SMTPRecipientsRefused: (550, '5.7.1 Unable to relay')
This means the server you used can not relay the message to the target recipient. This usually happens when your email server has configuration issues.

Related

Send email at specific time with millisecond precision

I would like to send email at given time preferably using gmail. The rationale behind this is that the school I am applying is ordering candidates based on when they receive the participation email after given time.
I could use gmail schedule send feature but there is X delay between sending email from gmail server to school email and it potentially should be achieveable to cut it down slightly so I thought about python script to do it. I think I can get around sending it at a given time but struggle to actually send the message.
There are threads in stackoverflow suggesting python solution e.g.: How do I schedule an email to send at a certain time using cron and smtp, in python? but unfortunately it looks like gmail disabled the option to send mails from non-authorized apps.
Other threads suggest that enabling less secure apps is needed. Unfortunately, this setting has been closed by Google. What could be the way around it?
My sample code:
`
def send_mail():
try:
server_ssl = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server_ssl.ehlo() # optional
print('Server initialized')
sent_from = gmail_user
to = ['xxxxxxxx#gmail.com']
subject = 'my subject'
body = 'my body'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
server_ssl.sendmail(sent_from, to, email_text)
server_ssl.close()
except Exception as inst:
print('Something went wrong')
print(type(inst)) # the exception instance
print(inst.args) # arguments stored in .args
print(inst)
`
is returning an error:
<class 'smtplib.SMTPSenderRefused'> (530, b'5.7.0 Authentication Required. Learn more at\n5.7.0 https://support.google.com/mail/?p=WantAuthError
You need to supply the login to the account, as well as an apps password. You cant just send an email without being authenticated to the mail server.
with smtplib.SMTP_SSL('smtp.gmail.com', 465, context=context) as server:
print( 'waiting to login...')
server.login(sender_email, password)
print( 'waiting to send...')
server.sendmail(sender_email, receiver_email, text)

Using domain email with Yagmail

I'm working in a company that uses Gmail to send and receive emails from a domain email. To make it clearer, let's say it's firstname#company.com.
Right now my goal is to make a simple script that will send the emails using a list from csv file. The code works fine when I use my personal Gmail email, but the problem starts when I change it to my business account - it seems that the script is ignoring the initialization step because it's not #gmail.com.
Not sure if it's needed, but right now I will be happy to at least run the "yagmail 101" code like the one below. Just for reference, I tried the smtplib as well with same result. The two-factor authentication is on, a 16-char password for Windows mail application was created.
#importing the Yagmail library
import yagmail
try:
#initializing the server connection
yag = yagmail.SMTP(user='firstname#company.com', password='mypassword')
#sending the email
yag.send(to='recipient_username#gmail.com', subject='Testing Yagmail', contents='Hurray, it worked!')
print("Email sent successfully")
except:
print("Error, email was not sent")
#importing the Yagmail library
import yagmail
# connect to smtp server.
yag_smtp_connection = yagmail.SMTP( user="user#company.com", password="mypassword",
host='yourSMTPserver')
# email subject
subject = 'Hello'
contents = ['Hello this email send via YAGMAIL']
# send the email
yag_smtp_connection.send('to#gmail.com', subject, contents)
print("Email send!")

Can't send multiple emails because I get aborted (disconnected)

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)

No email sending using smtplib - python

import smtplib
sender = 'den.callanan#gmail.com'
receiver = ['callanden#gmail.com']
message = """From: From Person <den.callanan#gmail.com>
To: To Person <callanden#gmail.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
try:
print("trying host and port...")
smtpObj = smtplib.SMTP('smtp.gmail.com', 465)
print("sending mail...")
smtpObj.sendmail(sender, receiver, message)
print("Succesfully sent email")
except SMTPException:
print("Error: unable to send email")
I've created two new email accounts (above), both on the same server (gmail) to test this.
It reaches the point in which it prints "trying host and port..." and does not go any further. So the problem should be with the address and port number I entered. But according to gmail's outgoing mail server details i've inputted them correctly. Any ideas what's wrong?
If I remove the port number or try a different port number such as 587 i'm provided with an error.
Sending email via Gmail's SMTP servers requires TLS and authentication. To authenticate, you will need to make an application-specific password for your account.
This script worked for me (though I used my own GMail email address and my own application-specific password). In the code below, replace APPLICATION_SPECIFIC_PASSWORD with the password you generated.
import smtplib
sender = 'den.callanan#gmail.com'
receiver = ['callanden#gmail.com']
message = """From: From Person <den.callanan#gmail.com>
To: To Person <callanden#gmail.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
try:
print("trying host and port...")
smtpObj = smtplib.SMTP_SSL('smtp.gmail.com', 465)
smtpObj.login("den.callanan#gmail.com", "APPLICATION_SPECIFIC_PASSWORD")
print("sending mail...")
smtpObj.sendmail(sender, receiver, message)
print("Succesfully sent email")
except smtplib.SMTPException:
print("Error: unable to send email")
import traceback
traceback.print_exc()
(To debug the problem, I added the print-traceback code in the except statement. The exceptions had specific information on how to get it to work. The code hung when accessing port 465, I think because of problems with TLS negotiation, so I had to try using port 587; then I got good debugging info that explained what to do.)
You can see info on the SMTP_SSL object here.

Sending email with python smtplib not working, confused about the "from" field

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.

Categories