I am automating the creation of Gmail drafts in Python using the Gmail API. I need to create letters in HTML format, but I also personally need to create a reserve of irreplaceable text, because this is correct.
I thought that all of the above worked for me, until I tried to make a reserve of irreplaceable text a little different from HTML. It seems like Google is committing to backing up plaintext for me, instead of using the one I provide, so if my body is html <HTML><BODY>HTML Body</BODY></HTML>
and my body is plaintext Plaintext body
, the final plaintext body will be HTML Body
, discarding the plaintext that I provided.
My question is : Does anyone know how to get the Gmail API to use the plaintext that I provide, instead of automatically generating a backup for me?
One of the important elements that I noticed: if I attach the HTML and Plaintext bodies in a different order, the opposite happens: GMail automatically generates an HTML body based on my plain text. Therefore, it seems that he pays attention only to the last attached body.
The cut-out version of the code I'm using:
import base64
import os
import httplib2
import oauth2client
from oauth2client import client
from oauth2client import tools
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from pathlib import Path
from apiclient import errors
from apiclient import discovery
SCOPES = 'https://mail.google.com/'
CLIENT_SECRET_FILE = 'client_id.json'
APPLICATION_NAME = 'Test Client'
def get_credentials():
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir, 'gmail-python-quickstart.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else:
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def CreateDraft(service, user_id, message_body):
message = {'message': message_body}
draft = service.users().drafts().create(userId=user_id, body=message).execute()
return draft
def CreateTestMessage(sender, to, subject):
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = to
plain_text = "Text email message. It plain. It text."
html_text = """\
<html>
<head></head>
<body>
<p>HTML email message</p>
<ol>
<li>As easy as one</li>
<li>two</li>
<li>three!</li>
</ol>
<p>Includes <a href="http://stackoverflow.com/">linktacular</a> goodness</p>
</body>
</html>
"""
msg.attach(MIMEText(plain_text, 'plain'))
msg.attach(MIMEText(html_text, 'html'))
print('-----\nHere is the message:\n\n{m}'.format(m=msg))
encoded = base64.urlsafe_b64encode(msg.as_string().encode('UTF-8')).decode('UTF-8')
return {'raw': encoded}
def main():
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
my_address = 'example@gmail.com'
test_message = CreateTestMessage(sender=my_address,
to='example@gmail.com',
subject='Subject line Here')
draft = CreateDraft(service, my_address, test_message)
if __name__ == '__main__':
main()
Update: The following are gists examples of what I send to Gmail and what is sent from Gmail, both in HTML-then- plaintext and plaintext-then-HTML orders (which generate different results)