python gmail API: 无法发送简单邮件

python gmail API: unable to send a simple mail

我稍微修改了 API (https://github.com/googleworkspace/python-samples/blob/master/gmail/snippet/send%20mail/send_message.py) 中的示例,只是为了测试 python 中简单测试电子邮件的发送。我收到以下错误,但我不知道如何更正它。

"'raw' RFC822 payload message string or uploading message via /upload/* URL required". Details: "[{'message': "'raw' RFC822 payload message string or uploading message via /upload/* URL required", 'domain': 'global', 'reason': 'invalidArgument'}]"

Python 3.9.7

感谢您的宝贵时间。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START gmail_quickstart]
from __future__ import print_function

import os.path

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

import base64
import os

from email.mime.text import MIMEText

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://mail.google.com/']


def gmail_send_message(creds):
    """Create and send an email message
    Print the returned  message id
    Returns: Message object, including message id
    Load pre-authorized user credentials from the environment.
    TODO(developer) - See https://developers.google.com/identity
    for guides on implementing OAuth2 for the application.
    """
    #creds, _ = google.auth.default()

    try:
        service = build('gmail', 'v1', credentials=creds)
        message = MIMEText('This is automated draft mail')
        message['To'] = 'recipient@gmail.com'
        message['From'] = 'sender@gmail.com'
        message['Subject'] = 'Automated draft'
        # encoded message
        encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode('utf8')

        print(encoded_message)
        create_message = {
            'message': {

                'raw': encoded_message
            }
        }
        # pylint: disable=E1101
        send_message = (service.users().messages().send
                        (userId="me", body=create_message).execute())
        print(F'Message Id: {send_message["id"]}')
    except HttpError as error:
        print(F'An error occurred: {error}')
        send_message = None
    return send_message


def main():
    """Shows basic usage of the Gmail API.
    """
    creds = None
    # The file token.json 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.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # 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(
                'key.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    gmail_send_message(creds)


if __name__ == '__main__':
    main()
# [END gmail_quickstart]

尝试改变这个:

create_message = {'message': {'raw': encoded_message}}

对此:

create_message = {'raw': encoded_message}

其余的对我来说似乎是正确的。

正如您在文档中看到的,您不需要 message 键:

The entire email message in an RFC 2822 formatted and base64url encoded string. Returned in messages.get and drafts.get responses when the format=RAW parameter is supplied.