如何通过用于python的gmail-api发送HTML格式的电子邮件 [英] How do I send HTML Formatted emails, through the gmail-api for python
问题描述
使用 GMail API示例中的示例代码:发送邮件,并遵循身份验证规则,通过gmail帐户发送以编程方式生成的电子邮件非常简单.在该示例中看不到的是如何将电子邮件设置为HTML格式.
Using the sample code from the GMail API Example: Send Mail, and after following rules for authentication, it's simple enough to send a programmatically generated email, via a gmail account. What isn't obvious from the example is how to set that email to be HTML formatted.
如何使用python在我的gmail-api发送消息中获取HTML格式?
message_body = "Hello!\nYou've just received a test message!\n\nSincerely,\n-Test Message Generator\n"
Hello!
You've just received a test message!
Sincerely,
-Test Message Generator
来自GMail-API的示例源代码
下面是该示例的稍作修改的版本,但仍然有效:
Example Source Code from GMail-API
Below is a slightly modified version of the example, but still works:
import argparse
import base64
from pprint import pformat
from pprint import pprint
import httplib2
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
SCOPES = 'https://mail.google.com/'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Test EMail App'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
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 = 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: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def create_message(sender, to, cc, subject, message_text):
"""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.
Returns:
An object containing a base64url encoded email object.
"""
print(sender + ', ' + to + ', ' + subject + ', ' + message_text)
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
message['cc'] = cc
pprint(message)
return {'raw': base64.urlsafe_b64encode(message.as_string())}
def send_message(service, user_id, message_in):
"""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.
"""
pprint(message_in)
try:
message = (service.users().messages().send(userId=user_id, body=message_in).execute())
pprint(message)
print ('Message Id: %s' % message['id'])
return message
except errors.HttpError, error:
print ('An error occurred: %s' % error)
def main(cli):
"""Shows basic usage of the Gmail API.
Creates a Gmail API service object and outputs a list of label names
of the user's Gmail account.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
email_msg = create_message(cli.addr_from, cli.addr_to, cli.addr_cc, cli.subject, cli.message)
msg_out = service.users().messages().send(userId = 'me', body = email_msg).execute()
pprint(msg_out)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--message', help = 'The message to send in the email', default='<MESSAGE = unfinished>')
parser.add_argument('-t', '--addr_to', help = 'the list of comma separated emails to send', default='cbsd.tools@gmail.com')
parser.add_argument('-s', '--subject', help = 'the email subject', default='<SUBJECT = undefined>')
parser.add_argument('-c', '--addr_cc', help = 'email CC\'s', default='')
parser.add_argument('-f', '--addr_from', help = 'Email address to send from', default='cbsd.tools@gmail.com')
cli = parser.parse_args()
pprint(dir(cli))
main(cli)
我尝试使用此代码及其上的变体,无法获得html格式的代码,也无法获得简单的转义字符以在需要的地方创建回车符.
Tried as I might, with this code, and variations on it, I could not get html formatted code, nor could I get simple escape characters to create carriage returns where they needed to be.
尝试以下操作也不起作用:
Trying the following didn't work either:
- 修改
line 69
以添加其他消息字典参数...即-
{'raw': base64.urlsafe_b64encode(message.as_string()), 'payload': {'mimeType': 'text/html'}}
- 如 GMail API文档 中所述li>
-
- modifying
line 69
to add additional message dictionary parameters... ie.{'raw': base64.urlsafe_b64encode(message.as_string()), 'payload': {'mimeType': 'text/html'}}
- As documented here in the GMail API Docs
-
\n
...即:\\n
或\\\n
并仅呈现为这些确切的字符 - 添加
<br> </br> <br/>
不会添加新行,而只是呈现为这些确切的字符 - 添加
\r
不会添加新行,而只是呈现为该确切字符
\n
... ie:\\n
nor\\\n
and just rendered as those exact characters- Adding
<br> </br> <br/>
did not add new lines and just rendered as those exact characters - Adding
\r
did not add new lines and just rendered as that exact character
原因这不是重复的问题
- 此SO链接处理多部分/已签名的消息一个>
- 我对多部分消息传递不感兴趣,因为它是一种优雅的解决方案.我希望整个消息为
HTML
. - 此外,此链接没有可接受的答案,并且给出的一个答案是非答案,因为它只是说明他们正在向Google发送问题声明.
- This SO link deals with multipart/signed messages
- I am uninterested in multipart messaging because it is an inelegant solution. I want the WHOLE message to be
HTML
. - Additionally, this link has no accepted answer, and the one answer present is a non-answer as it simply states that they are sending a problem statement to Google.
-
message = MIMEText(message_text, 'html')
<-添加'html'
作为MIMEText对象构造函数的第二个参数 message = MIMEText(message_text, 'html')
<-- add the'html'
as the second parameter of the MIMEText object constructor- 类email.mime.text.MIMEText(_text [,_subtype [,_charset]])
我们希望将其值显式传递给
_subtype
.在这种情况下,我们要传递:'html'
作为_subtype
. - class email.mime.text.MIMEText(_text[, _subtype[, _charset]])
We want to explicitly pass it a value to the
_subtype
. In this case, we want to pass:'html'
as the_subtype
.
推荐答案
进行了很多挖掘之后,我开始查看消息处理的python端,并注意到python对象实际上是在构造消息可以将base64编码发送到gmail-api消息对象构造函数中.
After doing a lot of digging around, I started looking in to the python side of the message handling, and noticed that a python object is actually constructing the message to be sent for base64 encoding into the gmail-api message object constructor.
请从上方看第63行:
message = MIMEText(message_text)
在所有尝试修改标头值和有效载荷dict(是
message
对象的成员)之后,最终对我有用的一个技巧是要进行设置(): The one trick that finally worked for me, after all the attempts to modify the header values and payload dict (which is a member of the
message
object), was to set (line 63
):Google为自己的gmail API提供的默认代码仅告诉您如何发送纯文本电子邮件,但它们隐藏了这样做的方式. 翼...
message = MIMEText(message_text)
The default code supplied by Google for their gmail API only tells you how to send plain text emails, but they hide how they're doing that. ala...
message = MIMEText(message_text)
我必须查找python类
email.mime.text.MIMEText
对象. 在这里,您将看到MIMEText对象的构造函数的以下定义:I had to look up the python class
email.mime.text.MIMEText
object. That's where you'll see this definition of the constructor for the MIMEText object:现在,您将不再需要Google或Python的
mime.text.MIMEText
对象def create_message(sender, to, cc, subject, message_text): """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. Returns: An object containing a base64url encoded email object. """ print(sender + ', ' + to + ', ' + subject + ', ' + message_text) message = MIMEText(message_text,'html') message['to'] = to message['from'] = sender message['subject'] = subject message['cc'] = cc pprint(message) return {'raw': base64.urlsafe_b64encode(message.as_string())}
这篇关于如何通过用于python的gmail-api发送HTML格式的电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- I am uninterested in multipart messaging because it is an inelegant solution. I want the WHOLE message to be
Reasons this is not a duplicate question
- 我对多部分消息传递不感兴趣,因为它是一种优雅的解决方案.我希望整个消息为