Daily agenda for all Google owned calendars - google-apps-script

I'm trying to get daily agenda of the events from all my calendars (personal, holidays, specific tasks etc) sent in one email.
I use the following code for one specific calendar, but don't know how to add all other owned calendars in the same code, is that even possible?
function sendAllCalendarsAgenda() {
var cal = CalendarApp.getOwnedCalendarById('?????????#group.calendar.google.com');
var events = cal.getEventsForDay(new Date());
var mailto = 'myEmailAddress#gmail.com';
if (events.length > 0) {
var body = 'Google Calendar - Events' + 'nn';
var tz = Session.getScriptTimeZone();
for (var i = 0; i < events.length; i++) {
body += Utilities.formatDate(events[i].getStartTime(), tz, 'MM:dd HH:mm') + ' ~ ';
body += Utilities.formatDate(events[i].getEndTime(), tz, 'MM:dd HH:mm') + ' :';
body += events[i].getTitle() + 'n';
}
MailApp.sendEmail(mailto, 'Google Calender - Summary', body);
}
}

Try this:
function sendAllCalendarsAgenda() {
const cals = CalendarApp.getAllCalendars();
let o = [];
var body = 'Google Calendar - Events Summary' + '\n\n';
cals.forEach(cal => {
var events = cal.getEventsForDay(new Date());
var mailto = 'myEmailAddress#gmail.com';
if (events.length > 0) {
var tz = Session.getScriptTimeZone();
for (var i = 0; i < events.length; i++) {
body += event[i].getTitle();
body += Utilities.formatDate(events[i].getStartTime(), tz, 'MM:dd HH:mm') + ' ~ ';
body += Utilities.formatDate(events[i].getEndTime(), tz, 'MM:dd HH:mm') + ' :';
}
o.push(body);
}
});
MailApp.sendEmail(mailto, 'Google Calendar - Summary', a.join('\n\n'));
}

Related

Exception: Service invoked too many times for one day: gmail - Gmail Auto Archive

Triggering code below every 15 minutes to archive labels fed from a google sheet and getting this error:
Exception: Service invoked too many times for one day: gmail.
at archiveThreadsByLabel(archiveOldMessagesByLabelAndCategory:52:24)
at go(archiveOldMessagesByLabelAndCategory:21:15)
Any edit suggestions so I can run it every 15 minutes? Super new to this so any help would be greatly appreciated.
Original source:
https://github.com/warwickallen/GMail-Archive-old-messages-by-label-and-category
Code:
function go() {
var fname = "Archive old messages by label and category";
var files = DriveApp.getFilesByName(fname);
var spreadsheet;
while ((typeof spreadsheet !== 'object') && files.hasNext())
{
try
{
spreadsheet = SpreadsheetApp.openById(files.next().getId());
}
catch (e)
{
Logger.log("WARNING: " + e.message)
}
}
if (typeof spreadsheet !== 'object')
{
Logger.log("FATAL: Cannot find a Google speadsheet called '" + fname + "'.");
return -1;
}
var count = archiveThreadsByLabel(getSheetData(spreadsheet, "label"));
count += archiveThreadsByCategory(getSheetData(spreadsheet, "category"));
Logger.log("INFO: Archived " + count + " threads.");
}
function getSheetData(spreadsheet, sheet_name)
{
var data_array = spreadsheet.getSheetByName(sheet_name).getDataRange().getValues();
data_array.shift(); // Remove the headings row.
var data_object = new Object;
data_array.forEach(function(datum) {data_object[datum[0]] = datum[1]});
return data_object;
}
function archiveThreadsByLabel(minAgesInHours) {
var blockSize = 50;
var start = 0;
var count = 0;
while (1)
{
var threads = GmailApp.getInboxThreads(start, blockSize);
if (threads.length < 1) break;
start += threads.length;
for (var label in minAgesInHours)
{
var maxTime = new Date();
var localCount = 0;
maxTime.setTime(maxTime.getTime() - minAgesInHours[label]*3600000);
for (var i = 0; i < threads.length; i++)
if (threads[i].getLastMessageDate() < maxTime)
{
var labels = threads[i].getLabels();
for (var j = 0; j < labels.length; j++)
if (labels[j].getName() == label)
{
Logger.log("INFO:\n " + threads[i].getFirstMessageSubject() + "\n " + threads[i].getLastMessageDate());
threads[i].moveToArchive();
localCount++;
break;
}
}
Logger.log("INFO: Archived " + localCount + " threads labelled '" + label + "' that are older than " + maxTime);
count += localCount;
}
Utilities.sleep(1000); // Google doesn't like it if GmailApp API calls are called too often in a short period of time.
}
return count;
}
function archiveThreadsByCategory(minAgesInHours) {
var blockSize = 50;
var count = 0;
for (var category in minAgesInHours)
{
var start = 0;
var localCount = 0;
var maxTime = new Date();
maxTime.setTime(maxTime.getTime() - minAgesInHours[category]*3600000);
var query = 'in:inbox category:' + category + ' before:' + maxTime.getFullYear() + '-' + (maxTime.getMonth() + 1) + '-' + (maxTime.getDate() + 1);
while (1)
{
var threads = GmailApp.search(query, start, blockSize);
if (threads.length < 1) break;
start += threads.length;
for (var i = 0; i < threads.length; i++)
if (threads[i].getLastMessageDate() < maxTime)
{
Logger.log("\n " + threads[i].getFirstMessageSubject() + "\n " + threads[i].getLastMessageDate());
threads[i].moveToArchive();
localCount++;
}
Utilities.sleep(1000); // Google doesn't like it if GmailApp API calls are called too often in a short period of time.
}
Logger.log("INFO: Archived " + localCount + " threads categorisaed as '" + category + "' that are older than " + maxTime);
count += localCount;
}
return count;
}
We have quotas in apps script.
Your error means that you reached the quota of reading/writing emails in a day.
20000 for consumer/free edition, 50000 for workspace accounts.
Easiest thing you can do is make the trigger interval longer that it won't go past the quota.
Note:
The quota resets daily (as per name suggests) although I'm not sure what time exactly.
Use MailApp.getRemainingDailyQuota() to check the remaining quota you have. You can check what methods does affect the quota by checking this everytime a method is executed in a test script. That way, you can estimate what your interval should be so you will not get past it.

Mark auto-replied emails a certain label during out of work hours

Currently I am using the following code, which works fine but I wonder if it is possible that I can mark emails which were auto-replied by a specific label, so that I can check when I return to work?
function autoReply() {
var interval = 5; // if the script runs every 5 minutes; change otherwise
var date = new Date();
var day = date.getDay();
var hour = date.getHours();
if ([4,5,6,0].indexOf(day) > -1 || (day == 1 && hour < 9) || (day == 3 && hour >= 17)) {
var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
var threads = GmailApp.search('is:inbox after:' + timeFrom);
var files = DriveApp.getRootFolder().getFilesByName('autoreply.html');
var htmlbody;
while (files.hasNext()) {
var file = files.next();
htmlbody = file.getBlob().getDataAsString('utf8');
}
for (var i = 0; i < threads.length; i++) {
if (threads[i].isUnread()){
threads[i].reply("", {
htmlBody: htmlbody
});
threads[i].markRead();
threads[i].markImportant();
}
}
}
}
So far, I can only get threads[i].markImportantwork, but threads[i].markStarred or other customised labels won't.
You need to use the method starMessages(messages)
Sample:
for (var i = 0; i < threads.length; i++) {
if (threads[i].isUnread()){
threads[i].reply("", {
htmlBody: htmlbody
});
GmailApp.starMessages(threads[i].getMessages());
}
}

Google calendar script title update

Can anyone help me to get the following script to work for calendarseries. It works perfectly for all single calendar events. But it there is a recurring event it only changes the colour and does not update the title.
I want the following to happen
User creates an event and they invite the shared calendar. This then updates the event title with the users name.
The even title only needs to be updated on the shared calendar
function Update_Business() {
var mycal = "xxxxxxxxxxxxxxxxxx#group.calendar.google.com";
var mainCal = "xxxxxxxxxxx#xxxxxxxxxx.com";
var First = new Date();
First.setHours(0, 0, 0, 0);
var Last = new Date();
Last.setDate(First.getDate() + 30);
var cal = CalendarApp.getCalendarById(mycal);
var events = cal.getEvents(First, Last, { search: '-At' });
for (var i = 0; i < events.length; i++) {
var ev = events[i];
Logger.log(ev.getTitle())
var title = ev.getEventSeries().getTitle();
var eventId = events[i]
var title = events[i].getEventSeries().getTitle();
var creator = events[i].getEventSeries().getCreators();
var contact = ContactsApp.getContact(creator);
var CreatorName = contact.getNickname()
events[i].getEventSeries().setTitle(CreatorName + " at " + title).setColor(11);
}
}
I haven't tested this code but I think it might help.
function Update_Business()
{
var mycal = "xxxxxxxxxxxxxxxxxx#group.calendar.google.com";
var mainCal = "xxxxxxxxxxx#xxxxxxxxxx.com";
var min=60 * 1000;
var hr=60 * min;
var day=24 * hr;
var wk=7 * day;
var First = new Date(new Date().setHours(0,0,0));
var Last = new Date(start.valueOf() + (30 * day));
var cal = CalendarApp.getCalendarById(mycal);
var events = cal.getEvents(First, Last, { search: '-At' });
for (var i = 0; i < events.length; i++)
{
var ev = events[i];
Logger.log(ev.getTitle())
var title,eventID,creator,contact,creatorname;
if(ev.isRecurringEvent())
{
title = ev.getEventSeries().getTitle();
eventID=ev.getEventSeries().getId();
creator=ev.getEventSeries().getCreators();
contact = ContactsApp.getContact(creator);
creatorname = contact.getNickname();
ev.getEventSeries().setTitle(creatorname + " at " + title).setColor(11);
}
else
{
title=ev.getTitle();
eventID=ev.getId();
creator=ev.getCreators();
contact = ContactsApp.getContact(creator);
creatorname = contact.getNickname();
ev.setTitle(creatorname + " at " + title).setColor(11);
}
}
}

RSVP to Calendar Event with Google App Script

Let me first express that programming is not my speciality so I will do my best to explain what I'm working on. At my employer, we have a company activity calendar on a free Gmail account and then we have separate accounts through Google Apps (paid) for each employee. I'm working on a script that pulls the events from said calendar, adds them to an agenda-styled email, and then sends the email to the Google Apps accounts. Our goal is to allow the employee to open the email, click an event he/she is interested in, and then RSVP to the event. It might be worth noting, the script is saved/running under the free account.
We have most of the code working but the RSVP feature is not appearing when the event is opened. We are making sure that the Google App account is logged in when the agenda email is viewed and that the account is an invited guest to the event. I suspect this is due to some type of authentication issue in the way we are generating the eventURL. I also believe this isn't working because the script is running as the "user" who already owns the calendar. If these two suspicions are true, I'm not sure how to fix it.
Here is the code for your review. I've removed the HTML formatting and our private calendar addresses.
function ordinal_suffix_of(i) {
var j = i % 10,
k = i % 100;
if (j == 1 && k != 11) {
return i + "st";
}
if (j == 2 && k != 12) {
return i + "nd";
}
if (j == 3 && k != 13) {
return i + "rd";
}
return i + "th";
}
function myFunction() {
var calendar = CalendarApp.getCalendarById('HIDDEN#group.calendar.google.com');
var now = new Date();
var oneWeekFromNow = new Date(now.getTime() + 604800000);
var twoWeeksFromNow = new Date(now.getTime() + 1209600000);
var threeWeeksFromNow = new Date(now.getTime() + 1814400000);
var eventsOneWeek = calendar.getEvents(now, oneWeekFromNow);
var eventsTwoWeeks = calendar.getEvents(oneWeekFromNow, twoWeeksFromNow);
var eventsThreeWeeks = calendar.getEvents(twoWeeksFromNow, threeWeeksFromNow);
var body = '';
for (i = 0; i < eventsOneWeek.length; i++) {
var day = ordinal_suffix_of(Utilities.formatDate(eventsOneWeek[i].getStartTime(), "GMT-0400", "d"));
var splitEventId = eventsOneWeek[i].getId().split('#');
var eventURL = "https://www.google.com/calendar/event?eid=" + Utilities.base64Encode(splitEventId[0] + " " + "HIDDEN#group.calendar.google.com");
var eventTitle = eventsOneWeek[i].getTitle();
var eventStart = Utilities.formatDate(eventsOneWeek[i].getStartTime(), "GMT-0400", "MMMMM");
eventStart += ' ' + day;
eventStart += Utilities.formatDate(eventsOneWeek[i].getStartTime(), "GMT-0400", " 'at' hh:mm a");
body += '';
}
for (i = 0; i < eventsTwoWeeks.length; i++) {
var day = ordinal_suffix_of(Utilities.formatDate(eventsTwoWeeks[i].getStartTime(), "GMT-0400", "d"));
var splitEventId = eventsTwoWeeks[i].getId().split('#');
var eventURL = "https://www.google.com/calendar/event?eid=" + Utilities.base64Encode(splitEventId[0] + " " + "HIDDEN#group.calendar.google.com");
var eventTitle = eventsTwoWeeks[i].getTitle();
var eventStart = Utilities.formatDate(eventsTwoWeeks[i].getStartTime(), "GMT-0400", "MMMMM");
eventStart += ' ' + day;
eventStart += Utilities.formatDate(eventsTwoWeeks[i].getStartTime(), "GMT-0400", " 'at' hh:mm a");
body += '';
}
for (i = 0; i < eventsThreeWeeks.length; i++) {
var day = ordinal_suffix_of(Utilities.formatDate(eventsThreeWeeks[i].getStartTime(), "GMT-0400", "d"));
var splitEventId = eventsThreeWeeks[i].getId().split('#');
var eventURL = "https://www.google.com/calendar/event?eid=" + Utilities.base64Encode(splitEventId[0] + " " + "HIDDEN#group.calendar.google.com");
var eventTitle = eventsThreeWeeks[i].getTitle();
var eventStart = Utilities.formatDate(eventsThreeWeeks[i].getStartTime(), "GMT-0400", "MMMMM");
eventStart += ' ' + day;
eventStart += Utilities.formatDate(eventsThreeWeeks[i].getStartTime(), "GMT-0400", " 'at' hh:mm a");
body += '';
}
GmailApp.sendEmail('HIDDEN#email.com', 'Testing Calendar Agenda', body,{'htmlBody':body});
}
Thank you in advance for any insight/help you can share! We greatly appreciate it!
Edit:
I copied the script over to my Google Apps account and adjusted the code to pull from my default calendar instead. I then created a new event on my calendar and invited my colleague to it. When I run the script and open the event, it displays an option to change my RSVP. When my colleague opens the same link, it displays the exact same option to change my RSVP status and nothing for his RSVP. This confirms that it's not isolated to the calendar or account and is specific to the link and how it's generated.

Trouble getting Google Sheets to Push to Calendar

I'm having a terrible time getting this code to work. I'm learning a lot, but I'm very much a beginner.
Here's the script:
//push new events to calendar function pushToCalendar() {
//spreadsheet variables
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange(1,1,5,25);
var values = range.getValues();
//calendar variables
var calendar = CalendarApp.getCalendarById('xxxx')
var numValues = 0; for (var i = 0; i < values.length; i++) {
//check to see if name and type are filled out - date is left off because length is "undefined"
if ((values[i][0].length > 0) && (values[i][2].length > 0)) {
//check if it's been entered before
if (values[i][16]!= 'y') {
//create event https://developers.google.com/apps-script/class_calendarapp#createEvent
var newEventTitle = 'values[i][1]' + ' ' + values[i][15] + ' - ' + values[i][3] + ' - ' + values[i][10] + ' Driver: Needed';
var newEvent = calendar.createAllDayEvent(newEventTitle, values[i][8]);
//get ID
var newEventId = newEvent.getId();
//mark as entered, enter ID
sheet.getRange(i+2,16).setValue('y');
sheet.getRange(i+2,17).setValue(newEventId);
} //could edit here with an else statement
}
numValues++; }
And here's a link to a dummy:
https://docs.google.com/spreadsheets/d/1gBXtHjEhnNSEkJYq2upCWtwkj1ZLWiUYv6KSuMH8Nds/edit?usp=sharing
There are few errors with code:
1.//push new events to calendar function pushToCalendar(). As you included the function statement in the comments, the whole statment was commented out.
For loop should start from i=1. This is because, when you take i=0, this is referred to as the name of columns row.
sheet.getRange(i+2,16) should be changed to sheet.getRange(i+1,16).
In var values = range.sheet.getRange(1, 1, sheet.getLastRow(), 25).getValues();
Here the code:
function pushToCalendar() {
//spreadsheet variables
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange(1,1,5,25);
var values = range.getValues();
Logger.log(values.length);
//calendar variables
var calendar = CalendarApp.getCalendarById('your calendar ID')
var numValues = 0;
for (var i = 1; i < values.length; i++) {
var check = values[i][0];
//check to see if name and type are filled out - date is left off because length is "undefined"
if ((values[i][0]) && (values[i][2].length > 0)) {
//check if it's been entered before
if (values[i][16]!= 'y') {
//create event https://developers.google.com/apps script/class_calendarapp#createEvent
var newEventTitle = 'values[i][1]' + ' ' + values[i][15] + ' - ' + values[i][3] + ' - ' + values[i][10] + ' Driver: Needed';
Logger.log(i);
Logger.log(values[i][8]);
var newEvent = calendar.createAllDayEvent(newEventTitle, values[i][8]);
//get ID
var newEventId = newEvent.getId();
//mark as entered, enter ID
sheet.getRange(i+1,16).setValue('y');
sheet.getRange(i+1,17).setValue(newEventId);
} //could edit here with an else statement
}
}
}
I tried the above code and was able to create events in my calendar.Let me know if you have any questions