From f56c8454fc28f0f64c0f1685c82ed0d2cd4f89cb Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 12 Aug 2017 01:42:17 +0100 Subject: [PATCH 1/3] Temporarily rename files --- app/{config.json => config.old.json} | 0 app/{index.js => index.old.js} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename app/{config.json => config.old.json} (100%) rename app/{index.js => index.old.js} (100%) diff --git a/app/config.json b/app/config.old.json similarity index 100% rename from app/config.json rename to app/config.old.json diff --git a/app/index.js b/app/index.old.js similarity index 100% rename from app/index.js rename to app/index.old.js From 5428e71f01691e6b11d3c36e43deaf79cfbc7336 Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 12 Aug 2017 01:44:35 +0100 Subject: [PATCH 2/3] Merge in template --- .gitignore | 5 ++--- CHANGELOG.md | 3 +++ app/config.json | 6 ++++++ app/index.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 7 ++++--- 5 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 app/config.json create mode 100644 app/index.js diff --git a/.gitignore b/.gitignore index f772ff4..7836b18 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ -# Project specific - -token.json +### Discord bots #### guilds.json +token.json log ### Node ### diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8deb76e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +## Unreleased \ No newline at end of file diff --git a/app/config.json b/app/config.json new file mode 100644 index 0000000..ddda549 --- /dev/null +++ b/app/config.json @@ -0,0 +1,6 @@ +{ + "saveIntervalSec": 60, + "commands": { + "version": "version" + } +} \ No newline at end of file diff --git a/app/index.js b/app/index.js new file mode 100644 index 0000000..11ba6b5 --- /dev/null +++ b/app/index.js @@ -0,0 +1,55 @@ +//node imports +const FileSystem = require("fs"); + +//external lib imports +const JsonFile = require("jsonfile"); + +//my imports +const DiscordUtil = require("discordjs-util"); + +//global vars +const SAVE_FILE = "./guilds.json"; + +module.exports = (client) => { + const config = require("./config.json"); + + const guildsData = FileSystem.existsSync(SAVE_FILE) ? fromJSON(JsonFile.readFileSync(SAVE_FILE)) : {}; + setInterval(() => writeFile(guildsData), config.saveIntervalSec * 1000); + + client.on("message", message => { + if (message.author.id !== client.user.id) { //check the bot isn't triggering itself + if (message.channel.type === "dm") + HandleMessage.DM(client, config, message); + else if (message.channel.type === "text" && message.member) + HandleMessage.Text(client, config, message, guildsData); + } + }); +}; + +const HandleMessage = { + DM: (client, config, message) => { + message.reply("This bot does not have any handling for direct messages. To learn more or get help please visit http://benji7425.github.io, or join my Discord server here: https://discord.gg/SSkbwSJ"); + }, + Text: (client, config, message, guildsData) => { + //handle admins invoking commands + if (message.content.startsWith(message.guild.me.toString()) //user is @mention-ing the bot + && message.member.permissions.has("ADMINISTRATOR")) //user has admin perms + { + const params = message.content.split(" "); //split the message at the spaces + switch (params[1]) { + //add handling for different commands here + case config.commands.version: + message.reply("v" + require("../package.json").version); + break; + } + } + } +}; + +function writeFile(guildsData) { + JsonFile.writeFile(SAVE_FILE, guildsData, err => { if (err) DiscordUtil.dateError("Error writing file", err); }); +} + +function fromJSON(json) { + throw "Not implemented"; +} \ No newline at end of file diff --git a/package.json b/package.json index 1223f18..b918016 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,10 @@ "name": "discord-bot-feed-linker", "version": "2.0.0", "description": "", - "main": "index.js", + "main": "app/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node wrapper.js" }, "repository": { "type": "git", @@ -24,4 +25,4 @@ "jsonfile": "3.0.1", "urijs": "1.18.10" } -} +} \ No newline at end of file From 6b9bf2f27f091f968b35c209802a32b8f70fa60c Mon Sep 17 00:00:00 2001 From: benji7425 Date: Sat, 12 Aug 2017 01:49:35 +0100 Subject: [PATCH 3/3] Update new index.js and config.json with application code --- app/config.json | 3 +- app/config.old.json | 5 --- app/index.js | 68 +++++++++++++++++++++++++++++++- app/index.old.js | 96 --------------------------------------------- 4 files changed, 69 insertions(+), 103 deletions(-) delete mode 100644 app/config.old.json delete mode 100644 app/index.old.js diff --git a/app/config.json b/app/config.json index ddda549..26971c6 100644 --- a/app/config.json +++ b/app/config.json @@ -1,6 +1,7 @@ { "saveIntervalSec": 60, "commands": { - "version": "version" + "version": "version", + "addFeed": "add-feed" } } \ No newline at end of file diff --git a/app/config.old.json b/app/config.old.json deleted file mode 100644 index 9fc31e9..0000000 --- a/app/config.old.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "commands": { - "addFeed": "!addfeed" - } -} \ No newline at end of file diff --git a/app/index.js b/app/index.js index 11ba6b5..68168c4 100644 --- a/app/index.js +++ b/app/index.js @@ -7,6 +7,10 @@ const JsonFile = require("jsonfile"); //my imports const DiscordUtil = require("discordjs-util"); +//app component imports +const GuildData = require("./models/guild-data.js"); +const FeedData = require("./models/feed-data.js"); + //global vars const SAVE_FILE = "./guilds.json"; @@ -16,6 +20,8 @@ module.exports = (client) => { const guildsData = FileSystem.existsSync(SAVE_FILE) ? fromJSON(JsonFile.readFileSync(SAVE_FILE)) : {}; setInterval(() => writeFile(guildsData), config.saveIntervalSec * 1000); + parseLinksInAllGuilds(client.guilds, guildsData).then(writeFile(guildsData)); + client.on("message", message => { if (message.author.id !== client.user.id) { //check the bot isn't triggering itself if (message.channel.type === "dm") @@ -41,15 +47,75 @@ const HandleMessage = { case config.commands.version: message.reply("v" + require("../package.json").version); break; + case config.commands.addFeed: + addFeed(client, guildsData, message); + break; } } } }; +function addFeed(client, guildsData, message) { + const feedData = createNewFeed(message); //create a new feed data instance from the data in our message + + //ask the user if they're happy with the details they set up, save if yes, don't if no + DiscordUtil.ask(client, message.channel, message.member, "Are you happy with this? " + feedData) + .then(responseMessage => { + + //if they responded yes, save the feed and let them know, else tell them to start again + if (message.content.toLowerCase() === "yes") { + saveFeed(guildsData, message.guild.id, feedData); + responseMessage.reply("Your new feed has been saved!"); + } + else + responseMessage.reply("Your feed has not been saved, please add it again with the correct details"); + + }); +} + +function parseLinksInAllGuilds(guilds, guildsData) { + const promises = []; + for (let guild of guilds) { + const guildData = guildsData[guild.id]; + if (guildData) + promises.push(guildData.cachePastPostedLinks()); + } + return Promise.all(promises); +} + +/** + * Create a new feed from the message object where the user is setting it up + * @param {Discord.Message} message + * @returns {FeedData} Newly created feed data object + */ +function createNewFeed(message) { + const parameters = message.content.split(" "); //expect !addfeed + const feedData = new FeedData({ + link: parameters[1], + channelName: parameters[2], + roleName: parameters[3] + }); + return feedData; +} + +/** + * Saves a passed feed data object into the passed guildsData object, for the specified guild + * @param {object} guildsData + * @param {string} guildID + * @param {FeedData} feedData + */ +function saveFeed(guildsData, guildID, feedData) { + if (!guildsData[guildID]) + guildsData[guildID] = new GuildData({ id: guildID, feeds: [] }); + + guildsData[guildID].feeds.push(feedData); +} + function writeFile(guildsData) { JsonFile.writeFile(SAVE_FILE, guildsData, err => { if (err) DiscordUtil.dateError("Error writing file", err); }); } function fromJSON(json) { - throw "Not implemented"; + const guildIDs = Object.keys(json); + guildIDs.forEach(guildID => { guildIDs[guildID] = new GuildData(guildIDs[guildID]); }); } \ No newline at end of file diff --git a/app/index.old.js b/app/index.old.js deleted file mode 100644 index a3d6606..0000000 --- a/app/index.old.js +++ /dev/null @@ -1,96 +0,0 @@ -//node imports -const FileSystem = require("fs"); - -//external lib imports -const JSONFile = require("jsonfile"); - -//my imports -const Util = require("discordjs-util"); - -//app component imports -const GuildData = require("./models/guild-data.js"); -const FeedData = require("./models/feed-data.js"); - -const SAVE_FILE = "./guilds.json"; - -//acts as on ready function -module.exports = (client) => { - const config = require("./config.json"); - const guildsData = FileSystem.existsSync(SAVE_FILE) ? parseJSON(JSONFile.readFileSync(SAVE_FILE)) : {}; //pull saved data from file - - parseLinksInAllGuilds(client.guilds, guildsData).then(writeFile(guildsData)); - - //set up an interval to check all the feeds - - //set up an on message handler to detect when links are posted - client.on("message", message => { - if (message.member.id !== client.user.id) { //make sure the bot ignores itself - - //check if the user is admin and is invoking the add feed command - if (message.member.permissions.has("ADMINISTRATOR") && message.content.startsWith(config.commands.setup)) { - const feedData = createNewFeed(message); //create a new feed data instance from the data in our message - - //ask the user if they're happy with the details they set up, save if yes, don't if no - Util.ask(client, message.channel, message.member, "Are you happy with this? " + feedData) - .then(responseMessage => { - - //if they responded yes, save the feed and let them know, else tell them to start again - if (message.content.toLowerCase() === "yes") { - saveFeed(guildsData, message.guild.id, feedData); - responseMessage.reply("Your new feed has been saved!"); - } - else - responseMessage.reply("Your feed has not been saved, please add it again with the correct details"); - - }); - } - } - }); -}; - -function parseLinksInAllGuilds(guilds, guildsData) { - const promises = []; - for (let guild of guilds) { - const guildData = guildsData[guild.id]; - if (guildData) - promises.push(guildData.cachePastPostedLinks()); - } - return Promise.all(promises); -} - -/** - * Create a new feed from the message object where the user is setting it up - * @param {Discord.Message} message - * @returns {FeedData} Newly created feed data object - */ -function createNewFeed(message) { - const parameters = message.content.split(" "); //expect !addfeed - const feedData = new FeedData({ - link: parameters[1], - channelName: parameters[2], - roleName: parameters[3] - }); - return feedData; -} - -/** - * Saves a passed feed data object into the passed guildsData object, for the specified guild - * @param {object} guildsData - * @param {string} guildID - * @param {FeedData} feedData - */ -function saveFeed(guildsData, guildID, feedData) { - if(!guildsData[guildID]) - guildsData[guildID] = new GuildData({ id: guildID, feeds: [] }); - - guildsData[guildID].feeds.push(feedData); -} - -function parseJSON(json) { - const guildIDs = Object.keys(json); - guildIDs.forEach(guildID => { guildIDs[guildID] = new GuildData(guildIDs[guildID]); }); -} - -function writeFile(guildsData) { - JSONFile.write(SAVE_FILE, guildsData, err => { if (err) Util.dateError(err); }); -} \ No newline at end of file