cannot send email with attachment from python? - python

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
msg = MIMEMultipart('multipart/related')
fromaddr = 'from#gmail.com'
toaddrs = 'to#gmail.com'
#provide gmail user name and password
username = 'to#gmail.com'
password = 'messifan'
filename = "1.jpg"
f = file(filename)
attachment = MIMEImage(f.read()) # error here
attachment.add_header('Content-Disposition', 'attachment', filename=filename)
.
.
server.sendmail(fromaddr, toaddrs, msg.as_string())
i am using this code to send email. i can attach text file using this script.(chenging MIMEImage to MIMEtext). but cannot attach image. the error is Could not guess Image mime subtype

Try
attachment = MIMEImage(f.read(), _subtype="jpeg") # error here

a bit of a guess here, but maybe try opening the file in binary mode?
f = file(filename, 'rb')

Looks to me like you created a "file" object, but you never opened it.
Where you have:
f = file(filename)
attachment = MIMEImage(f.read()) # error here
I think you instead need:
fp = open(filename, 'rb')
attachment = MIMEImage(fp.read())
fp.close()

Related

Send multiple emails with different attachments each

I have a list of text files and html files generated by two distinct functions. Each file is labeled signal1.txt, signal2, etc. and signal1.html, signal2.html, etc. I need to send an email with each file pair (signal1.txt and signal1.html, signal2.txt and signal.2.html, and so forth). I've tried several different ways, but I keep getting just one file pair attached (the last file number whatever it is). I have no problem sending one file type, but it gets messy when I try with two different files.
Any help is appreciated. The code is as follows.
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
import smtplib, ssl
import os
dirname = r'C:\Path\To\Files'
ext = ('.txt','html')
for files in os.scandir(dirname):
if files.path.endswith(ext):
def sendmail():
html_body = '''
<html>
<body>
<p style="font-size: 12;"> <strong>Alert</strong><br>{html}</p>
</body>
</html>
'''.format(html=html)
subject = f'Text file content'
senders_email = 'mail#mail.com'
receiver_email = 'mail#mail.com'
# Create a multipart message and set headers
message = MIMEMultipart('alternative')
message['From'] = senders_email
message['To'] = receiver_email
message['Subject'] = subject
#Attach email body
message.attach(MIMEText(html_body, 'html'))
# Name of the file to be attached
filename = f'signal.html'
# Open file in binary mode
with open(filename, 'rb') as attachment:
# Add file as application/octet-stream
part = MIMEBase('application', 'octet-stream')
part.set_payload(attachment.read())
# Encodes file in ASCII characters to send via email
encoders.encode_base64(part)
# Add header as key/value pair to attachment part
part.add_header(
'Content-Disposition',
f"attachment; filename= {filename}",
)
# Add attachment to message and convert message to string
message.attach(part)
text = message.as_string()
# Log into server using secure connection
context = ssl.create_default_context()
with smtplib.SMTP("smtp.mail.com", 25) as server:
# server.starttls(context=context)
# server.login(senders_email, 'password')
server.sendmail(senders_email, receiver_email, text)
print("Email sent!")
sendmail()
I've adapted one of these examples for your problem. This puts all the files in one email:
# Import smtplib for the actual sending function.
import smtplib
# Here are the email package modules we'll need.
from email.message import EmailMessage
import os
dirname = 'C:\Path\To\Files'
ext = ('.txt','html')
msg = EmailMessage()
msg['Subject'] = 'Text file content'
msg['From'] = 'mail#mail.com'
msg['To'] = 'mail#mail.com'
# Open the files in binary mode. You can also omit the subtype
# if you want MIMEImage to guess it.
for filename in os.scandir(dirname):
if filename.path.endswith(ext):
with open(filename, 'rb') as fp:
data = fp.read()
msg.add_attachment(data)
# Send the email via our own SMTP server.
with smtplib.SMTP('localhost') as s:
s.send_message(msg)
Found a way that worked using glob.
dirname = r'C:\Path\To\Files'
regex = create_txt_files(event_dict)
html_file = create_html_files(event_dict)
signalfiles = sorted(list(pathlib.Path(dirname).glob('*.txt')))
htmlfiles = sorted(list(pathlib.Path(dirname).glob('*.html')))
for i, path_html_file in enumerate(htmlfiles):
sendmail(html_file[i], regex[i], path_html_file)

How can I send random pdf files in email from a folder using Python?

I am trying to create an email bot that will send me a random pdf file from a folder. Though my code is not showing any error, I am not getting any mail. It'd be helpful if you can show me where I am going wrong and what should I do. Thank you.
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import os
import random
def send():
body = ""
sender_email = "email"
password = "my_password"
receiver_email = "email"
msg = MIMEMultipart()
msg['Subject'] = '[Email Test]'
msg['From'] = sender_email
msg['To'] = receiver_email
msg.attach(MIMEText(body, 'plain'))
path = "C:/Users/Asus/PycharmProjects/messenger_bot/files"
files = os.listdir(path)
index = random.randrange(0, len(files))
print(files[index])
attachment = open(os.path.join(path, random.choice(files)), 'rb')
payload = MIMEBase('application', 'octate-stream')
# payload = MIMEBase('application', 'pdf', Name=pdfname)
payload.set_payload(attachment.read())
# enconding the binary into base64
encoders.encode_base64(payload)
# add header with pdf name
payload.add_header('Content-Decomposition', 'attachment', filename=files)
msg.attach(payload)
# use gmail with port
session = smtplib.SMTP('smtp.gmail.com', 587)
# enable security
session.starttls()
# login with mail_id and password
session.login(sender_email, password)
text = msg.as_string()
session.sendmail(sender_email, receiver_email, text)
session.quit()
print('Mail Sent')
Are you sure that the sender email is correct?
change the sender_email from "email" to your actual email and it should work
From what I gather from official documentation. The issue you are having is because starttls takes a keyfile and a certfile together or a context by itself and you haven't given either.
try adding this:
context = ssl.create_default_context()
and then change your starttls() call to
starttls(context=context)

Create a text file, and email it without saving it locally

I would like to create a text file in Python, write something to it, and then e-mail it out (put test.txt as an email attachment).
However, I cannot save this file locally. Does anyone know how to go about doing this?
As soon as I open the text file to write in, it is saved locally on my computer.
f = open("test.txt","w+")
I am using smtplib and MIMEMultipart to send the mail.
StringIO is the way to go...
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from io import StringIO
email = MIMEMultipart()
email['Subject'] = 'subject'
email['To'] = 'recipient#example.com'
email['From'] = 'sender#example.com'
# Add the attachment to the message
f = StringIO()
# write some content to 'f'
f.write("content for 'test.txt'")
f.seek(0)
msg = MIMEBase('application', "octet-stream")
msg.set_payload(f.read())
encoders.encode_base64(msg)
msg.add_header('Content-Disposition',
'attachment',
filename='test.txt')
email.attach(msg)
I found this post while figuring out how to do this with the newer EmailMessage, which was introduced in Python 3.6 (see https://docs.python.org/3/library/email.message.html). It's slightly less code:
from email.message import EmailMessage
from io import StringIO
from smtplib import SMTP
message = EmailMessage()
message['Subject'] = 'Subject'
message['From'] = 'from#example.com'
message['To'] = 'to#example.com'
f = StringIO()
f.name = 'attachment.txt'
f.write('contents of file')
f.seek(0)
message.add_attachment(f.read(), filename=f.name)
with SMTP('yourmailserver.com', 25) as server:
server.send_message(message)

Python Emailed PDF Arriving with no name

I found and extended a script that will scan a directory and then email the pdfs inside it. The problem occurs when I receive the email. The PDFs are arriving as 'noname' files without an extension. I have to download them and manually add the extension to display them. Is there something I am missing here??
import sys
import os
import smtplib
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
COMMASPACE = ', '
def main():
sender = 'jp#voice.com'
password = 'pword'
recipients = 'j#gmail.com'
# Create enclosing (outer) message
outer = MIMEMultipart()
outer['Subject'] = 'TEST EMAIL'
outer['To'] = COMMASPACE.join(recipients)
outer['From'] = sender
outer.preamble = 'You will not see this in a MIMIE aware reader'
# list of attachments
attachments = r'C:/Users/Ace/Desktop/PDFTST/'
attach = os.listdir(attachments)
for file in attach:
try:
with open(attachments + file, 'rb') as fp:
msg = MIMEBase('application', "octet-stream")
msg.set_payload(fp.read())
encoders.encode_base64(msg)
outer.attach(msg)
except:
print("unable to open the attach. Error: ", sys.exc_info()[0])
raise
composed = outer.as_string()
try:
with smtplib.SMTP('smtp.gmail.com', 587) as s:
s.ehlo()
s.starttls()
s.ehlo()
s.login(sender, password)
s.sendmail(sender, recipients, composed)
s.close()
print("email sent!!!!")
except:
print("Unable to send email. Error: ", sys.exc_info()[0])
raise
if __name__ == '__main__':
main()
Joe's comment fixed similar situation I had with a text file. For your example, type:
msg = MIMEBase('application', "pdf", Name=file)
I think you should set the MIME type to application/pdf, not application/octet-stream.
Specify the filename like this:
msg.add_header('Content-Disposition', 'attachment', filename=filename)

Python: Attachment is showning in email body

I am trying to send an email using the Python email client. I have written the following code but it sends the attachemnt as the body and not as an attached file.
Could someone please tell me what is wrong with the code:
# Import smtplib for the actual sending function
import smtplib
# Here are the email package modules we'll need
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
EMAIL_LIST = ['rec#rec.com']
# Create the container (outer) email message.
msg = MIMEMultipart()
msg['Subject'] = 'THIS DOES NOT WORK'
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = 'send#sender.com'
print EMAIL_LIST
print '--------------------'
print ', '.join(EMAIL_LIST)
msg['To'] = ', '.join(EMAIL_LIST)
msg.preamble = 'THIS DOES NOT WORK'
fileName = 'c:\\p.trf'
with open(fileName, 'r') as fp:
attachment = MIMEText(fp.read())
fp.close()
msg.add_header('Content-Disposition', 'attachment', filename=fileName)
msg.attach(attachment)
# Send the email via our own SMTP server.
s = smtplib.SMTP('localhost')
s.sendmail('julka#pv.com', EMAIL_LIST, msg.as_string())
s.quit()
For the attachment, you should probably use, MIMEBase something like this:
import os
from email import encoders
from email.mime.base import MIMEBase
with open(fileName,'r') as fp:
attachment = MIMEBase('application','octet-stream')
attachment.set_payload(fp.read())
encoders.encode_base64(attachment)
attachment.add_header('Content-Disposition','attachment',filename=os.path.split(fileName)[1])
msg.attach(attachment)

Categories

Resources