我正在尝试使用Gmail API创建Gmail草稿。
在开发中它完美运行,但是当我部署它时,我收到一条错误消息。
POST http://myapp.appspot.com/emailDoc 500 (Internal Server Error)
这就是我的Flask路线功能:
# Flask Route
@app.route('/emailDoc', methods=["POST"])
def emailDoc():
# Get Oauth2 Credentials
credentials = Credentials().get_by_id('tokens')
if not authcheck(credentials):
return 'error'
# Create ReportLab PDF
buff = StringIO()
doc = SimpleDocTemplate(buff, pagesize=A4,
rightMargin=1.25*cm,leftMargin=1.25*cm,
topMargin=1.25*cm,bottomMargin=1.25*cm)
doc.build(genpdf(data))
# Create Email Message
message = MIMEMultipart()
message['to'] = to@email.com
message['from'] = 'me'
message['subject'] = 'Hello'
messageBody = MIMEText("Hello Wolrd")
messageFile = MIMEBase('application', 'pdf')
messageFile.set_payload(str(buff.getvalue()))
messageFile.add_header('Content-Disposition', 'attachment', filename='document.pdf')
message.attach(messageBody)
message.attach(messageFile)
# Oauth2 Flow
access_token = credentials.access_token
flow = AccessTokenCredentials(access_token, 'myapp')
http = flow.authorize(httplib2.Http())
# HTTP Request
obj = http.request(
uri='https://www.googleapis.com/gmail/v1/users/me/drafts',
method='POST',
body={
'message': {
'raw':base64.urlsafe_b64encode( message.as_string() )
}
},
headers={'content-type':'application/json'}
)[1]
return obj
这是我在Google Developers Console Logging标签中收到的错误消息。
Exception on /emailDoc [POST]
Traceback (most recent call last):
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/base/data/home/apps/s~admin-app/1.388311669567787470/main.py", line 471, in emailDoc
headers={'content-type':'application/json'}
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/oauth2client/client.py", line 589, in new_request
redirections, connection_type)
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/httplib2/__init__.py", line 1593, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/httplib2/__init__.py", line 1335, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/httplib2/__init__.py", line 1291, in _conn_request
response = conn.getresponse()
File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/gae_override/httplib.py", line 522, in getresponse
**extra_kwargs)
File "/base/data/home/apps/s~admin-app/1.388311669567787470/lib/httplib2/__init__.py", line 1091, in fixed_fetch
validate_certificate=validate_certificate)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/urlfetch.py", line 270, in fetch
allow_truncated, follow_redirects, validate_certificate)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/urlfetch.py", line 326, in make_fetch_call
request.set_payload(payload)
File "cpp_message.pyx", line 124, in cpp_message.SetScalarAccessors.Setter (third_party/apphosting/python/protobuf/proto1/cpp_message.cc:2229)
TypeError: <type 'dict'> has type <type 'dict'>, but expected one of: str, unicode
答案 0 :(得分:1)
在代码中的某个地方,您发送的是字典而不是字符串..我建议您使用gmail python library,它非常快速,并且每次调用都有代码捕捉。
"""Generates and submits an email as a draft.
"""
import base64
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import mimetypes
import os
from apiclient import errors
def CreateDraft(service, user_id, message_body):
"""Create and insert a draft email. Print the returned draft's message and id.
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_body: The body of the email message, including headers.
Returns:
Draft object, including draft id and message meta data.
"""
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, error:
print 'An error occurred: %s' % error
return None
def CreateMessage(sender, to, 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 base64 encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.b64encode(message.as_string())}
def CreateMessageWithAttachment(sender, to, subject, message_text, file_dir,
filename):
"""Create a message for an email.
Args:
sender: The email address of the sender.
to: The email address of the receiver.
subject: The subject of the email message.
message_text: The text of the email message.
file_dir: The directory containing the file to be attached.
filename: The name of the file to be attached.
Returns:
An object containing a base64 encoded email object.
"""
message = MIMEMultipart()
message['to'] = to
message['from'] = sender
message['subject'] = subject
msg = MIMEText(message_text)
message.attach(msg)
path = os.path.join(file_dir, filename)
content_type, encoding = mimetypes.guess_type(path)
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(path, 'rb')
msg = MIMEText(fp.read(), _subtype=sub_type)
fp.close()
elif main_type == 'image':
fp = open(path, 'rb')
msg = MIMEImage(fp.read(), _subtype=sub_type)
fp.close()
elif main_type == 'audio':
fp = open(path, 'rb')
msg = MIMEAudio(fp.read(), _subtype=sub_type)
fp.close()
else:
fp = open(path, 'rb')
msg = MIMEBase(main_type, sub_type)
msg.set_payload(fp.read())
fp.close()
msg.add_header('Content-Disposition', 'attachment', filename=filename)
message.attach(msg)
return {'raw': base64.b64encode(message.as_string())}
答案 1 :(得分:1)
http.request
要求body=
为字符串。在传递之前,您必须json.dumps
dict
。
# HTTP Request
obj = http.request(
uri='https://www.googleapis.com/gmail/v1/users/me/drafts',
method='POST',
# json encoded string
body=json.dumps({
'message': {
'raw':base64.urlsafe_b64encode( message.as_string() )
}
}),
headers={'content-type':'application/json'}
)[1]