How Macro's Email Service Integrates with Gmail Using OAuth and the Google API
Macro's email service connects to Gmail through an OAuth 2.0 identity provider that requests specific Google API scopes, utilizes refresh tokens for sustained access, and processes real-time mailbox updates via a Pub/Sub webhook forwarder.
The Macro repository implements a comprehensive Gmail integration that synchronizes user emails, manages contacts, and handles calendar data using Google's standard OAuth 2.0 protocol. This architecture combines Rust-based identity configuration, a dedicated REST API client, and containerized webhook forwarding to maintain secure, low-latency synchronization with Google Workspace accounts.
OAuth 2.0 Configuration and Gmail API Scopes
The integration begins in tooling/xtask/crates/xtask_local/src/local/kickstart.rs, where the Google-Gmail identity provider is initialized using the oauth2_base function. This configuration defines the OAuth 2.0 scopes required for mailbox modification, contact access, and calendar synchronization.
Macro requests the following Gmail-specific scopes during the authorization flow:
https://www.googleapis.com/auth/gmail.modify– Read, compose, send, and permanently delete emailshttps://www.googleapis.com/auth/contacts.readonly– Access the user's contactshttps://www.googleapis.com/auth/contacts.other.readonly– Access the user's "Other contacts"https://www.googleapis.com/auth/gmail.settings.basic– Manage basic mail settingshttps://www.googleapis.com/auth/calendar– Access calendar data
// tooling/xtask/crates/xtask_local/src/local/kickstart.rs
let oauth2 = oauth2_base(
"openid profile email \
https://www.googleapis.com/auth/gmail.modify \
https://www.googleapis.com/auth/contacts.readonly \
https://www.googleapis.com/auth/contacts.other.readonly \
https://www.googleapis.com/auth/gmail.settings.basic \
https://www.googleapis.com/auth/calendar",
);
Local development environments inject credentials through specific environment variables read by the xtask_local tooling:
GOOGLE_CLIENT_ID– The OAuth client identifierGOOGLE_CLIENT_SECRET_KEY– The confidential client secretGMAIL_TEST_ACCOUNT_TOKENS– A mapping of refresh tokens for test accounts
Gmail API Client and Token Management
The HTTP communication layer resides in tooling/seed_cli/src/entity/gmail/mod.rs. This Gmail entity constructs requests against the base URL https://gmail.googleapis.com/gmail/v1/users/me and handles bearer token authentication using access tokens obtained from the stored refresh tokens.
// tooling/seed_cli/src/entity/gmail/mod.rs
let url = format!("{}/gmail/v1/users/me/messages", GMAIL_BASE);
let resp = client
.get(&url)
.bearer_auth(access_token) // Token derived from refresh token flow
.send()
.await?
.json::<serde_json::Value>()
.await?;
The client implements retry logic and quota-throttling to handle Gmail API rate limits. All mailbox operations—including listing messages, sending mail, applying labels, and modifying thread states—route through this centralized module rather than using direct HTTP calls elsewhere in the codebase.
Real-Time Synchronization with Pub/Sub and Webhooks
To eliminate polling overhead, Macro leverages the Gmail watch API combined with Google Cloud Pub/Sub. When a user enables syncing, the service registers a watch that pushes change notifications to a configured Pub/Sub topic. The tooling/xtask/crates/xtask_local/src/local/gen_compose.rs file defines a gmail-forwarder sidecar container that subscribes to this topic and forwards validated events to the internal email service.
// tooling/xtask/crates/xtask_local/src/local/gen_compose.rs
services.insert(
"gmail_forwarder".to_string(),
Service {
image: "gmail-forwarder:latest".into(),
env: hashmap! {
"GMAIL_GCP_QUEUE".into() => "gmail-gcp-queue-local".into(),
"TARGET_WEBHOOK".into() => "http://email-service:8080/gmail/webhook".into(),
},
// ... additional configuration
},
);
Upon receiving a notification at http://email-service:8080/gmail/webhook, the email service validates the payload and emits internal domain events declared in crates/email/src/domain/events.rs to trigger downstream processing pipelines.
Secure Credential Management in Production
Production deployments use Doppler for secret management rather than flat environment files. The OAuth client secrets and service account keys are accessed through the macro_env_var crate, which provides type-safe secret retrieval that avoids std::env directly. The gmail-forwarder sidecar authenticates with Pub/Sub using the GMAIL_FORWARDER_SA_KEY environment variable, injected via the local environment configuration in tooling/xtask/crates/xtask_local/src/local/local_env.rs.
Summary
- OAuth Configuration:
kickstart.rsdefines the Google identity provider with comprehensive Gmail, Contacts, and Calendar scopes using theoauth2_basefunction and environment variables likeGOOGLE_CLIENT_ID. - API Client: The
seed_cligmailentity manages all REST communication withhttps://gmail.googleapis.com/gmail/v1/users/me, handling bearer token injection and retry logic. - Real-Time Delivery: A
gmail-forwardersidecar container consumes Pub/Sub messages and pushes Gmail watch notifications to the internal webhook endpoint at/gmail/webhook. - Security Architecture: Credentials are stored in Doppler for production and accessed via the
macro_env_varcrate, with local development supported throughxtask_localenvironment injection.
Frequently Asked Questions
What specific OAuth scopes does Macro request for Gmail access?
Macro requests the gmail.modify scope for full mailbox read/write access, contacts.readonly and contacts.other.readonly for contact synchronization, gmail.settings.basic for mail settings, and calendar for calendar integration. These are declared in the oauth2_base function within tooling/xtask/crates/xtask_local/src/local/kickstart.rs.
How does Macro receive email notifications without polling the Gmail API?
The service calls the Gmail watch API to register for push notifications, which Google delivers to a Cloud Pub/Sub topic. The gmail-forwarder sidecar defined in gen_compose.rs subscribes to this topic and forwards events to the internal webhook at http://email-service:8080/gmail/webhook, enabling near real-time synchronization without API polling.
Where are the Gmail OAuth credentials stored in Macro's architecture?
Production environments store credentials in Doppler, accessed at runtime through the macro_env_var crate. For local development, the xtask_local tooling reads GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET_KEY, and GMAIL_TEST_ACCOUNT_TOKENS from the host environment and injects them into containers via tooling/xtask/crates/xtask_local/src/local/local_env.rs.
Which component executes HTTP requests to the Gmail REST API?
The seed_cli gmail entity in tooling/seed_cli/src/entity/gmail/mod.rs executes all Gmail API calls. It builds requests against https://gmail.googleapis.com/gmail/v1/users/me, attaches bearer tokens obtained from refresh tokens, and manages response parsing and error handling.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →