Last active
March 3, 2025 20:07
-
-
Save Boettner-eric/41cabaa207ba4d257478f1d9a7985db2 to your computer and use it in GitHub Desktop.
Obsidian google calendar template
This file contains hidden or 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
const fs = require("fs").promises; | |
const path = require("path"); | |
const TOKEN_PATH = "path to google token files"; | |
async function calendar() { | |
try { | |
const files = await fs.readdir(TOKEN_PATH); | |
const tokenFiles = files.filter((file) => file.endsWith(".json")); | |
if (tokenFiles.length === 0) { | |
console.log("No token files found in directory"); | |
return ""; | |
} | |
const allEvents = []; | |
for (const file of tokenFiles) { | |
const filePath = path.join(TOKEN_PATH, file); | |
const accessToken = await getAccessToken(filePath); | |
if (accessToken) { | |
const events = await listEvents(accessToken); | |
if (events) { | |
allEvents.push(...events); | |
} | |
} | |
} | |
return format_events(allEvents); | |
} catch (error) { | |
console.error("Error reading calendar events:", error); | |
return ""; | |
} | |
} | |
function format_time(date) { | |
return `${date.getHours()}:${String(date.getMinutes()).padStart(2, "0")}`; | |
} | |
async function listEvents(accessToken) { | |
const today = new Date(); | |
const tomorrow = new Date(); | |
tomorrow.setHours(23, 59, 59, 999); | |
const params = new URLSearchParams({ | |
calendarId: "primary", | |
timeMin: today.toISOString(), | |
timeMax: tomorrow.toISOString(), | |
maxResults: 10, | |
singleEvents: true, | |
orderBy: "startTime", | |
}); | |
const data = await fetch({ | |
url: `https://www.googleapis.com/calendar/v3/calendars/primary/events?${params.toString()}`, | |
method: "GET", | |
headers: { authorization: accessToken }, | |
}); | |
const events = data.items; | |
if (!events || events.length === 0) { | |
console.log("No upcoming events found."); | |
return []; | |
} | |
return events; | |
} | |
function format_events(events) { | |
return events.reduce((acc, event) => { | |
const startTime = new Date(event.start.dateTime || event.start.date); | |
startTime.toLocaleTimeString("en-US", { timeZone: "America/Los_Angeles" }); | |
return acc + `- ${event.summary} @ ${format_time(startTime)}\n`; | |
}, ""); | |
} | |
async function getAccessToken(path) { | |
try { | |
const content = await fs.readFile(path); | |
const credentials = JSON.parse(content); | |
const resp = await fetch({ | |
url: "https://oauth2.googleapis.com/token", | |
method: "POST", | |
contentType: "application/x-www-form-urlencoded", | |
body: new URLSearchParams({ | |
client_id: credentials.client_id, | |
client_secret: credentials.client_secret, | |
refresh_token: credentials.refresh_token, | |
grant_type: "refresh_token", | |
}).toString(), | |
}); | |
const { access_token, _expires_in, _id_token, _scope, token_type } = resp; | |
return token_type + " " + access_token; | |
} catch (err) { | |
console.log(err); | |
return null; | |
} | |
} | |
async function fetch(request) { | |
try { | |
const response = await requestUrl(request); | |
if (response.status != 200) { | |
throw new Error(`Response status: ${response.status}`); | |
} | |
return response.json; | |
} catch (error) { | |
console.error(error.message); | |
} | |
} | |
module.exports = calendar; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment