Skip to content

Instantly share code, notes, and snippets.

@NathanAdhitya
Last active July 18, 2020 14:20
Show Gist options
  • Save NathanAdhitya/be71081064527ea2743878734f19109b to your computer and use it in GitHub Desktop.
Save NathanAdhitya/be71081064527ea2743878734f19109b to your computer and use it in GitHub Desktop.
a google classroom to discord webhook. WARNING: not the most efficient method (look: push notifs [can't afford that]). this takes (amount of classes * 2)+1 requests / run.
/**
* @file Enhances student laziness by automatically posting classroom announcements and assignments through a Discord Webhook.
* @author Nathan Adhitya <me@natha.my.id>
*/
/*
KNOWN THINGS THIS THING WON'T ACCOUNT FOR:
- Google servers cutting the amount of data returned is not accounted for.
- Updates to existing announcement/course works
- Support for class material?
*/
const scriptProperties = PropertiesService.getScriptProperties();
const hook = scriptProperties.getProperty("discordWebhook");
// Utility functions
function listAllCourses() {
const response = Classroom.Courses.list();
const courses = response.courses;
return Array.prototype.filter.call(courses, (element) => element.courseState === "ACTIVE");
}
function getNewEntries(course) {
const responseA = Classroom.Courses.Announcements.list(course.id);
const responseB = Classroom.Courses.CourseWork.list(course.id);
const announcements = responseA.announcements;
const courseWorks = responseB.courseWork;
const materials = course.
// Now, let's get the newest ones.
// TODO: Make this more efficient, just cut off the array since it is sorted descending.
const lastUpdate = Number(scriptProperties.getProperty(`${course.id}_lastUpdate`));
if (lastUpdate) {
const filteredAnnouncements = !announcements ? null : announcements.filter((announcement) => new Date(announcement.creationTime).getTime() > lastUpdate);
const filteredCourseWorks = !courseWorks ? null : courseWorks.filter((announcement) => new Date(announcement.creationTime).getTime() > lastUpdate);
// Update the last update data.
scriptProperties.setProperty(`${course.id}_lastUpdate`, String(Date.now()));
return {announcements: filteredAnnouncements, courseWorks: filteredCourseWorks}
}
// Update the last update data.
scriptProperties.setProperty(`${course.id}_lastUpdate`, String(Date.now()));
return {announcements, courseWorks};
}
function test(){
const courses = listAllCourses();
Array.prototype.forEach.call(courses, (entry) => {
const entries = getNewEntries(entry);
Logger.log(entries);
});
}
/**
* Here where you run the thing. yes. thing.
*/
function run(){
// Piling up discord's webhook embeds to prevent rate limits.
var embeds = [];
const courses = listAllCourses();
Array.prototype.forEach.call(courses, (entry) => {
const {announcements, courseWorks} = getNewEntries(entry);
if (announcements && announcements.length > 0) {
announcements.forEach((announcement) => {
embeds.push({
title: `New Announcement`,
url: announcement.alternateLink,
description: announcement.text.length > 2000 ? announcement.text.substr(0, 2000) + "..." : announcement.text,
color: 3066993,
author: {
name: entry.name,
url: entry.alternateLink
},
timestamp: announcement.updateTime,
});
});
}
if (courseWorks && courseWorks.length > 0) {
courseWorks.forEach((courseWork) => {
embeds.push({
title: `New Course Work: ${courseWork.title}`,
url: courseWork.alternateLink,
description: courseWork.description ? (courseWork.description.length > 2000 ? courseWork.description.substr(0, 2000) + "..." : courseWork.description) : "*No description specified.*",
color: 15105570,
author: {
name: entry.name,
url: entry.alternateLink
},
footer: {
text: courseWork.dueTime ? `Due at [T]: ${courseWork.dueTime.hours}:${courseWork.dueTime.minutes} ${courseWork.dueDate ? `[D]: ${courseWork.dueDate.day}D ${courseWork.dueDate.month}M ${courseWork.dueDate.year}Y` : ""}` : "No due specified.",
},
timestamp: courseWork.updateTime,
});
});
}
});
// stuff collected, let's shove em into discord's webhooks
while (embeds.length > 0) {
const data = embeds.slice(0,10);
// Remove 10 elements from embeds
embeds = embeds.splice(10);
Logger.log(data);
const options = {
"method": "post",
"contentType": "application/json",
"payload": JSON.stringify({embeds: data}),
};
const resp = UrlFetchApp.fetch(hook, options);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment