I would like to create a python script that will be able to send e-mail after getting triggered by something. (I have a Google Workspace)
Here is my python script:
import base64
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
scope_gmail_api = ['https://www.googleapis.com/auth/gmail.send']
authentication_credential = "credential.json"
def create_email(subject, message_text, to, from_email):
message = f"From: {from_email}\nSubject: {subject}\nTo: {to}\n\n{message_text}"
return {'raw': base64.urlsafe_b64encode(message.encode("utf-8")).decode("utf-8")}
def create_email_service():
creds = None
creds = ServiceAccountCredentials.from_json_keyfile_name(
authentication_credential, scope_gmail_api)
service = build('gmail', 'v1', credentials=creds)
return service
gmail_service = create_email_service()
def main():
subject = "Test Subject"
message_text = "Test"
to_email = "destination@domain.com"
from_email = "source@domain.com"
message = create_email(subject, message_text, to_email, from_email)
try:
sent_message = gmail_service.users().messages().send(userId='me', body=message).execute()
print(f'E-mail sent: Message ID: {sent_message["id"]}')
except Exception as e:
print(f'Error: {str(e)}')
if __name__ == '__main__':
main()
Here is the error message:
Error: <HttpError 400 when requesting https://gmail.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Precondition check failed.". Details: "[{'message': 'Precondition check failed.', 'domain': 'global', 'reason': 'failedPrecondition'}]">
I've read THIS StackOverflow comment but with the delegated_credentials = creds.with_subject('admin@mydomain.com')
the error message is:
AttributeError: 'ServiceAccountCredentials' object has no attribute 'with_subject'
What did I miss?
UPDATE: I also tried with:
credentials = service_account.Credentials.from_service_account_file(
authentication_credential, scopes=scope_gmail_api)
delegated_credentials = credentials.with_subject('admin@mydomain.com')
ERROR still:
ERROR: <HttpError 400 when requesting https://gmail.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Precondition check failed.". Details: "[{'message': 'Precondition check failed.', 'domain': 'global', 'reason': 'failedPrecondition'}]">
you could try this
import base64
from googleapiclient.discovery import build
from google.auth.transport.requests import Request
from google.oauth2 import service_account
scope_gmail_api = ['https://www.googleapis.com/auth/gmail.send']
authentication_credential = "credential.json"
def create_email(subject, message_text, to, from_email):
message = f"From: {from_email}\nSubject: {subject}\nTo: {to}\n\n{message_text}"
return {'raw': base64.urlsafe_b64encode(message.encode("utf-8")).decode("utf-8")}
def create_email_service():
credentials = service_account.Credentials.from_service_account_file(
authentication_credential, scopes=scope_gmail_api)
delegated_credentials = credentials.with_subject('admin@yourdomain.com')
# Check if the token is expired and refresh if necessary
if delegated_credentials.valid is None or not delegated_credentials.valid:
delegated_credentials.refresh(Request())
service = build('gmail', 'v1', credentials=delegated_credentials)
return service
gmail_service = create_email_service()
def main():
subject = "Test Subject"
message_text = "Test"
to_email = "destination@domain.com"
from_email = "source@domain.com"
message = create_email(subject, message_text, to_email, from_email)
try:
sent_message = gmail_service.users().messages().send(userId='me', body=message).execute()
print(f'E-mail sent: Message ID: {sent_message["id"]}')
except Exception as e:
print(f'Error: {str(e)}')
if __name__ == '__main__':
main()