To connect Gmail to OpenClaw, enable the Gmail API in Google Cloud Console, create OAuth 2.0 credentials, and configure your client ID, client secret, and refresh token in OpenClaw's config. OpenClaw then uses the Gmail API to read, send, label, and triage emails from your Gmail account. This is a direct API integration requiring a one-time OAuth authorization flow. Once configured, OpenClaw can automate email workflows, draft replies, and monitor your inbox without manual access.
Why Connect Gmail to OpenClaw?
Email remains the universal communication layer for business — invoices, contracts, customer inquiries, notifications, and correspondence all flow through inboxes. Connecting Gmail to OpenClaw means your AI agent can read your email, extract information, draft intelligent replies, categorize messages, and trigger workflows based on email content — all without manual copy-pasting between your inbox and other tools.
The Gmail API provides comprehensive access to your Gmail account. You can read specific messages or search your entire inbox using Gmail's search syntax (the same syntax as the web interface). You can send emails with attachments, apply or remove labels, mark messages as read or starred, move messages to trash, and create drafts. For automation, you can set up OpenClaw to poll for new messages in specific labels, respond to emails matching certain criteria, and forward summaries to other channels like Telegram or Discord.
This integration is more involved to set up than Telegram or Discord because Google requires OAuth 2.0 authentication — you need to create a Cloud project, enable the API, and complete an authorization flow. However, this one-time setup is straightforward and the resulting refresh token is long-lived, so you complete the authorization steps once and the integration runs indefinitely. This guide walks through each step clearly.
Integration method
Gmail uses Google's OAuth 2.0 authorization framework for API access. You create a project in Google Cloud Console, enable the Gmail API, and generate OAuth 2.0 credentials (client ID and client secret). After a one-time authorization flow that produces a refresh token, OpenClaw can call Gmail API endpoints on your behalf to read messages, send emails, manage labels, and search your inbox. The integration stores your credentials in OpenClaw's config and handles token refresh automatically.
Prerequisites
- A Gmail account that you want to connect to OpenClaw
- A Google Cloud account (free tier is sufficient — no billing required for Gmail API)
- OpenClaw installed and running on your machine
- A web browser to complete the OAuth authorization flow (needed once during setup)
- Basic familiarity with API credentials and config files
Step-by-step guide
Enable the Gmail API and Create OAuth 2.0 Credentials
Enable the Gmail API and Create OAuth 2.0 Credentials
Go to console.cloud.google.com and sign in with your Google account. Create a new project (or use an existing one) — click the project dropdown at the top, then 'New Project', give it a name like 'OpenClaw Gmail Integration', and click 'Create'. With your project selected, go to 'APIs & Services' > 'Library'. Search for 'Gmail API' and click on it. Click 'Enable' to activate it for your project. Next, create OAuth credentials. Go to 'APIs & Services' > 'Credentials' > 'Create Credentials' > 'OAuth client ID'. If prompted to configure the consent screen first, do that now: - User Type: External (unless you have a Google Workspace org) - App name: 'OpenClaw Gmail' - User support email: your email - Developer contact: your email - Scopes: add `https://www.googleapis.com/auth/gmail.modify` (covers read + send + label management) - Test users: add your Gmail address - Save and continue back to credential creation For 'Application type', select 'Desktop app' (this is important — it allows the local OAuth flow). Name it 'OpenClaw'. Click 'Create'. Google will show you your Client ID and Client Secret — download the JSON file and store it safely. These are your OAuth credentials.
1# Downloaded credentials JSON format (credentials.json):2{3 "installed": {4 "client_id": "123456789-abc.apps.googleusercontent.com",5 "project_id": "openclaw-gmail",6 "auth_uri": "https://accounts.google.com/o/oauth2/auth",7 "token_uri": "https://oauth2.googleapis.com/token",8 "client_secret": "GOCSPX-XXXXXXXXXXXXXXXXXXXX",9 "redirect_uris": ["http://localhost"]10 }11}Pro tip: Download the OAuth credentials JSON file when Google offers it — this saves you from navigating back to find your client secret. Store it in `~/.openclaw/` alongside your config file, outside version control.
Expected result: The Gmail API is enabled in your Google Cloud project and you have your OAuth 2.0 client ID and client secret from the downloaded credentials JSON.
Complete the OAuth Authorization Flow and Get a Refresh Token
Complete the OAuth Authorization Flow and Get a Refresh Token
Google's OAuth 2.0 requires a one-time authorization step where you sign in to your Google account and grant permission to the application. This produces an access token (short-lived) and a refresh token (long-lived) — OpenClaw uses the refresh token to get new access tokens automatically. The authorization URL follows a specific pattern using your client ID. Open the URL in a browser while signed into the Gmail account you want to connect. Google will show a consent screen listing the permissions you are granting — for `gmail.modify` scope, this includes read and write access to your Gmail. Click 'Allow'. After authorization, Google redirects to a localhost URL with an authorization `code` parameter. Copy that code and exchange it for tokens using the token exchange endpoint. The response includes both `access_token` and `refresh_token`. Copy the `refresh_token` — this is what goes into OpenClaw's config. The access token expires in one hour; the refresh token is permanent unless revoked. Note: if you see 'App is not verified' warning, click 'Advanced' > 'Go to OpenClaw Gmail (unsafe)' — this appears because the OAuth app is in testing mode, which is expected for personal use.
1# Step 1: Build authorization URL and open in browser:2# https://accounts.google.com/o/oauth2/v2/auth?3# client_id=YOUR_CLIENT_ID4# &redirect_uri=http://localhost5# &response_type=code6# &scope=https://www.googleapis.com/auth/gmail.modify7# &access_type=offline8# &prompt=consent910# Step 2: After browser redirect, copy 'code' from the URL:11# http://localhost/?code=4/0AYYYYYY...&scope=...1213# Step 3: Exchange code for tokens:14curl -X POST https://oauth2.googleapis.com/token \15 -H "Content-Type: application/x-www-form-urlencoded" \16 -d "code=YOUR_AUTH_CODE\17 &client_id=YOUR_CLIENT_ID\18 &client_secret=YOUR_CLIENT_SECRET\19 &redirect_uri=http://localhost\20 &grant_type=authorization_code"2122# Response includes:23# {"access_token": "ya29.xxx", "refresh_token": "1//xxx", "expires_in": 3600, ...}24# SAVE the refresh_token — it is only returned on the first authorizationPro tip: The refresh_token only appears on the first authorization (because of `prompt=consent`). If you lose it, go to myaccount.google.com/permissions, revoke access to your app, then repeat the authorization flow to get a new refresh token.
Expected result: You have completed the browser-based authorization and copied your refresh_token from the token exchange response.
Configure Gmail Credentials in OpenClaw
Configure Gmail Credentials in OpenClaw
Open `~/.openclaw/config.yaml` and add the Gmail integration block under `integrations`. You need four values from the previous steps: `client_id` and `client_secret` (from your OAuth credentials JSON), `refresh_token` (from the token exchange), and `user_email` (your Gmail address — used for identifying the account and as the sender in outgoing emails). The `scopes` field must match exactly what you authorized in the OAuth flow. If you authorized `gmail.modify`, list that scope. If you need more restricted access (read-only monitoring), use `gmail.readonly` instead — but you would need to complete a new authorization flow with that scope. The optional `poll_interval` controls how frequently OpenClaw checks for new messages matching your configured filters. Setting `max_results` limits how many messages are fetched per poll to prevent processing overload on inboxes with high volume. After saving, run `clawhub reload`. OpenClaw will immediately attempt to exchange your refresh token for an access token and verify the Gmail API connection.
1# ~/.openclaw/config.yaml2integrations:3 gmail:4 client_id: "123456789-abc.apps.googleusercontent.com"5 client_secret: "GOCSPX-XXXXXXXXXXXXXXXXXXXX"6 refresh_token: "1//0eXXXXXXXXXXXXXXXXXXXXXX"7 user_email: "you@gmail.com"8 scopes:9 - https://www.googleapis.com/auth/gmail.modify10 poll_interval: 60 # Seconds between inbox checks11 max_results: 10 # Max messages fetched per poll12 query: "is:unread in:inbox" # Gmail search query to filter messages13 label_filter: "" # Optional: restrict to specific label IDPro tip: The `query` field supports any Gmail search syntax you can use in the web interface — `from:boss@company.com`, `subject:invoice`, `has:attachment`, `newer_than:1d`. Combine multiple terms: `is:unread in:inbox from:support@`. This is the most powerful way to focus OpenClaw on the emails that matter.
Expected result: `clawhub reload` completes without errors and OpenClaw logs show a successful Gmail API connection with your account email confirmed.
Test Reading and Sending Emails
Test Reading and Sending Emails
Verify the integration by calling Gmail API endpoints directly to list recent messages and send a test email. This confirms that your OAuth credentials are working and that OpenClaw has the correct permissions. To list messages, call the `users.messages.list` endpoint with your Gmail search query. The response returns message IDs — to get the full content, call `users.messages.get` with a specific message ID. Messages are returned in a format where the body is base64url-encoded — decode it to read the content. To send an email, construct a MIME message, base64url-encode it, and POST it to the `users.messages.send` endpoint. The examples below show the complete flow for both operations. Send a test email to yourself first to confirm the send pipeline works before connecting it to automated workflows. Check that the email arrives in Gmail with the correct sender address, subject, and body.
1# Get access token from refresh token (needed for direct API testing):2curl -X POST https://oauth2.googleapis.com/token \3 -H "Content-Type: application/x-www-form-urlencoded" \4 -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&refresh_token=YOUR_REFRESH_TOKEN&grant_type=refresh_token"5# Returns: {"access_token": "ya29.xxx", "expires_in": 3600}67# List recent unread emails:8curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \9 "https://gmail.googleapis.com/gmail/v1/users/me/messages?q=is:unread+in:inbox&maxResults=5"1011# Send a test email (body is base64url-encoded MIME message):12# First, create the MIME message:13# From: you@gmail.com14# To: you@gmail.com15# Subject: OpenClaw Gmail Test16# 17# Test message from OpenClaw Gmail integration.1819# Encode and send:20MIME_MESSAGE=$(echo -e "From: you@gmail.com\nTo: you@gmail.com\nSubject: OpenClaw Gmail Test\n\nTest message from OpenClaw." | base64 -w 0 | tr '+/' '-_')21curl -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" \22 -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \23 -H "Content-Type: application/json" \24 -d "{\"raw\": \"$MIME_MESSAGE\"}"Pro tip: Gmail API uses base64url encoding (not standard base64) for message bodies. The difference: `+` becomes `-` and `/` becomes `_`. Standard base64 encode commands need `tr '+/' '-_'` appended to produce valid base64url output.
Expected result: The message list API returns recent email IDs, and the test email appears in your Gmail inbox with the correct sender and subject line.
Build an Email Automation Workflow
Build an Email Automation Workflow
With read and send confirmed, configure OpenClaw to act on incoming emails automatically. The common automation pattern is: poll for new emails matching a query, extract structured information (sender, subject, body snippet), process with AI, and take action (reply, label, notify via Telegram, log to Notion). Configure OpenClaw workflows with Gmail as the trigger source. The workflow receives the email event (with subject, from, body, message ID, thread ID), runs AI processing on the content, and calls back to Gmail API or other integrations with the result. For reply automation, use the `threadId` from the incoming message to create a reply in the same thread — Gmail groups replies by thread ID, so using it keeps conversations organized. RapidDev recommends saving AI-generated replies as drafts first (using the `users.drafts.create` endpoint) rather than sending automatically, at least during initial testing — it gives you a review step before responses go out to real contacts. The config below shows a simple email-to-Telegram notification workflow as a starting pattern.
1# ~/.openclaw/config.yaml — email notification workflow2workflows:3 gmail-support-alert:4 trigger:5 integration: gmail6 event: new_message7 conditions:8 - field: subject9 contains_any: ["urgent", "help", "issue", "broken"]10 actions:11 - type: ai-response12 prompt: "Summarize this email in 2 sentences: Subject: {{trigger.subject}} | From: {{trigger.from}} | Body: {{trigger.snippet}}"13 - type: integration-call14 integration: telegram15 endpoint: /sendMessage16 method: POST17 body:18 chat_id: YOUR_TELEGRAM_CHAT_ID19 text: "<b>New urgent email</b>\nFrom: {{trigger.from}}\nSubject: {{trigger.subject}}\n\n{{ai-response.output}}"20 parse_mode: HTML21 - type: integration-call22 integration: gmail23 endpoint: /gmail/v1/users/me/messages/{{trigger.message_id}}/modify24 method: POST25 body:26 addLabelIds: ["Label_urgent_id"]27 removeLabelIds: ["UNREAD"]Pro tip: To find Gmail label IDs (needed for the addLabelIds field), call `GET https://gmail.googleapis.com/gmail/v1/users/me/labels` with your access token. System labels use uppercase names (INBOX, UNREAD, STARRED); custom labels have generated IDs like Label_1234567890.
Expected result: OpenClaw detects new emails matching your query, processes them, and triggers your configured downstream actions — notifications, labels, or drafts.
Common use cases
Inbox Triage and Auto-Labeling
Use OpenClaw to monitor your Gmail inbox and automatically apply labels based on content. Route customer inquiries to a 'Support' label, flag invoices for review, and archive newsletter emails — all without manual sorting. OpenClaw reads new emails, analyzes content with AI, and calls the Gmail API to apply labels.
Build an OpenClaw workflow that reads new Gmail messages every 10 minutes and automatically labels them: 'Invoice' if they contain payment amounts, 'Support' if they mention help or issues, and 'Newsletter' if they include unsubscribe links
Copy this prompt to try it in OpenClaw
AI-Drafted Reply Generation
When a customer or contact emails asking a common question, OpenClaw reads the email, generates an appropriate draft reply using AI, and saves it as a Gmail draft — ready for you to review and send with one click. Reduces reply time from hours to minutes.
Configure OpenClaw to create a Gmail draft reply for every email in my 'Support' label that has been unread for more than 2 hours, using a professional and empathetic tone based on the email content
Copy this prompt to try it in OpenClaw
Email-to-Action Pipeline
Trigger OpenClaw workflows based on email content — when a new order confirmation email arrives from a specific sender, extract the order details and post them to a Notion database or send a Telegram notification. Email becomes an event source for cross-tool automation.
Set up OpenClaw to watch for order confirmation emails from orders@shopify.com and extract order number, customer name, and total into a structured format, then send a summary to my Telegram bot
Copy this prompt to try it in OpenClaw
Troubleshooting
invalid_grant error when OpenClaw tries to use the refresh token
Cause: The refresh token has been revoked, expired (this can happen if the Google account's password changed or the app was removed from account permissions), or the wrong refresh token was copied.
Solution: Go to myaccount.google.com/permissions, find your OpenClaw Gmail app and revoke it. Then repeat the authorization flow from Step 2 to generate a new refresh token. Update `refresh_token` in `~/.openclaw/config.yaml` and run `clawhub reload`.
1# Verify refresh token works by exchanging it manually:2curl -X POST https://oauth2.googleapis.com/token \3 -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&refresh_token=YOUR_REFRESH_TOKEN&grant_type=refresh_token"4# Error: {"error": "invalid_grant"} = token is expired or revoked403 Insufficient Permission — API returns 'Request had insufficient authentication scopes'
Cause: The OAuth scope authorized during setup does not include the permission needed for the API call. For example, authorizing `gmail.readonly` but trying to send emails (which requires `gmail.send` or `gmail.modify`).
Solution: Revoke the current authorization at myaccount.google.com/permissions and repeat the authorization flow with the correct scope (`gmail.modify` for full read/write). Update your OpenClaw config's `scopes` field to match and re-run authorization.
1# Required scopes by operation:2# Read messages: gmail.readonly or gmail.modify3# Send emails: gmail.send or gmail.modify4# Manage labels: gmail.modify5# Full access: gmail.modify (recommended for automation)Gmail API quota exceeded — 429 error with 'User Rate Limit Exceeded'
Cause: Gmail API has a default quota of 250 quota units per second per user. Bulk operations like reading many messages or sending many emails can hit this limit.
Solution: Add delays between bulk API calls. Reduce `max_results` in your OpenClaw config to fetch fewer messages per poll. For high-volume sending, Google recommends spreading sends over time rather than batching. You can request a quota increase in Google Cloud Console if needed.
1# Reduce polling frequency and batch size in config:2# poll_interval: 120 # Poll every 2 minutes instead of 60 seconds3# max_results: 5 # Fetch 5 messages at a time instead of 10Email message body is empty or returns garbled text
Cause: Gmail API returns message bodies as base64url-encoded strings. If not decoded correctly, the content appears as random characters or is empty if the decoder expected standard base64.
Solution: Ensure your base64 decoder handles base64url encoding (where `-` maps to `+` and `_` maps to `/`). Gmail messages also have multiple MIME parts — look in `payload.parts` for the `text/plain` or `text/html` part rather than `payload.body.data` directly for multi-part messages.
1# Decode Gmail message body in shell:2# First get message data, then decode:3echo "BASE64URL_ENCODED_BODY" | tr '-_' '+/' | base64 -dBest practices
- Request the minimum OAuth scope needed — use `gmail.readonly` if OpenClaw only needs to read emails, and only upgrade to `gmail.modify` or `gmail.send` when write access is genuinely required.
- Store OAuth credentials (client_id, client_secret, refresh_token) as environment variables and reference them in config with `${VAR_NAME}` rather than hardcoding them — these credentials grant full Gmail access to whoever possesses them.
- Use specific Gmail search queries in your `query` config field rather than monitoring all mail — `is:unread in:inbox from:customers@` is far more efficient than `is:unread` across thousands of emails per day.
- Save AI-generated replies as drafts for human review before enabling fully automated sending — this catch-net prevents off-target responses from reaching contacts during workflow development and fine-tuning.
- Mark processed emails as read after OpenClaw handles them to prevent double-processing on the next poll cycle — use the `users.messages.modify` endpoint to remove the UNREAD label after processing.
- Test with a dedicated Gmail label (create 'openclaw-test') and filter your query to `label:openclaw-test` during development — manually move test emails to that label to trigger workflows without touching your real inbox.
- Monitor your Google Cloud Console quota dashboard during initial deployment to catch unexpected API usage spikes before they cause rate limit errors in production workflows.
- Renew your OAuth app periodically — Google may expire OAuth app authorizations for inactive apps after extended periods, especially in testing mode. Check app status at myaccount.google.com/permissions.
Alternatives
Email Daily Summary is a digest-output integration (sends summaries to an inbox) rather than full bidirectional email access — use it if you only need to send automated summaries rather than read and interact with your inbox.
Outlook provides the same email automation capabilities via Microsoft Graph API — choose it if your team uses Microsoft 365 or Outlook accounts rather than Gmail.
Discord provides real-time channel messaging rather than email — better for team notifications and community communication where asynchronous email delivery is too slow.
Telegram delivers instant push notifications and has no OAuth complexity — use it instead of Gmail when you need real-time alerts sent to a person rather than managing an email inbox.
Frequently asked questions
How do I set up Gmail integration in OpenClaw?
Enable the Gmail API in Google Cloud Console, create an OAuth 2.0 Desktop App credential, complete the browser-based authorization flow to get a refresh token, and add `client_id`, `client_secret`, `refresh_token`, and `user_email` under `integrations.gmail` in `~/.openclaw/config.yaml`. Run `clawhub reload` to activate. The full process takes about 25 minutes on first setup.
What Gmail API scopes does OpenClaw need?
For most automation workflows, use `https://www.googleapis.com/auth/gmail.modify` — it covers reading messages, sending emails, applying labels, and modifying message state. If you only need to monitor emails without sending or labeling, `gmail.readonly` is more restrictive and requires fewer permissions on your Google account.
Why did my Gmail refresh token stop working?
Refresh tokens can be invalidated by several events: changing your Google account password, revoking the app at myaccount.google.com/permissions, leaving the OAuth app in testing mode for too long without verification, or Google security systems detecting unusual access patterns. If this happens, revoke and re-authorize: go to myaccount.google.com/permissions, remove OpenClaw Gmail, then repeat the authorization flow from Step 2 to generate a new refresh token.
Can OpenClaw read attachments from Gmail?
Yes — Gmail API returns attachment metadata in message parts. Each attachment has a `partId`, `filename`, and `body.attachmentId`. To download the attachment data, call `users.messages.attachments.get` with the message ID and attachment ID. The data is returned as base64url-encoded content which you decode to get the file bytes. OpenClaw can then process the attachment content in downstream workflow steps.
How do I configure OpenClaw Gmail integration without exposing credentials?
Use environment variable substitution in `~/.openclaw/config.yaml`: set `refresh_token: "${GMAIL_REFRESH_TOKEN}"` and export `GMAIL_REFRESH_TOKEN` in your shell profile (`~/.zshrc` or `~/.bash_profile`). Do the same for `client_id` and `client_secret`. This keeps credentials out of the config file so the file itself can be committed to version control safely.
Is there help available for complex Gmail + OpenClaw automation setups?
RapidDev's team helps teams configure Gmail integration in OpenClaw for complex scenarios including multi-account inbox management, AI-powered triage pipelines, and email-to-workflow automation. If you are stuck on OAuth setup, scope configuration, or building multi-step email automation, reach out for hands-on guidance.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation