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

使用Python调用Gmail API获取未读邮件时遇格式错误求助

解决Gmail API授权错误:Missing refresh_token, client_secret, client_id

错误原因

你当前传入Credentials.from_authorized_user_file()的gmail_credencials.json是桌面应用的客户端凭据文件,但这个方法需要的是用户完成OAuth2授权后生成的token文件(包含refresh_token、access_token、client_id等信息),二者格式完全不同,所以触发报错。

解决步骤

1. 安装依赖包

先确保安装必要的Google API工具库:

pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib

2. 整理凭据文件

把你下载的桌面应用凭据文件重命名为client_secret.json(如果自定义文件名,后续代码中对应修改即可)。

3. 完整功能代码

以下代码会自动完成首次授权(弹出浏览器引导登录),生成包含refresh_token的token.json,后续运行无需重复授权,同时实现获取未读邮件的功能:

import os
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from google.auth.transport.requests import Request

# Gmail API权限范围(只读权限足够)
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
# 授权后生成的token存储路径
TOKEN_FILE = 'token.json'
# 你的桌面应用凭据文件路径
CLIENT_SECRET_FILE = 'client_secret.json'

def get_gmail_service():
    creds = None
    # 检查本地是否已有有效token文件
    if os.path.exists(TOKEN_FILE):
        creds = Credentials.from_authorized_user_file(TOKEN_FILE, SCOPES)
    
    # 无有效凭据时,刷新或重新授权
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            # 启动本地服务器完成OAuth2授权流程
            flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
            creds = flow.run_local_server(port=0)
        # 保存token供下次直接使用
        with open(TOKEN_FILE, 'w') as token:
            token.write(creds.to_json())
    
    return build('gmail', 'v1', credentials=creds)

def fetch_unread_emails(service):
    # 调用Gmail API查询未读邮件
    results = service.users().messages().list(userId='me', q='is:unread').execute()
    messages = results.get('messages', [])
    
    if not messages:
        print("暂无未读邮件")
        return
    
    print(f"共找到 {len(messages)} 封未读邮件:")
    for msg in messages:
        # 获取邮件元数据(仅加载主题等关键信息,提升效率)
        msg_data = service.users().messages().get(userId='me', id=msg['id'], format='metadata').execute()
        # 从邮件头中提取主题
        subject = next(h['value'] for h in msg_data['payload']['headers'] if h['name'] == 'Subject')
        print(f"- {subject}")

if __name__ == '__main__':
    gmail_service = get_gmail_service()
    fetch_unread_emails(gmail_service)

关键说明

  • 首次运行代码会自动打开浏览器,要求你登录Google账号并授权应用访问Gmail,授权成功后本地会生成token.json,里面包含所需的refresh_token、client_id、client_secret等信息。
  • 后续运行代码会直接读取token.json,无需重复授权;如果token过期,会自动用refresh_token刷新。
  • q='is:unread'是Gmail的搜索语法,用于精准筛选未读邮件,你可以根据需求修改查询条件(比如添加from:xxx@xxx.com筛选发件人)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:15:44