-
Notifications
You must be signed in to change notification settings - Fork 46
Description
Hi. I have a script to convert a google sheets reading plan into google calendar events.
There are two errors that need to be solved:
There is also one parameter to be added.
Error 1. the script takes longer than 6 minutes to run: I am adding 3 events to all 365 days of the year. I need to be able to restart the script at the Google sheet row it left off at the last run.
Error 2. When I run the script, I can only run it once before I get this error message: [Error: You have been creating or deleting too many calendars or calendar events in a short time].
and the parameter is to change the time from busy to free so that items scheduled on this calendar do not create schedualing conflicts when people subscribe and add it to their own google calendars.
Can someone please review and offer suggestions.
Thank you.
Nick
Here is a sample of data from the spreadsheet:
Date | 1. Law History | 2. Wisdom Prophets | 3. New Testament Psalms | Credits |
2024-01-01 | Genesis 1:1 - 2:3 @ https://www.biblegateway.com/passage/?search=Genesis%201%3A1-2%3A3&version=NIV | Ezra 1 - 2 @ https://www.biblegateway.com/passage/?search=Ezra%201-2&version=NIV | Matthew 1:1 - 2:12 @ https://www.biblegateway.com/passage/?search=Matthew%201%3A1-2%3A12&version=NIV | This calendar is provided as a supplementary resource to the Journey Through the Bible Discipleship Course, 2nd Edition, 2023 |
2024-01-02 | Genesis 2:4 - 3:24 @ https://www.biblegateway.com/passage/?search=Genesis%202%3A4-3%3A24&version=NIV | Ezra 3:1 - 6 @ https://www.biblegateway.com/passage/?search=Ezra%203%3A1-6&version=NIV | Matthew 2:13 - 3:12 @ https://www.biblegateway.com/passage/?search=Matthew%202%3A13-3%3A12&version=NIV | This calendar is provided as a supplementary resource to the Journey Through the Bible Discipleship Course, 2nd Edition, 2023 |
2024-01-03 | Genesis 4 @ https://www.biblegateway.com/passage/?search=Genesis%204&version=NIV | Ezra 3:7 - 13 @ https://www.biblegateway.com/passage/?search=Ezra%203%3A7-13&version=NIV | Matthew 3:13 - 4:22 @ https://www.biblegateway.com/passage/?search=Matthew%203%3A13-4%3A22&version=NIV | This calendar is provided as a supplementary resource to the Journey Through the Bible Discipleship Course, 2nd Edition, 2023 |
here is the script I am working with so far:
// Global Constants
const CALENDAR_NAME = "NIV Simplified Reading Plan"; // Calendar name
const SHEET_NAME = "ReadingPlan"; // Sheet name (adjust if different)
const COLOR_LAW_HISTORY = "9"; // Color ID for Law & History events
const COLOR_WISDOM_PROPHETS = "6"; // Color ID for Wisdom & Prophets events
const COLOR_NEW_TESTAMENT = "2"; // Color ID for New Testament events
const SUBSCRIPTION_LINK = "Click to subscribe to email reminders: [https://calendar.google.com/calendar/u/0?cid=MDZhZGMxZjE2ZjU2ODdjNGZjNmIwZDM2ZmJjNDdiMzVkMTY3ZTViYmZmMjk0YWMyZmY0MGU3MDY4OGRiN2YyZkBncm91cC5jYWxlbmRhci5nb29nbGUuY29t]"; // Replace with actual link
// Column Indices for data (assuming consistent order in the sheet)
const DATE_COLUMN = 0;
const READING1_COLUMN = 1;
const READING2_COLUMN = 2;
const READING3_COLUMN = 3;
const CREDITS_COLUMN = 4;
//Max time for scripts is 6 minutes
//Line 37 change value of i to 199 when timeout exceeded to finish execution
function main() {
Logger.log("Script started running...");
createReadingPlanEvents();
}
function createReadingPlanEvents() {
try {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
if (!sheet) {
throw new Error(Sheet "${SHEET_NAME}" does not exist.);
}
const calendar = CalendarApp.getCalendarsByName(CALENDAR_NAME)[0];
if (!calendar) {
throw new Error(`Calendar "${CALENDAR_NAME}" does not exist.`);
}
const data = sheet.getDataRange().getValues();
Logger.log(`Headers: ${data[0].join(", ")}`);
for (let i = 0; i < data.length; i++) {
const row = data[i];
const date = new Date(row[DATE_COLUMN]);
if (isNaN(date.getTime()) || !row[READING1_COLUMN] || !row[READING2_COLUMN] || !row[READING3_COLUMN] || !row[CREDITS_COLUMN]) {
Logger.log(`Skipping row ${i + 1} due to missing or invalid data.`);
continue;
}
Logger.log(`Processing row ${i + 1}: Date = ${date.toDateString()}, Readings = ${row.slice(READING1_COLUMN, READING3_COLUMN + 1).join(", ")}`);
// Parse each reading for label and link
const [reading1Label, reading1Link] = parseReadingData(row[READING1_COLUMN]);
const [reading2Label, reading2Link] = parseReadingData(row[READING2_COLUMN]);
const [reading3Label, reading3Link] = parseReadingData(row[READING3_COLUMN]);
const recurrence = CalendarApp.newRecurrence().addYearlyRule();
// Add events for each reading category
addEvent(calendar, "1. Law & History", date, recurrence, `${reading1Label}\n${reading1Link}\nCredits: ${row[CREDITS_COLUMN]}`, COLOR_LAW_HISTORY);
addEvent(calendar, "2. Wisdom & Prophets", date, recurrence, `${reading2Label}\n${reading2Link}\nCredits: ${row[CREDITS_COLUMN]}`, COLOR_WISDOM_PROPHETS);
addEvent(calendar, "3. New Testament", date, recurrence, `${reading3Label}\n${reading3Link}\nCredits: ${row[CREDITS_COLUMN]}`, COLOR_NEW_TESTAMENT);
}
} catch (error) {
Logger.log(Script encountered an error: ${error.message});
}
}
// Helper function to add an event series to the calendar with error handling and logging
function addEvent(calendar, title, date, recurrence, description, colorId) {
try {
const eventSeries = calendar.createAllDayEventSeries(title, date, recurrence, {
description: ${description}\n\n${SUBSCRIPTION_LINK}
});
eventSeries.setColor(colorId);
Logger.log(Event series created: "${title}" on ${date.toDateString()} with color ID ${colorId});
const eventURL = "https://www.google.com/calendar/event?eid=" + Utilities.base64Encode(eventSeries.getId().split("@")[0] + " " + calendar.getId());
Logger.log(`Event series ID: ${eventURL}`);
} catch (e) {
Logger.log(Error creating event series "${title}" on ${date.toDateString()}: ${e.message});
}
}
// Helper function to parse the reading data (assuming "label - link" format)
function parseReadingData(reading) {
const split = reading.split(" @ ");
const label = split[0].trim();
const link = split[1] ? split[1].trim() : "";
Logger.log(Parsed reading: Label = "${label}", Link = "${link}");
return [label, link];
}