While sending an email with smtplib and trying to insert a variable into the message with this code:
smtpObj.sendmail('my email', 'my email', "Subject: Info for today. \nToday's weather is:",con)
(where con is weather scraped from the internet)
throws the following error:
File "C:\Python27\lib\smtplib.py", line 731, in sendmail
raise SMTPSenderRefused(code, resp, from_addr)
smtplib.SMTPSenderRefused: (501, '5.5.4 Invalid arguments', 'my email here')
However, when I simply use "+" to concatenate the two strings, rather than a comma, it works, but does not format properly, displaying as "..weather is:rain" rather than "..weather is: rain"
am I doing something wrong, or is this simply not possible?
However, when I simply use "+" to concatenate the two strings, rather than a comma, it works, but does not format properly, displaying as "..weather is:rain" rather than "..weather is: rain"
You are simply mis-constructing the string that begins with "Subject" here:
smtpObj.sendmail('my email', 'my email', "Subject: Info for today. \nToday's weather is:",con)
When you tack on con with a comma like you are doing here, Python thinks that you are passing conn as the mail_options argument of the sendmail() call, the same as your other arguments to that function. It does not understand that you are trying to cram con into that "Subject: ..." string.
However, when I simply use "+" to concatenate the two strings, rather than a comma, it works, but does not format properly, displaying as "..weather is:rain" rather than "..weather is: rain"
So you just need an extra space after the "..weather is:" bit? Just add the extra space in the string. I suggest you write your message with the con argument in one of these ways:
msg = "Subject: Info for today. \nToday's weather is: " + con
# or like this:
msg = "Subject: Info for today. \nToday's weather is: %s" % (con,)
And then send your email:
smtpObj.sendmail('my email', 'my email', msg)
Related
def mail():
server = smtplib.SMTP('smtp-mail.outlook.com',587)
server.starttls()
server.login(env, password)
server.sendmail(env,rec,msg =str(list))
print("Login no servidor efetuado com Sucesso")
print("Email enviado para " + rec)
server.close()
I use this code to send an email but the email comes empty i tryed to swap msg = str(list) to just list tried remove message and type in the third argument just a string and emails always come empty
server.sendmail(env,rec,msg =str(list))
You see what your message contains?
str(list)
Try typing this same thing in a scope in which list is not overwritten (because list is not reassigned in your mail function).
>>> str(list)
"<class 'list'>"
For sure that's not the right way of doing this.
What's more, in the same line of code above I don't see the assignation of env and rec, so I guess there must be some error there.
When I send an email the plain text is not wrapping. I read that you can't have more than 80 characters in a line or Gmail automatically makes a break and it makes the text look horrible on a phone. I put 'html' as second parameter in MIMETEXT(). This wraps the text, but does not include any Python escape characters. I can't figure out how to make line breaks?
Code:
I set MIMEText with 'html' parameter and this seems to wrap text, but in a block with out any of the Python escape characters being used.
def CreateMessageHtml(sender, to, subject, message_text):
msg = MIMEText(message_text,'html')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = to
return {'raw': base64.urlsafe_b64encode(msg.as_string())}
Issue is in the message_text, not sure how to create a line break because \n is not working.
def main():
df = pd.read_csv('testdata.csv')
for index,row in df.iterrows():
to = row['Email']
sender = "sender"
subject = "subject"
dedent_text = '''Hello {}, \n
Thank you for attending our last meeting. We would
like to see you again at our next event.'''.format(row['First'])
message_text = textwrap.dedent(dedent_text).strip()
SendMessage(sender, to, subject, message_text)
if __name__ == '__main__':
main()
In the function CreateMessageHtml the MIMEText object takes a subtype, which is 'HTML'. From the documentation: https://docs.python.org/2/library/email.mime.html#email.mime.text.MIMEText
class email.mime.text.MIMEText(_text[, _subtype[, _charset]])
Module: email.mime.text
A subclass of MIMENonMultipart, the MIMEText class is used to create MIME objects of major type text. _text is the string for the payload. _subtype is the minor type and defaults to plain.
Based on this you need to pass in a HTML formatted string. So I changed the dedent_text in the main function to:
dedent_text='''Hello {},
<p> Thank you for attending our last meeting.</P>
<p>We would like to see you again at our next
event.</p>'''.format(row['First'])
Now the text wraps on a phone with line breaks.
Try using triple quotes """ TEXT """ instead of triple apostrophes. Tried this:
mytext = """I'm going \n down down \n down """
print mytext
and the output was:
I'm going
down down
down
I have a sample code like following:
import smtplib
def send_mail(PASS,FAIL):
me = "XXXX"
you = "YYYY"
print "Start of program"
server = smtplib.SMTP('ZZZ', 25)
total_testcase = "15/12"
print total_testcase
message = """From: From Person <XXXX>
To: To Person <YYYY>
Subject: mail testing
%s
""" %total_testcase
print message
server.sendmail(me, you, message)
send_mail(8,9)
when I am sending the email it is delivering without the subject
But if I use the code instead of a function call - then it is delivering fine with subject. Anything I am missing in a function call. Please suggest.
The issue you're having is with the triple-quoted multi-line string. When you put it in your function, you're indenting all of its lines so that they line up with the rest of the code. However, this results in unnecessary (and inappropriate) spaces at the start of each line of the message after the first.
Leading spaces in the headers of an SMTP message indicate that the previous header should be continued. This means that all of your first three lines are combined into the From header.
You can fix this either by leaving out the leading spaces:
def send_mail(PASS,FAIL):
#...
message = """From: From Person <XXXX>
To: To Person <YYYY>
Subject: mail testing
%s
""" % total_testcase
#...
Or by using \n instead of real newlines in your string:
message = "From: From Person <XXXX>\nTo: To Person <YYYY>\nSubject: mail testing\n\n%s" % total_testcase
Or finally, you could keep the current code for the generation of the message, but strip out the leading whitespace afterwards:
def send_mail(PASS,FAIL):
#...
message = """From: From Person <XXXX>
To: To Person <YYYY>
Subject: mail testing
%s
""" % total_testcase
message = "\n".join(line if not line.startswith(" ") else line[4:]
for line in message.splitlines())
#...
This last option is a bit fragile, as it may strip out desired whitespace from lines in your total_testcase string (if it had multiple lines), not only the spaces added due to the multi-line string. It also will break if you're using tabs for indentation, or really anything other than four spaces. I'm not sure I'd actually recommend this approach.
A better version of the last approach is to use the textwrap.dedent function from the the standard library. It removes any indentation that is present at the start of every line in a string (but only the indentation that is common to all lines). This does require a small change to how you were creating message, as you need the first line to have the same leading spaces as all the rest (you'll also need to avoid adding any newlines without indentation in the extra text that comes from total_testcase).
Here's the code:
import textwrap
def send_mail(PASS,FAIL):
#...
# backslash after the quotes on the first line avoids a empty line at the start
message = """\
From: From Person <XXXX>
To: To Person <YYYY>
Subject: mail testing
%s
""" % total_testcase
message = textwrap.dedent(message)
#...
I am trying to write a python script to send an email that uses html formatting and involves a lot of non-breaking spaces. However, when I run it, some of the   strings are interrupted by spaces that occur every 171 characters, as can be seen by this example:
#!/usr/bin/env python
import smtplib
import socket
from email.mime.text import MIMEText
emails = ["my#email.com"]
sender = "test#{0}".format(socket.gethostname())
message = "<html><head></head><body>"
for i in range(20):
message += " " * 50
message += "<br/>"
message += "</body>"
message = MIMEText(message, "html")
message["Subject"] = "Test"
message["From"] = sender
message["To"] = ", ".join(emails)
mailer = smtplib.SMTP("localhost")
mailer.sendmail(sender, emails, message.as_string())
mailer.quit()
The example should produce a blank email that consists of only spaces, but it ends up looking something like this:
  ;
&nb sp;
& nbsp;
&nbs p;
&n bsp;
Edit: In case it is important, I am running Ubuntu 15.04 with Postfix for the smtp client, and using python2.6.
I can replicate this in a way but my line breaks come every 999 characters. RFC 821 says maximum length of a line is 1000 characters including the line break so that's probably why.
This post gives a different way to send a html email in python, and i believe the mime type "multipart/alternative" is the correct way.
Sending HTML email using Python
I'm the developer of yagmail, a package that tries to make it easy to send emails.
You can use the following code:
import yagmail
yag = yagmail.SMTP('me#gmail.com', 'mypassword')
for i in range(20):
message += " " * 50
message += "<br/>"
yag.send(contents = message)
Note that by default it will send a HTML message, and that it also adds automatically the alternative part for non HTML browsers.
Also, note that omitting the subject will leave an empty subject, and without a to argument it will send it to self.
Furthermore, note that if you set yagmail up correctly, you can just login using yag.SMTP(), without having to have username & password in the script (while still being secure). Omitting the password will prompt a getpass.
Adding an attachment is as simple as pointing to a local file, e.g.:
yag.send(contents = [message, 'previously a lot of whitespace', '/local/path/file.zip']
Awesome isn't it? Thanks for the allowing me to show a nice use case for yagmail :)
If you have any feature requests, issues or ideas please let me know at github.
I'm trying to send a text message over Tkinter. So you input sms:hello. That sends a text message that says hello. To do this it emails the word using the AT&T email server and GMail. So the program reads INFO.txt which contains all the email authentications g_user g_pass and m_num. Then it uses those to send an email which sends the text message.
Now my problem is that UnboundLocalError: local variable 'g_user' referenced before assignment. Which I know is caused by something not being a global variable. Can anyone help me out? I'm stumped...
root = Tk()
#open file
file=open('INFO.txt')
line=file.readline()
if 'Mobile_number:::' in line:
m_num=line[16:]
if 'GMail_name:::' in line:
g_user=line[13:]
if 'GMail_pass:::' in line:
g_pass=line[13:]
def callback(event):
text = inputfield.get()
if 'sms:' in text:
textmessage()
def textmessage():#sms:
import smtplib
#open file
file=open('INFO.txt')
line=file.readline()
if 'Mobile_number:::' in line:
m_num=line[16:]
if 'GMail_name:::' in line:
g_user=line[13:]
if 'GMail_pass:::' in line:
g_pass=line[13:]
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
sender = '{}#gmail.com'.format(g_user)
password='{}'.format(g_pass)
recipient = '{}#txt.att.net'.format(m_num)
subject = 'Gmail SMTP Test'
body = text[4:]
"Sends an e-mail to the specified recipient."
body = "" + body + ""
headers = ["From: " + sender,
"Subject: " + subject,
"To: " + recipient,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo
session.login(sender, password)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
session.quit()
text2=text[4:]
confirmation="SMS containing '{}' sent".format(text2)
tex.insert(END,confirmation)
tex=Text(root)
tex.pack(side='right')
inputfield = Entry(root)
inputfield.pack(side='bottom')
inputfield.bind('<Return>', callback)
root.mainloop()
The problem is most likely with this line:
sender = '{}#gmail.com'.format(g_user)
because the if statement condition (if 'GMail_name:::' in line) is evaluating to False and then your g_user variable is never defined in the local scope of that function.
Take a close look at the error message:
UnboundLocalError: local variable 'g_user' referenced before assignment
A pretty good rule of thumb is to assume that the error message is telling the truth. In this case it is telling you two very important details:
It thinks g_user is a local variable
It thinks g_user was used before it was set
To solve this, you need to answer why to one or both of those questions. Why does it think it is local, and/or why does it think it wasn't set? If you mentally step through the code, you'll probably answer one or both of those questions.
For example, ask youself the question "how does g_user" get set if 'GMail_name:::' in line returns false? Have you verified that the if statement is true? Is your code prepared to handle the case where it's false? Have you literally proven to yourself that the if statement is true, or are you just assuming it's true?
Also, answer this question: are you reading every line from INFO.txt, or are you reading a single line? If you're only reading a single line, is that intentional? It looks like you are expecting both the username and password to be at position [13:] in the line, which will be impossible if both values are different and both values are on the same line.
Since you are just now learning to program, don't just throw lines of code into a file and hope they work, and don't get others to solve your problems. think about what the computer is doing. Step through the code logically and the problems will become self-evident.