Merged release/v1.3.0 into master

This commit is contained in:
benji7425 2017-01-22 18:57:02 +00:00
commit 3c8b45154a
10 changed files with 198 additions and 79 deletions

View File

@ -1,5 +1,20 @@
# Changelog
## v1.3.0
### Added
- Deletion of "You have successfully subscribed" messages after a short delay (configurable)
- 'Developer' commands that can only be accessed by specified users
- !cacheList developer command to view the cached URLs
### Updated
- !logsplease is now a developer command
- Subscriptions are now done using a role
- !subscribe and !unsibscribe add and remove the user from the role
- !sublist command is now removed
- The role is mentioned when the link is posted, rather than a long chain of user IDs
## v1.2.1
### Fixed

View File

@ -1,14 +1,24 @@
{
"feedUrl": "https://www.youtube.com/feeds/videos.xml?user=EthosLab",
"channelID": "264420391282409473",
"serverID": "264420391282409473",
"pollingInterval": 5000,
"numLinksToCache": 10,
"messageDeleteDelay": 10000,
"youtubeMode": true,
"logRequestMessage": "!logsplease",
"subscribeRequestMessage": "!subscribe",
"unsubscribeRequestMessage": "!unsubscribe",
"subscribersListRequestMessage": "!sublist",
"helpRequestMessage": "!help",
"allowSubscriptions": true,
"subscribersRoleID": "272788856447959040",
"logFile": "./log",
"subscribersFile": "./subscribers.json"
"userCommands": {
"subscribe": "!subscribe",
"unsubscribe": "!unsubscribe",
"help": "!help"
},
"developerCommands": {
"logUpload": "!logsplease",
"cacheList": "!cacheList"
},
"developers": [
"117966411548196870"
]
}

11
docs/.gitrepo Normal file
View File

@ -0,0 +1,11 @@
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = git@github.com:benji7425/discord-feed-bot.wiki.git
branch = master
commit = f70e48b91074ad051eec48679d013409a79ed53e
parent = 21bc8bdaeb42f8eca6218fbe1910ddcc75d56c3c
cmdver = 0.3.1

View File

@ -2,9 +2,18 @@
There is a very basic level of interaction with the bot available via chat commands, all of which are prefixed with an exclamation mark '!'
## User commands
| command | action |
|--------------|-----------------------------------------------------------------------------------------|
| !help | list available commands |
| !subscribe | subscribe to feed notifications, so your username gets tagged when a new link is posted |
| !unsubscribe | unsubscribe from feed notifications |
| !sublist | view list of subscribed users |
## Developer commands
Requires your user ID to be specified in the developers list in config.json
| command | action |
|-------------|----------------------------|
| !logsplease | upload the log file |
| !cacheList | report all the cached URLs |

View File

@ -0,0 +1,31 @@
# Configuration
| parameter | description |
|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------|
| feedUrl | the RSS feed to check |
| channelID | report all the cached URLs |
| serverID | id of the server the bot is installed on - require to use subscriptions |
| pollingInterval | interval in ms to check the RSS feed |
| numLinksToCache | number of posted links to cache and check against before posting - turn this up if users post a lot of links in the channel |
| messageDeleteDelay | time in ms to leave response messages before deleting (eg "You have successfully subscribed") |
| youtubeMode | whether or not to convert YouTube links to their short url - recommended if you are pulling links from a YouTube channel feed |
| allowSubscriptions | whether or not to have the bot mention a role when it posts a link |
| subscribersRoleID | the ID of the role to mention when posting a link - you can find this by typing \@role in discord and copying out just the numeric part |
| developers | array of developer IDs - add a new one by putting a comma at the end of the one above and putting the ID in double quotes |
## How to find IDs
- Make sure developer mode is turned on in discord
- User Settings > Appearance > Developer Mode
| id | how to find |
|----------------------------|-----------------------------------------------|
| channelID | right click on the channel > copy ID |
| serverID | right click on the server name > copy ID |
| subscribersRoleID | type \@role in discord, copy the numeric part |
| user ID (to add developer) | right click on user > copy ID |
## Note about subsriptions
For subscriptions to work the bot needs the "Manage roles" permission, and needs to be in a role *higher than* the subscribers role

View File

@ -4,9 +4,11 @@
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
5. Edit *config.json* to include your server/channel details (see configuration page for more info)
6. Create *bot-config.json* to include your bot token:
`{
"token": "abc123blahblahblahyourtokengoeshere"
}`
7. Run `node feed-bot.js`
7. Run `node feed-bot.js`
See configuration page for more detail on configuration options

View File

@ -0,0 +1,10 @@
# Troubleshooting
## Bot can't add users to role
- Make sure the bot's role has the "Manage Roles" permission
- Make sure the bot's role is higher than the subscribers role
## Other stuff
Feel free to contact me at the email on my GitHub profile :)

View File

@ -37,6 +37,7 @@ var DiscordClient = {
DiscordClient.checkPastMessagesForLinks(); //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
//set the interval function to check the feed
intervalFunc = () => {
Feed.check((err, articles) => {
Links.validate(err, articles, DiscordClient.post);
@ -61,36 +62,17 @@ var DiscordClient = {
});
}
else {
switch (message) {
case Config.subscribeRequestMessage:
Subscriptions.subscribe(channelID, userID, user);
break;
case Config.unsubscribeRequestMessage:
Subscriptions.unsubscribe(channelID, userID, user);
break;
case Config.subscribersListRequestMessage:
DiscordClient.bot.sendMessage({
to: Config.channelID,
message: DiscordClient.bot.fixMessage("<@" + Subscriptions.subscribers.join("> <@") + ">")
});
break;
case Config.helpRequestMessage:
DiscordClient.bot.sendMessage({
to: Config.channelID,
message: Config.subscribeRequestMessage + ", " + Config.unsubscribeRequestMessage + ", " + Config.subscribersListRequestMessage
});
//iterate over all of our message triggers to see if the message sent requires any action
for (var i = 0; i < DiscordClient.messageTriggers.length; i++) {
var messageTrigger = DiscordClient.messageTriggers[i];
if (message === messageTrigger.message) {
//check if its locked to a channel or to a specific user
if ((messageTrigger.channelID && messageTrigger.channelID === channelID) || (messageTrigger.userIDs && messageTrigger.userIDs.includes(userID)))
messageTrigger.action(user, userID, channelID, message);
}
}
}
}
else if (message === Config.logRequestMessage) {
DiscordClient.bot.uploadFile({
to: channelID,
file: Config.logFile
}, (err, message) => {
if (err) Log.error("Failed to upload log file: " + message, err);
else Log.event("Uploaded log file for user " + user + "(" + userID + ")");
});
}
},
checkPastMessagesForLinks: function () {
var limit = 100;
@ -121,58 +103,100 @@ var DiscordClient = {
});
},
post: function (link) {
var tags = "";
for (var userID in Subscriptions.subscribers)
tags += "<@" + Subscriptions.subscribers[userID] + "> ";
//send a messsage containing the new feed link to our discord channel
DiscordClient.bot.sendMessage({
to: Config.channelID,
message: tags + link
}, function (err, message) {
if (err) {
Log.error("ERROR: Failed to send message" + message ? message : "", err);
//if there is an error posting the message, check if it is because the bot isn't connected
if (!DiscordClient.bot.connected) DiscordClient.onDisconnect();
}
message: Subscriptions.mention() + link
});
}
},
//actions to perform when certain messages are detected, along with channel or user requirements
messageTriggers: [
{
message: Config.userCommands.subscribe,
action: (user, userID, channelID, message) => { if (Config.allowSubscriptions) Subscriptions.subscribe(user, userID, channelID, message); },
channelID: Config.channelID
},
{
message: Config.userCommands.unsubscribe,
action: (user, userID, channelID, message) => { if (Config.allowSubscriptions) Subscriptions.unsubscribe(user, userID, channelID, message); },
channelID: Config.channelID
},
{
message: Config.userCommands.help,
action: (user, userID, channelID, message) => {
DiscordClient.bot.sendMessage({
to: Config.channelID,
message: Config.userCommands.join(" + ")
});
},
channelID: Config.channelID
},
{
message: Config.developerCommands.logUpload,
action: (user, userID, channelID, message) => {
DiscordClient.bot.uploadFile({
to: channelID,
file: Config.logFile
});
},
userIDs: Config.developers
},
{
message: Config.developerCommands.cacheList,
action: (user, userID, channelID, message) => {
DiscordClient.bot.sendMessage({
to: channelID,
message: Links.cached.join(", ")
});
},
userIDs: Config.developers
}
]
};
var Subscriptions = {
subscribers: [],
parse: function () {
JsonFile.readFile(Config.subscribersFile, (err, obj) => {
if (err) Log.error("Unable to parse json subscribers file", err);
this.subscribers = obj || [];
});
},
subscribe: function (channelID, userID, user) {
if (this.subscribers.indexOf(userID) === -1) {
this.subscribers.push(userID); //subscribe the user if they aren't already subscribed
this.writeToFile();
Log.event("Subscribed user " + (user ? user + "(" + userID + ")" : userID));
subscribe: function (user, userID, channelID, message) {
DiscordClient.bot.addToRole({
serverID: Config.serverID,
userID: userID,
roleID: Config.subscribersRoleID
},
(err) => {
if (err) Log.raw(err); //log the error if there is an error
else { //else go ahead and confirm subscription
Log.event("Subscribed user " + (user ? user + "(" + userID + ")" : userID));
DiscordClient.bot.sendMessage({
to: channelID,
message: "You have successfully subscribed"
DiscordClient.bot.sendMessage({
to: channelID,
message: "You have successfully subscribed"
}, (err, response) => { setTimeout(() => { DiscordClient.bot.deleteMessage({ channelID: channelID, messageID: response.id }); }, Config.messageDeleteDelay); }); //delete the subscription confirmation message after a delay
}
});
}
},
unsubscribe: function (channelID, userID, user) {
if (this.subscribers.indexOf(userID) > -1) {
this.subscribers.splice(this.subscribers.indexOf(userID), 1);
this.writeToFile();
Log.event("Unsubscribed user " + (user ? user + "(" + userID + ")" : userID));
DiscordClient.bot.sendMessage({
to: channelID,
message: "You have successfully unsubscribed"
});
}
},
writeToFile: function () {
JsonFile.writeFile(Config.subscribersFile, this.subscribers, (err) => { if (err) Log.error("Unable to write subscribers to json file", err); });
unsubscribe: function (user, userID, channelID, message) {
DiscordClient.bot.removeFromRole({
serverID: Config.serverID,
userID: userID,
roleID: Config.subscribersRoleID
},
(err) => {
if (err) Log.raw(err); //log the error if there is an error
else { //else go ahead and confirm un-subscription
Log.event("Unsubscribed user " + (user ? user + "(" + userID + ")" : userID));
DiscordClient.bot.sendMessage({
to: channelID,
message: "You have successfully unsubscribed"
}, (err, response) => { setTimeout(() => { DiscordClient.bot.deleteMessage({ channelID: channelID, messageID: response.id }); }, Config.messageDeleteDelay); }); //delete the un-subscription confirmation message after a delay
}
});
},
mention: function () {
return Config.allowSubscriptions ? "<@&" + Config.subscribersRoleID + "> " : "";
}
};
@ -265,7 +289,6 @@ var intervalFunc = () => { }; //do nothing by default
//IIFE to kickstart the bot when the app loads
(function () {
Subscriptions.parse();
DiscordClient.startup();
setInterval(() => { intervalFunc(); }, Config.pollingInterval);
})();

7
log.js
View File

@ -20,6 +20,10 @@ function log(message) {
}
}
function logRaw(obj) {
Console.log(obj);
}
module.exports = {
info: function (message) {
if (message)
@ -36,5 +40,8 @@ module.exports = {
//log the message, attach innerEx information if it was passed
log("[ERROR] " + message + (innerEx ? ". Inner exception details: " + (innerEx.message || innerEx) : ""));
}
},
raw: function (obj) {
if (obj) logRaw(obj);
}
};

View File

@ -1,9 +1,10 @@
{
"name": "discord-feed-bot",
"version": "1.0.0",
"version": "1.3.0",
"description": "discord-feed-bot",
"main": "index.js",
"scripts": {
"start": "node feed-bot.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {