部署后创建 Gmail 草稿不起作用
Creating Gmail draft after deployment not working
我正在尝试使用 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 开发人员控制台日志记录选项卡中收到的错误消息。
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
在您的代码中的某处,您发送的是字典而不是字符串。我建议您使用 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())}
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]
我正在尝试使用 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 开发人员控制台日志记录选项卡中收到的错误消息。
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
在您的代码中的某处,您发送的是字典而不是字符串。我建议您使用 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())}
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]