Skip to content

Instantly share code, notes, and snippets.

@Zro617
Last active September 17, 2016 00:33
Show Gist options
  • Save Zro617/408364854245ee4af83c77b83d7f1bf8 to your computer and use it in GitHub Desktop.
Save Zro617/408364854245ee4af83c77b83d7f1bf8 to your computer and use it in GitHub Desktop.
Adds desktop notifications for Scratch (https://scratch.mit.edu)
// ==UserScript==
// @name Scratch Notifications
// @namespace zro617.github.io
// @description Adds desktop notifications for Scratch messages
// @include https://scratch.mit.edu/*
// @version 1.21
// @grant none
// ==/UserScript==
if (typeof Scratch.INIT_DATA.LOGGED_IN_USER === "undefined") well_poop_you_need_to_log_in;
class ScratchMessage {
constructor(e) {
this.e = e;
this.id = e.dataset.receiptId;
this.what = this.who = this.where = this.when = this.link = this.body = this.icon = "";
let links = e.querySelectorAll("a");
let text = e.textContent.trim();
if (text.match(/ is now following you/)) {
this.what = "follow";
this.who = links[0].innerHTML;
this.link = links[0].href;
} else if (text.match(/ commented on/)) {
this.what = "comment";
this.who = links[0].innerHTML;
this.where = links[1].innerHTML;
this.link = links[1].href;
this.body = e.querySelector("span.comment-snippet").innerHTML;
} else if (text.match(/ replied to/)) {
this.what = "reply";
this.who = links[0].innerHTML;
this.where = links[1].innerHTML;
this.link = links[1].href;
this.body = e.querySelector("span.comment-snippet").innerHTML;
} else if (text.match(/ loved/)) {
this.what = "love";
this.who = links[0].innerHTML;
this.where = links[1].innerHTML;
this.link = links[1].href;
} else if (text.match(/ favorited/)) {
this.what = "fave";
this.who = links[0].innerHTML;
this.where = links[1].innerHTML;
this.link = links[1].href;
} else if (text.match(/ remixed/)) {
this.what = "remix";
this.who = links[0].innerHTML;
this.where = links[1].innerHTML;
this.body = links[2].innerHTML;
this.link = links[2].href;
} else if (text.match(/ invited/)) {
this.what = "invite";
this.who = links[0].innerHTML;
this.where = links[1].innerHTML;
this.link = links[2].href;
} else if (text.match(/new activity/)) {
this.what = "studio activity";
this.where = links[0].innerHTML;
this.link = links[0].href;
} else if (text.match(/new posts/)) {
this.what = "forum activity";
this.where = links[0].innerHTML;
this.link = links[0].href;
}
// Beware of missing timestamp for certain messages
this.when = e.parentElement.firstElementChild.innerHTML;
let time = e.querySelector("span.time");
if (time) this.when += " " + time.innerHTML;
// need a better icon
this.icon = Scratch.INIT_DATA.LOGGED_IN_USER.model.thumbnail_url || "https://cdn.scratch.mit.edu/scratchr2/static/__0c1805349a6fe15c01c668d3f8acd971__/images/nav-notifications.png";
/*
if (this.who) {
let xhr = new XMLHttpRequest();
xhr.open("GET","https://scratch.mit.edu/users/"+this.who+"/",true);
xhr.onload = function() {
if (xhr.status == 200) i = xhr.response.querySelector("div.avatar img").src;
};
xhr.send();
}
*/
console.log(this);
}
get title() {
switch (this.what) {
case "follow": return this.who + " added you";
case "comment": return this.who + " commented on " + this.where;
case "reply": return this.who + " replied on " + this.where;
case "love": return this.who + " ❤'d " + this.where;
case "fave": return this.who + " ⭐'d " + this.where;
case "remix": return this.who + " remixed " + this.where;
case "invite": return this.who + " invited you to " + this.where;
case "studio activity": return "New activity in " + this.where;
case "forum activity": return "New posts in " + this.where;
default: return "Message from Scratch";
}
}
notify() {
let x = new Notification(this.title,{
body:this.body + "\n" + this.when,
icon:this.icon,
tag:this.id,
requireInteraction:true
});
x.addEventListener("click",(function(e){
window.open(this.link,"_blank").focus();
}).bind(this));
}
}
let read = [];
let purge = () => {
let body = JSON.stringify(read);
let xhr = new XMLHttpRequest();
xhr.open("POST","https://scratch.mit.edu/messages/ajax/messages-clear/",true);
xhr.setRequestHeader("X-CSRFToken",document.cookie.match(/scratchcsrftoken=([a-zA-Z0-9]+)/)[1]);
xhr.setRequestHeader("Cookie",document.cookie);
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
xhr.setRequestHeader("Referer","https://scratch.mit.edu/messages/");
xhr.setRequestHeader("Content-Length",body.length);
xhr.send(body);
read = [];
};
let check = () => {
if (Notification.permission != "granted") return;
let xhr = new XMLHttpRequest();
xhr.open("GET","https://scratch.mit.edu/messages/",true);
xhr.responseType = "document";
xhr.onload = function() {
if (xhr.status != 200) return;
let messages = xhr.response.querySelectorAll("li.unread");
if (!messages.length) return;
for (let m of messages) {
var message = new ScratchMessage(m);
message.notify();
read.push(message.id);
}
purge();
};
xhr.send();
};
Notification.requestPermission();
window.setInterval(check,10000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment