I’ve been using Gmail with my company domain through Google SMTP for manual email sending for over a year without problems. Now I’m trying to automate this process using the Gmail API.
I can successfully create drafts, read labels, and send messages through the API. The emails show up as sent in my Gmail interface, but recipients never receive them (not even in spam).
I think the issue might be one of these:
- Emails are flagged as suspicious and filtered out
- The API only marks emails as sent without actually delivering them
- My app needs to be published instead of running in test mode
When I compare email headers from manual sends vs API sends, I see this suspicious header:
Received: from 814388093175 named unknown by gmailapi.google.com with HTTPREST; Thu, 27 Jun 2024 01:16:36 -0400
This “unknown” source probably causes delivery servers to reject the emails. How can I fix this?
Here’s my code:
import base64
from email.message import EmailMessage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import os
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
def build_email_content(recipient_name, target_email, sender_email):
email_obj = EmailMessage()
email_obj['Subject'] = f'Hello {recipient_name}'
email_obj['From'] = sender_email
email_obj['To'] = target_email
email_obj.set_content('Welcome message')
with open('template.html', 'r') as template_file:
html_content = template_file.read()
return {"raw": base64.urlsafe_b64encode(email_obj.as_bytes()).decode()}
def execute_send():
credentials = None
PERMISSIONS = ["https://www.googleapis.com/auth/gmail.modify", "https://www.googleapis.com/auth/gmail.compose", "https://www.googleapis.com/auth/gmail.readonly", "https://mail.google.com/"]
if os.path.exists("auth_token.json"):
credentials = Credentials.from_authorized_user_file("auth_token.json", PERMISSIONS)
if not credentials or not credentials.valid:
if credentials and credentials.expired and credentials.refresh_token:
credentials.refresh(Request())
else:
auth_flow = InstalledAppFlow.from_client_secrets_file("client_secrets.json", PERMISSIONS)
credentials = auth_flow.run_local_server(port=0)
with open("auth_token.json", "w") as token_file:
token_file.write(credentials.to_json())
try:
gmail_service = build("gmail", "v1", credentials=credentials)
email_message = build_email_content('John Smith', '[email protected]', '[email protected]')
result = gmail_service.users().messages().send(userId="me", body=email_message).execute()
print(f'Sent message ID: {result["id"]}')
except HttpError as err:
print(f"Error occurred: {err}")
if __name__ == "__main__":
execute_send()