此代码
var cal = CalendarApp.getCalendarById("Calendar Id");
var startTime = new Date(1850, 0, 1);
var endTime = new Date(2100, 0, 1);
var events = cal.getEvents(startTime, endTime);
Logger.log(events);
var sp = PropertiesService.getScriptProperties();
sp.setProperty("events", JSON.stringify(events));
events = JSON.parse(sp.getProperty("events"));
Logger.log(events);
退货:
Info [CalendarEvent, CalendarEvent, CalendarEvent, CalendarEvent, CalendarEvent]
Info [{}, {}, {}, {}, {}]
为什么?怎么了?
为什么
CalendarEvent
是一个Google应用程序脚本类,事件是该类的实例。
检查财产所有权和可枚举性得出以下结果:
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()
( - 有自己的道具(参见
getOwnPropertyNames()
( CalendarEvent
继承自Object
1(参见toString()
(
现在,看看JSON.stringify()
对对象的作用(这是MDN的描述,但如果深入研究ECMAScript规范,您会发现SerializeJSONObject
操作依赖于抽象的EnumerableOwnPropertyName
(:
所有其他Object实例(包括Map、Set、WeakMap和WeakSet(将只序列化其可枚举属性
这就引出了你的第二个问题:
怎么了
由于没有可枚举的自身属性,因此序列化的结果是"{}"
。
该怎么办
用PropertiesService
存储事件没有多大意义——即使你想好了存储的方法,你也会很快遇到较大事件集合的配额问题。什么是存储引用,那么使用getId()
方法进行存储,使用getEventById()
进行检索如何?
样本
//...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(不要忘记首先通过转到Resources
->Cloud Platform project
->APIs and Services
->Library
为GCP项目启用它(。这个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
}
}
请注意,必须设置要与JWT令牌(由getOAuthToken()
获得(一起传递的OAuth范围。如果应用程序清单中有明确的作用域列表(appscript.json
的oauthScopes
字段(,请添加"https://www.googleapis.com/auth/calendar.events.readonly"
或更合适的列表。
票据
- 我的意思是,由于原型继承,
CalendarEvent
的实例有一个对象作为其原型 - 使用
getUserProperties()
比使用getScriptProperties()
更可取,除非需要脚本范围的设置(请参阅参考文献中的官方指南(。脚本属性在用户之间共享,并计入脚本所有者的配额 - 要使用第二个示例,必须启用V8运行时(从问题示例来看,不清楚是否使用了它(
参考
- MDN的可枚举性解释
- MDN上的
JSON.stringify()
文档 - 日历事件
getId()
文档 getEventById()
文档- 日历API参考
- Google API的OAuth作用域
PropertiesService
指南