Last active
August 13, 2021 15:00
-
-
Save adamjohnson/bf601ea10611a0a46566eb66060b332d to your computer and use it in GitHub Desktop.
Pull events from a public Google Calendar using the Google Calendar API. Based off of: https://stackoverflow.com/a/56496854/908059
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Google Calendar API</title> | |
</head> | |
<body> | |
<h1>Events:</h1> | |
<div id="js-gcal-event"> | |
<!-- SVG loader By Sam Herbert (@sherb). http://goo.gl/7AJzbL --> | |
<svg aria-hidden="true" width="35" height="35" viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg" stroke="#2c2a29"><g fill="none" fill-rule="evenodd" stroke-width="2"><circle cx="22" cy="22" r="1"><animate attributeName="r" begin="0s" dur="1.8s" values="1; 20" calcMode="spline" keyTimes="0; 1" keySplines="0.165, 0.84, 0.44, 1" repeatCount="indefinite"/><animate attributeName="stroke-opacity" begin="0s" dur="1.8s" values="1; 0" calcMode="spline" keyTimes="0; 1" keySplines="0.3, 0.61, 0.355, 1" repeatCount="indefinite"/></circle><circle cx="22" cy="22" r="1"><animate attributeName="r" begin="-0.9s" dur="1.8s" values="1; 20" calcMode="spline" keyTimes="0; 1" keySplines="0.165, 0.84, 0.44, 1" repeatCount="indefinite"/><animate attributeName="stroke-opacity" begin="-0.9s" dur="1.8s" values="1; 0" calcMode="spline" keyTimes="0; 1" keySplines="0.3, 0.61, 0.355, 1" repeatCount="indefinite"/></circle></g></svg> | |
<p>Loading...</p> | |
</div> | |
<p>Solution from László L. L. on <a href="https://stackoverflow.com/a/56496854/908059">Stack Overflow</a>, modified to use lighter dependencies (MomentJS > DayJS, jQuery > vanilla javascript).</p> | |
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?version=3.52.1&features=Array.prototype.forEach,console,Date.prototype.toISOString,document,Intl,Map,Promise,Set"></script> | |
<script src="https://unpkg.com/[email protected]/dayjs.min.js"></script> | |
<script src="https://unpkg.com/[email protected]/plugin/localizedFormat.js"></script> | |
<script>dayjs.extend(window.dayjs_plugin_localizedFormat)</script> | |
<script src="https://apis.google.com/js/api.js"></script> | |
<script src="google-calendar.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This solution makes use of "simple access" to google, providing only an API Key. | |
* This way we can only get access to public calendars. To access a private calendar, | |
* we would need to use OAuth 2.0 access. | |
* | |
* Solution from László L. L. on Stack Overflow: | |
* https://stackoverflow.com/a/56496854/908059 | |
* | |
* Dependencies: day.js & the localizedFormat plugin for day.js: | |
* https://day.js.org/en/ | |
* | |
* "Simple" vs. "Authorized" access: https://developers.google.com/api-client-library/javascript/features/authentication | |
* Examples of "simple" vs OAuth 2.0 access: https://developers.google.com/api-client-library/javascript/samples/samples#authorizing-and-making-authorized-requests | |
* | |
* We will make use of "Option 1: Load the API discovery document, then assemble the request." | |
* as described in https://developers.google.com/api-client-library/javascript/start/start-js | |
*/ | |
function printCalendar () { | |
// The "Calendar ID" from your calendar settings page, "Calendar Integration" secion: | |
var calendarId = '[email protected]'; | |
// 1. Create a project using google's wizzard: https://console.developers.google.com/start/api?id=calendar | |
// 2. Create credentials: | |
// a) Go to https://console.cloud.google.com/apis/credentials | |
// b) Create Credentials / API key | |
// c) Since your key will be called from any of your users' browsers, set "Application restrictions" to "None", | |
// leave "Website restrictions" blank; you may optionally set "API restrictions" to "Google Calendar API" | |
var apiKey = 'YOUR_API_KEY'; | |
// You can get a list of time zones from here: http://www.timezoneconverter.com/cgi-bin/zonehelp | |
var userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; | |
if (!userTimeZone) { | |
userTimeZone = 'America/New_York'; | |
} | |
// Initializes the client with the API key and the Translate API. | |
gapi.client.init({ | |
'apiKey': apiKey, | |
// Discovery docs docs: https://developers.google.com/api-client-library/javascript/features/discovery | |
'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'] | |
}).then(function () { | |
// Use Google's "apis-explorer" for research: https://developers.google.com/apis-explorer/#s/calendar/v3/ | |
// Events: list API docs: https://developers.google.com/calendar/v3/reference/events/list | |
return gapi.client.calendar.events.list({ | |
'calendarId': calendarId, | |
'timeZone': userTimeZone, | |
'singleEvents': true, | |
'timeMin': (new Date()).toISOString(), // gathers only events not happened yet | |
'maxResults': 20, | |
'orderBy': 'startTime' | |
}); | |
}).then(function (response) { | |
console.log(response); // TODO: Remove! | |
if (response.result.items) { | |
var getNowPlayingDiv = document.getElementById('js-gcal-event'); // Make sure your HTML has This ID! | |
// Create a table with events: | |
var calendarRows = ['<table class="gcal-event"><tbody>']; | |
response.result.items.forEach(function (entry) { | |
var eventDate = dayjs(entry.start.dateTime).format('LLL'); // eg: March 26, 2020 6:00 PM | |
var eventEndsAt = dayjs(entry.end.dateTime).format('LT'); // eg: 7:00 PM | |
calendarRows.push('' + | |
'<tr class="gcal-event__tr">' + | |
'<td class="gcal-event__td-time">' + | |
'<time datetime="' + entry.start.dateTime + '" class="gcal-event__time-start">' + eventDate + '</time> - ' + | |
'<time datetime="' + entry.end.dateTime + '" class="gcal-event__time-end">' + eventEndsAt + '</time>' + | |
'</td>' + | |
'<td class="gcal-event__td-event-name">' + entry.summary + '</td>' + | |
'</tr>'); | |
}); | |
calendarRows.push('</tbody></table>'); | |
getNowPlayingDiv.innerHTML = calendarRows.join(''); | |
} | |
}, function (reason) { | |
console.log('Error: ' + reason.result.error.message); | |
}); | |
} | |
// Loads the JavaScript client library and invokes `start` afterwards. | |
gapi.load('client', printCalendar); |
I included a short if else to avoid that issue for all-day events:
if (entry.start.date == undefined) {var eventDate = dayjs(entry.start.dateTime).format('DD.MM.YY H:mm');} // eg: March 26, 2020 6:00 PM
else {var eventDate = dayjs(entry.start.date).format('DD.MM.YY');}
👍 Good catch guys. Thanks.
i get a console error:
TypeError: e.fromNow is not a function
at o (humanTime.ts:32)
at s (humanTime.tsx:15)
at e.view (TerminalPost.js:26)
at Function.a (render.js:30)
at render.js:155
at render.js:160
at l (render.js:66)
at u (render.js:50)
at render.js:134
at l (render.js:63)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hi there!
I was getting my current date/time instead of the event date. My html looked like this:
<time datetime="undefined" class="gcal-event__time-start">
It seems their response has changed on
entry.start.dateTime
toentry.start.date
edit: it seems thats the response for all-day events, if you input a time, it responds with
dateTime