From 2bfbf3c661b6c8a56253cfaf86c9bc82934c89a6 Mon Sep 17 00:00:00 2001 From: Tagadda <36127788+Tagadda@users.noreply.github.com> Date: Sat, 9 Jun 2018 12:29:07 +0200 Subject: [PATCH] Implements commands --- CommandBase.js | 7 ++++++ README.md | 8 +++---- bot.js | 20 +++++++++++++--- commands/BlockDomain.js | 18 ++++++++++++++ commands/MuteUser.js | 18 ++++++++++++++ commands/Unfollow.js | 18 ++++++++++++++ index.js | 53 ++++++++++++++++++++++++++++++++++++++--- package.json | 1 + 8 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 CommandBase.js create mode 100644 commands/BlockDomain.js create mode 100644 commands/MuteUser.js create mode 100644 commands/Unfollow.js diff --git a/CommandBase.js b/CommandBase.js new file mode 100644 index 0000000..2222d78 --- /dev/null +++ b/CommandBase.js @@ -0,0 +1,7 @@ +class CommandBase { + constructor(client) { + this.client = client; + } +} + +module.exports = CommandBase; \ No newline at end of file diff --git a/README.md b/README.md index d8a9df9..5e94206 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,13 @@ This bot listens on the Federated Timeline and follows everyone. This bot respect the #nobot tag. If you don't want to be followed by the bot anymore, -just DM "unfollow" to the bot, and it'll never follow you again. [WIP] +just DM "unfollow" to the bot, and it'll never follow you again. |Command|What is does| |---|---| -|unfollow|[WIP] The bot will unfollow and mure you so it'll never follow you again.| -|blockuser <user@domain.tld>|[WIP] The bot will mute the targeted user. If followed, it'll unfollow they too. Admin only.| -|blockdomain <domain.tld>|[WIP] The bot will mute the targeted domain. If users from this domain are followed, it'll unfollow them. Admin only.| +|unfollow|The bot will unfollow and mure you so it'll never follow you again.| +|blockuser <user@domain.tld>|The bot will mute the targeted user. If followed, it'll unfollow they too. Admin only.| +|blockdomain <domain.tld>|The bot will mute the targeted domain. If users from this domain are followed, it'll unfollow them. Admin only.| ## Running the bot diff --git a/bot.js b/bot.js index 63dab79..753137b 100644 --- a/bot.js +++ b/bot.js @@ -1,9 +1,6 @@ const EventEmitter = require('events'); const MastodonAPI = require('mastodon-api'); -// Todo: Implements mute_user and block_domain -// Todo: Implements unfollow - class Bot extends EventEmitter { /** * Constructor @@ -110,6 +107,15 @@ class Bot extends EventEmitter { follow(id) { this.M.post('accounts/' + id + '/follow'); } + + /** + * Unfollow a user + * @param {int} id + */ + unfollow(id) { + this.M.post('accounts/' + id + '/unfollow'); + } + /** * Mute an user * @param {int} id @@ -118,5 +124,13 @@ class Bot extends EventEmitter { this.M.post('accounts/' + id + '/mute'); } + /** + * Block a domain + * @param {string} domain + */ + block_domain(domain) { + this.M.post('domain_blocks', { domain }); + } } + module.exports = Bot; \ No newline at end of file diff --git a/commands/BlockDomain.js b/commands/BlockDomain.js new file mode 100644 index 0000000..1a9753e --- /dev/null +++ b/commands/BlockDomain.js @@ -0,0 +1,18 @@ +const CommandBase = require('../CommandBase'); + +class BlockDomain extends CommandBase { + constructor(client) { + super(client); + this.name = 'blockdomain'; + this.admin_only = true; + this.required_args = 1; + } + + execute(msg, args) { + this.client.block_domain(args[0]); + + this.client.fav(msg.status.id); + } +} + +module.exports = BlockDomain; \ No newline at end of file diff --git a/commands/MuteUser.js b/commands/MuteUser.js new file mode 100644 index 0000000..116465b --- /dev/null +++ b/commands/MuteUser.js @@ -0,0 +1,18 @@ +const CommandBase = require('../CommandBase'); + +class MuteUser extends CommandBase { + constructor(client) { + super(client); + this.name = 'muteuser'; + this.admin_only = true; + this.required_args = 1; + } + + execute(msg, args) { + this.client.mute_user(args[0]); + + this.client.fav(msg.status.id); + } +} + +module.exports = MuteUser; \ No newline at end of file diff --git a/commands/Unfollow.js b/commands/Unfollow.js new file mode 100644 index 0000000..9505c02 --- /dev/null +++ b/commands/Unfollow.js @@ -0,0 +1,18 @@ +const CommandBase = require('../CommandBase'); + +class Unfollow extends CommandBase { + constructor(client) { + super(client); + this.name = 'unfollow'; + } + + execute(msg) { + this.client.unfollow(msg.account.id); + + this.client.mute_user(msg.account.id); + + this.client.fav(msg.status.id); + } +} + +module.exports = Unfollow; \ No newline at end of file diff --git a/index.js b/index.js index 7e3c39a..fadc7a8 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,23 @@ const Bot = require("./bot"); const striptags = require('striptags'); +const fs = require('fs'); +const Dict = require('collections/dict'); const config = require('./config.json'); +// Hardcode admins since Mastodon API doesn't provide such thing... +const admins = ['tagadmin', 'Dhveszak', 'Incandescente']; + const client = new Bot(config, [{api_point: "public", events: ["update"]}, {api_point: "user", events: ["notification"]}]); +const commands = new Dict(); +const commandFiles = fs.readdirSync(__dirname + "/commands/"); +for (const file of commandFiles) { + const commandClass = require(__dirname + "/commands/" + file); + const command = new commandClass(client); + commands.set(command.name, command) +} + // Following list const following = []; @@ -16,6 +29,7 @@ client.start().then(() => { }); }); +// When a toot arrives in Federated Timeline client.on('update', (msg) => { const acct = msg.account.acct; const id = parseInt(msg.account.id); @@ -45,10 +59,43 @@ client.on('update', (msg) => { console.log("NOW FOLLOWS: " + acct); }); +// When a toto arrives in notifications (mentions) client.on("notification", (msg) => { if (msg.type !== "mention") return; - // Todo: Implement unfollow command - // Todo: Implement blockuser command - // Todo: Implement blockdomain command + if (!admins.some((e) => { return e === msg.account.acct;})) return; + + const status = striptags(msg.status.content); + + if (!status.startsWith(client.me.acct)) return; + + const args = stripped.slice(client.me.acct + 1).trim().split(/ +/); + const commandName = args.shift().toLowerCase(); + + //Check if command exists + if (!this.commands.has(commandName)) { + return; + } + const command = this.commands.get(commandName); + + //Check if command is disabled + if (command.disabled === true) return; + + //Check if command is AdminOnly + if(command.admin_only === true && !admins.some((e) => { return e === msg.account.acct;})) return; + + //Check args length + if (command.required_args > args) { + return; + } + + console.log(`CMD: ${commandName} from ${msg.account.acct}`); + + //Execute the command + try { + command.execute(msg, args); + } + catch (error) { + console.error(error); + } }); \ No newline at end of file diff --git a/package.json b/package.json index 8f668da..cd1f73e 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "federationbot", "version": "0.0.1", "dependencies": { + "collections": "^5.1.2", "mastodon-api": "^1.3.0", "striptags": "^3.1.1" } -- GitLab