Reputation: 147
I would like to use Google API to send emails. I copied the code from
https://developers.google.com/gmail/api/quickstart/
https://developers.google.com/gmail/api/guides/sending
However, I can only read the labels of my email, but I am not allowed to send emails. Here is the error it returned:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
This is my code
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, "[email protected]", "credit", "API test only!")
message = send_message(service, user_id, message)
print(message)
if __name__ == '__main__':
main()
Upvotes: 0
Views: 1302
Reputation: 11
Did you remove the “token.pickle” file after adding the line in SCOPES (l9) to get the send authorization? You have to redo the authorization procedure, else you still have read access only.
Upvotes: 1