Почему это так?
CalendarEvent
- это класс скрипта Google Apps, экземплярами которого являются события.
Проверка права собственности и перечисления дает следующее:
function stringified() {
const event = CalendarApp.createAllDayEvent('Party', new Date());
const eventToString = JSON.stringify(event);
Logger.log(eventToString); // -> {}
Logger.log(Object.keys(event)); // -> []
Logger.log(Object.getOwnPropertyNames(event)); // -> [toString,...]
Logger.log(Object.getPrototypeOf(event)); // -> {}
Logger.log(event.toString()); // -> CalendarEvent
}
Что это говорит нам?
- нет перечисляемых реквизитов, к которым мы можем получить доступ (см.
Object.keys()
). - есть собственных реквизитов (см. * 1021) *).
CalendarEvent
наследуется от Object
1 (см. toString()
).
Теперь посмотрите, что JSON.stringify()
делает для объектов (это это описание из MDN, но если вы загляните в ECMAScript spe c, вы увидите, что SerializeJSONObject
операция зависит от абстрактного EnumerableOwnPropertyName
):
Все другие экземпляры объектов (включая Map, Set, WeakMap и WeakSet) будут иметь только сериализованные перечисляемые им свойства
, что приводит нас ко второму вопросу:
Что такое неправильно?
Поскольку нет перечисляемых собственных свойств, в результате сериализации получается "{}"
.
Что делать?
Это Не имеет смысла хранить события с PropertiesService
- вы быстро столкнетесь с проблемами квот в больших коллекциях событий, даже если вы найдете способ хранения. Что значит хранить ссылку , так как насчет использования метода getId()
для хранения и getEventById()
для извлечения?
Sample
//...get event somehow
const store = PropertiesService.getUserProperties();
store.deleteProperty('events'); // demo only
const eventIds = store.getProperty('events') || '[]';
const id = event.getId();
const idList = JSON.parse(eventIds);
idList.push(id);
store.setProperty('events',JSON.stringify(idList));
Logger.log(store.getProperty('events'));
Что еще можно сделать?
Использовать API-интерфейс календаря (не забудьте сначала включить его для своего проекта GCP, перейдя к Resources
-> Cloud Platform project
- > APIs and Services
-> Library
). Этот API является REST API, который можно запрашивать с помощью старых добрых HTTP-запросов:
function listEvents() {
const calendar = CalendarApp.getCalendarById('yourEmailHere');
const endpoint = `https://www.googleapis.com/calendar/v3/calendars/${calendar.getId()}/events`;
const query = {};
const preparedQuery = Object
.entries(query)
.map(param =>`${param[0]}=${param[1]}`)
.join('&');
const resp = UrlFetchApp.fetch(`${endpoint}?${preparedQuery}`,{
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
}
});
if(resp.getResponseCode() === 200) {
//process the response
}
}
Обратите внимание, что необходимо установить область OAuth, передаваемую с токеном JWT (полученный из getOAuthToken()
). Если в манифесте приложения имеется явный список областей (oauthScopes
поле appscript.json
), добавьте "https://www.googleapis.com/auth/calendar.events.readonly"
или более подходящий.
Примечания
- Под этим я подразумеваю, что экземпляр
CalendarEvent
имеет объект в качестве прототипа из-за наследования прототипа. - Использование
getUserProperties()
предпочтительнее getScriptProperties()
, если не требуется настройка на уровне сценария (см. официальное руководство в ссылках). Свойства сценария являются общими для всех пользователей и учитываются в квотах владельца сценария. - Чтобы использовать второй пример, время выполнения V8 должно быть включено (из примера вопроса неясно, является ли оно используется).
Ссылка
- Перечислимость Объяснение в MDN
JSON.stringify()
документы в MDN - события календаря
getId()
документы getEventById()
документы - Календарь API ссылка
- Области OAuth для API Google
PropertiesService
guide