commit 18d8b9186a8f000c709783cc005144efc38a7e78
Author: Agastya Chandrakant <acagastya@outlook.com>
Date: Sun, 16 Aug 2020 02:38:19 +0530
initial commit
Diffstat:
6 files changed, 216 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+config.gitignore.json
diff --git a/config.js b/config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ server: "irc.freenode.net",
+ nick: "timebot",
+ channels: ["#nie", "##lipsum"],
+ maintainers: ["acagastya"]
+};
diff --git a/config.json b/config.json
@@ -0,0 +1,10 @@
+{
+ "channels": [
+ "#foo",
+ "##bar"
+ ],
+ "alias": {
+ "john": "America/New_York",
+ "doe": "Australia/Sydney",
+ }
+}
diff --git a/index.js b/index.js
@@ -0,0 +1,140 @@
+const fs = require("fs");
+const moment = require("moment-timezone");
+const irc = require("irc");
+
+const { server, nick, maintainers } = require("./config");
+const FILE = "./config.json";
+let { alias, channels } = JSON.parse(fs.readFileSync(FILE));
+
+const ircClient = new irc.Client(server, nick, { channels });
+
+ircClient.addListener("error", errorHandler);
+
+ircClient.addListener("message", normalMsg);
+
+ircClient.addListener("pm", inviteHandler);
+
+function inviteHandler(sender, msg) {
+ if (!msg.startsWith("#")) return;
+ channels.push(msg);
+ fs.writeFileSync(
+ FILE,
+ JSON.stringify({ channels, alias }, null, 2) + "\n",
+ err => {
+ if (err) {
+ ircClient.say(sender, `Error occurred: ${err}.`);
+ return;
+ }
+ }
+ );
+ ircClient.join(msg);
+ ircClient.say(sender, "Attempted to join.");
+ channels = JSON.parse(fs.readFileSync(FILE));
+}
+
+function normalMsg(sender, channel, msg) {
+ if (msg.includes(`${nick} help`)) showHelp(channel, msg);
+ else if (msg.includes(`${nick} ls `)) showList(channel, msg);
+ else if (msg.includes(`${nick} add `)) addAlias(sender, channel, msg);
+ else if (msg.includes(`${nick} rm `)) deleteAlias(sender, channel, msg);
+ else if (msg.includes(`${nick} `)) sayTime(channel, msg);
+ else if (msg.includes(nick)) showHelp(channel, msg);
+}
+
+function errorHandler(msg) {
+ for (const maintainer of maintainers)
+ ircClient.say(maintainer, `${nick} error: ${msg}`);
+}
+
+function showHelp(channel, msg) {
+ ircClient.say(channel, `Use "${nick} help" to show help.`);
+ ircClient.say(
+ channel,
+ `Use "${nick} ls <timezone>" to show a list of valid timezones.`
+ );
+ ircClient.say(
+ channel,
+ `Use "${nick} <timezone>" to display current time of <timezone>.`
+ );
+ ircClient.say(
+ channel,
+ `Use "${nick} add <alias>:<timezone>" for adding an alias for a timezone.`
+ );
+ ircClient.say(
+ channel,
+ `Use "${nick} rm <alias>" from removing an alias for a timezone.`
+ );
+}
+
+function showList(channel, msg) {
+ const reg = new RegExp(`${nick}:? ls (.*)`);
+ const zone = msg.match(reg)[1];
+ const allZones = moment.tz.names().map(el => el.replace(/_/g, " "));
+ const res = allZones
+ .filter(el => el.toLowerCase().includes(zone.toLowerCase()))
+ .join(", ");
+ ircClient.say(channel, res);
+}
+
+function sayTime(channel, msg) {
+ const reg = new RegExp(`${nick}:? (.*)`);
+ const zone = msg.match(reg)[1].replace(/ /g, "_");
+ const machineReadableZone = alias[zone] || zone;
+ const TZ = moment.tz.names().includes(machineReadableZone)
+ ? machineReadableZone
+ : "UTC";
+ let time = moment.tz(TZ).format("HH:mm MMM DD z");
+ ircClient.say(channel, time);
+}
+
+function addAlias(sender, channel, msg) {
+ if (!maintainers.includes(sender)) {
+ ircClient.say(channel, "Only maintainers allowed to add aliases.");
+ return;
+ }
+ if (!msg.includes(":")) {
+ ircClient.say(channel, "Wrong syntax.");
+ showHelp(channel);
+ return;
+ }
+ const reg = new RegExp(`${nick}:? add (.*)`);
+ const [key, value] = msg.match(reg)[1].split(":");
+ const machineReadableValue = value.replace(/ /g, "_");
+ if (moment.tz.names().includes(machineReadableValue)) {
+ alias[key] = machineReadableValue;
+ fs.writeFileSync(
+ FILE,
+ JSON.stringify({ channels, alias }, null, 2) + "\n",
+ err => {
+ if (err) {
+ ircClient.say(channel, `Error occurred: ${err}`);
+ return;
+ }
+ alias = JSON.parse(fs.readFileSync(FILE)).alias;
+ ircClient.say(channel, `Alias for ${key} has been added.`);
+ }
+ );
+ }
+}
+
+function deleteAlias(sender, channel, msg) {
+ if (!maintainers.includes(sender)) {
+ ircClient.say(channel, "Only maintainers allowed to delete aliases.");
+ return;
+ }
+ const reg = new RegExp(`${nick}:? rm (.*)`);
+ const key = msg.match(reg)[1];
+ delete alias[key];
+ fs.writeFileSync(
+ FILE,
+ JSON.stringify({ channels, alias }, null, 2) + "\n",
+ err => {
+ if (err) {
+ ircClient.say(channel, `Error occurred: ${err}`);
+ return;
+ }
+ alias = JSON.parse(fs.readFileSync(FILE)).alias;
+ ircClient.say(channel, `Alias for ${key} now does not exist.`);
+ }
+ );
+}
diff --git a/package.json b/package.json
@@ -0,0 +1,9 @@
+{
+ "dependencies": {
+ "irc": "^0.5.2",
+ "moment-timezone": "^0.5.31"
+ },
+ "scripts": {
+ "start": "node index.js"
+ }
+}
diff --git a/yarn.lock b/yarn.lock
@@ -0,0 +1,49 @@
+# 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"
+
+moment-timezone@^0.5.31:
+ version "0.5.31"
+ resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.31.tgz#9c40d8c5026f0c7ab46eda3d63e49c155148de05"
+ integrity sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA==
+ dependencies:
+ moment ">= 2.9.0"
+
+"moment@>= 2.9.0":
+ version "2.27.0"
+ resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
+ integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
+
+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"