index.js (4045B)
1 // node imports 2 const fs = require("fs"); 3 4 // npm imports 5 const moment = require("moment-timezone"); 6 const irc = require("irc"); 7 8 // local imports 9 const { 10 channels, 11 maintainers, 12 nick, 13 password, 14 server, 15 } = require("./config.js"); 16 17 // constants 18 const FILE = "./alias.json"; 19 let alias = JSON.parse(fs.readFileSync(FILE)); 20 21 const ircClient = new irc.Client(server, nick, { 22 channels, 23 userName: "timebot", 24 realName: "timebot", 25 sasl: true, 26 password, 27 floodProtection: true, 28 floodProtectionDelay: 1000, 29 }); 30 31 // irc event-listeners 32 ircClient.addListener("error", errorHandler); 33 34 ircClient.addListener("message", normalMsg); 35 36 ircClient.addListener("pm", pmHandler); 37 38 // event listener functions 39 function errorHandler(msg) { 40 const err = JSON.stringify(msg); 41 for (const maintainer of maintainers) 42 ircClient.say(maintainer, `${nick} error: ${err}`); 43 } 44 45 function normalMsg(sender, channel, msg) { 46 if (msg.includes(`${nick} help`)) showHelp(channel, msg); 47 else if (msg.includes(`${nick} ls `)) showList(sender, msg); 48 else if (msg.includes(`${nick} add `)) addAlias(sender, channel, msg); 49 else if (msg.includes(`${nick} rm `)) deleteAlias(sender, channel, msg); 50 else if (msg.includes(`${nick} link`)) giveLink(sender); 51 else if (msg.includes(`${nick} `)) sayTime(channel, msg); 52 } 53 54 function pmHandler(sender, msg) { 55 handleKill(sender, msg); 56 } 57 58 // helper functions 59 function addAlias(sender, channel, msg) { 60 if (!maintainers.includes(sender)) { 61 ircClient.say(channel, "Only maintainers allowed to add aliases."); 62 return; 63 } 64 if (!msg.includes(":")) { 65 ircClient.say(channel, "Wrong syntax, see <https://w.wiki/yes>"); 66 return; 67 } 68 const reg = new RegExp(`${nick}:? add (.*)`); 69 let [key, value] = msg.match(reg)[1].split(":"); 70 key = key.toLowerCase(); 71 const machineReadableValue = value.replace(/ /g, "_"); 72 if (moment.tz.names().includes(machineReadableValue)) { 73 alias[key] = machineReadableValue; 74 fs.writeFileSync( 75 FILE, 76 JSON.stringify(Object.assign({}, alias), null, 2) + "\n", 77 (err) => { 78 if (err) { 79 ircClient.say(channel, `Error occurred: ${err}`); 80 delete alias[key]; 81 return; 82 } 83 } 84 ); 85 alias = JSON.parse(fs.readFileSync(FILE)); 86 ircClient.say(channel, `Alias for ${key} has been added.`); 87 } 88 } 89 90 function deleteAlias(sender, channel, msg) { 91 if (!maintainers.includes(sender)) { 92 ircClient.say(channel, "Only maintainers allowed to delete aliases."); 93 return; 94 } 95 const reg = new RegExp(`${nick}:? rm (.*)`); 96 const key = msg.match(reg)[1].toLowerCase(); 97 const val = alias[key]; 98 delete alias[key]; 99 fs.writeFileSync( 100 FILE, 101 JSON.stringify(Object.assign({}, alias), null, 2) + "\n", 102 (err) => { 103 if (err) { 104 ircClient.say(channel, `Error occurred: ${err}`); 105 if (val) alias[key] = val; 106 return; 107 } 108 } 109 ); 110 alias = JSON.parse(fs.readFileSync(FILE)); 111 ircClient.say(channel, `Alias for ${key} now does not exist.`); 112 } 113 114 function giveLink(sender) { 115 ircClient.say(sender, "https://time-convertor.toolforge.org"); 116 } 117 118 function handleKill(sender, msg) { 119 if (msg != "KILL") return; 120 if (!maintainers.includes(sender)) return; 121 process.abort(); 122 } 123 124 function sayTime(channel, msg) { 125 const reg = new RegExp(`${nick}:? (.*)`); 126 const zone = msg.match(reg)[1].replace(/ /g, "_"); 127 const machineReadableZone = alias[zone.toLowerCase()] || zone; 128 const TZ = moment.tz.names().includes(machineReadableZone) 129 ? machineReadableZone 130 : "UTC"; 131 let time = moment.tz(TZ).format("HH:mm MMM DD z"); 132 ircClient.say(channel, time); 133 } 134 135 function showHelp(channel) { 136 ircClient.say(channel, "Docs: <https://w.wiki/yes>"); 137 } 138 139 function showList(sender, msg) { 140 const reg = new RegExp(`${nick}:? ls (.*)`); 141 const zone = msg.match(reg)[1].toLowerCase(); 142 const allZones = moment.tz.names().map((el) => el.replace(/_/g, " ")); 143 const res = allZones 144 .filter((el) => el.toLowerCase().includes(zone)) 145 .join(", "); 146 ircClient.say(sender, res); 147 }