I am trying to write a program that logins with a Gmail id and sends a mail to a provided id.
import smtplib
email = input('Enter your email\n')
password = input('Enter your password\n')
reciever = input("To whom you want to send?\n")
content = input("Enter content below:\n")
mail= smtplib.SMTP('smtp.gmail.com',587)
mail.ehlo()
mail.starttls()
mail.login(email,password)
mail.send_message(email,reciever,content)
But when I execute the program I get this error...
Enter your email
soham.nandy2006#gmail.com
Enter your password
x
To whom you want to send?
soham.nandy#outlook.com
Enter content below:
HELLOOOO
Traceback (most recent call last):
File "c:/Users/soham/Desktop/Python Crack/main.py", line 15, in <module>
mail.send_message(email,reciever,content)
File "C:\Users\soham\AppData\Local\Programs\Python\Python38-32\lib\smtplib.py", line 928, in send_message
resent = msg.get_all('Resent-Date')
AttributeError: 'str' object has no attribute 'get_all'
PS C:\Users\soham\Desktop\Python Crack>
P.S- I am writing x instead of my password for security issue (In the program the password is correct)
You need to pass MIMEMultipart object, not strings, when you use send_message:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# collect data from user
email = input('Enter your email\n')
password = input('Enter your password\n')
reciever = input("To whom you want to send?\n")
content = input("Enter content below:\n")
# set up a server
mail = smtplib.SMTP('smtp.gmail.com', 587)
mail.ehlo()
mail.starttls()
mail.login(email, password)
# create and specify parts of the email
msg = MIMEMultipart()
msg['From'] = email
msg['To'] = reciever
msg['Subject'] = 'sample subject' # maybe you want to collect it as well?
msg.attach(MIMEText(content, 'plain'))
mail.send_message(msg)
mail.quit()
You are using the wrong function to send your email. You should use mail.sendmail() instead of mail.send_message(). The difference is the order of the arguements and in the first function, the message is a string, in the second it is a Message object.
https://docs.python.org/3/library/smtplib.html#smtplib.SMTP.sendmail
Related
How can I adjust the code below to send emails to the given recipient in an infinite loop?. I have tried below but I am getting an error:
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.message import EmailMessage
# Open the plain text file whose name is in textfile for reading.
with open(r'C:\Users\David\Documents\Hello.txt') as fp:
# Create a text/plain message
msg = EmailMessage()
msg.set_content(fp.read())
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'yes'
msg['From'] = "example1#hotmail.com"
msg['To'] = "example2#hotmail.com"
# Login
s =server = smtplib.SMTP('smtp.office365.com', 587)
s.starttls()
s.login('example1#hotmail.com',"password")
i = 0
while True:
# Sending the message
s.send_message(msg)
s.quit()
i = i + 1
There are a couple of problems here:
While loop not properly indented (but maybe that was a copy/paste formatting error into StackOveflow?)
SMTP connection is started once, before the loop but quit on every iteration within the loop. (Either keep it open for the whole loop or connnect and quit within each iteration).
Here's updated code (untested) with the above fixes:
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.message import EmailMessage
# Open the plain text file whose name is in textfile for reading.
with open(r'C:\Users\David\Documents\Hello.txt') as fp:
# Create a text/plain message
msg = EmailMessage()
msg.set_content(fp.read())
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'yes'
msg['From'] = "example1#hotmail.com"
msg['To'] = "example2#hotmail.com"
i = 0
while True:
# Login
s =server = smtplib.SMTP('smtp.office365.com', 587)
s.starttls()
s.login('example1#hotmail.com',"password")
# Sending the message
s.send_message(msg)
s.quit()
i = i + 1
I want to have this code where I can have a csv file with a row of names next to a row of emails and then email every email on the list but have every name in the message.
Here is my code:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import csv
def nobrackets(current):
return str(current).replace('[','').replace(']','')
def noastrick(current):
return str(current).replace('\'','').replace('\'','')
email = 'xxxxxxxxxx'
password = 'xxxxxxxx'
send_to_email = []
subject = 'Whats up doc' # The subject line
message = ()
names = []
msg = MIMEMultipart()
msg['Subject'] = 'Whats up doc'
# Attach the message to the MIMEMultipart object
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
with open('Emails.csv','r') as csv_file:
csv_reader=csv.reader(csv_file)
for line in csv_reader:
names.append(line[0])
names_var = names
send_to_email.append(line[1])
send_to_email_var = send_to_email
message = (f"Hey {noastrick(nobrackets(names_var))} how has your day been?")
msg.attach(MIMEText(message, 'plain'))
msg['From'] = 'xxxxxxxxx'
msg['To'] = send_to_email_var
server.login(email, password)
text = msg.as_string() # You now need to convert the MIMEMultipart object to a string to send
server.sendmail(email, send_to_email_var, text)
names.clear()
message = ()
send_to_email = []
server.quit()
The error I get is File/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/email/_policybase.py", line 369, in _fold
parts.append(h.encode(linesep=self.linesep, maxlinelen=maxlinelen))
AttributeError: 'list' object has no attribute 'encode'
The reason I change the lists into variables is because I thought that might fix the error I got. I am somewhat new to python, and I realized the error is in a file called _policybase.py and it might be like built into the python application I installed on my computer, but I don't know how to edit that file, or fix that error.
This answer by #snakecharmerb is mostly correct:
The problem is that the code is setting msg['to'] to a list instead of a string. smtplib.server.sendmail will accept a list of strings as its toaddrs argument, but an email message does not (if multiple to addresses are required, call msg['to'] = address once for each address).
However, you don't need to send the mail to each recipient individually via a for-loop. Instead just assign the list as comma-separated string to msg["To"] like this:
msg["To"] = ", ".join(send_to_email_var)
The problem is that the code is setting msg['to'] to a list instead of a string. smtplib.server.sendmail will accept a list of strings as its toaddrs argument, but an email message does not (if multiple to addresses are required, call msg['to'] = address once for each address).
Also, it isn't necessary to stringify the message to send it: instead, use smtplib.server.send_message
This code ought to work:
with open('Emails.csv','r') as csv_file:
csv_reader=csv.reader(csv_file)
for line in csv_reader:
names_var = line[0]
send_to_email_var = line[1]
msg = MIMEMultipart()
msg['Subject'] = 'Whats up doc'
message = (f"Hey {noastrick(nobrackets(names_var))} how has your day been?")
msg.attach(MIMEText(message, 'plain'))
msg['From'] = 'xxxxxxxxx'
msg['To'] = send_to_email_var
server.login(email, password)
server.send_message(msg, email, send_to_email_var)
server.quit()
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.
I found a small program that will send my phone a text message through my gmail, but when I send the text it adds on "[Attachment(s) removed]", is there any way to remove that?
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
email = "Your Email"
pas = "Your Pass"
sms_gateway = 'number#tmomail.net'
# The server we use to send emails in our case it will be gmail but every email provider has a different smtp
# and port is also provided by the email provider.
smtp = "smtp.gmail.com"
port = 587
# This will start our email server
server = smtplib.SMTP(smtp,port)
# Starting the server
server.starttls()
# Now we need to login
server.login(email,pas)
# Now we use the MIME module to structure our message.
msg = MIMEMultipart()
msg['From'] = email
msg['To'] = sms_gateway
# Make sure you add a new line in the subject
msg['Subject'] = "You can insert anything\n"
# Make sure you also add new lines to your body
body = "You can insert message here\n"
# and then attach that body furthermore you can also send html content.
msg.attach(MIMEText(body, 'plain'))
sms = msg.as_string()
server.sendmail(email,sms_gateway,sms)
# lastly quit the server
server.quit()
When you are doing the server.sendmail step just send the body string. So instead it would be:
import smtplib
email = "Your Email"
pas = "Your Pass"
sms_gateway = 'number#tmomail.net'
smtp = "smtp.gmail.com"
port = 587
# This will start our email server
server = smtplib.SMTP(smtp,port)
# Starting the server
server.starttls()
# Now we need to login
server.login(email,pas)
body = "Yo, im done."
server.sendmail(email,sms_gateway,body)
# lastly quit the server
server.quit()
I am writing an automation Python Script. My intention is to email multiple unique attachments to multiple unique recipients. For example l have 1000 unique statements that must be emailed to 1000 unique clients. I want my Python script to be able to pick an attachment automatically and send it to the right recipient!
I have created the script and that creates the pdf attachments and name them after each email address of recipients so that l can use the names to pick the attachment and match that with the email of the recipient.
It Picks attachment perfectly BUT the problems it keeps incrementing attachment to users in each iteration..
#1.READING FILE NAMES WHICH ARE EMAIL ADDRESS FOR RECEPIENTS
import os, fnmatch
filePath = "C:/Users/DAdmin/Pictures/"
def readFiles(path):
fileNames =fnmatch.filter(os.listdir(path), '*.pdf')
i=0
pdfFilesNamesOnly=[]
while i < len(fileNames):
s =fileNames[i]
removeThePdfExtension= s[0:-4]
pdfFilesNamesOnly.append(removeThePdfExtension)
i+=1
return pdfFilesNamesOnly
-----------------------------------------------------------
#2.SENDING AN EMAIL WITH UNIQUE ATTACHMENT TO MULTIPLE UNIQUE RECEPIENTS
import smtplib
import mimetypes
from optparse import OptionParser
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.application import MIMEApplication
import os,fnmatch
from readFileNames import readFiles
filePath = "C:/Users/DAdmin/Pictures/"
listOfEmails= readFiles(filePath)# Files are named after emails
def sendEmails(listOfFiNames): #sends the email
email = 'goddietshe#gmail.com' # Your email
password = '#####' # Your email account password
send_to_list = listOfEmails# From the file names
#creating a multipart object
subject ="MONTHLY STATEMENTS"
mg = MIMEMultipart('alternative')
mg['From'] = email
mg['To'] = ",".join(send_to_list)
mg['Subject'] = subject
mg.attach(MIMEText("Please receive your monthly statement",'plain'))
# Attaching a file now before emailing. (Where l have a problem)
for i in listOfEmails:
if i in send_to_list:
newFile = (i+'.pdf') # create the name of the attachment to email using the name(which is the email) and will be used to pick the attachment
with open(newFile,'rb') as attachment:
part = MIMEBase('application','x- pdf')
part.set_payload(attachment.read())
attachment.close()
encoders.encode_base64(part)
part.add_header('Content- Disposition','attachment; filename="%s"' % newFile )
mg.attach(part)
text =mg.as_string() # converting the message obj to a string/text obj
server = smtplib.SMTP('smtp.gmail.com', 587) # Connect to the server
server.starttls() # Use TLS
server.login(email, password) # Login to the email server
# this is where it is emailing stuff
server.sendmail(email, i , text) # Send the email
server.quit() # Logout of the email server
print("The mail was sent")
#print("Failed ")
sendEmails(listOfFiNames)
I expect it to email each unique attachment to each unique recipient who are 1000 automatically
You reuse mg (message), using only attach, so your attachments pile up. You need to substitute the whole previous content with new content using set_payload because there is no "remove" method.
In doing this, you have to remember to re-add the text which you set before the loop:
mg.attach(MIMEText("Please receive your monthly statement",'plain'))
for i in listOfEmails:
because by using set_payload you lose all previous parts you attached. I'd just save this as a variable and then add it in the loop.
Moreover:
mg['To'] = ",".join(send_to_list)
This line makes all messages send to all people. You need to move this part to the loop as well, setting only one email address at once.
EDIT Applying those changes:
def sendEmails(): #sends the email
email = 'goddietshe#gmail.com' # Your email
password = '#####' # Your email account password
#creating a multipart object
subject ="MONTHLY STATEMENTS"
mg = MIMEMultipart('alternative')
mg['From'] = email
# mg['To'] = ",".join(listOfEmails) # NO!
mg['Subject'] = subject
text_content = MIMEText("Please receive your monthly statement",'plain')) #safe it for later, rather than attach it - we'll have to re-attach it every loop run
for i in listOfEmails:
if i in send_to_list:
newFile = (i+'.pdf') # create the name of the attachment to email using the name(which is the email) and will be used to pick the attachment
with open(newFile,'rb') as attachment:
part = MIMEBase('application','x- pdf')
part.set_payload(attachment.read())
attachment.close()
encoders.encode_base64(part)
part.add_header('Content- Disposition','attachment; filename="%s"' % newFile )
mg.set_payload(text_content) #change the whole content into text only (==remove previous attachment)
mg.attach(part) #keep this - new attachment
mg["To"] = i # send the email to the current recipient only!
text =mg.as_string() # converting the message obj to a string/text obj
server = smtplib.SMTP('smtp.gmail.com', 587) # Connect to the server
server.starttls() # Use TLS
server.login(email, password) # Login to the email server
# this is where it is emailing stuff
server.sendmail(email, i , text) # Send the email
server.quit() # Logout of the email server
print("The mail was sent")
**Works very fine like this. Thanks #h4z3**
def sendEmail():
email = 'goddietshetu#gmail.com' # Your email
password = '####' # Your email account password
subject ="MONTHLY STATEMENTS"
#creating a multipart object
mg = MIMEMultipart('alternative')
mg['From'] = email
mg['Subject'] = subject
# attaching a file now
listOfEmails = readFileNames(filePath)
for i in listOfEmails:
attachment =open(i+'.pdf','rb')
part = MIMEBase('application','octet-stream')
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',f"attachment; filename= {i}.pdf")
mg.set_payload(mg.attach(MIMEText("",'plain')))
mg.attach(MIMEText("Please receive your monthly statement",'plain'))
mg.attach(part)
mg['To'] = i
text =mg.as_string() # converting the message obj to a string/text obj
server = smtplib.SMTP('smtp.gmail.com', 587) # Connect to the server
server.starttls() # Use TLS
server.login(email, password) # Login to the email server
server.sendmail(email, i , text) # Send the email
server.quit() # Logout of the email serv
print("The mail was sent")
sendEmail()