Skip to content

Instantly share code, notes, and snippets.

@Prof9
Last active September 22, 2022 18:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Prof9/77cb2a94c3546798bb6c to your computer and use it in GitHub Desktop.
Save Prof9/77cb2a94c3546798bb6c to your computer and use it in GitHub Desktop.
LiveBot: node.js script that notifies you when someone starts streaming specific games on Twitch or Hitbox.
var http = require("http");
var https = require("https");
// Stream objects are passed around in the code below. These are the properties:
// stream.platform = "Twitch" or "Hitbox"
// stream.name = name of the streamer
// stream.game = name of game (set in updateGame() call)
// stream.desc = stream status/description
// stream.url = url of stream
// stream.viewers = current amount of viewers
// The streams that are currently active.
var currentStreams = [];
// The streams that became inactive in the previous frame.
// Workaround for Twitch API reporting a stream going live when it goes down.
var purgedStreams = [];
function getUrl(url, onend, onerror) {
// Choose the appropriate protocol.
var protocol;
if ((/^http:\/\//).test(url)) {
protocol = http;
} else if ((/^https:\/\//).test(url)) {
protocol = https;
} else {
onerror();
}
// Make the request.
//console.log("GET " + url);
var chunks = [];
var request = protocol.get(url, function(response) {
if (response.statusCode == 200) {
response.on("data", function(chunk) {
chunks.push(chunk);
});
response.on("end", function() {
onend(Buffer.concat(chunks));
});
} else {
request.abort();
onerror();
}
}).on("error", function(e) {
console.log("HTTP error: " + e.message);
onerror();
});
}
function updateStreams(platform, gamename, streams, clean) {
if (typeof clean === "undefined") clean = false;
if (clean === true) {
// Delete all current streams that are not active anymore.
for (var i = 0; i < currentStreams.length; i++) {
// Check if stream is no longer in active streams of same platform and game.
if (currentStreams[i].platform == platform &&
currentStreams[i].game == gamename &&
findStream(streams, currentStreams[i]) < 0) {
// Remove the stream from the active streams.
purgedStreams.push(currentStreams.splice(i--, 1));
}
}
}
// Add all new active streams.
for (var i = 0; i < streams.length; i++) {
var stream = streams[i];
// Check if stream is currently not in active streams.
var streamIndex = findStream(currentStreams, stream);
if (streamIndex < 0) {
// Add it to the active streams.
currentStreams.push(stream);
// Report the stream as active if it's not in the purged streams.
if (findStream(purgedStreams, stream) < 0) {
reportStream(stream);
}
} else {
// Update the stream.
currentStreams[streamIndex] = stream;
}
}
// Clear all purged streams.
for (var i = 0; i < purgedStreams.length; i++) {
// Remove purged stream if it has the same game.
if (purgedStreams[i].game == gamename) {
purgedStreams.splice(i--, 1);
}
}
if (clean === true) {
//console.log(currentStreams.length + " streams active.");
}
}
function findStream(array, stream) {
// Find the first index of the stream in the array using streamEquals().
for (var i = 0; i < array.length; i++) {
if (streamEquals(array[i], stream)) {
return i;
}
}
return -1;
}
function streamEquals(stream1, stream2) {
return stream1.url == stream2.url &&
stream1.game == stream2.game &&
stream1.desc == stream2.desc;
}
function getStreams(platform, gamename, gameid, ondata, onend, onerror, maxtries,
interval, page, pagesize, tries) {
// Set default parameters.
if (typeof maxtries === "undefined") maxtries = 2;
if (typeof page === "undefined") page = 0;
if (typeof interval === "undefined") interval = 3000;
if (typeof tries === "undefined") tries = maxtries;
if (typeof pagesize === "undefined") pagesize = 25;
// Form request URL.
var url;
if (platform == "Twitch") { url = "https://api.twitch.tv/kraken/streams"; }
if (platform == "Hitbox") { url = "http://api.hitbox.tv/media/live/list"; }
url += "?game=" + encodeURIComponent(gameid);
url += "&limit=" + pagesize;
url += "&offset=" + page * pagesize;
if (platform == "Hitbox") { url += "&fast=" + true; }
// Make the API request.
getUrl(url, function(data) {
// Check Hitbox empty return value.
if (platform == "Hitbox" && data == "no_media_found") {
onend();
return;
}
// Pass received streams.
data = JSON.parse(data);
if (platform == "Twitch") ondata(extractTwitchStreams(data, gamename));
if (platform == "Hitbox") ondata(extractHitboxStreams(data, gamename));
// Determine whether there are more pages to get.
page++;
var more = false;
if (platform == "Twitch") more = page * pagesize < data._total;
if (platform == "Hitbox") more = data.livestream.length == pagesize;
if (more) {
// Get next page, if necessary.
getStreams(platform, gamename, gameid, ondata, onend, onerror,
maxtries, interval, page, pagesize, maxtries);
} else {
// Signify end of data.
onend();
}
}, function() {
// Form error message.
var status = "Error returned from " + platform + " API: page="
+ page + ", gamename=" + gamename + ".";
if (--tries > 0) {
// Retry, if there are tries left.
status += " Retrying in " + interval + "ms (" + tries + " left)...";
console.log(status);
setTimeout(function() {
getStreams(platform, gamename, gameid, ondata, onend, onerror,
maxtries, interval, page, pagesize, maxtries);
}, interval);
} else {
// Abort.
status += " Request aborted.";
console.log(status);
onerror();
}
});
}
function extractTwitchStreams(data, gamename) {
var results = [];
for (var i = 0; i < data.streams.length; i++) {
var stream = data.streams[i];
results.push({
platform: "Twitch",
name: stream.channel.display_name,
game: gamename,
url: stream.channel.url,
desc: stream.channel.status,
viewers: stream.viewers
});
}
return results;
}
function extractHitboxStreams(data, gamename) {
var results = [];
for (var i = 0; i < data.livestream.length; i++) {
var stream = data.livestream[i];
results.push({
platform: "Hitbox",
name: stream.media_display_name,
game: gamename,
url: "http://hitbox.tv/" + stream.media_name,
desc: stream.media_status,
viewers: stream.media_views
});
}
return results;
}
function updateGame(platform, gamename, gameid) {
if (typeof gameid === "undefined") gameid = gamename;
var results = [];
//console.log("--------------------------------");
getStreams(platform, gamename, gameid, function(data) {
// Got some streams; add them to the rest.
results = results.concat(data);
}, function() {
// Call successful; clean up inactive streams.
updateStreams(platform, gamename, results, true);
}, function() {
// Call (partially) failed; do not clean up inactive streams.
updateStreams(platform, gamename, results, false);
});
}
function reportStream(stream) {
// Modify this method to do whatever you want to do when a stream goes live.
console.log(stream.name + " is now playing " + stream.game + "! \""
+ stream.desc + "\" - " + stream.url);
}
function initQueue(queue) {
return setInterval(function() {
var game = queue.games.shift();
updateGame(queue.platform, game.name, game.id || game.name);
queue.games.push(game);
// Put the length for one cycle (in ms) here.
}, 30000 / queue.games.length);
}
// Initialize Twitch queue.
initQueue({
platform: "Twitch",
games: [
{ name: "Mega Man Battle Network" },
{ name: "Rockman EXE Operate Shooting Star" },
{ name: "Mega Man Battle Network 2" },
{ name: "Mega Man Battle Network 3" },
{ name: "Mega Man Battle Network 4" },
{ name: "Rockman EXE 4.5 Real Operation" },
{ name: "Mega Man Battle Network 5" },
{ name: "Mega Man Battle Network 5: Double Team DS" },
{ name: "Mega Man Battle Network 6" },
{ name: "Mega Man Battle Chip Challenge" },
{ name: "Mega Man Network Transmission" },
{ name: "Rockman EXE WS" },
{ name: "Mega Man Star Force" },
{ name: "Mega Man Star Force 2" },
{ name: "Mega Man Star Force 3" },
{ name: "Mega Man Battle Network Chrono X" }
]
});
// Initialize Hitbox queue.
initQueue({
platform: "Hitbox",
games: [
{ name: "Mega Man Battle Network", id: 7705 },
{ name: "Rockman EXE Operate Shooting Star", id: 21710 },
{ name: "Mega Man Battle Network 2", id: 5312 },
{ name: "Mega Man Battle Network 3", id: 11480 },
{ name: "Mega Man Battle Network 4", id: 4021 },
{ name: "Rockman EXE 4.5 Real Operation", id: 10393 },
{ name: "Mega Man Battle Network 5", id: 10999 },
{ name: "Mega Man Battle Network 5: Double Team DS", id: 8916 },
{ name: "Mega Man Battle Network 6", id: 7535 },
{ name: "Mega Man Battle Chip Challenge", id: 15975 },
{ name: "Mega Man Star Force", id: 2567 },
{ name: "Mega Man Star Force 2", id: 16953 },
{ name: "Mega Man Star Force 3", id: 17652 }
]
});
@ali-kingX
Copy link

Can you make it so it just checks for if a person starts twitch streaming so i can hook it up with my discord bot to show if the person started streaming

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment