日历服务:使用PropertiesService存储和检索事件 [英] Calendar Service: Store and retrieve events using PropertiesService
问题描述
此代码
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脚本类,事件是其实例.
CalendarEvent
is a Google Apps Script class which events are instances of.
检查财产所有权和可枚举性会得出以下结果:
Checking property ownership and enumerability yields the following:
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()
).
- there are no enumerable props we can access (see
Object.keys()
). - there are own props (see
getOwnPropertyNames()
). CalendarEvent
inherits fromObject
1 (seetoString()
).
现在,查看JSON.stringify()
对对象的作用(这是MDN的描述,但是如果您深入研究ECMAScript规范,您会发现SerializeJSONObject
Now, look at what JSON.stringify()
does for objects (this is a description from MDN, but if you dig into the ECMAScript spec, you will see that SerializeJSONObject
operation depends on abstract EnumerableOwnPropertyName
):
所有其他Object实例(包括Map,Set,WeakMap和WeakSet)将仅对其可枚举的属性进行序列化
哪个引导我们回答您的第二个问题:
Which leads us to your second question:
怎么了?
由于没有可枚举的自身属性,因此序列化结果为"{}"
.
Since there are no enumerable own properties, the serialization results in "{}"
.
该怎么办?
使用PropertiesService
存储事件并没有多大意义-即使您想出一种存储方式,也可以很快进入大型事件集合的配额问题.什么是存储引用,那么如何使用getId()
方法存储和getEventById()
检索呢?
It does not make much sense to store events with PropertiesService
- you will quickly get into quota issues on larger event collections even if you figure a way to store. What does, is to store a reference, so how about using getId()
method to store and getEventById()
to retrieve?
样品
//...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'));
还有什么要做?
使用Calendar API(不要忘记先通过Resources
-> Cloud Platform project
-> APIs and Services
-> Library
为您的GCP项目启用它).该API是一种REST API,您可以通过以下良好的旧HTTP请求进行查询:
Use the Calendar API (don't forget to enablle it for your GCP project first by going to Resources
-> Cloud Platform project
-> APIs and Services
-> Library
). This API is a REST API that you can query with good old HTTP requests like that:
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令牌一起传递的OAuth范围(由getOAuthToken()
获取).如果应用程序清单中有明确的作用域列表(appscript.json
的oauthScopes
字段),请添加"https://www.googleapis.com/auth/calendar.events.readonly"
或更合适的列表.
Note that one would have to set the OAuth scope to be passed with the JWT token (obtained by getOAuthToken()
). If there is an explicit scope list in application manifest (oauthScopes
field of appscript.json
), add "https://www.googleapis.com/auth/calendar.events.readonly"
or a more appropriate one.
注释
- 我的意思是,由于原型继承,
CalendarEvent
的实例具有一个对象作为其原型.
除非需要脚本范围的设置,否则 - 使用
getUserProperties()
优于getScriptProperties()
(请参阅参考资料中的官方指南).脚本属性在用户之间共享,并计入脚本所有者的配额. - 要使用第二个示例,必须启用(从问题示例中尚不清楚是否使用了它).
- By this I mean that an instance of
CalendarEvent
has an object as its prototype due to prototypal inheritance. - Usage of
getUserProperties()
is preferrable togetScriptProperties()
unless a script-wide setup is needed (see official guide in references). Script properties are shared across users and count toward quotas of the script owner. - To use the second sample, V8 runtime has to be enabled (from the question sample it is unclear if it is used).
参考
-
在MDN上
- Enumerability 解释
-
JSON.stringify()
文档在MDN上 - 日历事件
getId()
文档 -
getEventById()
文档 - 日历API 参考
- Google API的OAuth范围
-
PropertiesService
指南
- Enumerability explanation on MDN
JSON.stringify()
docs on MDN- Calendar events
getId()
docs getEventById()
docs- Calendar API reference
- OAuth scopes for Google APIs
PropertiesService
guide
这篇关于日历服务:使用PropertiesService存储和检索事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!