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

如何无需重复认证通过GCP API读取Google Calendar日程用于仪表盘

解决方案

方法1:使用刷新令牌持久化授权(无需服务账号)

你现在的授权流程每次都走浏览器验证是因为没有持久化授权凭证,通过以下步骤可以实现长期免验证:

  • 首次授权时自动获取长期有效的刷新令牌
  • 将包含刷新令牌的凭证存储到本地文件
  • 后续程序启动时直接读取本地凭证,access_token过期时会自动用刷新令牌换取新的凭证,无需再次走浏览器授权流程
    注意:如果你的GCP OAuth应用的发布状态为「测试」,刷新令牌默认7天过期,你需要在GCP控制台的「OAuth 同意屏幕」页面将应用发布状态改为「正式发布」,就可以获得长期有效的刷新令牌。
    对应的Python代码示例:
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

SCOPES = [
    'https://www.googleapis.com/auth/calendar.readonly', 
    "openid",
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/userinfo.profile"
]

client_config = {
    'installed': {
        'client_id': '123456.apps.googleusercontent.com',
        'project_id': 'test-dashboard',
        'auth_uri': 'https://accounts.google.com/o/oauth2/auth',
        'token_uri': 'https://oauth2.googleapis.com/token',
        'auth_provider_x509_cert_url': 'https://www.googleapis.com/oauth2/v1/certs',
        'client_secret': 'secret',
        'redirect_uris': ['urn:ietf:wg:oauth:2.0:oob', 'http://localhost']
        }
    }

creds = None
# 本地有存储的token文件就直接读取
if os.path.exists('token.json'):
    creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# 凭证不存在或者过期失效
if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
        # 自动用刷新令牌换新的access token
        creds.refresh(Request())
    else:
        # 首次运行走浏览器授权
        flow = InstalledAppFlow.from_client_config(client_config, SCOPES)
        creds = flow.run_local_server()
    # 把新的凭证存到本地
    with open('token.json', 'w') as token:
        token.write(creds.to_json())

service = build('calendar', 'v3', credentials=creds)

# 后续业务逻辑不变
page_token = None
cal = {}
while True:
  calendar_list = service.calendarList().list(pageToken=page_token).execute()
  for calendar_list_entry in calendar_list['items']:
    cal[calendar_list_entry['summary']] = calendar_list_entry
  page_token = calendar_list.get('nextPageToken')
  if not page_token:
    break

方法2:服务账号读取个人Gmail日历方案

个人Gmail账号可以使用服务账号读取日历,你之前返回空结果是因为没有给服务账号授予日历的访问权限,无需使用全域委派,操作步骤如下:

  1. 在GCP控制台的服务账号页面复制服务账号的邮箱地址(格式类似xxx@xxx.iam.gserviceaccount.com)
  2. 打开Google日历网页端,找到你要读取的日历,点击「设置和共享」
  3. 在「与特定的人共享」选项下,点击「添加人员」,粘贴服务账号邮箱,权限选择「查看所有事件详情」,保存即可
    对应的Python代码示例:
from google.oauth2 import service_account
from googleapiclient.discovery import build

SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
SERVICE_ACCOUNT_FILE = '你的服务账号密钥文件路径.json'

creds = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

service = build('calendar', 'v3', credentials=creds)

# 注意这里要指定你共享给服务账号的日历ID,不要用primary,个人账号的primary日历不会自动出现在calendarList里
calendar_id = "你的个人Gmail地址,或者日历设置里的日历ID"
events = service.events().list(calendarId=calendar_id).execute()

关于全域委派的说明

你的理解正确,全域委派仅适用于Google Workspace企业账号,只能访问所属企业域名下的用户资源,个人Gmail账号没有对应的企业域名,无法使用全域委派功能访问个人日历。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:54:04