我正在建立一个内部流程,以使用GMAIL API创建电子邮件草稿模板。我遵循了快速入门指南并启用了API并进行了测试。经过进一步的谷歌搜索之后,我有一段工作代码可以发送电子邮件,但也应该能够按照drafts.create指南创建电子邮件草稿。在此阶段,我不断收到以下错误:
发生错误:https://www.googleapis.com/gmail/v1/users//drafts?alt=json返回了“无效的消息值:请工作”
我最初遇到的错误是无效的权限错误,我相信已通过删除.credentials中的gmail-python-email-send.json文件并更新权限和重新运行代码来解决此问题。范围通过google dev控制台。
如果我查看gmail-python-email-send.json文件,现在它包含以下作用域,而以前只包含send元素:
“范围”:[“ https://www.googleapis.com/auth/gmail.compose”,“ https://www.googleapis.com/auth/gmail.modify”,“ https://mail.google.com/”]
import httplib2
import os
import oauth2client
from oauth2client import client, tools, file
import base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from apiclient import errors, discovery
import mimetypes
from email.mime.image import MIMEImage
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
SCOPES = [
'https://mail.google.com/',
'https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/gmail.compose'
]
CLIENT_SECRET_FILE = 'G://Myfilepath'
APPLICATION_NAME = 'appName'
def get_credentials():
home_dir = os.path.expanduser('~')
print(home_dir)
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-email-send.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
credentials = tools.run_flow(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def SendMessage(sender, to, subject, msgHtml, msgPlain, attachmentFile=None):
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
if attachmentFile:
message1 = createMessageWithAttachment(sender, to, subject, msgHtml, msgPlain, attachmentFile)
else:
message1 = CreateMessageHtml(sender, to, subject, msgHtml, msgPlain)
result = SendMessageInternal(service, "me", message1)
return result
def SendMessageInternal(service, user_id, message):
try:
message = (service.users().messages().send(userId=user_id, body=message).execute())
print('Message Id: %s' % message['id'])
return message
except errors.HttpError as error:
print('An error occurred: %s' % error)
return "Error"
return "OK"
def CreateDraft(service, user_id, message_body):
try:
message = {'message': message_body}
draft = service.users().drafts().create(userId = user_id, body=message).execute()
print ('Draft id: %s\nDraft message: %s' % (draft['id'], draft['message']))
return draft
except errors.HttpError as error:
print('An error occurred: %s' % error)
return None
def CreateMessageHtml(sender, to, subject, msgHtml, msgPlain):
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = to
msg.attach(MIMEText(msgPlain, 'plain'))
msg.attach(MIMEText(msgHtml, 'html'))
return {'raw': base64.urlsafe_b64encode(msg.as_string().encode()).decode()}
def createMessageWithAttachment(
sender, to, subject, msgHtml, msgPlain, attachmentFile):
"""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.
msgHtml: Html message to be sent
msgPlain: Alternative plain text message for older email clients
attachmentFile: The path to the file to be attached.
Returns:
An object containing a base64url encoded email object.
"""
message = MIMEMultipart('mixed')
message['to'] = to
message['from'] = sender
message['subject'] = subject
messageA = MIMEMultipart('alternative')
messageR = MIMEMultipart('related')
messageR.attach(MIMEText(msgHtml, 'html'))
messageA.attach(MIMEText(msgPlain, 'plain'))
messageA.attach(messageR)
message.attach(messageA)
print("create_message_with_attachment: file: %s" % attachmentFile)
content_type, encoding = mimetypes.guess_type(attachmentFile)
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(attachmentFile, 'rb')
msg = MIMEText(fp.read(), _subtype=sub_type)
fp.close()
elif main_type == 'image':
fp = open(attachmentFile, 'rb')
msg = MIMEImage(fp.read(), _subtype=sub_type)
fp.close()
elif main_type == 'audio':
fp = open(attachmentFile, 'rb')
msg = MIMEAudio(fp.read(), _subtype=sub_type)
fp.close()
else:
fp = open(attachmentFile, 'rb')
msg = MIMEBase(main_type, sub_type)
msg.set_payload(fp.read())
fp.close()
filename = os.path.basename(attachmentFile)
msg.add_header('Content-Disposition', 'attachment', filename=filename)
message.attach(msg)
return {'raw': base64.urlsafe_b64encode(message.as_string().encode()).decode()}
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
def main():
to = "testEmail"
sender = "myemail"
subject = "subject"
msgHtml = "Hi<br/>Html Email"
msgPlain = "Hi\nPlain Email"
SendMessage(sender, to, subject, msgHtml, msgPlain)
CreateDraft(service,sender,'Test working')
if __name__ == '__main__':
main()
我希望输出会创建草稿消息,如果遇到错误,我会期望权限错误。错误已更改的事实使我相信我已经解决了权限问题,但是我可能是错的,或者我对该过程的了解已完全消失。