日历服务。使用PropertiesService存储和检索事件

问题描述 投票:0回答:1

此代码

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 [{}, {}, {}, {}, {}]

为什么会这样?有什么问题?

javascript google-apps-script google-calendar-api
1个回答
3
投票

为什么会这样?

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
}

这告诉我们什么?

  1. 没有 可数 我们可以访问的道具(见 Object.keys()).
  2. 自己 道具 getOwnPropertyNames()).
  3. CalendarEvent 继承自 Object1 (见 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 -> -> -> -&gt 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" 或更合适的。

  1. 我的意思是,一个 CalendarEvent 由于原型继承,它的原型是一个对象。
  2. 的用法 getUserProperties() 胜过 getScriptProperties() 除非需要在整个脚本范围内进行设置 (参见参考资料中的官方指南)。脚本属性是跨用户共享的,并计入脚本所有者的配额。
  3. 要使用第二个示例,V8运行时必须是 启用 (从题例看不清楚是否使用)。

参考资料

  1. 枚举性 解释 在MDN上
  2. JSON.stringify() 文件 在MDN上
  3. 日历活动 getId() 文件
  4. getEventById() 文件
  5. 日历API 参考
  6. OAuth范围 用于谷歌API
  7. PropertiesService 指南
© www.soinside.com 2019 - 2024. All rights reserved.