Gmail API 读取凭据 'utf-8' 编解码器无法解码位置 0 中的字节 0x80:起始字节无效
Gmail API Reading credentials 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
我认为 Gmail API 和 Python3 存在问题。
文档中的原始代码在 Python2 中,但出于多种原因,包括我的应用程序已经在使用 Python3,我将代码传递给 python3。
所以......在解决了几个问题之后,包括一个 400 请求错误,(这显然是我提供给 google 的授权没有正确完成)我正面临(我希望)显然我正在尝试读取文件的最后一个问题
即使只是 token.read()
也会产生同样的问题。
一旦您授权 google 访问您的电子邮件帐户并且该应用程序可以自动发送电子邮件,token.pickle 文件就会自动生成。
我知道 credentials.json 文件是正确的,因为这是告诉 google 你是谁的关键,它总是正确读取我的凭据,重定向我以授权我的应用程序。
这是发送电子邮件的应用程序,我认为它非常简单,我按照文档查看了 other issues like this one 终于做到了这一点:
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.errors import HttpError
# from httplib2 import Http
# from oauth2client import client, tools, file
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
from apiclient import errors
SCOPES = 'https://mail.google.com/'
def SendMessage(service, user_id, message):
"""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.
"""
try:
message = (service.users().messages().send(userId=user_id, body=message)
.execute())
print(f'Message Id: {message["id"]}')
return message
except errors.HttpError as error:
print(f'An error occurred: {error}')
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 base64url encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
message_bytes = message.as_string().encode('utf-8')
# return { 'raw': base64.urlsafe_b64encode(message.as_string()) }
# return { 'raw': base64.urlsafe_b64encode(message_bytes) }
raw = base64.urlsafe_b64encode(message_bytes)
return raw.decode()
def main():
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'r') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('gmail', 'v1', credentials=creds)
# Create
message = CreateMessage('my-email@gmail.com', 'destination@gmail.com', 'Testing Gmail API', 'Hi GMAIL API')
# Send
SendMessage(service, "me", message)
if __name__ == '__main__':
main()
如果有人已经解决了这个问题,我真的不知道该怎么办。
谢谢!
在您的脚本中,当未创建 token.pickle
时,Gmail API 可以通过在第一次授权时创建 token.pickle
来使用。但是在message = (service.users().messages().send(userId=user_id, body=message).execute())
处出现了'raw' RFC822 payload message string or uploading message via /upload/* URL required
的错误。所以在这种情况下,请修改如下。
发件人:
raw = base64.urlsafe_b64encode(message_bytes)
return raw.decode()
收件人:
raw = base64.urlsafe_b64encode(message_bytes).decode('utf-8')
return {'raw': raw}
经过以上修改,当你的脚本运行作为第2个运行时,读取已经创建好的token.pickle
时,会出现错误。我认为这个错误在你的标题中。遇到这种情况,请修改如下。
发件人:
with open('token.pickle', 'r') as token:
收件人:
with open('token.pickle', 'rb') as token:
据此,我认为该脚本有效。
对了,如果取码时出现错误,也请修改如下。
发件人:
creds = flow.run_local_server(port=0)
收件人:
creds = flow.run_local_server()
注:
- 关于授权,您可以在the official document的快速入门中看到示例脚本。
如果这不是您问题的方向,我深表歉意。
我认为 Gmail API 和 Python3 存在问题。 文档中的原始代码在 Python2 中,但出于多种原因,包括我的应用程序已经在使用 Python3,我将代码传递给 python3。
所以......在解决了几个问题之后,包括一个 400 请求错误,(这显然是我提供给 google 的授权没有正确完成)我正面临(我希望)显然我正在尝试读取文件的最后一个问题
即使只是 token.read()
也会产生同样的问题。
一旦您授权 google 访问您的电子邮件帐户并且该应用程序可以自动发送电子邮件,token.pickle 文件就会自动生成。
我知道 credentials.json 文件是正确的,因为这是告诉 google 你是谁的关键,它总是正确读取我的凭据,重定向我以授权我的应用程序。
这是发送电子邮件的应用程序,我认为它非常简单,我按照文档查看了 other issues like this one 终于做到了这一点:
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.errors import HttpError
# from httplib2 import Http
# from oauth2client import client, tools, file
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
from apiclient import errors
SCOPES = 'https://mail.google.com/'
def SendMessage(service, user_id, message):
"""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.
"""
try:
message = (service.users().messages().send(userId=user_id, body=message)
.execute())
print(f'Message Id: {message["id"]}')
return message
except errors.HttpError as error:
print(f'An error occurred: {error}')
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 base64url encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
message_bytes = message.as_string().encode('utf-8')
# return { 'raw': base64.urlsafe_b64encode(message.as_string()) }
# return { 'raw': base64.urlsafe_b64encode(message_bytes) }
raw = base64.urlsafe_b64encode(message_bytes)
return raw.decode()
def main():
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'r') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('gmail', 'v1', credentials=creds)
# Create
message = CreateMessage('my-email@gmail.com', 'destination@gmail.com', 'Testing Gmail API', 'Hi GMAIL API')
# Send
SendMessage(service, "me", message)
if __name__ == '__main__':
main()
如果有人已经解决了这个问题,我真的不知道该怎么办。
谢谢!
在您的脚本中,当未创建 token.pickle
时,Gmail API 可以通过在第一次授权时创建 token.pickle
来使用。但是在message = (service.users().messages().send(userId=user_id, body=message).execute())
处出现了'raw' RFC822 payload message string or uploading message via /upload/* URL required
的错误。所以在这种情况下,请修改如下。
发件人:
raw = base64.urlsafe_b64encode(message_bytes)
return raw.decode()
收件人:
raw = base64.urlsafe_b64encode(message_bytes).decode('utf-8')
return {'raw': raw}
经过以上修改,当你的脚本运行作为第2个运行时,读取已经创建好的token.pickle
时,会出现错误。我认为这个错误在你的标题中。遇到这种情况,请修改如下。
发件人:
with open('token.pickle', 'r') as token:
收件人:
with open('token.pickle', 'rb') as token:
据此,我认为该脚本有效。
对了,如果取码时出现错误,也请修改如下。
发件人:
creds = flow.run_local_server(port=0)
收件人:
creds = flow.run_local_server()
注:
- 关于授权,您可以在the official document的快速入门中看到示例脚本。
如果这不是您问题的方向,我深表歉意。