enwnbot

Converts MediaWiki [[links]] and {{templates}} to links on IRC
git clone http://git.hanabi.in/repos/enwnbot.git
Log | Files | Refs | README | LICENSE

commit 66cfef5ab7313aed1d06c030be52271f7bd67b01
Author: Agastya Chandrakant <acagastya@outlook.com>
Date:   Fri, 22 May 2020 13:51:08 +0530

initial commit

Diffstat:
A.gitignore | 1+
ALICENSE | 30++++++++++++++++++++++++++++++
AREADME.md | 42++++++++++++++++++++++++++++++++++++++++++
Aconfig.js | 11+++++++++++
Airc.js | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apackage.json | 8++++++++
Ayarn.lock | 37+++++++++++++++++++++++++++++++++++++
7 files changed, 197 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/LICENSE b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, Agastya Chandrakant +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\ No newline at end of file diff --git a/README.md b/README.md @@ -0,0 +1,42 @@ +Converts MediaWiki [[links]] and {{templates}} to links. + +# Installation + +To run this project, run the following commands after cloning it. + +```sh +cd <DIR> +yarn # or `npm i` +yarn start # or `npm run start` +``` + +# Configuration + +Use the `config.js` to configure the bot. + +- Specify the bot's IRC nick in `botName`. (eg. `linkBot`) +- Mention the list of channels to monitor in `channels`. +- Specify IRC channel in `server`. (eg. `irc.freenode.net`) +- API should be specified in `URL`. (eg. `https://en.wikinews.org/w/index.php?title=`) + +Additionally, the bot reports any errors to its maintainers. + +- Mention the list of maintainers in the `maintainers` array. +- PM to the bot will not be forwarded to anyone, unless it starts with a particular string mentioned in `report`. If the bot gets a PM which starts with `report`, it will forward the PM to a list of admins. **Note:** This could be abused, so specifying `report` as `/` might be a good idea. +- Specify the list of admins who would like to receive PM of the forwarded message in `admins`. + +Sample `config.js` looks like: + +```js +const config = { + admins: ['jdoe', 'samsmith'], + botName: 'linkBot', + channels: ['#foo', '##bar'], + maintainers: ['list', 'of', 'maintainers'], + report: '!ADMIN', + server: 'irc.freenode.net', + URL: 'https://en.wikinews.org/w/index.php?title=', +}; +``` + +**Note:** In case if your message contains templates and you don't want the bot to announce the link -- add `--nl` at the end of the message. diff --git a/config.js b/config.js @@ -0,0 +1,11 @@ +const config = { + admins: ['jdoe'], + botName: 'linkBOT', + channels: ['#foo', '##bar'], + maintainers: ['ssmith'], + report: '!ADMIN', + server: 'irc.freenode.net', + URL: 'https://en.wikinews.org/w/index.php?title=', +}; + +module.exports = config; diff --git a/irc.js b/irc.js @@ -0,0 +1,68 @@ +const irc = require('irc'); + +const { + admins, + botName, + channels, + maintainers, + report, + server, + URL, +} = require('./config'); + +const client = new irc.Client(server, botName, { + channels, +}); + +function pm(sender, msg) { + client.say(sender, 'I am a bot.'); + if (msg.startsWith(report)) + admins.forEach((admin) => + client.say(admin, `Message from ${sender}: ${msg}`) + ); +} + +function err(msg) { + maintainers.forEach((maintainer) => + client.say(maintainer, `Error: ${JSON.stringify(msg)}`) + ); +} + +function handleLink(link, channel) { + const len = link.length; + const trimmed = link.substr(2, len - 4); + let [main, anchor] = trimmed.split('#'); + main = main.replace(/ /g, '%20'); + if (anchor) anchor = anchor.replace(/ /g, '_'); + let final; + if (anchor) final = `${main}#${anchor}`; + else final = main; + client.say(channel, `${URL}${final}`); +} + +function handleTemplate(template, channel) { + const len = template.length; + const word = template + .substr(2, len - 4) + .split('|')[0] + .replace(/ /g, '%20'); + client.say(channel, `${URL}Template:${word}`); +} + +function groupChat(from, to, msg) { + if (msg.toLowerCase().includes(`thanks ${botName}`)) + client.say(to, `You are welcome, ${from}.`); + const regex1 = /\[{2}(.*?)\]{2}/g; + const regex2 = /\{{2}(.*?)\}{2}/g; + const links = msg.match(regex1); + const templates = msg.match(regex2); + links && links.forEach((link) => handleLink(link, to)); + templates && + !msg.endsWith('--nl') && + templates.forEach((template) => handleTemplate(template, to)); +} + +client.addListener('error', err); +client.addListener('pm', pm); +client.addListener('message', groupChat); +// channels.forEach(client.join); diff --git a/package.json b/package.json @@ -0,0 +1,8 @@ +{ + "dependencies": { + "irc": "^0.5.2" + }, + "scripts": { + "start": "node irc.js" + } +} diff --git a/yarn.lock b/yarn.lock @@ -0,0 +1,37 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +iconv@~2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/iconv/-/iconv-2.2.3.tgz#e084d60eeb7d73da7f0a9c096e4c8abe090bfaed" + integrity sha1-4ITWDut9c9p/CpwJbkyKvgkL+u0= + dependencies: + nan "^2.3.5" + +irc-colors@^1.1.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/irc-colors/-/irc-colors-1.5.0.tgz#08834c01ead88b0fd88386a5f2af8f2b0bb963fb" + integrity sha512-HtszKchBQTcqw1DC09uD7i7vvMayHGM1OCo6AHt5pkgZEyo99ClhHTMJdf+Ezc9ovuNNxcH89QfyclGthjZJOw== + +irc@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/irc/-/irc-0.5.2.tgz#3714f4768365a96d0b2f776bc91166beb2464bbc" + integrity sha1-NxT0doNlqW0LL3dryRFmvrJGS7w= + dependencies: + irc-colors "^1.1.0" + optionalDependencies: + iconv "~2.2.1" + node-icu-charset-detector "~0.2.0" + +nan@^2.3.3, nan@^2.3.5: + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + +node-icu-charset-detector@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/node-icu-charset-detector/-/node-icu-charset-detector-0.2.0.tgz#c2320da374ddcb671fc54cb4a0e041e156ffd639" + integrity sha1-wjINo3Tdy2cfxUy0oOBB4Vb/1jk= + dependencies: + nan "^2.3.3"