Skip to content

Instantly share code, notes, and snippets.

@MBraedley
Forked from paucoma/gglCalEventsOnSpreadSheet.gs
Last active October 3, 2020 11:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MBraedley/bf9985034d759755c1f0e6b40ef14862 to your computer and use it in GitHub Desktop.
Save MBraedley/bf9985034d759755c1f0e6b40ef14862 to your computer and use it in GitHub Desktop.
Script to read Google Calendar Events and Count total Hours
var gblFromYear = 2020;
var gblFromMonth = 01;
var gblFromDay = 01;
var gblToYear = 2021;
var gblToMonth = 01;
var gblToDay = 01; // Not Included as time is 00:00 of specified day
var gblTimeZone ="GMT-04:00"
//Calendar to Search in
var gblCalendarName = "WorkFromHome";
//Free text search terms to find events that match these terms in any field, except for extended properties.
var gblEventQuery = "";
var gblOutput = [];
//Here are the headers definition for our sheet
gblOutput.push(["Event","Date","Durration"]);
//A global variable for the totalizer of hours
gblLastLine = ["Total","",0];
var totals = {};
function RunMe(){
fillMySheetWithCalendarEventDetails(
gblCalendarName,
gblEventQuery,
new Date(gblFromYear,gblFromMonth-1, gblFromDay),
new Date(gblToYear,gblToMonth-1,gblToDay)
);
}
//new Date(Year, Month,...) Where month goes from 0-11
function RunLast24h(){
var MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
var now = new Date();
var now_pre24h = new Date(now.getTime() - MILLIS_PER_DAY);
fillMySheetWithCalendarEventDetails(
gblCalendarName,
gblEventQuery,
now_pre24h,
now
);
}
function RunToday(){
var MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
var today = new Date();
var tomorrow = new Date(today.getTime() + MILLIS_PER_DAY);
today.setHours(00);
today.setMinutes(00);
tomorrow.setHours(00);
tomorrow.setMinutes(00);
fillMySheetWithCalendarEventDetails(
gblCalendarName,
gblEventQuery,
today,
tomorrow
);
}
function RunYesterday(){
var MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
var today = new Date();
var yesterday = new Date(today.getTime() - MILLIS_PER_DAY);
today.setHours(00);
today.setMinutes(00);
yesterday.setHours(00);
yesterday.setMinutes(00);
fillMySheetWithCalendarEventDetails(
gblCalendarName,
gblEventQuery,
yesterday,
today
);
}
function fillMySheetWithCalendarEventDetails(myCalendarName,myEventName,myFromDate,myToDate){
var mySheet = SpreadsheetApp.getActiveSheet();
var eventsInTime = getMyCalendarEventsInTime(myCalendarName,myEventName,myFromDate,myToDate);
var range = mySheet.getRange(mySheet.getActiveCell().getRow(),mySheet.getActiveCell().getColumn(),2,1);
if(eventsInTime){
processDetailsFromMyEvents(eventsInTime);
range = mySheet.getRange(mySheet.getActiveCell().getRow(),mySheet.getActiveCell().getColumn(),
gblOutput.length,gblOutput[0].length);
range.setValues(gblOutput);
}else{
range.setValues([["Script Errors"], [Logger.getLog()]]);
}
}
//Pre: Requires an existing event
//Post: Returns an array of values
function getDetail1FromEvent(myEvent){
var myDetails = [];
var myStartDate;
var myEndDate;
var myDiffWorkDays = 0;
if (myEvent.start.date) {
// All-day event if this field exists. Assume 8 hours.
myStartDate = new Date(getDateFromIso(myEvent.start.date));
myEndDate = new Date(getDateFromIso(myEvent.end.date));
myDiffWorkDays = ((myEndDate - myStartDate)/(1000 * 60 * 60 * 24));
} else {
myStartDate = new Date(getDateFromIso(myEvent.start.dateTime));
myEndDate = new Date(getDateFromIso(myEvent.end.dateTime));
myDiffWorkDays = ((myEndDate - myStartDate)/(1000 * 60 * 60 * 8));
}
myDetails = [myEvent.summary,Utilities.formatDate(myStartDate,gblTimeZone,"YYYY/MM/dd"), myDiffWorkDays];
if ( !(myEvent.summary in totals) )
{
totals[myEvent.summary] = myDiffWorkDays;
}
else
{
totals[myEvent.summary] += myDiffWorkDays;
}
//gblLastLine[2] is my hours Totalizer
gblLastLine[2] = gblLastLine[2] + myDiffWorkDays;
return myDetails;
}
// Chcek : https://developers.google.com/calendar/v3/reference/events#resource for a list
function processDetailsFromMyEvents(myEvents){
if (myEvents.items && myEvents.items.length > 0) {
for (var i = 0; i < myEvents.items.length; i++) {
var event = myEvents.items[i];
var details1 = getDetail1FromEvent(event);
if (details1.length > 0){
gblOutput.push(details1);
}
}
if (gblOutput.length > 1)
{
gblOutput.push(gblLastLine);
gblOutput.push(["", "", ""]);
for (const [key, value] of Object.entries(totals))
{
gblOutput.push([key, "", value]);
}
}
} else {
Logger.log('No events found.');
}
}
function getMyCalendarEventsInTime(myCalendarName,myEventName,myFromDate,myToDate){
Logger.log("%s <-> %s", myFromDate.toISOString(), myToDate.toISOString());
var myCalId = getCalendarKey(myCalendarName);
Logger.log('Calendar Name "'+ myCalendarName + '" associated to key : <'+ myCalId+'>');
try{
var myEvents = Calendar.Events.list(myCalId, {
timeMin: myFromDate.toISOString(),
timeMax: myToDate.toISOString(),
q: myEventName,
singleEvents: true,
orderBy: 'startTime'
});
} catch (e) {
Logger.log('Calendar.Events.list(...) yielded an error: ' + e);
}
//Logger.log(myEvents);
return myEvents;
}
function getCalendarKey(myKey) {
var calendars, pageToken;
var myCalId = '';
do {
calendars = Calendar.CalendarList.list({
maxResults: 100,
pageToken: pageToken
});
if (calendars.items && calendars.items.length > 0) {
for (var i = 0; i < calendars.items.length; i++) {
var calendar = calendars.items[i];
if (calendar.summary==myKey){
myCalId = calendar.id;
return myCalId;
}
}
if (myCalId == ''){
Logger.log('Specified gblCalendarName "'+myKey+'" not found amoung your Calendars.');
}
} else {
Logger.log('No calendars found.');
}
pageToken = calendars.nextPageToken;
} while (pageToken);
return myCalId;
}
// Function posted by PAUL SOWDEN
// http://delete.me.uk/2005/03/iso8601.html
function getDateFromIso(string) {
try{
var aDate = new Date();
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\\.([0-9]+))?)?" +
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
//var d = string.match(new RegExp(regexp));
var d = string.match(regexp);
var offset = 0;
//var d = new Date(year, month, day, hours, minutes, seconds, milliseconds);
var date = new Date(d[1], 0, 1);
if (d[3]) { date.setMonth(d[3] - 1); }
if (d[5]) { date.setDate(d[5]); }
if (d[7]) { date.setHours(d[7]); }
if (d[8]) { date.setMinutes(d[8]); }
if (d[10]) { date.setSeconds(d[10]); }
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
time = (Number(date) + (offset * 60 * 1000));
return aDate.setTime(Number(time));
} catch(e){
return;
}
}
/*
**Steps**
1. Go to your google Drive and start a new Empty SpreadSheet.
2. Go to the Menu: Tools --> Script Editor --> Blank Document.
3. Copy+paste the code into the new Code.gs and Save the File
4. Go to the Menu: Resources --> Advanced Google Services
5. Scroll till you find the **Calendar API** and turn it **ON**
6. Once enabled return to the window with the code and click OK to return.
7. Modify the gbl... vars to suit your interest.
8. Go to the Menu --> Run --> RunMe
9. An Authorization request will popup, (only the first time you run it)
9a. Select your google account, click continue
9b. It will say "This App isn't verified", click Advanced, then Goto <project name> (unsafe)
9c. It will tell you which permission are required, Click Allow
10. If all went well you should be able to return to the Sheet and see the results.
----
Run --> RunMe : Runs Using the Defined Range
Run --> RunLast24h : Runs using the last 24h as date range
Run --> RunToday : events from Today
Run --> RunYesterday: events from Yesterday
*/
@paucoma
Copy link

paucoma commented Oct 3, 2020

Thanks for Sharing your Massages to the code, it has motivated me to improve the original version to include a summary grouped by event names as you have done and include all day events aswell.
Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment