首页 > 解决方案 > 使用 Google API 在 Python 脚本中发送电子邮件

问题描述

我想使用 Google API 发送电子邮件。我从

https://developers.google.com/gmail/api/quickstart/

https://developers.google.com/gmail/api/guides/sending

但是,我只能阅读电子邮件的标签,但不能发送电子邮件。这是它返回的错误:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Login Required",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Login Required"
 }
}

这是我的代码

from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from google.auth.transport.requests import Request

SCOPES = [
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/userinfo.profile',
    # Add other requested scopes.
    'https://www.googleapis.com/auth/gmail.send'
]

def create_message(sender, to, subject, message_text):
    message = MIMEText(message_text)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    return {'raw': message.as_string()}

def send_message(service, user_id, message):
    """
    Sends an email message.
    Arguments:
    service: an authorized Gmail API service instance.
    user_id: User's email address. To indicate the authenticated user, the special value "me" can be used.
    message: Message to be sent.
    """
    message = (service.users().messages().send(userId=user_id, body=message)
               .execute())
    print('Message Id: %s' % message['id'])
    return message

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', 'rb') 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)
    # Call the Gmail API
    user_id = "me"
    results = service.users().labels().list(userId=user_id).execute()
    labels = results.get('labels', [])
    print("labels: ", labels)
    message = create_message(user_id, "foo@gmail.com", "credit", "API test only!")
    message = send_message(service, user_id, message)
    print(message)

if __name__ == '__main__':
    main()

标签: pythongoogle-apigoogle-oauthgmail-api

解决方案


在 SCOPES (l9) 中添加该行以获得发送授权后,您是否删除了“token.pickle”文件?您必须重做授权程序,否则您仍然只有读取权限。


推荐阅读