使用谷歌服务帐户创建公共日历

时间:2021-05-05 18:45:26

标签: google-api calendar google-calendar-api

我一直在尝试使用 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)

这将创建日历并插入事件,但它不是公开的。

1 个答案:

答案 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()

输出:

enter image description here

参考: