此代码
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 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()
).getOwnPropertyNames()
). CalendarEvent
继承自 Object
1 (见 toString()
).现在,看看 JSON.stringify()
对对象的作用(这是MDN的描述,但如果你深入了解ECMAScript规范,你会发现 SerializeJSONObject
运作 取决于抽象的 EnumerableOwnPropertyName
):
所有其他的对象实例(包括Map, Set, WeakMap, and 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 (别忘了先在你的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()
除非需要在整个脚本范围内进行设置 (参见参考资料中的官方指南)。脚本属性是跨用户共享的,并计入脚本所有者的配额。参考资料