From 55ab0b58df4f8a70440c589350810be0f326fb0c Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 00:40:33 +0000 Subject: [PATCH 01/21] Added check for existing timer so we don't start a new one on reconnect --- feed-bot.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/feed-bot.js b/feed-bot.js index 2cfe5b0..194c2de 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -14,9 +14,11 @@ var url = Url.parse(Config.feedUrl); //placeholder for our bot - we need to check for connectivity before assigning this though var bot; +var timer = false; var latestFeedLink = ""; var linkRegExp = new RegExp(["http", "https", "www"].join("|")); var cachedLinks = []; + //caches a link so we can check again later function cacheLink(link) { //cheaty way to get around http and https not matching @@ -49,7 +51,11 @@ Dns.resolve("discordapp.com", function (err) { checkPreviousMessagesForLinks(); logEvent("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); - setInterval(checkFeedAndPost, Config.pollingInterval); + + if(!timer){ + setInterval(checkFeedAndPost, Config.pollingInterval); + timer = true; + } }); bot.on("disconnect", function (err, code) { From a51f0853a68a6fa7aef38bc6266671fdae11a783 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 5 Nov 2016 01:08:17 +0000 Subject: [PATCH 02/21] Updated to use separate logging class + many helpful comments --- feed-bot.js | 85 +++++++++++++++++++++++++++++------------------------ log.js | 26 ++++++++++++++++ 2 files changed, 73 insertions(+), 38 deletions(-) create mode 100644 log.js diff --git a/feed-bot.js b/feed-bot.js index 194c2de..c423aa6 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -1,4 +1,3 @@ -var console = require("console"); //for console logging var Dns = require("dns"); //for connectivity checking var Url = require("url"); //for url parsing var Uri = require("urijs"); //for finding urls within message strings @@ -6,8 +5,7 @@ var Discord = require("discord.io"); //for obvious reasons var FeedRead = require("feed-read"); //for rss feed reading var BotConfig = require("./botConfig.json"); //bot config file containing bot token var Config = require("./config.json"); //config file containing other settings - -var verboseLogging = false; +var log = require("./log.js"); //some very simple logging functions I made //get a URL object from the feedUrl so we can examine it and check connectivity later var url = Url.parse(Config.feedUrl); @@ -26,7 +24,7 @@ function cacheLink(link) { //store the new link if not stored already if (!cachedLinks.includes(link)) { cachedLinks.push(link); - logEvent("Cached URL: " + link); + log.info("Cached URL: " + link); } //get rid of the first array element if we have reached our cache limit if (cachedLinks.length > (Config.numLinksToCache || 10)) @@ -35,7 +33,7 @@ function cacheLink(link) { //check if we can connect to discordapp.com to authenticate the bot Dns.resolve("discordapp.com", function (err) { - if (err) reportError("CONNECTION ERROR: Unable to locate discordapp.com to authenticate the bot (you are probably not connected to the internet). Details: " + (err.message || err)); + if (err) log.error("CONNECTION ERROR: Unable to locate discordapp.com to authenticate the bot (you are probably not connected to the internet).", err); else { //if there was no error, go ahead and create and authenticate the bot bot = new Discord.Client({ @@ -45,10 +43,10 @@ Dns.resolve("discordapp.com", function (err) { //when the bot is ready, set a polling interval for the rss feed bot.on("ready", function () { - logEvent(new Date().toLocaleString() + " Registered bot " + bot.username + " - (" + bot.id + ")"); + log.info("Registered bot " + bot.username + " - (" + bot.id + ")"); - //as we don't have any links cached, we need to check recent messages - checkPreviousMessagesForLinks(); + //as we don't have any links cached, we need to check recent messages + checkPreviousMessagesForLinks(); logEvent("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); @@ -59,16 +57,19 @@ Dns.resolve("discordapp.com", function (err) { }); bot.on("disconnect", function (err, code) { - logEvent("Bot was disconnected! " + code != null ? code : "No disconnect code provided"); - if (err) reportError("Bot disconnect error: " + (err.message || err)); - logEvent("Trying to reconnect bot"); + //do a bunch of logging + log.event("Bot was disconnected! " + code ? code : "No disconnect code provided", "Discord.io"); + if (err) log.error("Bot disconnected!", err); + log.info("Trying to reconnect bot"); + + //then actually attempt to reconnect bot.connect(); }); bot.on("message", function (user, userID, channelID, message) { //check if the message contains a link, in the right channel, and not the latest link from the rss feed if (channelID === Config.channelID && linkRegExp.test(message) && (message !== latestFeedLink)) { - logEvent("Detected posted link in this message: " + message); + log.event("Detected posted link in this message: " + message, "Discord.io"); //detect the url inside the string, and cache it Uri.withinString(message, function (url) { cacheLink(url); @@ -82,39 +83,49 @@ Dns.resolve("discordapp.com", function (err) { function checkFeedAndPost() { //check that we have an internet connection (well not exactly - check that we have a connection to the host of the feedUrl) Dns.resolve(url.host, function (err) { - if (err) reportError("CONNECTION ERROR: Cannot resolve host (you are probably not connected to the internet). Details: " + (err.message || err)); + if (err) log.error("CONNECTION ERROR: Cannot resolve host (you are probably not connected to the internet)", err); else FeedRead(Config.feedUrl, checkLinkAndPost); }); } //checks if the link has been posted previously, posts if not function checkLinkAndPost(err, articles) { - if (err) reportError("FEED ERROR: Error reading RSS feed. Details: " + (err.message || err)); + if (err) log.error("FEED ERROR: Error reading RSS feed.", err); else { //get the latest link and check if it has already been posted and cached var latestLink = articles[0].link.replace("https", "http"); + //check whether the latest link out the feed exists in our cache if (!cachedLinks.includes(latestLink)) { - logEvent("Attempting to post new link: " + latestLink); + log.info("Attempting to post new link: " + latestLink); + + //send a messsage containing the new feed link to our discord channel bot.sendMessage({ to: Config.channelID, message: latestLink }, function (err, message) { - if(err) reportError("ERROR: Failed to send message: " + (err.message || err) + " " + message); - logEvent("Checking bot connectivity"); - if (bot.connected) - logEvent("Connectivity seems fine - I have no idea why the message didn't post"); - else { - reportError("Bot appears to be disconnected! Attempting to reconnect...") - bot.connect(); - } + if (err) { + log.error("ERROR: Failed to send message: " + message.substring(0, 15) + "...", err); + //if there is an error posting the message, check if it is because the bot isn't connected + if (bot.connected) + log.info("Connectivity seems fine - I have no idea why the message didn't post"); + else { + log.error("Bot appears to be disconnected! Attempting to reconnect...", err); + //attempt to reconnect + bot.connect(); + } + } }); + + //finally make sure the link is cached, so it doesn't get posted again cacheLink(latestLink); } else if (latestFeedLink != latestLink) - logEvent("Didn't post new feed link because already detected as posted " + latestLink); + //alternatively, if we have a new link from the feed, but its been posted already, just alert the console + log.info("Didn't post new feed link because already detected as posted " + latestLink); + //ensure our latest feed link variable is up to date, so we can track when the feed updates latestFeedLink = latestLink; } } @@ -122,17 +133,24 @@ function checkLinkAndPost(err, articles) { //gets last 100 messages and extracts any links found (for use on startup) function checkPreviousMessagesForLinks() { var limit = 100; - logEvent("Attempting to check past " + limit + " messages for links"); + log.info("Attempting to check past " + limit + " messages for links"); + + //get the last however many messsages from our discord channel bot.getMessages({ channelID: Config.channelID, limit: limit }, function (err, messages) { - if (err) reportError("Error fetching discord messages. Details: " + (err.message || err)); + if (err) log.error("Error fetching discord messages.", err); else { - logEvent("Pulled last " + messages.length + " messages, scanning for links"); + log.info("Pulled last " + messages.length + " messages, scanning for links"); + + //extract an array of strings from the array of message objects var messageContents = messages.map((x) => { return x.content; }).reverse(); - for (var message in messageContents) { - message = messageContents[message]; + + for (var messageIdx in messageContents) { + message = messageContents[messageIdx]; + + //test if the message contains a url if (linkRegExp.test(message)) //detect the url inside the string, and cache it Uri.withinString(message, function (url) { @@ -142,13 +160,4 @@ function checkPreviousMessagesForLinks() { } } }); -} - -function logEvent(message) { - console.log(new Date().toLocaleString() + " " + message); -} - -//logs error to console with a timestamp -function reportError(message) { - console.log(new Date().toLocaleString() + " ERROR: " + message); } \ No newline at end of file diff --git a/log.js b/log.js new file mode 100644 index 0000000..2e7e103 --- /dev/null +++ b/log.js @@ -0,0 +1,26 @@ +var console = require("console"); + +function log(message) { + if (message) + //attach a formatted date string to the beginning of everything we log + console.log(new Date().toLocaleString() + " " + message); +} + +module.exports = { + info: function (message) { + if (message) + this.log("INFO: " + message); + }, + event: function (message, sender) { + //if we received a message, log it - include sender information if it was passed + if (message) { + log("EVENT: " + (sender ? sender + " has sent an event: " : "") + messsage); + } + }, + error: function (message, innerEx) { + if (message) { + //log the message, attach innerEx information if it was passed + log("ERROR: " + message + (innerEx ? ". Inner exception details: " + (innerEx.message || innerEx) : "")); + } + } +} \ No newline at end of file From 4d64ee7da249d228de9765eef7e08f5640bebc6f Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 00:51:12 +0000 Subject: [PATCH 03/21] Updated my eslint config --- .eslintrc.json | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index c34b295..3b41d57 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -11,13 +11,9 @@ }, "rules": { "indent": [ - "error", + "warn", "tab" ], - "linebreak-style": [ - "error", - "windows" - ], "quotes": [ "warn", "double" @@ -26,7 +22,7 @@ "error", "always" ], - "no-undef": "warn", + "no-undef": "error", "no-unused-vars": "warn" } } \ No newline at end of file From 9c4a569242e63bbeedd2f2d7c9a77c9692453dd8 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 00:51:40 +0000 Subject: [PATCH 04/21] Fixed a call to an old, non-existant method --- feed-bot.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feed-bot.js b/feed-bot.js index c423aa6..bf8c5e3 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -43,12 +43,12 @@ Dns.resolve("discordapp.com", function (err) { //when the bot is ready, set a polling interval for the rss feed bot.on("ready", function () { - log.info("Registered bot " + bot.username + " - (" + bot.id + ")"); + log.info("Registered bot " + bot.username + " - (" + bot.id + ")"); //as we don't have any links cached, we need to check recent messages - checkPreviousMessagesForLinks(); + checkPreviousMessagesForLinks(); - logEvent("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); + log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); if(!timer){ setInterval(checkFeedAndPost, Config.pollingInterval); From 436d474787963a891434ba475868e9a7f0422302 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 00:55:39 +0000 Subject: [PATCH 05/21] Fixed missing variable declaration --- feed-bot.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/feed-bot.js b/feed-bot.js index bf8c5e3..9bddad3 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -45,12 +45,12 @@ Dns.resolve("discordapp.com", function (err) { bot.on("ready", function () { log.info("Registered bot " + bot.username + " - (" + bot.id + ")"); - //as we don't have any links cached, we need to check recent messages + //as we don't have any links cached, we need to check recent messages checkPreviousMessagesForLinks(); log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); - - if(!timer){ + + if (!timer) { setInterval(checkFeedAndPost, Config.pollingInterval); timer = true; } @@ -61,7 +61,7 @@ Dns.resolve("discordapp.com", function (err) { log.event("Bot was disconnected! " + code ? code : "No disconnect code provided", "Discord.io"); if (err) log.error("Bot disconnected!", err); log.info("Trying to reconnect bot"); - + //then actually attempt to reconnect bot.connect(); }); @@ -98,7 +98,7 @@ function checkLinkAndPost(err, articles) { //check whether the latest link out the feed exists in our cache if (!cachedLinks.includes(latestLink)) { log.info("Attempting to post new link: " + latestLink); - + //send a messsage containing the new feed link to our discord channel bot.sendMessage({ to: Config.channelID, @@ -117,7 +117,7 @@ function checkLinkAndPost(err, articles) { } } }); - + //finally make sure the link is cached, so it doesn't get posted again cacheLink(latestLink); } @@ -148,7 +148,7 @@ function checkPreviousMessagesForLinks() { var messageContents = messages.map((x) => { return x.content; }).reverse(); for (var messageIdx in messageContents) { - message = messageContents[messageIdx]; + var message = messageContents[messageIdx]; //test if the message contains a url if (linkRegExp.test(message)) From de65f9b720859bc45ea9a71d121030041a8ea65a Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 00:57:37 +0000 Subject: [PATCH 06/21] Updated bot-config file name to follow convention --- README.md | 2 +- feed-bot.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7d8d18a..4769181 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Feel free to contact me with suggestions and feature requests - if you need a ne 3. Open a terminal in cloned/extracted folder 4. Run `npm install` and wait for it to finish 5. Edit *config.json* to include your RSS feed and channel ID -6. Create *botConfig.json* to include your bot token: +6. Create *bot-config.json* to include your bot token: `{ "token": "abc123blahblahblahyourtokengoeshere" }` diff --git a/feed-bot.js b/feed-bot.js index 9bddad3..91dead3 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -3,7 +3,7 @@ var Url = require("url"); //for url parsing var Uri = require("urijs"); //for finding urls within message strings var Discord = require("discord.io"); //for obvious reasons var FeedRead = require("feed-read"); //for rss feed reading -var BotConfig = require("./botConfig.json"); //bot config file containing bot token +var BotConfig = require("./bot-config.json"); //bot config file containing bot token var Config = require("./config.json"); //config file containing other settings var log = require("./log.js"); //some very simple logging functions I made From 87f78ffac03203c72862408c9f46ca6ecd7d0d14 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 01:34:37 +0000 Subject: [PATCH 07/21] Added changelog file --- changelog.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 changelog.md diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..3a1c517 --- /dev/null +++ b/changelog.md @@ -0,0 +1,13 @@ +# Changelog + +## Unreleased + +### Added + +- Added new logging class to handle logging + +### Changed +- Changed expected name for bot config file to bot-config.json rather than botConfig.json + +### Fixed +- Fixed new timer being created every time the bot reconnected \ No newline at end of file From 5a5c9dd9eb22d71e6342cf57f876dd3c1c861ec8 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 21:33:37 +0000 Subject: [PATCH 08/21] Renamed log to Log --- feed-bot.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/feed-bot.js b/feed-bot.js index 91dead3..6d80268 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -5,7 +5,7 @@ var Discord = require("discord.io"); //for obvious reasons var FeedRead = require("feed-read"); //for rss feed reading var BotConfig = require("./bot-config.json"); //bot config file containing bot token var Config = require("./config.json"); //config file containing other settings -var log = require("./log.js"); //some very simple logging functions I made +var Log = require("./log.js"); //some very simple logging functions I made //get a URL object from the feedUrl so we can examine it and check connectivity later var url = Url.parse(Config.feedUrl); @@ -24,7 +24,7 @@ function cacheLink(link) { //store the new link if not stored already if (!cachedLinks.includes(link)) { cachedLinks.push(link); - log.info("Cached URL: " + link); + Log.info("Cached URL: " + link); } //get rid of the first array element if we have reached our cache limit if (cachedLinks.length > (Config.numLinksToCache || 10)) @@ -33,7 +33,7 @@ function cacheLink(link) { //check if we can connect to discordapp.com to authenticate the bot Dns.resolve("discordapp.com", function (err) { - if (err) log.error("CONNECTION ERROR: Unable to locate discordapp.com to authenticate the bot (you are probably not connected to the internet).", err); + if (err) Log.error("CONNECTION ERROR: Unable to locate discordapp.com to authenticate the bot (you are probably not connected to the internet).", err); else { //if there was no error, go ahead and create and authenticate the bot bot = new Discord.Client({ @@ -43,12 +43,12 @@ Dns.resolve("discordapp.com", function (err) { //when the bot is ready, set a polling interval for the rss feed bot.on("ready", function () { - log.info("Registered bot " + bot.username + " - (" + bot.id + ")"); + Log.info("Registered bot " + bot.username + " - (" + bot.id + ")"); //as we don't have any links cached, we need to check recent messages checkPreviousMessagesForLinks(); - log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); + Log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); if (!timer) { setInterval(checkFeedAndPost, Config.pollingInterval); @@ -58,9 +58,9 @@ Dns.resolve("discordapp.com", function (err) { bot.on("disconnect", function (err, code) { //do a bunch of logging - log.event("Bot was disconnected! " + code ? code : "No disconnect code provided", "Discord.io"); - if (err) log.error("Bot disconnected!", err); - log.info("Trying to reconnect bot"); + Log.event("Bot was disconnected! " + code ? code : "No disconnect code provided", "Discord.io"); + if (err) Log.error("Bot disconnected!", err); + Log.info("Trying to reconnect bot"); //then actually attempt to reconnect bot.connect(); @@ -69,7 +69,7 @@ Dns.resolve("discordapp.com", function (err) { bot.on("message", function (user, userID, channelID, message) { //check if the message contains a link, in the right channel, and not the latest link from the rss feed if (channelID === Config.channelID && linkRegExp.test(message) && (message !== latestFeedLink)) { - log.event("Detected posted link in this message: " + message, "Discord.io"); + Log.event("Detected posted link in this message: " + message, "Discord.io"); //detect the url inside the string, and cache it Uri.withinString(message, function (url) { cacheLink(url); @@ -83,21 +83,21 @@ Dns.resolve("discordapp.com", function (err) { function checkFeedAndPost() { //check that we have an internet connection (well not exactly - check that we have a connection to the host of the feedUrl) Dns.resolve(url.host, function (err) { - if (err) log.error("CONNECTION ERROR: Cannot resolve host (you are probably not connected to the internet)", err); + if (err) Log.error("CONNECTION ERROR: Cannot resolve host (you are probably not connected to the internet)", err); else FeedRead(Config.feedUrl, checkLinkAndPost); }); } //checks if the link has been posted previously, posts if not function checkLinkAndPost(err, articles) { - if (err) log.error("FEED ERROR: Error reading RSS feed.", err); + if (err) Log.error("FEED ERROR: Error reading RSS feed.", err); else { //get the latest link and check if it has already been posted and cached var latestLink = articles[0].link.replace("https", "http"); //check whether the latest link out the feed exists in our cache if (!cachedLinks.includes(latestLink)) { - log.info("Attempting to post new link: " + latestLink); + Log.info("Attempting to post new link: " + latestLink); //send a messsage containing the new feed link to our discord channel bot.sendMessage({ @@ -105,12 +105,12 @@ function checkLinkAndPost(err, articles) { message: latestLink }, function (err, message) { if (err) { - log.error("ERROR: Failed to send message: " + message.substring(0, 15) + "...", err); + Log.error("ERROR: Failed to send message: " + message.substring(0, 15) + "...", err); //if there is an error posting the message, check if it is because the bot isn't connected if (bot.connected) - log.info("Connectivity seems fine - I have no idea why the message didn't post"); + Log.info("Connectivity seems fine - I have no idea why the message didn't post"); else { - log.error("Bot appears to be disconnected! Attempting to reconnect...", err); + Log.error("Bot appears to be disconnected! Attempting to reconnect...", err); //attempt to reconnect bot.connect(); @@ -123,7 +123,7 @@ function checkLinkAndPost(err, articles) { } else if (latestFeedLink != latestLink) //alternatively, if we have a new link from the feed, but its been posted already, just alert the console - log.info("Didn't post new feed link because already detected as posted " + latestLink); + Log.info("Didn't post new feed link because already detected as posted " + latestLink); //ensure our latest feed link variable is up to date, so we can track when the feed updates latestFeedLink = latestLink; @@ -133,16 +133,16 @@ function checkLinkAndPost(err, articles) { //gets last 100 messages and extracts any links found (for use on startup) function checkPreviousMessagesForLinks() { var limit = 100; - log.info("Attempting to check past " + limit + " messages for links"); + Log.info("Attempting to check past " + limit + " messages for links"); //get the last however many messsages from our discord channel bot.getMessages({ channelID: Config.channelID, limit: limit }, function (err, messages) { - if (err) log.error("Error fetching discord messages.", err); + if (err) Log.error("Error fetching discord messages.", err); else { - log.info("Pulled last " + messages.length + " messages, scanning for links"); + Log.info("Pulled last " + messages.length + " messages, scanning for links"); //extract an array of strings from the array of message objects var messageContents = messages.map((x) => { return x.content; }).reverse(); From 0766a8351b15aa4de00f2b4ea1a849d7c27f8d7d Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 21:53:13 +0000 Subject: [PATCH 09/21] Added youtube mode toggle with full url -> share url conversion --- config.json | 3 ++- feed-bot.js | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index 596b3ea..2822763 100644 --- a/config.json +++ b/config.json @@ -2,5 +2,6 @@ "feedUrl": "https://www.youtube.com/feeds/videos.xml?user=EthosLab", "channelID": "241238530376990722", "pollingInterval": 5000, - "numLinksToCache": 10 + "numLinksToCache": 10, + "youtubeMode": true } \ No newline at end of file diff --git a/feed-bot.js b/feed-bot.js index 6d80268..ddfe1cd 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -17,6 +17,9 @@ var latestFeedLink = ""; var linkRegExp = new RegExp(["http", "https", "www"].join("|")); var cachedLinks = []; +var youtubeShareUrl = "http://youtu.be/"; +var youtubeFullUrl = "http://www.youtube.com/watch?v="; + //caches a link so we can check again later function cacheLink(link) { //cheaty way to get around http and https not matching @@ -31,6 +34,18 @@ function cacheLink(link) { cachedLinks.shift(); } +function checkCache(link) { + if (Config.youtubeMode && link.includes(youtubeFullUrl)) { + return cachedLinks.includes(convertToYoutubeShareUrl(link)); + } + return cachedLinks.includes(link); +} + +function convertToYoutubeShareUrl(fullUrl){ + var shareUrl = fullUrl.replace(youtubeFullUrl, youtubeShareUrl); + shareUrl.splice(0, shareUrl.indexOf("&")); +} + //check if we can connect to discordapp.com to authenticate the bot Dns.resolve("discordapp.com", function (err) { if (err) Log.error("CONNECTION ERROR: Unable to locate discordapp.com to authenticate the bot (you are probably not connected to the internet).", err); @@ -96,7 +111,7 @@ function checkLinkAndPost(err, articles) { var latestLink = articles[0].link.replace("https", "http"); //check whether the latest link out the feed exists in our cache - if (!cachedLinks.includes(latestLink)) { + if (!checkCache(latestLink)) { Log.info("Attempting to post new link: " + latestLink); //send a messsage containing the new feed link to our discord channel From 33f325e1347aa8a2054398f0d95196881c42816d Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 22:11:13 +0000 Subject: [PATCH 10/21] Fixed conversion from full url to share url returning undefined Also fixed a typo in log.js --- .gitignore | 3 ++- feed-bot.js | 10 ++++++++-- log.js | 40 ++++++++++++++++++++-------------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 961e6b0..699ef30 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,5 @@ jspm_packages # Output of 'npm pack' *.tgz -/botConfig.json \ No newline at end of file +/botConfig.json +/bot-config.json \ No newline at end of file diff --git a/feed-bot.js b/feed-bot.js index ddfe1cd..4b97c88 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -41,9 +41,13 @@ function checkCache(link) { return cachedLinks.includes(link); } -function convertToYoutubeShareUrl(fullUrl){ +function convertToYoutubeShareUrl(fullUrl) { var shareUrl = fullUrl.replace(youtubeFullUrl, youtubeShareUrl); - shareUrl.splice(0, shareUrl.indexOf("&")); + var ampersandIdx = shareUrl.indexOf("&"); + if (ampersandIdx > -1) + return shareUrl.slice(0, ampersandIdx); + else + return shareUrl; } //check if we can connect to discordapp.com to authenticate the bot @@ -112,6 +116,8 @@ function checkLinkAndPost(err, articles) { //check whether the latest link out the feed exists in our cache if (!checkCache(latestLink)) { + if (Config.youtubeMode && latestLink.includes(youtubeFullUrl)) + latestLink = convertToYoutubeShareUrl(latestLink); Log.info("Attempting to post new link: " + latestLink); //send a messsage containing the new feed link to our discord channel diff --git a/log.js b/log.js index 2e7e103..8a8b115 100644 --- a/log.js +++ b/log.js @@ -1,26 +1,26 @@ var console = require("console"); function log(message) { - if (message) - //attach a formatted date string to the beginning of everything we log - console.log(new Date().toLocaleString() + " " + message); + if (message) + //attach a formatted date string to the beginning of everything we log + console.log(new Date().toLocaleString() + " " + message); } module.exports = { - info: function (message) { - if (message) - this.log("INFO: " + message); - }, - event: function (message, sender) { - //if we received a message, log it - include sender information if it was passed - if (message) { - log("EVENT: " + (sender ? sender + " has sent an event: " : "") + messsage); - } - }, - error: function (message, innerEx) { - if (message) { - //log the message, attach innerEx information if it was passed - log("ERROR: " + message + (innerEx ? ". Inner exception details: " + (innerEx.message || innerEx) : "")); - } - } -} \ No newline at end of file + info: function (message) { + if (message) + log("INFO: " + message); + }, + event: function (message, sender) { + //if we received a message, log it - include sender information if it was passed + if (message) { + log("EVENT: " + (sender ? sender + " has sent an event: " : "") + message); + } + }, + error: function (message, innerEx) { + if (message) { + //log the message, attach innerEx information if it was passed + log("ERROR: " + message + (innerEx ? ". Inner exception details: " + (innerEx.message || innerEx) : "")); + } + } +}; \ No newline at end of file From e2b61936d0cd4f060c4b2467204852475a91e006 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Fri, 2 Dec 2016 22:13:22 +0000 Subject: [PATCH 11/21] Updated changelog --- changelog.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 3a1c517..a901050 100644 --- a/changelog.md +++ b/changelog.md @@ -4,10 +4,13 @@ ### Added -- Added new logging class to handle logging +- New logging class to handle logging +- Added togglable YouTube mode + - Converts full URLs to YouTube share URLs + - Checks against both YouTube full and share URLs to ensure same video not posted twice ### Changed - Changed expected name for bot config file to bot-config.json rather than botConfig.json ### Fixed -- Fixed new timer being created every time the bot reconnected \ No newline at end of file +- New timer being created every time the bot reconnected \ No newline at end of file From f5bab14a15929b1daae235968f4346e40301fc9b Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 3 Dec 2016 00:23:15 +0000 Subject: [PATCH 12/21] Refactored YouTube and Link related vars and functions into own objects --- feed-bot.js | 92 ++++++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/feed-bot.js b/feed-bot.js index 4b97c88..c3e7436 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -13,42 +13,48 @@ var url = Url.parse(Config.feedUrl); //placeholder for our bot - we need to check for connectivity before assigning this though var bot; var timer = false; -var latestFeedLink = ""; -var linkRegExp = new RegExp(["http", "https", "www"].join("|")); -var cachedLinks = []; -var youtubeShareUrl = "http://youtu.be/"; -var youtubeFullUrl = "http://www.youtube.com/watch?v="; +var YouTube = { + url: { + share: "http://youtu.be/", + full: "http://www.youtube.com/watch?v=", + convertShareToFull: function (shareUrl) { + return shareUrl.replace(this.share, this.full); + }, + convertFullToShare: function (fullUrl) { + var shareUrl = fullUrl.replace(this.share, this.full); -//caches a link so we can check again later -function cacheLink(link) { - //cheaty way to get around http and https not matching - link = link.replace("https://", "http://"); - //store the new link if not stored already - if (!cachedLinks.includes(link)) { - cachedLinks.push(link); - Log.info("Cached URL: " + link); + if (shareUrl.includes("&")) + shareUrl = shareUrl.slice(0, fullUrl.indexOf("&")); + + return shareUrl; + } + }, +}; + +var Links = { + regExp: new RegExp(["http", "https", "www"].join("|")), + cached: [], + latestFromFeed: "", + cache: function (link) { + //cheaty way to get around http and https not matching + link = link.replace("https://", "http://"); + //store the new link if not stored already + if (!this.cached.includes(link)) { + this.cached.push(link); + Log.info("Cached URL: " + link); + } + //get rid of the first array element if we have reached our cache limit + if (this.cached.length > (Config.numLinksToCache || 10)) + this.cached.shift(); + }, + checkCache: function (link) { + if (Config.youtubeMode && link.includes(link)) { + return this.cached.includes(YouTube.convertFullToShare(link)); + } + return this.cached.includes(link); } - //get rid of the first array element if we have reached our cache limit - if (cachedLinks.length > (Config.numLinksToCache || 10)) - cachedLinks.shift(); -} - -function checkCache(link) { - if (Config.youtubeMode && link.includes(youtubeFullUrl)) { - return cachedLinks.includes(convertToYoutubeShareUrl(link)); - } - return cachedLinks.includes(link); -} - -function convertToYoutubeShareUrl(fullUrl) { - var shareUrl = fullUrl.replace(youtubeFullUrl, youtubeShareUrl); - var ampersandIdx = shareUrl.indexOf("&"); - if (ampersandIdx > -1) - return shareUrl.slice(0, ampersandIdx); - else - return shareUrl; -} +}; //check if we can connect to discordapp.com to authenticate the bot Dns.resolve("discordapp.com", function (err) { @@ -87,11 +93,11 @@ Dns.resolve("discordapp.com", function (err) { bot.on("message", function (user, userID, channelID, message) { //check if the message contains a link, in the right channel, and not the latest link from the rss feed - if (channelID === Config.channelID && linkRegExp.test(message) && (message !== latestFeedLink)) { + if (channelID === Config.channelID && Links.regExp.test(message) && (message !== Links.latestFromFeed)) { Log.event("Detected posted link in this message: " + message, "Discord.io"); //detect the url inside the string, and cache it Uri.withinString(message, function (url) { - cacheLink(url); + Links.cache(url); return url; }); } @@ -115,9 +121,9 @@ function checkLinkAndPost(err, articles) { var latestLink = articles[0].link.replace("https", "http"); //check whether the latest link out the feed exists in our cache - if (!checkCache(latestLink)) { - if (Config.youtubeMode && latestLink.includes(youtubeFullUrl)) - latestLink = convertToYoutubeShareUrl(latestLink); + if (!Links.checkCache(latestLink)) { + if (Config.youtubeMode && latestLink.includes(YouTube.fullUrl)) + latestLink = YouTube.convertFullToShare(latestLink); Log.info("Attempting to post new link: " + latestLink); //send a messsage containing the new feed link to our discord channel @@ -140,14 +146,14 @@ function checkLinkAndPost(err, articles) { }); //finally make sure the link is cached, so it doesn't get posted again - cacheLink(latestLink); + Links.cache(latestLink); } - else if (latestFeedLink != latestLink) + else if (Links.latestFromFeed != latestLink) //alternatively, if we have a new link from the feed, but its been posted already, just alert the console Log.info("Didn't post new feed link because already detected as posted " + latestLink); //ensure our latest feed link variable is up to date, so we can track when the feed updates - latestFeedLink = latestLink; + Links.latestFromFeed = latestLink; } } @@ -172,10 +178,10 @@ function checkPreviousMessagesForLinks() { var message = messageContents[messageIdx]; //test if the message contains a url - if (linkRegExp.test(message)) + if (Links.regExp.test(message)) //detect the url inside the string, and cache it Uri.withinString(message, function (url) { - cacheLink(url); + Links.cache(url); return url; }); } From 03e7712be0e831d95798c2574f1e0c32604797f3 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 3 Dec 2016 00:56:31 +0000 Subject: [PATCH 13/21] Refactored Feed and Links related vars/functions into own objects --- feed-bot.js | 271 ++++++++++++++++++++++++++-------------------------- 1 file changed, 136 insertions(+), 135 deletions(-) diff --git a/feed-bot.js b/feed-bot.js index c3e7436..52582d3 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -7,12 +7,93 @@ var BotConfig = require("./bot-config.json"); //bot config file containing bot t var Config = require("./config.json"); //config file containing other settings var Log = require("./log.js"); //some very simple logging functions I made -//get a URL object from the feedUrl so we can examine it and check connectivity later -var url = Url.parse(Config.feedUrl); +var isTimer = false; -//placeholder for our bot - we need to check for connectivity before assigning this though -var bot; -var timer = false; +var Bot = { + bot: null, + startup: function () { + //check if we can connect to discordapp.com to authenticate the bot + Dns.resolve("discordapp.com", function (err) { + if (err) Log.error("CONNECTION ERROR: Unable to locate discordapp.com to authenticate the bot (you are probably not connected to the internet).", err); + else { + //if there was no error, go ahead and create and authenticate the bot + this.bot = new Discord.Client({ + token: BotConfig.token, + autorun: true + }); + + //set up the bot's event handlers + this.bot.on("ready", this.onReady); + this.bot.on("disconnect", this.onDisconnect); + this.bot.on("message", this.onMessage); + } + }); + }, + onReady: function () { + Log.info("Registered bot " + this.bot.username + " - (" + this.bot.id + ")"); + + //as we don't have any links cached, we need to check recent messages + this.checkPastMessagesForLinks(); + + Log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); + + if (!isTimer) { + setInterval(Feed.checkAndPost, Config.pollingInterval); + isTimer = true; + } + }, + onDisconnect: function (err, code) { + //do a bunch of logging + Log.event("Bot was disconnected! " + code ? code : "No disconnect code provided", "Discord.io"); + if (err) Log.error("Bot disconnected!", err); + Log.info("Trying to reconnect bot"); + + //then actually attempt to reconnect + this.bot.connect(); + }, + onMessage: function (user, userID, channelID, message) { + //check if the message contains a link, in the right channel, and not the latest link from the rss feed + if (channelID === Config.channelID && Links.regExp.test(message) && (message !== Links.latestFromFeed)) { + Log.event("Detected posted link in this message: " + message, "Discord.io"); + //detect the url inside the string, and cache it + Uri.withinString(message, function (url) { + Links.cache(url); + return url; + }); + } + }, + //gets last 100 messages and extracts any links found (for use on startup) + checkPastMessagesForLinks: function () { + var limit = 100; + Log.info("Attempting to check past " + limit + " messages for links"); + + //get the last however many messsages from our discord channel + Bot.bot.getMessages({ + channelID: Config.channelID, + limit: limit + }, function (err, messages) { + if (err) Log.error("Error fetching discord messages.", err); + else { + Log.info("Pulled last " + messages.length + " messages, scanning for links"); + + //extract an array of strings from the array of message objects + var messageContents = messages.map((x) => { return x.content; }).reverse(); + + for (var messageIdx in messageContents) { + var message = messageContents[messageIdx]; + + //test if the message contains a url + if (Links.regExp.test(message)) + //detect the url inside the string, and cache it + Uri.withinString(message, function (url) { + Links.cache(url); + return url; + }); + } + } + }); + } +}; var YouTube = { url: { @@ -53,138 +134,58 @@ var Links = { return this.cached.includes(YouTube.convertFullToShare(link)); } return this.cached.includes(link); + }, + validateAndPost: function (err, articles) { + if (err) Log.error("FEED ERROR: Error reading RSS feed.", err); + else { + //get the latest link and check if it has already been posted and cached + var latestLink = articles[0].link.replace("https", "http"); + + //check whether the latest link out the feed exists in our cache + if (!this.checkCache(latestLink)) { + if (Config.youtubeMode && latestLink.includes(YouTube.fullUrl)) + latestLink = YouTube.convertFullToShare(latestLink); + Log.info("Attempting to post new link: " + latestLink); + + //send a messsage containing the new feed link to our discord channel + Bot.bot.sendMessage({ + to: Config.channelID, + message: latestLink + }, function (err, message) { + if (err) { + Log.error("ERROR: Failed to send message: " + message.substring(0, 15) + "...", err); + //if there is an error posting the message, check if it is because the bot isn't connected + if (Bot.bot.connected) + Log.info("Connectivity seems fine - I have no idea why the message didn't post"); + else { + Log.error("Bot appears to be disconnected! Attempting to reconnect...", err); + + //attempt to reconnect + Bot.bot.connect(); + } + } + }); + + //finally make sure the link is cached, so it doesn't get posted again + this.cache(latestLink); + } + else if (this.latestFromFeed != latestLink) + //alternatively, if we have a new link from the feed, but its been posted already, just alert the console + Log.info("Didn't post new feed link because already detected as posted " + latestLink); + + //ensure our latest feed link variable is up to date, so we can track when the feed updates + this.latestFromFeed = latestLink; + } } }; -//check if we can connect to discordapp.com to authenticate the bot -Dns.resolve("discordapp.com", function (err) { - if (err) Log.error("CONNECTION ERROR: Unable to locate discordapp.com to authenticate the bot (you are probably not connected to the internet).", err); - else { - //if there was no error, go ahead and create and authenticate the bot - bot = new Discord.Client({ - token: BotConfig.token, - autorun: true - }); - - //when the bot is ready, set a polling interval for the rss feed - bot.on("ready", function () { - Log.info("Registered bot " + bot.username + " - (" + bot.id + ")"); - - //as we don't have any links cached, we need to check recent messages - checkPreviousMessagesForLinks(); - - Log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); - - if (!timer) { - setInterval(checkFeedAndPost, Config.pollingInterval); - timer = true; - } - }); - - bot.on("disconnect", function (err, code) { - //do a bunch of logging - Log.event("Bot was disconnected! " + code ? code : "No disconnect code provided", "Discord.io"); - if (err) Log.error("Bot disconnected!", err); - Log.info("Trying to reconnect bot"); - - //then actually attempt to reconnect - bot.connect(); - }); - - bot.on("message", function (user, userID, channelID, message) { - //check if the message contains a link, in the right channel, and not the latest link from the rss feed - if (channelID === Config.channelID && Links.regExp.test(message) && (message !== Links.latestFromFeed)) { - Log.event("Detected posted link in this message: " + message, "Discord.io"); - //detect the url inside the string, and cache it - Uri.withinString(message, function (url) { - Links.cache(url); - return url; - }); - } +var Feed = { + urlObj: Url.parse(Config.feedUrl), + checkAndPost: function () { + //check that we have an internet connection (well not exactly - check that we have a connection to the host of the feedUrl) + Dns.resolve(this.urlObj.host, function (err) { + if (err) Log.error("CONNECTION ERROR: Cannot resolve host (you are probably not connected to the internet)", err); + else FeedRead(Config.feedUrl, Links.checkAndPost); }); } -}); - -function checkFeedAndPost() { - //check that we have an internet connection (well not exactly - check that we have a connection to the host of the feedUrl) - Dns.resolve(url.host, function (err) { - if (err) Log.error("CONNECTION ERROR: Cannot resolve host (you are probably not connected to the internet)", err); - else FeedRead(Config.feedUrl, checkLinkAndPost); - }); -} - -//checks if the link has been posted previously, posts if not -function checkLinkAndPost(err, articles) { - if (err) Log.error("FEED ERROR: Error reading RSS feed.", err); - else { - //get the latest link and check if it has already been posted and cached - var latestLink = articles[0].link.replace("https", "http"); - - //check whether the latest link out the feed exists in our cache - if (!Links.checkCache(latestLink)) { - if (Config.youtubeMode && latestLink.includes(YouTube.fullUrl)) - latestLink = YouTube.convertFullToShare(latestLink); - Log.info("Attempting to post new link: " + latestLink); - - //send a messsage containing the new feed link to our discord channel - bot.sendMessage({ - to: Config.channelID, - message: latestLink - }, function (err, message) { - if (err) { - Log.error("ERROR: Failed to send message: " + message.substring(0, 15) + "...", err); - //if there is an error posting the message, check if it is because the bot isn't connected - if (bot.connected) - Log.info("Connectivity seems fine - I have no idea why the message didn't post"); - else { - Log.error("Bot appears to be disconnected! Attempting to reconnect...", err); - - //attempt to reconnect - bot.connect(); - } - } - }); - - //finally make sure the link is cached, so it doesn't get posted again - Links.cache(latestLink); - } - else if (Links.latestFromFeed != latestLink) - //alternatively, if we have a new link from the feed, but its been posted already, just alert the console - Log.info("Didn't post new feed link because already detected as posted " + latestLink); - - //ensure our latest feed link variable is up to date, so we can track when the feed updates - Links.latestFromFeed = latestLink; - } -} - -//gets last 100 messages and extracts any links found (for use on startup) -function checkPreviousMessagesForLinks() { - var limit = 100; - Log.info("Attempting to check past " + limit + " messages for links"); - - //get the last however many messsages from our discord channel - bot.getMessages({ - channelID: Config.channelID, - limit: limit - }, function (err, messages) { - if (err) Log.error("Error fetching discord messages.", err); - else { - Log.info("Pulled last " + messages.length + " messages, scanning for links"); - - //extract an array of strings from the array of message objects - var messageContents = messages.map((x) => { return x.content; }).reverse(); - - for (var messageIdx in messageContents) { - var message = messageContents[messageIdx]; - - //test if the message contains a url - if (Links.regExp.test(message)) - //detect the url inside the string, and cache it - Uri.withinString(message, function (url) { - Links.cache(url); - return url; - }); - } - } - }); -} \ No newline at end of file +}; \ No newline at end of file From 0d4e06c0cfa1da43fe85be828a5345bd063c74d9 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 3 Dec 2016 01:04:38 +0000 Subject: [PATCH 14/21] Added proper check for first run, so we only execute startup once --- feed-bot.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/feed-bot.js b/feed-bot.js index 52582d3..24852b0 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -1,13 +1,16 @@ +//external library imports var Dns = require("dns"); //for connectivity checking var Url = require("url"); //for url parsing var Uri = require("urijs"); //for finding urls within message strings var Discord = require("discord.io"); //for obvious reasons var FeedRead = require("feed-read"); //for rss feed reading + +//my imports +var Log = require("./log.js"); //some very simple logging functions I made var BotConfig = require("./bot-config.json"); //bot config file containing bot token var Config = require("./config.json"); //config file containing other settings -var Log = require("./log.js"); //some very simple logging functions I made -var isTimer = false; +var IS_FIRST_RUN = true; var Bot = { bot: null, @@ -30,17 +33,21 @@ var Bot = { }); }, onReady: function () { - Log.info("Registered bot " + this.bot.username + " - (" + this.bot.id + ")"); + if (IS_FIRST_RUN) { + IS_FIRST_RUN = false; - //as we don't have any links cached, we need to check recent messages - this.checkPastMessagesForLinks(); + Log.info("Registered bot " + this.bot.username + " - (" + this.bot.id + ")"); + Log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); - Log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); - - if (!isTimer) { + //set up the timer to check the feed setInterval(Feed.checkAndPost, Config.pollingInterval); - isTimer = true; } + else { + Log.info("Bot reconnected!"); + } + + //we need to check past messages for links on startup, but also on reconnect because we don't know what has happened during the downtime + this.checkPastMessagesForLinks(); }, onDisconnect: function (err, code) { //do a bunch of logging From ff4d44ed882f3f0bf3ecb53036ebd83c0c86dd04 Mon Sep 17 00:00:00 2001 From: Benji Higgins Date: Sat, 3 Dec 2016 01:05:58 +0000 Subject: [PATCH 15/21] Updated name of changelog file to match convention --- changelog.md => CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename changelog.md => CHANGELOG.md (86%) diff --git a/changelog.md b/CHANGELOG.md similarity index 86% rename from changelog.md rename to CHANGELOG.md index a901050..5b31263 100644 --- a/changelog.md +++ b/CHANGELOG.md @@ -13,4 +13,4 @@ - Changed expected name for bot config file to bot-config.json rather than botConfig.json ### Fixed -- New timer being created every time the bot reconnected \ No newline at end of file +- New timer being created every time the bot reconnected From 124a8a16680613c662cfa36f4e794644bb102f52 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 3 Dec 2016 01:37:02 +0000 Subject: [PATCH 16/21] Fixed this. references that weren't working how I expected --- feed-bot.js | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/feed-bot.js b/feed-bot.js index 24852b0..08c139b 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -20,15 +20,15 @@ var Bot = { if (err) Log.error("CONNECTION ERROR: Unable to locate discordapp.com to authenticate the bot (you are probably not connected to the internet).", err); else { //if there was no error, go ahead and create and authenticate the bot - this.bot = new Discord.Client({ + Bot.bot = new Discord.Client({ token: BotConfig.token, autorun: true }); //set up the bot's event handlers - this.bot.on("ready", this.onReady); - this.bot.on("disconnect", this.onDisconnect); - this.bot.on("message", this.onMessage); + Bot.bot.on("ready", Bot.onReady); + Bot.bot.on("disconnect", Bot.onDisconnect); + Bot.bot.on("message", Bot.onMessage); } }); }, @@ -36,7 +36,7 @@ var Bot = { if (IS_FIRST_RUN) { IS_FIRST_RUN = false; - Log.info("Registered bot " + this.bot.username + " - (" + this.bot.id + ")"); + Log.info("Registered bot " + Bot.bot.username + " - (" + Bot.bot.id + ")"); Log.info("Setting up timer to check feed every " + Config.pollingInterval + " milliseconds"); //set up the timer to check the feed @@ -47,7 +47,7 @@ var Bot = { } //we need to check past messages for links on startup, but also on reconnect because we don't know what has happened during the downtime - this.checkPastMessagesForLinks(); + Bot.checkPastMessagesForLinks(); }, onDisconnect: function (err, code) { //do a bunch of logging @@ -56,7 +56,7 @@ var Bot = { Log.info("Trying to reconnect bot"); //then actually attempt to reconnect - this.bot.connect(); + Bot.bot.connect(); }, onMessage: function (user, userID, channelID, message) { //check if the message contains a link, in the right channel, and not the latest link from the rss feed @@ -107,10 +107,10 @@ var YouTube = { share: "http://youtu.be/", full: "http://www.youtube.com/watch?v=", convertShareToFull: function (shareUrl) { - return shareUrl.replace(this.share, this.full); + return shareUrl.replace(YouTube.share, YouTube.full); }, convertFullToShare: function (fullUrl) { - var shareUrl = fullUrl.replace(this.share, this.full); + var shareUrl = fullUrl.replace(YouTube.share, YouTube.full); if (shareUrl.includes("&")) shareUrl = shareUrl.slice(0, fullUrl.indexOf("&")); @@ -128,19 +128,19 @@ var Links = { //cheaty way to get around http and https not matching link = link.replace("https://", "http://"); //store the new link if not stored already - if (!this.cached.includes(link)) { - this.cached.push(link); + if (!Links.cached.includes(link)) { + Links.cached.push(link); Log.info("Cached URL: " + link); } //get rid of the first array element if we have reached our cache limit - if (this.cached.length > (Config.numLinksToCache || 10)) - this.cached.shift(); + if (Links.cached.length > (Config.numLinksToCache || 10)) + Links.cached.shift(); }, checkCache: function (link) { if (Config.youtubeMode && link.includes(link)) { - return this.cached.includes(YouTube.convertFullToShare(link)); + return Links.cached.includes(YouTube.convertFullToShare(link)); } - return this.cached.includes(link); + return Links.cached.includes(link); }, validateAndPost: function (err, articles) { if (err) Log.error("FEED ERROR: Error reading RSS feed.", err); @@ -149,7 +149,7 @@ var Links = { var latestLink = articles[0].link.replace("https", "http"); //check whether the latest link out the feed exists in our cache - if (!this.checkCache(latestLink)) { + if (!Links.checkCache(latestLink)) { if (Config.youtubeMode && latestLink.includes(YouTube.fullUrl)) latestLink = YouTube.convertFullToShare(latestLink); Log.info("Attempting to post new link: " + latestLink); @@ -174,14 +174,14 @@ var Links = { }); //finally make sure the link is cached, so it doesn't get posted again - this.cache(latestLink); + Links.cache(latestLink); } - else if (this.latestFromFeed != latestLink) + else if (Links.latestFromFeed != latestLink) //alternatively, if we have a new link from the feed, but its been posted already, just alert the console Log.info("Didn't post new feed link because already detected as posted " + latestLink); //ensure our latest feed link variable is up to date, so we can track when the feed updates - this.latestFromFeed = latestLink; + Links.latestFromFeed = latestLink; } } }; @@ -190,9 +190,14 @@ var Feed = { urlObj: Url.parse(Config.feedUrl), checkAndPost: function () { //check that we have an internet connection (well not exactly - check that we have a connection to the host of the feedUrl) - Dns.resolve(this.urlObj.host, function (err) { + Dns.resolve(Links.urlObj.host, function (err) { if (err) Log.error("CONNECTION ERROR: Cannot resolve host (you are probably not connected to the internet)", err); else FeedRead(Config.feedUrl, Links.checkAndPost); }); } -}; \ No newline at end of file +}; + +//IIFE to kickstart the bot when the app loads +(function(){ + Bot.startup(); +})(); \ No newline at end of file From 1624b3a8b055aa249fb1c438ed911741a383a72f Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 3 Dec 2016 01:52:16 +0000 Subject: [PATCH 17/21] Fixed a bunch of wrong references from quick copy-pastes --- feed-bot.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/feed-bot.js b/feed-bot.js index 08c139b..30b05c0 100644 --- a/feed-bot.js +++ b/feed-bot.js @@ -107,10 +107,10 @@ var YouTube = { share: "http://youtu.be/", full: "http://www.youtube.com/watch?v=", convertShareToFull: function (shareUrl) { - return shareUrl.replace(YouTube.share, YouTube.full); + return shareUrl.replace(YouTube.url.share, YouTube.url.full); }, convertFullToShare: function (fullUrl) { - var shareUrl = fullUrl.replace(YouTube.share, YouTube.full); + var shareUrl = fullUrl.replace(YouTube.url.full, YouTube.url.share); if (shareUrl.includes("&")) shareUrl = shareUrl.slice(0, fullUrl.indexOf("&")); @@ -127,6 +127,11 @@ var Links = { cache: function (link) { //cheaty way to get around http and https not matching link = link.replace("https://", "http://"); + + if(Config.youtubeMode && link.includes(YouTube.url.full)){ + link = YouTube.url.convertFullToShare(link); + } + //store the new link if not stored already if (!Links.cached.includes(link)) { Links.cached.push(link); @@ -138,7 +143,7 @@ var Links = { }, checkCache: function (link) { if (Config.youtubeMode && link.includes(link)) { - return Links.cached.includes(YouTube.convertFullToShare(link)); + return Links.cached.includes(YouTube.url.convertFullToShare(link)); } return Links.cached.includes(link); }, @@ -150,8 +155,8 @@ var Links = { //check whether the latest link out the feed exists in our cache if (!Links.checkCache(latestLink)) { - if (Config.youtubeMode && latestLink.includes(YouTube.fullUrl)) - latestLink = YouTube.convertFullToShare(latestLink); + if (Config.youtubeMode && latestLink.includes(YouTube.url.full)) + latestLink = YouTube.url.convertFullToShare(latestLink); Log.info("Attempting to post new link: " + latestLink); //send a messsage containing the new feed link to our discord channel @@ -190,9 +195,9 @@ var Feed = { urlObj: Url.parse(Config.feedUrl), checkAndPost: function () { //check that we have an internet connection (well not exactly - check that we have a connection to the host of the feedUrl) - Dns.resolve(Links.urlObj.host, function (err) { + Dns.resolve(Feed.urlObj.host, function (err) { if (err) Log.error("CONNECTION ERROR: Cannot resolve host (you are probably not connected to the internet)", err); - else FeedRead(Config.feedUrl, Links.checkAndPost); + else FeedRead(Config.feedUrl, Links.validateAndPost); }); } }; From 437b5d5ad68337945a0d9eef14e4dce773d944b4 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 3 Dec 2016 01:53:23 +0000 Subject: [PATCH 18/21] Updated changelog to note refactor --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b31263..dc57926 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,13 @@ ### Added -- New logging class to handle logging - Added togglable YouTube mode - Converts full URLs to YouTube share URLs - Checks against both YouTube full and share URLs to ensure same video not posted twice +- New logging class to handle logging ### Changed +- Major refactor of a significant portion of the bot's code - should be easier to maintain now, but may have introduced some new bugs - Changed expected name for bot config file to bot-config.json rather than botConfig.json ### Fixed From 8763397ef06f3577c5187431688e19f298c88eed Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 3 Dec 2016 02:20:27 +0000 Subject: [PATCH 19/21] Updated readme to include new YouTube mode feature --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4769181..326bc44 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,9 @@ # Features - Posts latest link from RSS feed into specified Discord channel -- Doesn't post the link if it has already been posted in last 100 messages - Configurable polling interval - -# Planned features - -- Addition of user-defined URLs to match as 'sent' (ie if a user posts a youtu.be link, the bot will still post a youtube.com link, even if they point to the same palce - I would like to add a setting whereby you can specify alternate hosts to match) +- Doesn't post the link if it has already been posted in last 100 messages +- YouTube mode - detects both youtube.com and youtu.be links, and doesn't post again if *either* have already been posted (BETA) Feel free to contact me with suggestions and feature requests - if you need a new feature, just let me know and I will see what I can do! (No promises though :p) From e9d86ddc03d461df6546c1a48cd701a3b8d315bd Mon Sep 17 00:00:00 2001 From: Benji Higgins Date: Sat, 3 Dec 2016 20:09:06 +0000 Subject: [PATCH 20/21] Updated README to reference releases page --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 326bc44..f314600 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ Feel free to contact me with suggestions and feature requests - if you need a ne # Installation 1. Make sure you have nodejs (v6+) and npm installed -2. Clone repo or download zip and extract somewhere -3. Open a terminal in cloned/extracted folder +2. Download the zip from [releases](https://github.com/benji7425/discord-feed-bot/releases) and extract +3. Open a terminal in extracted folder 4. Run `npm install` and wait for it to finish 5. Edit *config.json* to include your RSS feed and channel ID 6. Create *bot-config.json* to include your bot token: From d698e2e17584e194dad8dc59eb018e4b996e0f7c Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 3 Dec 2016 20:11:31 +0000 Subject: [PATCH 21/21] Updated changelog for 1.1.0 pre-release --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc57926..e8eb5db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 1.1.0 pre ### Added