cambridgecircus
cambridgecircus

Reputation: 145

Specifying "From" field using Gmail API with service account with domain-wide authority (Python)

I have a webapp sending mail through the Gmail API using a service account that is impersonating a user account ([email protected]) through domain-wide access.

The emails are sending fine, but I want my emails to have a custom "From" field (say, "Custom From" <[email protected]>).

However, spoofing the "From" tag in my MIMEText message doesn't change that the emails are sent with [email protected] in the "From" field. I suspect when the service account impersonates the user account, it overrides the MIME message fields? My question is if we can change this behaviour. Perhaps there are some anti-spoofing mechanisms built into the API?

Below is the relevant code.

import base64
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from googleapiclient.discovery import build
from google.oauth2 import service_account

creds = service_account.Credentials.from_service_account_file(
            'path/to/service/account/file.json', 
            scopes=['https://www.googleapis.com/auth/gmail.send'])
creds = creds.with_subject('[email protected]')  ## The impersonation

service = build('gmail', 'v1', credentials=creds)

msg = MIMEMultipart('alternative')
msg.attach(MIMEText("<h1>Test message</h1>", 'html'))
msg.attach(MIMEText("Test message", 'plain'))
msg['Subject'] = 'Test subject'
msg['Bcc'] = '[email protected]'

msg['reply-to'] = '[email protected]'  ## This is fine
msg['From'] = '"Custom From" <[email protected]>'  ## The custom "From" field that gets overridden

create_message = {'raw': base64.urlsafe_b64encode(msg.as_bytes()).decode()}
service.users().messages().send(userId="me", body=create_message).execute()

and the received email:

...
MIME-Version: 1.0
reply-to: [email protected]
From: [email protected]
...

Upvotes: 0

Views: 87

Answers (1)

Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 117254

Messages are sent from the user who is authenticated.

The only way to change the from to that would be to delegate to that user

creds = creds.with_subject('[email protected]')  

Upvotes: 1

Related Questions