Служба календаря Google Apps Script: сохраняйте и извлекайте события, используя PropertiesService - PullRequest
0 голосов
/ 03 апреля 2020

Этот код

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

Почему это так? Что не так?

1 Ответ

3 голосов
/ 04 апреля 2020

Почему это так?

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. есть собственных реквизитов (см. * 1021) *).
  3. 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" или более подходящий.

Примечания

  1. Под этим я подразумеваю, что экземпляр CalendarEvent имеет объект в качестве прототипа из-за наследования прототипа.
  2. Использование getUserProperties() предпочтительнее getScriptProperties(), если не требуется настройка на уровне сценария (см. официальное руководство в ссылках). Свойства сценария являются общими для всех пользователей и учитываются в квотах владельца сценария.
  3. Чтобы использовать второй пример, время выполнения V8 должно быть включено (из примера вопроса неясно, является ли оно используется).

Ссылка

  1. Перечислимость Объяснение в MDN
  2. JSON.stringify() документы в MDN
  3. события календаря getId() документы
  4. getEventById() документы
  5. Календарь API ссылка
  6. Области OAuth для API Google
  7. PropertiesService guide
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...