You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本调用Gmail API报错:web类型客户端缺失redirect_uris

Fixing oauth2client.clientsecrets.InvalidClientSecretsError: Missing property "redirect_uris" for Gmail Scripts

Hey there, let's unpack what's happening with your Gmail script and that pesky error.

First, let's get to the root of the issue: Google's OAuth2 framework requires the redirect_uris field for "Web application" type client IDs. This isn't a random quirk of the oauth2client library—it's part of the official OAuth2 spec for web apps, which rely on redirects to complete the authorization flow.

Why your script worked before

Chances are, your original client_secret.json was tied to a Desktop app type client ID (not a Web application). Desktop/script-based apps have different OAuth2 rules—they don't need a custom redirect URI (Google uses a default value like urn:ietf:wg:oauth:2.0:oob for terminal-based auth) and the oauth2client library doesn't enforce the redirect_uris field for this type.

Possible reasons it broke now:

  • You might have recreated your client ID in Google Cloud Console and accidentally selected "Web application" instead of "Desktop app".
  • You updated the oauth2client library to a newer version that enforces stricter validation of client secret fields for Web app types.

How to fix this

You have two solid options:

Option 1: Switch to a Desktop app client ID (recommended for local scripts)

This is the cleanest fix since you don't need redirects for a local script:

  1. Go to your Google Cloud Console Credentials page
  2. Either delete your existing "Web application" client ID or create a new one
  3. Create a new OAuth client ID, select Desktop app as the application type
  4. Download the new client_secret.json and replace your current file
  5. Your script should work as it did before—no need to add redirect_uris at all

Option 2: Keep using Web app type (if you have to)

If you must stick with a Web app client ID, you need to keep the redirect_uris field in your client_secret.json—even if you don't actively use the redirect. You can use a placeholder valid for local testing:

{
  "web": {
    "client_id": "your-client-id",
    "client_secret": "your-client-secret",
    "redirect_uris": ["http://localhost:8000"],
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token"
  }
}

The library just needs this field to exist and have a valid URI format—you don't need to run a server at that localhost address for a simple send-only script.

Quick code check

Make sure your flow initialization aligns with the client type. For Desktop apps, the standard setup looks like this:

from oauth2client import client, tools
from oauth2client.file import Storage

CLIENT_SECRET_FILE = 'client_secret.json'
SCOPES = ['https://www.googleapis.com/auth/gmail.send']

def get_credentials():
    storage = Storage('gmail-token.json')
    credentials = storage.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        credentials = tools.run_flow(flow, storage)
    return credentials

This will handle the authorization flow in your terminal (or pop up a browser window) without needing a redirect server.


内容的提问来源于stack exchange,提问作者codyc4321

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:41:27