Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save gndpwnd/e2759965e5b9a40431aeced86e1cb42b to your computer and use it in GitHub Desktop.

Select an option

Save gndpwnd/e2759965e5b9a40431aeced86e1cb42b to your computer and use it in GitHub Desktop.

credit: DjMuffinTops

Google-Calendar-API-to-Discord-Webhook

Copy and paste this script into a Google Cloud Apps Script project at https://script.google.com

You will need to replace CHANNEL_POST_URL and CALENDAR_ID in the script with your Discord Webhook URL and your Google Calendar's Calendar ID respectively. You can also modify minInAdvance to change the amount of minutes ahead of time the events should show up. The default value should be 1 minute.

Then, you must enable Calendar API under Services on the left side of the Apps Script Page. Click the + button next to Services and look for Calendar API and enable it. v3 of the Calendar API should work fine.

You Will then need to setup a trigger to run the postEventsToChannel function every minute image

You should see any events that will start within the next minute posted into an embed into the discord channel your webhook was on

image

// TODO: loop through updatetimes[] to get multiple notifications about events starting.
// This Google Apps Script Will Send a POST to a Discord Webhook creating embed messages of any events starting within the next minute of execution.
// Any events that have already started will not appear.
// This script should be triggered every minute using Google Triggers.
const CHANNEL_POST_URL = "https://discord.com/api/webhooks/1003371753772437534/43lGojtgtcLZFgwWr3LgjC665M4lt2q4ml7MaVHjqUkyO_0J9jPmNuijhe7A6Rwzr1hq";
const CALENDAR_ID = "mscroboticsdev@gmail.com";
const NO_VALUE_FOUND = "N/A";
const minsInAdvance = 15; // Set the number of minutes in advance you'd like events to be posted to discord. Must be 1 or greater
// Import Luxon
eval(UrlFetchApp.fetch('https://cdn.jsdelivr.net/npm/luxon@2.0.2/build/global/luxon.min.js').getContentText());
let DateTime = luxon.DateTime;
const DTnow = DateTime.now().startOf('minute'); // Will consider 'now' as the beginning the minute to deal with second offsets issues with trigger over time.
function postEventsToChannel() {
//var updatetimes = [10080,4320,1440,240,120,60,30,15,0]
//var arrayLength = updatetimes.length;
//for (var i = 0; i < arrayLength; i++) {
// minsInAdvance = updatetimes[i]
//}
// .list parameters. See https://developers.google.com/calendar/api/v3/reference/events/list?hl=en
let optionalArgs = {
timeMin: DTnow.toISO(),
timeMax: DTnow.plus({minutes: minsInAdvance}).toISO(), // Will only show events starting in the next x minutes
showDeleted: false,
singleEvents: true,
orderBy: 'startTime'
};
let response = Calendar.Events.list(CALENDAR_ID, optionalArgs);
let events = response.items;
if (events.length > 0) {
for (i = 0; i < events.length; i++) {
let event = events[i];
let ISOStartDate = event.start.dateTime || event.start.date;
let ISOEndDate = event.end.dateTime || event.end.date;
// The Calendar API's .list function will continously return events whose endDate has not been reached yet (timeMin is based on the event's end time)
// Since this script is meant to run every minute, we have to skip these events ourselves
if (DateTime.fromISO(ISOStartDate) < DTnow.plus({minutes: minsInAdvance - 1})) {
Logger.log(`Event ${event.summary} [${event.id}] has already started. Skipping`);
continue;
}
// Build the POST request
let options = {
"method": "post",
"headers": {
"Content-Type": "application/json",
},
"payload": JSON.stringify({
"content": "‌",
"embeds": [{
"author": {
"name": `${event.summary}`,
"icon_url": "https://cdn.discordapp.com/attachments/696400605908041794/888874282950750238/1200px-Google_Calendar_icon_28202029.png"
},
"timestamp": DTnow.toISO(),
"description":`[Google Event Link](${event.htmlLink})`,
"color": 1425196,
"fields":[
{
"name":"Start Time",
"value": ISOToDiscordUnix(ISOStartDate) ?? NO_VALUE_FOUND,
"inline":false
},
{
"name":"End Time",
"value":ISOToDiscordUnix(ISOEndDate) ?? NO_VALUE_FOUND,
"inline":false
},
{
"name":"Location",
"value":event.location ?? NO_VALUE_FOUND,
"inline":false
},
{
"name":"Description",
"value":event.description ?? NO_VALUE_FOUND,
"inline":false
}
]
}]
})
};
Logger.log(options, null, 2);
UrlFetchApp.fetch(CHANNEL_POST_URL, options);
}
} else {
Logger.log(`No events starting within ${minsInAdvance} minute(s) found.`);
}
}
/**
* Converts an ISO string into a discord formatted timestamp
*/
function ISOToDiscordUnix(isoString) {
return `<t:${Math.floor(DateTime.fromISO(isoString).toSeconds())}:F>`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment