我一直在尝试使用 Google 服务帐户创建公共日历,然后向其中插入一些事件。
在确保事件是公开的 ('visibility': 'public'
) 后,我仍然无法访问它们。然后我读到日历本身必须是公开的,但在谷歌 documentation 中,新日历的 insert
函数没有参数允许将其创建为公共日历(docs ).
这是我为此编写的小型 util 类:
import json
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from google.oauth2 import service_account
class CalendarUtils:
SCOPES = ['https://www.googleapis.com/auth/calendar']
SERVICE_ACCOUNT_FILE = 'token.json'
CAL_MAPPING_JSON_PATH = 'calendar_mapping.json'
def __init__(self):
creds = service_account.Credentials.from_service_account_file(
self.SERVICE_ACCOUNT_FILE, scopes=self.SCOPES)
self.service = build('calendar', 'v3', credentials=creds)
self.mapping = json.load(open(self.CAL_MAPPING_JSON_PATH))
def list_all_calendars(self):
res = self.service.calendarList().list().execute()
return res['items']
def create_new_calendar(self, location_name):
calendar = {
'summary': location_name,
'timeZone': 'America/Los_Angeles',
'visibility': 'public',
}
return self.service.calendars().insert(body=calendar).execute()
def insert_event(self, location_name, event):
exiting_calendars = [i['name'] for i in self.mapping['map']]
if location_name not in exiting_calendars:
calendar_id = self.create_new_calendar(location_name)['id']
self.mapping['map'].append({'name': location_name, 'calendar_id': calendar_id})
json.dump(self.mapping, open(self.CAL_MAPPING_JSON_PATH, 'w'))
else:
calendar_id = [i for i in self.mapping['map'] if i['name'] == location_name][0]['calendar_id']
event = self.service.events().insert(calendarId=calendar_id, body=event).execute()
print(f'Event created: {event.get("htmlLink")}')
if __name__ == '__main__':
cal_util = CalendarUtils()
event = {
'summary': 'Google I/O 2015',
'location': '800 Howard St., San Francisco, CA 94103',
'description': 'A chance to hear more about Google\'s developer products.',
'start': {
'dateTime': '2015-05-28T09:00:00-07:00',
'timeZone': 'America/Los_Angeles',
},
'end': {
'dateTime': '2015-05-28T17:00:00-07:00',
'timeZone': 'America/Los_Angeles',
},
'visibility': 'public',
'privateCopy': False,
'locked': False,
'anyoneCanAddSelf': True,
}
cal_util.insert_event('test', event)
这将创建日历并插入事件,但它不是公开的。
答案 0 :(得分:1)
要公开日历,您需要将日历 Acl 的范围类型设置为 default
。
示例:
rules = {
"role": "reader",
"scope": {
"type": "default",
}
}
created_rule = service.acl().insert(calendarId='Insert calendar id here', body=rules).execute()
在这里,我在使用服务帐户创建的日历中创建了一个事件,并在其中应用了 Acl
eventDetails = {
'summary': '67407093 test event',
'location': 'Dummy',
'description': 'Dummy',
'start': {
'dateTime': '2021-05-28T09:00:00-07:00',
'timeZone': 'America/Los_Angeles',
},
'end': {
'dateTime': '2021-05-28T17:00:00-07:00',
'timeZone': 'America/Los_Angeles',
}
}
event = service.events().insert(calendarId='Insert calendar id here', body=eventDetails).execute()
输出:
参考: