Python调用Google Calendar API服务账号认证返回空列表问题咨询
问题解答
1. 服务账号是否是合适的方案?
是,服务账号非常适合这种无交互的服务端运行场景,你选的方向没问题,只是配置步骤少了几步,代码也有小问题。
2. 是否需要将服务账号和个人谷歌账号关联?
需要,但不是用你代码里的with_subject方法,这个方法是Google Workspace(原GSuite)用户专属的全域权限模拟功能,普通个人Gmail账号没有这个权限,加了反而会导致权限异常。正确的关联方式是手动把你要访问的个人日历共享给服务账号:
- 打开你的Google日历,找到对应日历点击「设置和共享」
- 下拉到「与特定用户共享」板块,点击「添加用户」
- 填入你服务账号的邮箱地址(在你下载的
credentials.json里的client_email字段),权限选择「查看所有活动详情」即可满足拉取需求
3. 有没有更简便的实现方式?
API Key只能访问完全公开的日历,私有个人日历无法用API Key访问,没有更简单的方案,不过除了服务账号之外,还有另一种更适合个人用户的方案:你可以先在自己有浏览器的电脑上跑一遍官网的InstalledAppFlow授权流程,生成的token.json文件可以直接复制到树莓派上使用,后续token刷新不需要人工交互,也不会触发浏览器调用,操作起来比配置服务账号更简单。
4. 是否需要使用GSuite?
完全不需要,个人Gmail账号就可以正常使用服务账号方案访问私有日历,只要不用Workspace专属的模拟用户功能即可。
修正后的代码
你原来的代码主要有两个问题:一是加了普通账号不支持的with_subject调用,二是调用了calendarList().list()接口,这个接口返回的是当前认证身份(也就是服务账号)自己创建的日历列表,服务账号默认没有创建任何日历,所以返回空是正常的,你需要直接指定要访问的日历ID(就是你的个人Gmail地址)拉取活动即可:
from __future__ import print_function import os.path from googleapiclient.discovery import build from google.oauth2 import service_account # 如果只是拉取活动可以用只读scope,权限更安全 SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'] # 替换成你自己的Gmail地址,就是日历的ID TARGET_CALENDAR_ID = "你的个人Gmail地址@gmail.com" def main(): creds = service_account.Credentials.from_service_account_file("credentials.json", scopes=SCOPES) service = build('calendar', 'v3', credentials=creds) print("拉取未来10条日历活动:") # 调用活动接口,直接指定目标日历ID events_result = service.events().list( calendarId=TARGET_CALENDAR_ID, maxResults=10, singleEvents=True, orderBy='startTime' ).execute() events = events_result.get('items', []) if not events: print('没有找到即将到来的活动。') for event in events: start = event['start'].get('dateTime', event['start'].get('date')) print(start, event['summary']) if __name__ == '__main__': main()
内容的提问来源于stack exchange,提问作者phatmanace
相关产品推荐
相关产品推荐

