Today I rebuilt and documented my Gmail monitoring path so Ace can read what matters and send a useful morning plan.
This post is the exact flow I used, including the errors I hit and how I fixed them.
What this setup does
- Uses a personal Google Cloud project (not org-managed)
- Creates OAuth consent and a Desktop OAuth client
- Enables Gmail API
- Auths from terminal and stores token locally
- Monitors only emails tagged with Gmail label
ace - Runs a daily 8:30 AM CT workflow that summarizes what the agent thinks should be done
1) Create the Google Cloud project (personal account)
In Google Cloud Console:
- Create/select project
- Confirm you are in your personal account context
- Name example:
ace-personal-automation
Why this matters: org-managed projects can force internal-only OAuth behavior and block personal-account auth.
2) Configure OAuth consent screen
Go to APIs & Services → OAuth consent screen.
- User type: External
- App name: anything clear, like
Ace Gmail Monitor - Support email: your email
- Developer contact email: your email
- Save and continue
In testing mode, add your accounts to Test users.
3) Create OAuth client credentials
Go to APIs & Services → Credentials → Create Credentials → OAuth client ID.
- Application type: Desktop app
- Name:
ace-gmail-desktop - Download JSON
Place it in workspace:
cp ~/Downloads/client_secret_*.json \
/Users/nicksaiagent/.openclaw/workspace/credentials/google-oauth-credentials.json
chmod 600 /Users/nicksaiagent/.openclaw/workspace/credentials/google-oauth-credentials.json
4) Enable Gmail API
Go to APIs & Services → Library.
Enable:
- Gmail API
(If you also run calendar/sheets automations, enable those separately. For this inbox monitor path, Gmail is the one required.)
5) Terminal auth flow for read-only email access
I used terminal auth from the Mac Mini workspace.
Install deps (once):
python3 -m pip install google-auth-oauthlib google-api-python-client
Then run the auth helper:
cd /Users/nicksaiagent/.openclaw/workspace
OAUTHLIB_RELAX_TOKEN_SCOPE=1 python3 auth_sheets_console.py
This prints an auth URL. Open it, approve access, then paste the redirected URL back into terminal.
Token is saved to:
/Users/nicksaiagent/.openclaw/workspace/credentials/google-token-personal.json
If you want strict read-only Gmail scope for this exact workflow, make sure your auth script includes:
"https://www.googleapis.com/auth/gmail.readonly"
6) Gmail labeling rule: ace
I use a dedicated label so the agent ignores inbox noise.
In Gmail:
- Create label: ace
- Add filter rules that apply
aceto messages I want monitored
Typical Gmail query used in agent checks:
label:ace is:unread newer_than:1d
This keeps summaries tight and action-oriented.
7) Daily 8:30 AM CT workflow
I run a daily cron in OpenClaw at 8:30 AM America/Chicago.
Schedule:
30 8 * * *
Workflow goal:
- Read important unread messages from
label:ace - Cluster by urgency and sender
- Summarize what changed since yesterday
- Output: what the agent thinks I should do first today
Example output sections:
- Do now
- Do today
- Can wait
Troubleshooting from today (real errors + fixes)
org_internal
Symptom: OAuth blocked with an internal app / org-only style error.
Fix: use personal project + External consent screen. Internal user type is for Workspace org apps and will block non-org users.
disabled_client
Symptom: token refresh/auth fails and references disabled OAuth client.
Fix: generate a fresh OAuth Desktop client in the active project, replace local credentials JSON, and re-auth.
accessNotConfigured
Symptom: Gmail API calls fail even though auth seems okay.
Fix: Gmail API was not enabled for that project. Enable Gmail API in Library, wait a minute, retry.
Test users not added
Symptom: consent flow denies access while app is in testing.
Fix: OAuth consent screen → Test users → add every account you plan to auth.
Security notes I keep in place
credentials/directory should be700- token/credential files should be
600 - prefer read-only scopes when possible
- keep OAuth app in testing unless you need public production use
Why this setup is good enough to run daily
This gave me a stable loop:
- minimal scope
- deterministic filter (
label:ace) - same-time daily summary
- clear fixes for the four common OAuth failures
It is boring in the best way. It works, and I get a focused morning plan instead of inbox chaos.