diff --git a/README.md b/README.md index 79f428e34a645f10e045300fef994836ac56be76..f9c54a590b98ba4605197d08b76af6a61ba0814a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is a work in progress. This is a Federation Bot working with the Mastodon API. -This bot listens on the Federated Timeline and follows everyone. +This bot listens on the Federated Timeline and follows everyone. It also listen reblogs. This bot respect the #nobot tag. diff --git a/bot.js b/bot.js index f274e28bce679a0ef50a6e40d1495e4a246319de..55a18e6c055296784851a635b47b17511d250687 100644 --- a/bot.js +++ b/bot.js @@ -7,7 +7,7 @@ class Bot extends EventEmitter { * Constructor * @param {string} api_url * @param {string} access_token - * @param {array} listen_on + * @param {array} to_listen */ constructor({api_url, access_token}, to_listen) { super(); @@ -28,14 +28,13 @@ class Bot extends EventEmitter { access_token: this.access_token }); + for(const listen of this.to_listen) { this.listeners.set(listen, this.M.stream('streaming/' + listen.api_point)); this.listeners.get(listen).on('message', (msg) => { - for(const event of listen.events) { - if (msg.event === event) { - this.emit(msg.event, msg.data) - } + if (msg.event === listen.event) { + this.emit(listen.emit_on, msg.data) } }) } diff --git a/index.js b/index.js index 752e9120d2c567435623eb6ef9383ef10d5cd56d..377eccc30471c89e9c4d9311e844389dd433448e 100644 --- a/index.js +++ b/index.js @@ -4,8 +4,9 @@ const fs = require('fs'); const config = require('./config.json'); // Init -const client = new Bot(config, [{api_point: "public", events: ["update"]}, - {api_point: "user", events: ["notification"]}]); +const client = new Bot(config, [{api_point: "public", event: "update", emit_on: "federated"}, + {api_point: "user", event: "notification", emit_on: "mentions"}, + {api_point: "user", event: "update", emit_on: "home"}]); const admins = new Set(config.admins); @@ -22,9 +23,7 @@ for (const file of commandFiles) { // Start the bot and populate following client.start().then(() => { client.following_list().then((result) => { - for(const account of result) { - following.add(account.acct) - } + for(const account of result) following.add(account.acct) console.log(`I'm currently following ${following.size} accounts.`) }); @@ -33,54 +32,24 @@ 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); - const acct_parts = acct.split('@'); - - if (acct_parts.length === 1) { - console.log('LOCAL ACCOUNT: ' + acct); - return; - } - - // Don't follow locked accounts - if(msg.account.locked === true) { - console.log("LOCKED: " + acct); - return; - } - - // Don't follow other bots - if(msg.account.bot === true) { - console.log("BOT: " + acct); - return; - } - - // Respect #nobot - if (striptags(msg.account.note).match(/#nobot/i)) { - client.mute_user(id); - console.log("MUTED #nobot: " + acct); - return; - } - - // This will be... not optimal I think. - if (following.has(acct)) { - console.log('ALREADY FOLLOWS: ' + acct); - return; - } +client.on('federated', (msg) => { + follow_or_not_follow(msg); +}); - following.add(acct); - client.follow(id); - console.log("NOW FOLLOWS: " + acct); +// Listen reblogs on Home +client.on('home', (msg) => { + if (msg.reblog !== null) follow_or_not_follow(msg.reblog); }); -// When a toto arrives in notifications (mentions) -client.on("notification", (msg) => { +// When a toot mention the bot +client.on("mentions", (msg) => { if (msg.type !== "mention") return; const status = striptags(msg.status.content); let full_acct = '@' + client.me.acct; + // Starting with @username@domain or @username (local toots) if (!status.startsWith(full_acct) || !status.startsWith('@' + client.me.username)) return; const args = status.slice(client.me.acct.length + 1).trim().split(/ +/); @@ -99,9 +68,7 @@ client.on("notification", (msg) => { if(command.admin_only === true && !admins.has(msg.account.acct)) return; //Check args length - if (command.required_args > args) { - return; - } + if (command.required_args > args) return; console.log(`CMD: ${commandName} from ${msg.account.acct}`); @@ -117,4 +84,44 @@ client.on("notification", (msg) => { process.on('SIGINT', () => { console.info("Exiting..."); process.exit(); -}); \ No newline at end of file +}); + +function follow_or_not_follow(msg) { + const acct = msg.account.acct; + const id = parseInt(msg.account.id); + const acct_parts = acct.split('@'); + + if (acct_parts.length === 1) { + console.log('LOCAL ACCOUNT: ' + acct); + return; + } + + // Don't follow locked accounts + if(msg.account.locked === true) { + console.log("LOCKED: " + acct); + return; + } + + // Don't follow other bots + if(msg.account.bot === true) { + console.log("BOT: " + acct); + return; + } + + // Respect #nobot + if (striptags(msg.account.note).match(/#nobot/i)) { + client.mute_user(id); + console.log("MUTED #nobot: " + acct); + return; + } + + // This will be... not optimal I think. + if (following.has(acct)) { + console.log('ALREADY FOLLOWS: ' + acct); + return; + } + + following.add(acct); + client.follow(id); + console.log("NOW FOLLOWS: " + acct); +} \ No newline at end of file diff --git a/package.json b/package.json index 4a0d7770948d13c32f3d45150f2d6d8b53304012..4a412a4003b7863b9e98707b074125fecf6a4a2a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "federationbot", - "version": "0.0.2", + "version": "0.0.3", "dependencies": { "mastodon-api": "^1.3.0", "striptags": "^3.1.1",