Python: attach .txt to an email - python

I did some google researches and found a lot of stuff. Unfortunately I do not understand what I found so I need to open a new "public request". As I told in my title already I want to attach a .txt file to my email. Sorry to ask that again after thousands of people already did this, but here is my method to send the mail:
import smtplib, ssl
from email.mime.multipart import MIMEMultipart
from email.mime.multipart import MIMEBase
from email.mime.text import MIMEText
from email.utils import formatdate
from email import encoders
import config
#creating file to write the keys in later
file = open("my_filename.txt", "w+")
#creating subject and message for the email
subject = "Test123 new / updated"
msg = "look in attachment"
def send_mail(subject, msg)
try:
server = smtplib.SMTP("smtp.gmail.com:587")
server.ehlo()
server.starttls()
server.login(config.EMAIL_ADDRESS, config.PASSWORD)
message = "Subject: {}\n\n{}".format(subject, msg)
server.sendmail(config.EMAIL_ADDRESS, config.EMAIL_RECEIVER, message)
server.quit()
print("success: Email sent!")
except:
print("Email failed to send")
This worked fine for me (just managed it with some research too. To attach the file finally I found something like that:
msg = MIMEMultipart()
#some other code to create a mail with subject and stuff like that
msg.attach(MIMEText(text))
If I change "text" to "my_filename.txt" it do not work. What do I need to change?

ahh, I had an other own idea. I removed the line "msg = "look in attachment"" and instead of this I used the method file.read(). So my line where I send the mail looks like this now:
server.sendmail(config.EMAIL_ADDRESS, config.EMAIL_RECEIVER, file.read())

Related

Email sender python bot which can send Emails to multiple recipient with their names in message

I have a csv file in which one column is name and other is email. I have to send the email to all the members listed in csv with their name from the name column in the message. Also some names does not have the email so i want to ignore that name.
This is how my csv file looks like
So, I tried this code. It is sending the emails individually to each member but sending the same name i.e. the last one to each email address.
can anyone help me to resolve this...?
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import csv
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email import *
from itertools import islice
df=pd.read_csv("emails.csv")
df.isnull()
df.isnull().sum()
df['email'].fillna("NO Email",inplace=True)
X=df.iloc[:,2].values
y=df.iloc[:,0].values
FROM= "mail#gmail.com"
TO=X
password=input("enter password:")
message= MIMEMultipart()
message['From'] = FROM
message['Subject'] = "subject line"
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(FROM,password)
for j in TO:
if(j=="NO Email"):
#i_iter=iter(i)
print("No email found ")#+ next(islice(i_iter,1)))
for i in y:
#next(i_iter)
print("Name skip")
continue
else:
i=0
for i in range(len(y)):
message = MIMEText("""hii..........{}""".format(y[i]))
#i+=1
print("Login success")
server.sendmail(FROM,j,message.as_string())
print("email has been send to ",j)
You are replacing the original message inside the loop, so what you end up passing to server.sendmail is not a valid email message.
Probably try something like
from email.message import EmailMessage
import smtplib
import logging
FROM = "mail#gmail.com"
with smtplib.SMTP('smtp.gmail.com', 587) as server:
server.starttls()
server.login(FROM, password)
logging.info("Login success")
for address, recipient in zip(X, y):
if address == "NO Email":
logging.warning("No email found: %s", recipient)
continue
message = EmailMessage()
message['From'] = FROM
message['Subject'] = "subject line"
message.set_content("""hii..........{}""".format(recipient))
server.send_message(message)
logging.info("email has been sent to %s", recipient)
Notice how we use zip() to align the two columns, and replace the rather haphazard mix of random email functions with, basically, the first example from https://docs.python.org/3/library/email.examples.html and also more tangentially use logging instead of print for diagnostic messages.

Email alert if file doesn't exist - Python

I'm very new to python.
I have a folder called "etc" with a filename password.txt when generates every night. I would like to run a python script in windows task on daily basis to check if password.txt doesn't exist then send email to abc#ouremail.co.uk else do not send any email.
I want to trigger email based on the below condition. When the condition is "false" send email else no action taken. How can I achieve it, any help on this would be greatly appreciated.
os.path.isfile("/etc/password.txt")
True
Kind regards,
Biswa
Check if File Exists using the os.path Module
The os.path module provides some useful functions for working with pathnames. The module is available for both Python 2 and 3
import os.path
if os.path.isfile('filename.txt'):
print ("File exist")
else:
print ("File not exist")
Then to send an email you can use smtplib (one topic here)
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
msg = MIMEMultipart()
msg['From'] = 'me#gmail.com'
msg['To'] = 'you#gmail.com'
msg['Subject'] = 'simple email in python'
message = 'here is the email'
msg.attach(MIMEText(message))
mailserver = smtplib.SMTP('smtp.gmail.com',587)
# identify ourselves to smtp gmail client
mailserver.ehlo()
# secure our email with tls encryption
mailserver.starttls()
# re-identify ourselves as an encrypted connection
mailserver.ehlo()
mailserver.login('me#gmail.com', 'mypassword')
mailserver.sendmail('me#gmail.com','you#gmail.com',msg.as_string())
mailserver.quit()

python 3.5 on windows. the program should send a text file which it reads and it sends an emty message

tried it before and it worked don't know what happend..
at first it should read a text file. and I've tried reading and printing it manually and it worked so that part is ok. I think. but every time I try to send the message I get an empty message
import smtplib as s
#file settings
filename = open("D:\pythonscripts\hey_hey.txt", 'a+')
content = filename.read()
#recivers list
recivers = ['somemail#gmail.com']
#tries to send the message
def send_mail(username, password, msg):
#connects to smtp gmail server
server = s.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username, password)
try:
server.sendmail(username, recivers[0], msg)
print("massage sent")
except:
server.close()
print("error while sending the massage\nquitung server...")
send_mail('somemail#gmail.com', 'ferari_car', content)
Try this instead:
filename = open("D:\\pythonscripts\\hey_hey.txt", 'r') # r, not a+, and escape the backslashes
a+ opens the file for appending, which puts the file position at the end of the file. So when you try to read it, you'll get nothing.
hey all thank you for helping me out. evenchely I managed to send the message with the text file as an attachment instead of the message's body..
import smtplib as s
from os.path import basename
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
#file settings
filename = open("D:\\pythonscripts\\hey_hey.txt", 'r')
content= filename.read()
print(content)
#recivers list
recivers = ['somemail#gmail.com']
#tries to send the message
def send_mail(username, password, message, send_to, subject):
#message settings
msg = MIMEMultipart()
msg['From'] = username
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(MIMEText(message))
#connects to smtp gmail server
server = s.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username, password)
try:
server.sendmail(username, send_to, msg.as_string())
print("massage sent")
except:
server.close()
print("error while sending the massage\nquitung server...")
send_mail('othermail#gmail.com', 'ferari_car', content, recivers[0], "the mail stuff")

Python: Trying to send attachments via email ~ string error?

I'm trying to send attachments via email with python but I'm getting this error:
msg.attach(msgImage)
AttributeError: 'str' object has no attribute 'attach'
Here is the code:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.mime.image import MIMEImage
def send_email():
fromaddr = 'testevpsa1#gmail.com'
toaddrs = 'Toemail'
global msg
subject = 'RESPOSTA'
message = 'Subject: %s\n\n%s' % (subject, msg)
username = 'testevpsa1#gmail.com'
password = 'xxxxxxxx'
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username,password)
fp = open ('C:\Python27\Scripts\pares.txt', 'rb')
msgImage = MIMEImage (fp.read(), _subtype='txt')
fp.close()
msg.attach(msgImage)
server.sendmail(fromaddr, toaddrs, message, msg.as_string())
server.quit()
msg = 'Email test, please, see the attachments'
send_email()
Anyone has a hint of what is the problem?
Your code is weird and incorrect. You start using advanced concepts without a basic knowledge of the language, smtp protocol and email module.
msg variable in your code has str type. str is a plain string - a list of characters. It doesn't have method .attach.
I guess you wanted to use an instance of the class email.message instead of a string. Also, there's no need to use global variable. Global variables are bad, and it's totally unnecessary to use global variable in your case.

Email and smtplib modules in Python - some basic emailing questions

I've just started learning Python and I'm trying to code a bot where it emails a HTML message along with a .docx (Microsoft Word) attachment. Here's my code and it works fine, but I'm confused with a few of the parameters.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import os
#Email Variables
myemail = "myemail#hotmail.com"
recipient = "recipientemail#hotmail.com"
#Specifying MIME variables to include in email header
mime_details = MIMEMultipart('mixed')
mime_details['Subject'] = "This is my email subject!"
mime_details['From'] = myemail
mime_details['To'] = recipient
#Creating body of message
html_body = """\
<html>\
<p>\
My email message!
</p>\
</html>\
"""
#Attaching File To Email
os.chdir('C:\\Users\Kyle\Desktop\')
openfile = open('testfile.docx', 'rb')
doc = MIMEApplication(openfile.read(), _subtype='vnd.openxmlformats-officedocument.wordprocessingml.document')
doc.add_header('Content-Disposition', 'attachment', filename='My Content.docx')
mime_details.attach(doc)
openfile.close()
#Recording MIME types of email parts
htmlpart = MIMEText(html_body, _subtype='html')
#Attaching parts to message container
mime_details.attach(htmlpart)
#Sending message via SMTP server
s = smtplib.SMTP(host='smtp.live.com', port=587)
s.ehlo()
s.starttls()
s.login(myemail, 'password')
s.sendmail(myemail, recipient, mime_details.as_string())
s.quit()
I have a few questions regarding the code above, and I would greatly appreciate it if you can help me clear whatever confused thoughts I have regarding the modules above.
A) The add_header module
mime_details['Subject'] = "This is my email subject!"
mime_details['From'] = myemail
mime_details['To'] = recipient
As you can see from the snippet above, I clearly defined each header variable in the MIMEMultipart envelope. According to Python's docs, these values will be added to the header directly. I tried using the add_header() method directly as an alternative, something like:
mime_details.add_header(Subject = "This is my email subject!", To = recipient, From = myemail)
But it gave me errors. Any idea why?
B) At the last few lines of my code, I had to append a .as_string() to the payload I was sending. I tried taking it out but it gave me a TypeError: expected string or buffer.
The Python docs give me this:
as_string(unixfrom=False, maxheaderlen=0, policy=None)
Return the entire message flattened as a string.
I assume that I have to append this in every case? the mime_details object has two parts to it - the HTML message and the .docx file. Both will be converted to strings? What about image files?
C) When I open my file to attach, I read it in 'rb' mode.
Here's the code:
openfile = open('testfile.docx', 'rb')
I tried using 'r' but it raises an error. I've read up on this and 'rb' mode simply opens the file in binary. Why would it make sense to open a .docx file in binary mode? Am I to use 'rb' mode for ALL non.txt files?
D) Finally, I've seen some people use base64 encoding for attachments. I've searched around and a particularly popular script over here is below (from How to send email attachments with Python):
import smtplib, os
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
from email import encoders
def send_mail( send_from, send_to, subject, text, files=[], server="localhost", port=587, username='', password='', isTls=True):
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = subject
msg.attach( MIMEText(text) )
for f in files:
part = MIMEBase('application', "octet-stream")
part.set_payload( open(f,"rb").read() )
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="{0}"'.format(os.path.basename(f)))
msg.attach(part)
smtp = smtplib.SMTP(server, port)
if isTls: smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.quit()
Why does content need to be encoded in base64? Does this apply to all files and is a general thing to be added, or can I ignore this? What situations am I to invoke that method?
Finally, being a noob at Python, some of my code above may be redundant\badly structured. If you have any tips\suggestions on how I can improve my simply script, please do let me know.
Thank you!

Categories