I am using the Gmail API in Python 3 to send emails with attachments, based on their example code
I've got the following to create the message:
def create_message_with_attachment(
sender, to, subject, message_text, files):
"""Create a message for an email.
Args:
sender: Email address of the sender.
to: Email address of the receiver.
subject: The subject of the email message.
message_text: The text of the email message.
file: The path to the file to be attached.
Returns:
An object containing a base64url encoded email object.
"""
message = MIMEMultipart()
message['to'] = to
message['from'] = sender
message['subject'] = subject
msg = MIMEText(message_text)
message.attach(msg)
for file in files:
content_type, encoding = mimetypes.guess_type(file)
if content_type is None or encoding is not None:
content_type = 'application/octet-stream'
main_type, sub_type = content_type.split('/', 1)
if main_type == 'text':
fp = open(file, 'rb')
msg = MIMEText(fp.read(), _subtype=sub_type)
fp.close()
elif main_type == 'image':
fp = open(file, 'rb')
msg = MIMEImage(fp.read(), _subtype=sub_type)
fp.close()
elif main_type == 'audio':
fp = open(file, 'rb')
msg = MIMEAudio(fp.read(), _subtype=sub_type)
fp.close()
else:
fp = open(file, 'rb')
msg = MIMEBase(main_type, sub_type)
msg.set_payload(fp.read())
fp.close()
filename = os.path.basename(file)
msg.add_header('Content-Disposition', 'attachment', filename=filename)
message.attach(msg)
raw = base64.urlsafe_b64encode(message.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
And the following to send:
def send_message(service, user_id, message):
"""Send an email message.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
message: Message to be sent.
Returns:
Sent Message.
"""
try:
message = (service.users().messages().send(userId=user_id, body=message).execute())
print ('Sent! Message Id: %s' % message['id'])
return message
except httplib2.HttpLib2Error as error:
return None
print ('An error occurred: %s' % error)
When I send a mail created like this (I need to send pdf's, but tried with a zip as well with the same results) it works but the files are corrupted. I'm assuming this happens during the base64 encoding.
I saw in another post that adding encoders.encode_base64(msg)
(just above/below filename = os.path.basename(file)
in my case) solves the issue, however when I add that line I get: ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
Apparently it does that when it doesn't like a file?
Any idea what I'm doing wrong?
The encoding procedure described in the Google documentation for sending emails is based on Python 2. I assume you are using Python 3.
To adapt the guide to the new Python version two modifications need to be implemented.
return {'raw': base64.urlsafe_b64encode(message.as_string())}
to return {'raw': base64.urlsafe_b64encode(message.as_bytes()).decode()}
. You have done this already.msg.set_payload(contents)
request you need to add an additional line encoders.encode_base64(msg)
. This is what you were missing.Now that you added it, mind that
encoders
is a module of the packagefrom email import encoders
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.