有没有办法加速up/batchGoogle日历read/writes?
Is there a way to speed up/batch Google Calendar read/writes?
我是 Google Apps 脚本的新手,并且在进行此项目时正在学习 javascript。在介绍性代码实验室的过程中,我注意到 best practice 使用一条命令将所有数据读取到一个数组中,执行操作,然后使用一条命令将其写入。
我知道如何使用 Google 表格来完成此操作,但我如何使用 Google 日历来实现此操作?我看到了一些讨论 batching with Google Calendar API and Advanced Google Services 的链接,但我不明白如何使用这些信息。
我基本上希望批量编辑事件而不是在 for
循环中重复访问 Google 日历。
function deleteMonth() {
// Set Date range to delete
var today = new Date();
var firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
var lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);
// read spreadsheet data and get User Info from ss
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var idSheet = spreadsheet.getSheetByName('User Info');
//Get users from sheet in array of objects with properties from column header in
//'User Info' (name, email, year, calName, calID, early, late)
var userInfo = getSheetData(idSheet);
var deletedNames = "";
for (i = 0; i < userInfo.length; i++) {
var calID = userInfo[i].calID;
// if we have calID proceed to delete events
if (calID) {
console.time("get events");
var calendar = CalendarApp.getCalendarById(calID);
var events = calendar.getEvents(firstDay, lastDay);
console.timeEnd("get events");
// Delete events and add deleted name to string
// deletedNames
for (i = 0; i < events.length; i++) {
console.time("delete event");
deletedNames += events[i].getTitle() + ", ";
events[i].deleteEvent();
console.timeEnd("delete event");
}
}
}
spreadsheet.toast("Deleted events: \n" + deletedNames);
}
console.time()
的时间输出:
其他听起来相关的相关链接:
我相信你的目标如下
- 您想通过 Google Apps 脚本使用批处理删除多个日历一个月内的所有事件。
- 您想降低上述过程的过程成本。
为此,这个答案怎么样?
问题和解决方法:
日历API 可以处理批处理请求。批量请求可以 运行 100 个请求通过一个 API 调用并且可以用异步进程处理。由此,我认为可以降低工艺成本。但是,不幸的是,在现阶段,多个日历 ID 不能在一批中使用。当请求包含多个日历ID时,会出现Cannot perform operations on different calendars in the same batch request.
的错误。因此,在您的情况下,一个日历 ID 中一个月中的所有事件都可以在一批请求中删除。需要请求日历 ID 的数量。我想将此作为当前的解决方法。
顺便说一句,作为你scrit的修改点,在你的脚本中,变量i
被用在第一个for循环和第二个for循环中。这样, userInfo
的所有值都不会被使用。请注意这一点。
示例脚本:
在你 运行 脚本之前,please enable Calendar API at Advanced Google services。
function deleteMonth() {
var today = new Date();
var firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
var lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var idSheet = spreadsheet.getSheetByName('User Info');
var userInfo = getSheetData(idSheet);
var deletedNames = "";
var requests = []; // For batch requests.
for (i = 0; i < userInfo.length; i++) {
var req = [];
var calID = userInfo[i].calID;
if (calID) {
var calendar = CalendarApp.getCalendarById(calID);
var events = calendar.getEvents(firstDay, lastDay);
for (j = 0; j < events.length; j++) {
deletedNames += events[j].getTitle() + ", ";
var e = events[j];
req.push({
method: "DELETE",
endpoint: `https://www.googleapis.com/calendar/v3/calendars/${calID}/events/${e.getId().replace("@google.com", "")}`,
});
}
}
requests.push(req);
}
// Run batch requests.
requests.forEach(req => {
const limit = 100;
const split = Math.ceil(req.length / limit);
const boundary = "xxxxxxxxxx";
for (let i = 0; i < split; i++) {
const object = {batchPath: "batch/calendar/v3", requests: req.splice(0, limit)};
const payload = object.requests.reduce((s, e, i) => s += "Content-Type: application/http\r\nContent-ID: " + i + "\r\n\r\n" + e.method + " " + e.endpoint + "\r\nContent-Type: application/json; charset=utf-8\r\n\r\n" + JSON.stringify(e.requestBody) + "\r\n--" + boundary + "\r\n", "--" + boundary + "\r\n");
const params = {method: "post", contentType: "multipart/mixed; boundary=" + boundary, payload: payload, headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}, muteHttpExceptions: true};
var res = UrlFetchApp.fetch("https://www.googleapis.com/" + object.batchPath, params);
console.log(res.getContentText())
}
})
spreadsheet.toast("Deleted events: \n" + deletedNames);
}
注:
- 请在 V8 中使用此脚本。
参考文献:
我是 Google Apps 脚本的新手,并且在进行此项目时正在学习 javascript。在介绍性代码实验室的过程中,我注意到 best practice 使用一条命令将所有数据读取到一个数组中,执行操作,然后使用一条命令将其写入。
我知道如何使用 Google 表格来完成此操作,但我如何使用 Google 日历来实现此操作?我看到了一些讨论 batching with Google Calendar API and Advanced Google Services 的链接,但我不明白如何使用这些信息。
我基本上希望批量编辑事件而不是在 for
循环中重复访问 Google 日历。
function deleteMonth() {
// Set Date range to delete
var today = new Date();
var firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
var lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);
// read spreadsheet data and get User Info from ss
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var idSheet = spreadsheet.getSheetByName('User Info');
//Get users from sheet in array of objects with properties from column header in
//'User Info' (name, email, year, calName, calID, early, late)
var userInfo = getSheetData(idSheet);
var deletedNames = "";
for (i = 0; i < userInfo.length; i++) {
var calID = userInfo[i].calID;
// if we have calID proceed to delete events
if (calID) {
console.time("get events");
var calendar = CalendarApp.getCalendarById(calID);
var events = calendar.getEvents(firstDay, lastDay);
console.timeEnd("get events");
// Delete events and add deleted name to string
// deletedNames
for (i = 0; i < events.length; i++) {
console.time("delete event");
deletedNames += events[i].getTitle() + ", ";
events[i].deleteEvent();
console.timeEnd("delete event");
}
}
}
spreadsheet.toast("Deleted events: \n" + deletedNames);
}
console.time()
的时间输出:
其他听起来相关的相关链接:
我相信你的目标如下
- 您想通过 Google Apps 脚本使用批处理删除多个日历一个月内的所有事件。
- 您想降低上述过程的过程成本。
为此,这个答案怎么样?
问题和解决方法:
日历API 可以处理批处理请求。批量请求可以 运行 100 个请求通过一个 API 调用并且可以用异步进程处理。由此,我认为可以降低工艺成本。但是,不幸的是,在现阶段,多个日历 ID 不能在一批中使用。当请求包含多个日历ID时,会出现Cannot perform operations on different calendars in the same batch request.
的错误。因此,在您的情况下,一个日历 ID 中一个月中的所有事件都可以在一批请求中删除。需要请求日历 ID 的数量。我想将此作为当前的解决方法。
顺便说一句,作为你scrit的修改点,在你的脚本中,变量i
被用在第一个for循环和第二个for循环中。这样, userInfo
的所有值都不会被使用。请注意这一点。
示例脚本:
在你 运行 脚本之前,please enable Calendar API at Advanced Google services。
function deleteMonth() {
var today = new Date();
var firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
var lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var idSheet = spreadsheet.getSheetByName('User Info');
var userInfo = getSheetData(idSheet);
var deletedNames = "";
var requests = []; // For batch requests.
for (i = 0; i < userInfo.length; i++) {
var req = [];
var calID = userInfo[i].calID;
if (calID) {
var calendar = CalendarApp.getCalendarById(calID);
var events = calendar.getEvents(firstDay, lastDay);
for (j = 0; j < events.length; j++) {
deletedNames += events[j].getTitle() + ", ";
var e = events[j];
req.push({
method: "DELETE",
endpoint: `https://www.googleapis.com/calendar/v3/calendars/${calID}/events/${e.getId().replace("@google.com", "")}`,
});
}
}
requests.push(req);
}
// Run batch requests.
requests.forEach(req => {
const limit = 100;
const split = Math.ceil(req.length / limit);
const boundary = "xxxxxxxxxx";
for (let i = 0; i < split; i++) {
const object = {batchPath: "batch/calendar/v3", requests: req.splice(0, limit)};
const payload = object.requests.reduce((s, e, i) => s += "Content-Type: application/http\r\nContent-ID: " + i + "\r\n\r\n" + e.method + " " + e.endpoint + "\r\nContent-Type: application/json; charset=utf-8\r\n\r\n" + JSON.stringify(e.requestBody) + "\r\n--" + boundary + "\r\n", "--" + boundary + "\r\n");
const params = {method: "post", contentType: "multipart/mixed; boundary=" + boundary, payload: payload, headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}, muteHttpExceptions: true};
var res = UrlFetchApp.fetch("https://www.googleapis.com/" + object.batchPath, params);
console.log(res.getContentText())
}
})
spreadsheet.toast("Deleted events: \n" + deletedNames);
}
注:
- 请在 V8 中使用此脚本。