I modified very slightly the example from the API (https://github.com/googleworkspace/python-samples/blob/master/gmail/snippet/send%20mail/send_message.py), just to test the sending of a simple test email in python. I get the following error and I do not know how to correct this.
"'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
Thank you for your time.
yann
#!/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]
Try changing this:
create_message = {'message': {'raw': encoded_message}}
to this:
create_message = {'raw': encoded_message}
The rest seems right to me.
As you can see in the documentation, you don't need the message key:
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.