Google API 对 Calendar.Events.import() 的错误请求

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

当我尝试在假期日历上运行大多数普通的 Google API 脚本时,出现以下错误。它之前已经工作了几个月,我似乎无法调试为什么它不再工作了。有谁知道 API 是否在未记录的情况下发生更改或服务已关闭? 脚本

// To learn how to use this script, refer to the documentation:
// https://developers.google.com/apps-script/samples/automations/vacation-calendar

/*
Copyright 2022 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Set the ID of the team calendar to add events to. You can find the calendar's
// ID on the settings page.
let TEAM_CALENDAR_ID = '[email protected]';

// Set the email address of the Google Group that contains everyone in the team.
// Ensure the group has less than 500 members to avoid timeouts.
let GROUP_EMAIL = 'foobar.com';

let KEYWORDS = ['vacation', 'ooo', 'out of office', 'offline', 'pto'];
let MONTHS_IN_ADVANCE = 3;

/**
 * Sets up the script to run automatically every hour.
 */
function setup() {
  let triggers = ScriptApp.getProjectTriggers();
  //ScriptApp.deleteTrigger(triggers[0]);
  if (triggers.length > 0) {
    throw new Error('Triggers(' + triggers.length + ') are already setup.');
  }
  ScriptApp.newTrigger('sync').timeBased().everyHours(1).create();
  // Runs the first sync immediately.
  sync();
}

/**
 * Looks through the group members' public calendars and adds any
 * 'vacation' or 'out of office' events to the team calendar.
 */
function sync() {
  // Defines the calendar event date range to search.
  let today = new Date();
  let maxDate = new Date();
  maxDate.setMonth(maxDate.getMonth() + MONTHS_IN_ADVANCE);

  // Determines the time the the script was last run.
  let lastRun = PropertiesService.getScriptProperties().getProperty('lastRun');
  lastRun = lastRun ? new Date(lastRun) : null;

  // Gets the list of users in the Google Group.
  let groupEmail = GroupsApp.getGroupByEmail(GROUP_EMAIL);
  let users = groupEmail.getUsers();
  
  // Gets the list of groups in the Google Group.
  let groupsInMain = groupEmail.getGroups();
  
  //Add each subgroup to the list of users 
  let numberRuns = 0;
  groupsInMain.forEach(function(group) {
    console.log('%s users in user list', users.length);
    let subgroupInGroupsInMain = group.getGroups();
    subgroupInGroupsInMain.forEach(function(subgroup) {
      users = addUserToGroup(subgroup.getUsers(), users);
    }); //End foreach second group of groups
    users = addUserToGroup(group.getUsers(), users);
    numberRuns++;
  });// End foreach first group of groups
console.log('%s users in user list -- Start', users.length);

// Unique the Users list
//users.forEach(function(userA) {
//  console.log('User %s in user list', userA.getEmail());
//});
var usersList = uniqueUsers(users);
console.log('groups: ' + numberRuns + ' uniques: ' + usersList.length);
//usersList.forEach(function(userB) {
//  console.log('User %s in user list', userB.getEmail());
//});

  // For each user, finds events having one or more of the keywords in the event
  // summary in the specified date range. Imports each of those to the team
  // calendar.
  let count = 0;
  usersList.forEach(function(user) {
    let username = user.getEmail().split('@')[0];
    console.log('Importing ' + username + '\'s emails');
    KEYWORDS.forEach(function(keyword) {
      let events = findEvents(user, keyword, today, maxDate, lastRun);
      events.forEach(function(event) {
        importEvent(username, event);
        count++;
      }); // End foreach event.
    }); // End foreach keyword.
  }); // End foreach user.

  PropertiesService.getScriptProperties().setProperty('lastRun', today);
  console.log('Imported ' + count + ' events');
}

/**
 * Uniques a given array and spits out the new array
 * @param {[]} An array, assumed of Users
 */
function uniqueUsers(arr)
{
  var u = {}, a = [];
    for(var i = 0; i < arr.length; ++i){
        if(!u.hasOwnProperty(arr[i])) {
            a.push(arr[i]);
            u[arr[i]] = 1;
        }
    }
    return a;
}

/**
 * Adds all the users of a group to a list of users
 * @param {Group} group to pull users from 
 * @param {User[]} list of users to be added to
 */
function addUserToGroup(group, users) {
  let count = 0;
  for (var i = 0; i < group.length; i++) {
    var user = group[i];
    users.push(user);
    count++;
    //console.log('Adding %s to user list', user.getEmail());
  }
  console.log('Adding ' + count + ' from ' + group.getEmail + ' to user list');
  return users;
}

/**
 * Imports the given event from the user's calendar into the shared team
 * calendar.
 * @param {string} username The team member that is attending the event.
 * @param {Calendar.Event} event The event to import.
 */
function importEvent(username, event) {
  event.summary = '[' + username + '] ' + event.summary;
  event.organizer = {
    id: TEAM_CALENDAR_ID,
  };
  event.attendees = [];
  console.log('Importing: %s', event.summary);
  try {
    Calendar.Events.import(event, TEAM_CALENDAR_ID);
  } catch (e) {
    console.error('Error attempting to import event: %s. Skipping.',
        e.toString());
  }
}



/**
 * In a given user's calendar, looks for occurrences of the given keyword
 * in events within the specified date range and returns any such events
 * found.
 * @param {Session.User} user The user to retrieve events for.
 * @param {string} keyword The keyword to look for.
 * @param {Date} start The starting date of the range to examine.
 * @param {Date} end The ending date of the range to examine.
 * @param {Date} optSince A date indicating the last time this script was run.
 * @return {Calendar.Event[]} An array of calendar events.
 */
function findEvents(user, keyword, start, end, optSince) {
  let params = {
    q: keyword,
    timeMin: formatDateAsRFC3339(start),
    timeMax: formatDateAsRFC3339(end),
    showDeleted: true,
  };
  if (optSince) {
    // This prevents the script from examining events that have not been
    // modified since the specified date (that is, the last time the
    // script was run).
    params.updatedMin = formatDateAsRFC3339(optSince);
  }
  let pageToken = null;
  let events = [];
  do {
    params.pageToken = pageToken;
    let response;
    try {
      response = Calendar.Events.list(user.getEmail(), params);
    } catch (e) {
      console.error('Error retriving events for %s, %s: %s; skipping',
          user, keyword, e.toString());
      continue;
    }
    events = events.concat(response.items.filter(function(item) {
      return shoudImportEvent(user, keyword, item);
    }));
    pageToken = response.nextPageToken;
  } while (pageToken);
  return events;
}

/**
 * Determines if the given event should be imported into the shared team
 * calendar.
 * @param {Session.User} user The user that is attending the event.
 * @param {string} keyword The keyword being searched for.
 * @param {Calendar.Event} event The event being considered.
 * @return {boolean} True if the event should be imported.
 */
function shoudImportEvent(user, keyword, event) {
  // Filters out events where the keyword did not appear in the summary
  // (that is, the keyword appeared in a different field, and are thus
  // is not likely to be relevant).
  if (event.summary.toLowerCase().indexOf(keyword) < 0) {
    return false;
  }
  //if (!event.isAllDayEvent())
    // If the event is not an all day event, don't import it
   // return false;
  if (!event.organizer || event.organizer.email == user.getEmail()) {
    // If the user is the creator of the event, always imports it.
    return true;
  }
  // Only imports events the user has accepted.
  if (!event.attendees) return false;
  let matching = event.attendees.filter(function(attendee) {
    return attendee.self;
  });
  return matching.length > 0 && matching[0].responseStatus == 'accepted';
}

/**
 * Returns an RFC3339 formated date String corresponding to the given
 * Date object.
 * @param {Date} date a Date.
 * @return {string} a formatted date string.
 */
function formatDateAsRFC3339(date) {
  return Utilities.formatDate(date, 'UTC', 'yyyy-MM-dd\'T\'HH:mm:ssZ');
}

Error trace

  • 我检查了处理 API 错误,其中提到检查时间范围,但在我调试时似乎填充得很好。
  • RFC3339 日期似乎是正确的

似乎现在为此添加了一个问题跟踪器

google-apps-script google-calendar-api
1个回答
0
投票
当根据文档检查您的代码时,我会说在代码的第 202 行和 217 行上您有

return shoudImportEvent(user, keyword, item);

shouldImportEvent 中缺少一个 l

return shouldImportEvent(user, keyword, item);

我相信这将是您的问题。

填充团队假期样本

© www.soinside.com 2019 - 2024. All rights reserved.