From 3f9afc14847e751138475aa4a3a4dcd25337b986 Mon Sep 17 00:00:00 2001 From: Fntsrlike Date: Mon, 30 Mar 2015 17:12:27 +0800 Subject: [PATCH 01/24] Change username to account on IRC's identify --- config.sample.js | 2 +- lib/irc-msg-encoder.js | 6 ------ lib/irc-to-slack.js | 1 - lib/ircbot.js | 16 +++++++++++----- lib/name-map.js | 25 ++++++++----------------- 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/config.sample.js b/config.sample.js index 7d63838..8b52b8a 100644 --- a/config.sample.js +++ b/config.sample.js @@ -16,7 +16,7 @@ config.channels = { }; config.users = { - 'ircLogin (not nick)': 'slackUser' + 'ircAccount': 'slackUser' }; App( config ).start(); diff --git a/lib/irc-msg-encoder.js b/lib/irc-msg-encoder.js index 87ebf76..148afd6 100644 --- a/lib/irc-msg-encoder.js +++ b/lib/irc-msg-encoder.js @@ -12,7 +12,6 @@ var IrcMsgEncoder = function(message, type) { this.message = message; this.channelMap = {}; - this.userMap = {}; this.nickMap = {}; }; @@ -25,11 +24,6 @@ IrcMsgEncoder.prototype.setChanelMap = function(map) { return this; }; -IrcMsgEncoder.prototype.setUserMap = function(map) { - this.userMap = map; - return this; -}; - IrcMsgEncoder.prototype.setNickMap = function(map) { this.nickMap = map; return this; diff --git a/lib/irc-to-slack.js b/lib/irc-to-slack.js index e69759b..92dd40d 100644 --- a/lib/irc-to-slack.js +++ b/lib/irc-to-slack.js @@ -17,7 +17,6 @@ var IrcToSlack = function(config) { IrcToSlack.prototype._prepareMessage = function(message, type) { return IrcMsgEncoder(message, type) .setChanelMap(this.ircBot.config.channels) - .setUserMap(this.nameMap.getIrcWhoIsMap()) .setNickMap(this.nameMap.getIrcNickMap()) .autoMention().encodeMention().encodeAmpersand().toString(); }; diff --git a/lib/ircbot.js b/lib/ircbot.js index 8e1a7a1..580f3ce 100755 --- a/lib/ircbot.js +++ b/lib/ircbot.js @@ -75,8 +75,10 @@ IrcBot.prototype._trackUserExisting = function() { if (whois.user === botUsername) { return; } - var slackName = this.nameMap.getSlackNameByIrcWhoIs(whois.user); - this.nameMap.setSlackNameByIrcNick(slackName, nick); + if (typeof whois.account !== "undefined") { + var slackName = this.nameMap.getSlackNameByIrcAccount(whois.account); + this.nameMap.setSlackNameByIrcNick(slackName, nick); + } }.bind(this)); }.bind(this)); this.systemSpeak(channel, 'I\'m all over you slackers'); @@ -90,8 +92,10 @@ IrcBot.prototype._trackUserEntering = function() { return; } else { - var slackName = this.nameMap.getSlackNameByIrcWhoIs(whois.user); - this.nameMap.setSlackNameByIrcNick(slackName, nick); + if (typeof whois.account !== "undefined") { + var slackName = this.nameMap.getSlackNameByIrcAccount(whois.account); + this.nameMap.setSlackNameByIrcNick(slackName, nick); + } this.systemSpeak(channel, 'i\'m watching you slacker @' + slackName); } }.bind(this)); @@ -103,7 +107,9 @@ IrcBot.prototype._trackUserNicking = function() { return; } var slackName = this.nameMap.getSlackNameByIrcNick(oldNick); - this.nameMap.replaceIrcNick(oldNick, newNick); + if (typeof slackName !== "undefined") { + this.nameMap.replaceIrcNick(oldNick, newNick); + } channels.forEach(function(channel) { this.systemSpeak(channel, 'don\'t think you can hide slacker @' + slackName); }.bind(this)); diff --git a/lib/name-map.js b/lib/name-map.js index d0e8c2f..be30952 100644 --- a/lib/name-map.js +++ b/lib/name-map.js @@ -14,26 +14,17 @@ var NameMap = function(config) { users: {} }); - this.whoIsMap = {}; // ircWhoIs : slackName + this.accountMap = {}; // freenode account : slack username this.nickMap = {}; // ircNick : slackName this.isChecked = false; this._checkMapType(); }; -NameMap.prototype._addTiledePrefix = function() { - Object.keys(this.whoIsMap).forEach(function(username) { - if (username[0] !== '~') { - this.whoIsMap['~' + username] = this.whoIsMap[username]; - delete this.whoIsMap[username]; - } - }.bind(this)); -}; - NameMap.prototype._checkMapType = function() { if (_.isString(this.config.users)) { this._updateMap(); } else { - this.whoIsMap = this.config.users; + this.accountMap = this.config.users; this.isChecked = true; } }; @@ -49,7 +40,7 @@ NameMap.prototype._getUserMapByUrl = function(url) { url: url }, function(error, response, body) { this._check(body); - this.whoIsMap = JSON.parse(body); + this.accountMap = JSON.parse(body); this.isChecked = true; if (this.config.isAutoTildeAdded) { @@ -66,20 +57,20 @@ NameMap.prototype._updateMap = function() { }.bind(this), this.config.listUpdatedPeriod * 1000); }; -NameMap.prototype.getIrcWhoIsMap = function() { - return this.whoIsMap; +NameMap.prototype.getIrcAccountMap = function() { + return this.accountMap; }; NameMap.prototype.getIrcNickMap = function() { - return this.whoIsMap; + return this.nickMap; }; NameMap.prototype.getSlackNameByIrcNick = function(ircNick) { return this.nickMap[ircNick]; }; -NameMap.prototype.getSlackNameByIrcWhoIs = function(ircWhoIs) { - return this.whoIsMap[ircWhoIs]; +NameMap.prototype.getSlackNameByIrcAccount = function(ircAccount) { + return this.accountMap[ircAccount]; }; NameMap.prototype.setSlackNameByIrcNick = function(slackName, ircNick) { From cbee5ccf26081fe6e5e81a85aa34f0b2623a3616 Mon Sep 17 00:00:00 2001 From: Fntsrlike Date: Fri, 17 Apr 2015 17:34:11 +0800 Subject: [PATCH 02/24] Add multi-channels feature --- README.md | 2 +- config.sample.js | 2 +- lib/slack-to-irc.js | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b8342d9..1564af7 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ var config = { username: 'slackbot-username', token: 'XXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXX', incomeUrl: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX', - outgoingToken: 'XXXXXXXXXXXXXXXXXXXXXXXX', + outgoingToken: ['XXXXXXXXXXXXXXXXXXXXXXXX'], }; // Channels map diff --git a/config.sample.js b/config.sample.js index 8b52b8a..e501d5e 100644 --- a/config.sample.js +++ b/config.sample.js @@ -7,7 +7,7 @@ var config = { username: 'slackbot-username', token: 'XXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXX', incomeUrl: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX', - outgoingToken: 'XXXXXXXXXXXXXXXXXXXXXXXX', + outgoingToken: ['XXXXXXXXXXXXXXXXXXXXXXXX'], serverPort: 80 }; diff --git a/lib/slack-to-irc.js b/lib/slack-to-irc.js index 12ee762..57b4fa6 100644 --- a/lib/slack-to-irc.js +++ b/lib/slack-to-irc.js @@ -48,8 +48,11 @@ SlackToIRC.prototype._server = function() { SlackToIRC.prototype._requestHandler = function(req, res) { req.on('data', function(data) { - var payload = querystring.parse(data.toString()); - if (payload.token === this.config.outgoingToken && payload.user_name !== 'slackbot') { + var + payload = querystring.parse(data.toString()), + isTokenValid = _.contains(this.config.outgoingToken, payload.token); + + if (isTokenValid && payload.user_name !== 'slackbot') { this._sentMessage(payload); res.end('Done.'); } @@ -60,7 +63,7 @@ SlackToIRC.prototype._requestHandler = function(req, res) { SlackToIRC.prototype._sentMessage = function(payload) { var message = this._decodeMessage(payload.text), - channel = Object.keys(this.config.channels)[0], + channel = _.invert(this.config.channels)['#' + payload.channel_name], name = payload.user_name; if (this.config.showSlackChannel) { From 5269d74229aa9a57bbd356495fea097812535a8d Mon Sep 17 00:00:00 2001 From: Fntsrlike Date: Fri, 17 Apr 2015 20:05:58 +0800 Subject: [PATCH 03/24] Update README.md about user mapping --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1564af7..7eaf025 100644 --- a/README.md +++ b/README.md @@ -63,10 +63,10 @@ config.channels = { }; // Users map -// Index is not nick, but username at IRC. It could be get by `/whois`. +// Index is not nick, but account name at IRC. It could be get by `/whois`. // Value is slack's username. config.users = { - 'ircLogin (not nick)': 'slackUser' + 'ircAccount': 'slackUser' }; ``` From ab7f90022d47b9085fd8d0eb823b60a1950b94fa Mon Sep 17 00:00:00 2001 From: Fntsrlike Date: Sat, 18 Apr 2015 04:18:54 +0800 Subject: [PATCH 04/24] Improve dockerfile to decrease npm install time --- Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index ce9fad5..1af6e22 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,6 @@ -FROM node:0.10 +FROM fntsrlike/node-irc:latest MAINTAINER Ruoshi Ling -# Requirment libs -RUN apt-get update && apt-get install -y libicu-dev - # Node_modules Cache COPY ./package.json /app/package.json COPY ./README.md /app/README.md From c311d4ef98ae2660d1850607bd91d9bdfee55949 Mon Sep 17 00:00:00 2001 From: Fntsrlike Date: Sat, 18 Apr 2015 04:47:40 +0800 Subject: [PATCH 05/24] Improve package.json --- package.json | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index f069b7b..45b0863 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,12 @@ { "name": "slack-irc-syncbot", + "version": "0.1.4", "description": "Synchronize messages between Slack and IRC.", - "version": "0.1.3", + "keywords": [ + "slack", + "irc" + ], "homepage": "https://github.com/fntsrlike/slack-irc-syncbot", - "author": { - "name": "Roushi Ling", - "email": "fntsrlike@gmail.com", - "url": "http://fntsr.tw/" - }, - "repository": { - "type": "git", - "url": "git://github.com/fntsrlike/slack-irc-syncbot.git" - }, "bugs": { "url": "https://github.com/fntsrlike/slack-irc-syncbot/issues" }, @@ -21,21 +16,27 @@ "url": "https://github.com/fntsrlike/slack-irc-syncbot/blob/master/LICENSE" } ], - "engines": { - "node": "*" + "author": { + "name": "Roushi Ling", + "email": "fntsrlike@gmail.com", + "url": "http://fntsr.tw/" + }, + "contributors": { + "name": "Shunyi", + "email": "M157q.tw@gmail.com", + "url": "http://m157q.github.io" + }, + "repository": { + "type": "git", + "url": "git://github.com/fntsrlike/slack-irc-syncbot.git" }, "dependencies": { - "irc": "~0.3.6", - "is-online": "^3.0.0", + "irc": "~0.3.11", + "is-online": "~3.2.0", "request": "~2.33.0", - "underscore": "^1.7.0" + "underscore": "~1.8.3" }, - "devDependencies": {}, - "bin": { - "bot": "bin/bot.js" - }, - "keywords": [ - "slack", - "irc" - ] + "engines": { + "node": ">= 0.10.10" + } } From 5a4fa5c6e5d03277749f3a497c244241672deaef Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 13:28:01 +0800 Subject: [PATCH 06/24] Add docker-compose support --- docker-compose.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3ceee69 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,8 @@ +app: + build: ./ + environment: + - TZ=Asia/Taipei + volumns: + - ./config.js:/app/config.js + ports: + - "8080:80" From 0f464340fbbbf8f5564a647a9b23c5c7967d089a Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 14:41:16 +0800 Subject: [PATCH 07/24] To avoid warning about memory leak detected --- lib/ircbot.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ircbot.js b/lib/ircbot.js index 580f3ce..7afeb26 100755 --- a/lib/ircbot.js +++ b/lib/ircbot.js @@ -25,6 +25,7 @@ var IrcBot = function(config) { this._configureClient(); this.client = new Irc.Client(this.config.server, this.config.nick, this.irc); + this.client.setMaxListeners(0); // To avoid warning about memory leak detected this._handleErrors(); return this; From 84852f264eb8f30ce5c9ee84c134829ce1b3234f Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 14:46:57 +0800 Subject: [PATCH 08/24] Update node-irc version to resolve #10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45b0863..0b4d60e 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "url": "git://github.com/fntsrlike/slack-irc-syncbot.git" }, "dependencies": { - "irc": "~0.3.11", + "irc": ">=0.3.12", "is-online": "~3.2.0", "request": "~2.33.0", "underscore": "~1.8.3" From 3f7bd42fdf5d91a0537135b39dd6d1762998d830 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 15:37:58 +0800 Subject: [PATCH 09/24] Resolve #18 to avoid bot crash when it cant say --- lib/ircbot.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/ircbot.js b/lib/ircbot.js index 7afeb26..045363b 100755 --- a/lib/ircbot.js +++ b/lib/ircbot.js @@ -131,7 +131,14 @@ IrcBot.prototype.addListener = function(type, listener) { IrcBot.prototype.speak = function(channel, message) { if (!this.config.isSilent) { - this.client.say(channel, message); + try { + this.client.say(channel, message); + } catch (e) { + console.log("[DEBUG] Something wrong when IRCBot say"); + console.log(e); + console.log("[DEBUG] End"); + } + } }; From 8bbf5fb312f0d332cd884d877ccc91ca882feac5 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 16:36:51 +0800 Subject: [PATCH 10/24] Update coding style by JSHint --- lib/app.js | 2 +- lib/ircbot.js | 30 ++++++++++++++---------------- lib/slack-msg-decoder.js | 6 +++--- lib/slack-res.js | 4 ++-- lib/slack-to-irc.js | 2 +- lib/slackbot.js | 2 +- 6 files changed, 22 insertions(+), 24 deletions(-) diff --git a/lib/app.js b/lib/app.js index cfb5383..68495ba 100644 --- a/lib/app.js +++ b/lib/app.js @@ -24,7 +24,7 @@ var App = function(config) { this._precheck(); this.nameMap = NameMap(this.config); this.ircBot = IrcBot(this.config); - this.ircToSlack = IrcToSlack(this.config) + this.ircToSlack = IrcToSlack(this.config); this.slackBot = SlackBot(this.config); this.slackRes = SlackRes(this.config); this.slackToIrc = SlackToIrc(this.config); diff --git a/lib/ircbot.js b/lib/ircbot.js index 045363b..ea9215f 100755 --- a/lib/ircbot.js +++ b/lib/ircbot.js @@ -45,9 +45,9 @@ IrcBot.prototype._configureClient = function() { floodProtection: true }; - nodeIrcOptions.forEach(function(opt) { - if (this.config[opt]) { - this.irc[opt] = this.config[opt]; + nodeIrcOptions.forEach(function (opt) { + if (this.config[opt] !== undefined) { + this.irc[opt] = this.config.opt; } }.bind(this)); }; @@ -55,8 +55,8 @@ IrcBot.prototype._configureClient = function() { IrcBot.prototype._handleErrors = function() { this.client.addListener('error', function(message) { var - channel = message.args[1], - errorMessage = this.mapPronouns(message.args[2]); + channel = message.args[1], + errorMessage = this.mapPronouns(message.args[2]); this.systemSpeak(channel, 'I don\'t feel so well because ' + errorMessage); }.bind(this)); @@ -76,7 +76,7 @@ IrcBot.prototype._trackUserExisting = function() { if (whois.user === botUsername) { return; } - if (typeof whois.account !== "undefined") { + if (whois.account !== undefined) { var slackName = this.nameMap.getSlackNameByIrcAccount(whois.account); this.nameMap.setSlackNameByIrcNick(slackName, nick); } @@ -92,11 +92,9 @@ IrcBot.prototype._trackUserEntering = function() { if (whois.user === botUsername) { return; } - else { - if (typeof whois.account !== "undefined") { - var slackName = this.nameMap.getSlackNameByIrcAccount(whois.account); - this.nameMap.setSlackNameByIrcNick(slackName, nick); - } + if (whois.account !== undefined) { + var slackName = this.nameMap.getSlackNameByIrcAccount(whois.account); + this.nameMap.setSlackNameByIrcNick(slackName, nick); this.systemSpeak(channel, 'i\'m watching you slacker @' + slackName); } }.bind(this)); @@ -108,7 +106,7 @@ IrcBot.prototype._trackUserNicking = function() { return; } var slackName = this.nameMap.getSlackNameByIrcNick(oldNick); - if (typeof slackName !== "undefined") { + if (slackName !== undefined) { this.nameMap.replaceIrcNick(oldNick, newNick); } channels.forEach(function(channel) { @@ -134,9 +132,9 @@ IrcBot.prototype.speak = function(channel, message) { try { this.client.say(channel, message); } catch (e) { - console.log("[DEBUG] Something wrong when IRCBot say"); + console.log('[DEBUG] Something wrong when IRCBot say'); console.log(e); - console.log("[DEBUG] End"); + console.log('[DEBUG] End'); } } @@ -153,8 +151,8 @@ IrcBot.prototype.mapPronouns = function(message) { 'you': 'i', 'you\'re': 'i\'m' }; - return message.split(' ').map(function(word) { - return map[word.toLowerCase()] ? map[word.toLowerCase()] : word; + return message.split(' ').map(function (word) { + return map[word.toLowerCase()] || word; }).join(' '); }; diff --git a/lib/slack-msg-decoder.js b/lib/slack-msg-decoder.js index d61be8e..c937576 100644 --- a/lib/slack-msg-decoder.js +++ b/lib/slack-msg-decoder.js @@ -5,12 +5,12 @@ var SlackMsgDecoder = function(message) { return new SlackMsgDecoder(message); } - if (typeof this.message == "string") { + if (typeof this.message === 'string') { this.message = message; } else { - console.log("[DEBUG] Got type error message:" + message) - this.message = "" + console.log('[DEBUG] Got type error message:' + message); + this.message = ''; } this.channelMap = {}; diff --git a/lib/slack-res.js b/lib/slack-res.js index 135d281..26dd83c 100644 --- a/lib/slack-res.js +++ b/lib/slack-res.js @@ -32,7 +32,7 @@ SlackRes.prototype._updateUsers = function() { request.get({ url: 'https://slack.com/api/users.list?token=' + this.config.token }, function(error, response, body) { - if (!error && response.statusCode == 200) { + if (!error && response.statusCode === 200) { this._check(body); var @@ -58,7 +58,7 @@ SlackRes.prototype._updateChannels = function() { request.get({ url: 'https://slack.com/api/channels.list?token=' + this.config.token }, function(error, response, body) { - if (!error && response.statusCode == 200) { + if (!error && response.statusCode === 200) { this._check(body); var diff --git a/lib/slack-to-irc.js b/lib/slack-to-irc.js index 57b4fa6..627282b 100644 --- a/lib/slack-to-irc.js +++ b/lib/slack-to-irc.js @@ -24,7 +24,7 @@ SlackToIRC.prototype.setIrcBot = function(bot) { SlackToIRC.prototype.setSlackRes = function(resource) { this.slackRes = resource; return this; -} +}; SlackToIRC.prototype.listen = function() { this.config.avatarMap = this.slackRes.getAvatarMap(); diff --git a/lib/slackbot.js b/lib/slackbot.js index f1b022a..a0b01a5 100644 --- a/lib/slackbot.js +++ b/lib/slackbot.js @@ -23,7 +23,7 @@ SlackBot.prototype.send = function(method, args) { form: { payload: JSON.stringify(args) } }, function(error, response, body) { if (error || body.error) { - throw 'Error:', error || body.error; + throw 'Error:' + (error || body.error); } }); }; From 68530acfb54688fa87fd1b6d46e2ca50c711026d Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 17:28:53 +0800 Subject: [PATCH 11/24] Improve error handler of request get method --- lib/slack-res.js | 59 +++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/lib/slack-res.js b/lib/slack-res.js index 26dd83c..d9aaa7f 100644 --- a/lib/slack-res.js +++ b/lib/slack-res.js @@ -32,25 +32,24 @@ SlackRes.prototype._updateUsers = function() { request.get({ url: 'https://slack.com/api/users.list?token=' + this.config.token }, function(error, response, body) { - if (!error && response.statusCode === 200) { - this._check(body); - - var - res = JSON.parse(body), - userMap = this.getUserMap(), - avatarMap = this.getAvatarMap(); - - res.members.map(function(member) { - userMap[member.id] = member.name; - avatarMap[member.name] = member.profile.image_48; - }); - - this.setUsers(res.members); - this.setUserMap(userMap); - this.setAvatarMap(avatarMap); - } else { - console.error('Error! Can\'t get resource! Please check the Internet'); + if (error || response.statusCode !== 200) { + return console.error('Error! Can\'t get resource! Please check the Internet'); } + + this._check(body); + + var res = JSON.parse(body); + var userMap = this.getUserMap(); + var avatarMap = this.getAvatarMap(); + + res.members.map(function(member) { + userMap[member.id] = member.name; + avatarMap[member.name] = member.profile.image_48; + }); + + this.setUsers(res.members); + this.setUserMap(userMap); + this.setAvatarMap(avatarMap); }.bind(this)); }; @@ -58,22 +57,20 @@ SlackRes.prototype._updateChannels = function() { request.get({ url: 'https://slack.com/api/channels.list?token=' + this.config.token }, function(error, response, body) { - if (!error && response.statusCode === 200) { - this._check(body); + if (error || response.statusCode !== 200) { + return console.error('Error! Can\'t get resource! Please check the Internet'); + } + this._check(body); - var - channelMap = this.getChannelMap(), - res = JSON.parse(body); + var channelMap = this.getChannelMap(); + var res = JSON.parse(body); - res.channels.map(function(channel) { - channelMap[channel.id] = channel.name; - }); + res.channels.map(function(channel) { + channelMap[channel.id] = channel.name; + }); - this.setChannels(res.channels); - this.setChannelMap(channelMap); - } else { - console.error('Error! Can\'t get resource! Please check the Internet'); - } + this.setChannels(res.channels); + this.setChannelMap(channelMap); }.bind(this)); }; From f3cc162b98bf3ff44df339e896de912a12b2d9ff Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 17:30:53 +0800 Subject: [PATCH 12/24] Change code style of variable declare --- lib/app.js | 21 ++++++++++----------- lib/irc-to-slack.js | 15 +++++++-------- lib/ircbot.js | 9 ++++----- lib/name-map.js | 4 ++-- lib/slack-msg-decoder.js | 5 ++--- lib/slack-res.js | 4 ++-- lib/slack-to-irc.js | 20 +++++++++----------- lib/slackbot.js | 4 ++-- 8 files changed, 38 insertions(+), 44 deletions(-) diff --git a/lib/app.js b/lib/app.js index 68495ba..b3bc54c 100644 --- a/lib/app.js +++ b/lib/app.js @@ -1,12 +1,12 @@ 'use strict'; -var _ = require('underscore'), - IrcBot = require('./ircbot'), - IrcToSlack = require('./irc-to-slack'), - SlackBot = require('./slackbot'), - SlackRes = require('./slack-res'), - SlackToIrc = require('./slack-to-irc'), - NameMap = require('./name-map'); +var _ = require('underscore'); +var IrcBot = require('./ircbot'); +var IrcToSlack = require('./irc-to-slack'); +var SlackBot = require('./slackbot'); +var SlackRes = require('./slack-res'); +var SlackToIrc = require('./slack-to-irc'); +var NameMap = require('./name-map'); var App = function(config) { if (!(this instanceof App)) { @@ -64,10 +64,9 @@ App.prototype._precheck = function() { }; App.prototype._confirmReady = function(callback) { - var - checkingCycle = 0.1, - isReady = !_.isEmpty(this.slackRes.getUserMap()) && this.nameMap.isChecked, - isTimeout = this.config.initializeTimeoutLimit < this.confirmCounter; + var checkingCycle = 0.1; + var isReady = !_.isEmpty(this.slackRes.getUserMap()) && this.nameMap.isChecked; + var isTimeout = this.config.initializeTimeoutLimit < this.confirmCounter; this.confirmCounter += checkingCycle; diff --git a/lib/irc-to-slack.js b/lib/irc-to-slack.js index 92dd40d..f308002 100644 --- a/lib/irc-to-slack.js +++ b/lib/irc-to-slack.js @@ -1,7 +1,7 @@ 'use strict'; -var _ = require('underscore'), - IrcMsgEncoder = require('./irc-msg-encoder'); +var _ = require('underscore'); +var IrcMsgEncoder = require('./irc-msg-encoder'); var IrcToSlack = function(config) { if (!(this instanceof IrcToSlack)) { @@ -22,12 +22,11 @@ IrcToSlack.prototype._prepareMessage = function(message, type) { }; IrcToSlack.prototype._sentToSlack = function(type, from, to, message) { - var - username = from, - avatar = this.config.iconUrl, - avatars = this.config.avatarMap, - hasAvatar = false, - isNickExist = !!this.nameMap.getSlackNameByIrcNick(from); + var username = from; + var avatar = this.config.iconUrl; + var avatars = this.config.avatarMap; + var hasAvatar = false; + var isNickExist = !!this.nameMap.getSlackNameByIrcNick(from); if (this.config.isMapName && isNickExist) { username = this.nameMap.getSlackNameByIrcNick(from); diff --git a/lib/ircbot.js b/lib/ircbot.js index ea9215f..d4f1019 100755 --- a/lib/ircbot.js +++ b/lib/ircbot.js @@ -1,7 +1,7 @@ 'use strict'; -var _ = require('underscore'), - Irc = require('irc'); +var _ = require('underscore'); +var Irc = require('irc'); var IrcBot = function(config) { if (!(this instanceof IrcBot)) { @@ -54,9 +54,8 @@ IrcBot.prototype._configureClient = function() { IrcBot.prototype._handleErrors = function() { this.client.addListener('error', function(message) { - var - channel = message.args[1], - errorMessage = this.mapPronouns(message.args[2]); + var channel = message.args[1]; + var errorMessage = this.mapPronouns(message.args[2]); this.systemSpeak(channel, 'I don\'t feel so well because ' + errorMessage); }.bind(this)); diff --git a/lib/name-map.js b/lib/name-map.js index be30952..621e777 100644 --- a/lib/name-map.js +++ b/lib/name-map.js @@ -1,7 +1,7 @@ 'use strict'; -var _ = require('underscore'), - request = require('request'); +var _ = require('underscore'); +var request = require('request'); var NameMap = function(config) { if (!(this instanceof NameMap)) { diff --git a/lib/slack-msg-decoder.js b/lib/slack-msg-decoder.js index c937576..97c2d5e 100644 --- a/lib/slack-msg-decoder.js +++ b/lib/slack-msg-decoder.js @@ -44,9 +44,8 @@ SlackMsgDecoder.prototype.decodeChannel = function() { SlackMsgDecoder.prototype.decodeUser = function() { this.message = this.message.replace(/<@U\w{8}>/g, function(matched) { - var - memberId = matched.match(/@(U\w{8})/)[1], - map = this.userMap; + var memberId = matched.match(/@(U\w{8})/)[1]; + var map = this.userMap; return '@' + map[memberId]; }.bind(this)); diff --git a/lib/slack-res.js b/lib/slack-res.js index d9aaa7f..13765d8 100644 --- a/lib/slack-res.js +++ b/lib/slack-res.js @@ -1,7 +1,7 @@ 'use strict'; -var _ = require('underscore'), - request = require('request'); +var _ = require('underscore'); +var request = require('request'); var SlackRes = function(config) { if (!(this instanceof SlackRes)) { diff --git a/lib/slack-to-irc.js b/lib/slack-to-irc.js index 627282b..88ed552 100644 --- a/lib/slack-to-irc.js +++ b/lib/slack-to-irc.js @@ -1,9 +1,9 @@ 'use strict'; -var _ = require('underscore'), - http = require('http'), - querystring = require('querystring'), - SlackMsgDecoder = require('./slack-msg-decoder'); +var _ = require('underscore'); +var http = require('http'); +var querystring = require('querystring'); +var SlackMsgDecoder = require('./slack-msg-decoder'); var SlackToIRC = function(config) { if (!(this instanceof SlackToIRC)) { @@ -48,9 +48,8 @@ SlackToIRC.prototype._server = function() { SlackToIRC.prototype._requestHandler = function(req, res) { req.on('data', function(data) { - var - payload = querystring.parse(data.toString()), - isTokenValid = _.contains(this.config.outgoingToken, payload.token); + var payload = querystring.parse(data.toString()); + var isTokenValid = _.contains(this.config.outgoingToken, payload.token); if (isTokenValid && payload.user_name !== 'slackbot') { this._sentMessage(payload); @@ -61,10 +60,9 @@ SlackToIRC.prototype._requestHandler = function(req, res) { }; SlackToIRC.prototype._sentMessage = function(payload) { - var - message = this._decodeMessage(payload.text), - channel = _.invert(this.config.channels)['#' + payload.channel_name], - name = payload.user_name; + var message = this._decodeMessage(payload.text); + var channel = _.invert(this.config.channels)['#' + payload.channel_name]; + var name = payload.user_name; if (this.config.showSlackChannel) { name = name + '@' + payload.channel_name; diff --git a/lib/slackbot.js b/lib/slackbot.js index a0b01a5..db3e126 100644 --- a/lib/slackbot.js +++ b/lib/slackbot.js @@ -1,7 +1,7 @@ 'use strict'; -var _ = require('underscore'), - request = require('request'); +var _ = require('underscore'); +var request = require('request'); var SlackBot = function(config) { if (!(this instanceof SlackBot)) { From 655b8d0641a6b03aa5da6cf7eae586a23f2c1f00 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 17:47:19 +0800 Subject: [PATCH 13/24] Improve coding style of requires --- lib/app.js | 1 + lib/irc-to-slack.js | 1 + lib/slack-to-irc.js | 1 + 3 files changed, 3 insertions(+) diff --git a/lib/app.js b/lib/app.js index b3bc54c..1a2a8cd 100644 --- a/lib/app.js +++ b/lib/app.js @@ -1,6 +1,7 @@ 'use strict'; var _ = require('underscore'); + var IrcBot = require('./ircbot'); var IrcToSlack = require('./irc-to-slack'); var SlackBot = require('./slackbot'); diff --git a/lib/irc-to-slack.js b/lib/irc-to-slack.js index f308002..9cd52cc 100644 --- a/lib/irc-to-slack.js +++ b/lib/irc-to-slack.js @@ -1,6 +1,7 @@ 'use strict'; var _ = require('underscore'); + var IrcMsgEncoder = require('./irc-msg-encoder'); var IrcToSlack = function(config) { diff --git a/lib/slack-to-irc.js b/lib/slack-to-irc.js index 88ed552..b6ac81c 100644 --- a/lib/slack-to-irc.js +++ b/lib/slack-to-irc.js @@ -3,6 +3,7 @@ var _ = require('underscore'); var http = require('http'); var querystring = require('querystring'); + var SlackMsgDecoder = require('./slack-msg-decoder'); var SlackToIRC = function(config) { From db9f593ed6e92f34bd79d7f1549b2b3f80012733 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 18:31:26 +0800 Subject: [PATCH 14/24] Fix docker-compose typo --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3ceee69..c512a54 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ app: build: ./ environment: - TZ=Asia/Taipei - volumns: + volumes: - ./config.js:/app/config.js ports: - "8080:80" From 18d8540a7b42a8e04c5644c61b7e3908d3cea1a2 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 15 Aug 2015 18:41:27 +0800 Subject: [PATCH 15/24] Fix message type judge error --- lib/slack-msg-decoder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/slack-msg-decoder.js b/lib/slack-msg-decoder.js index 97c2d5e..e05b83e 100644 --- a/lib/slack-msg-decoder.js +++ b/lib/slack-msg-decoder.js @@ -5,7 +5,7 @@ var SlackMsgDecoder = function(message) { return new SlackMsgDecoder(message); } - if (typeof this.message === 'string') { + if (typeof message === 'string') { this.message = message; } else { From a57df9a0e1e28942e25f515b935fa3917a374864 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sun, 16 Aug 2015 00:52:30 +0800 Subject: [PATCH 16/24] Rename sample file of configuration --- README.md | 6 +++--- config.sample.js => config.js.sample | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename config.sample.js => config.js.sample (100%) diff --git a/README.md b/README.md index 7eaf025..93a6711 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ cd slack-irc-syncbot npm install ``` -Write your own configuration file (Refer `config.sample.js`) is a good starting point for building your own. The details can refer Configure part in below. +Write your own configuration file (Refer `config.js.sample`) is a good starting point for building your own. The details can refer Configure part in below. Save this to a file in the root of the project then run your bot with: @@ -23,7 +23,7 @@ This project also support docker. you can clone the project and configure it. BT ```shell $ git clone https://github.com/fntsrlike/slack-irc-syncbot.git $ cd slack-irc-syncbot -$ cp config.sample.js config.js +$ cp config.js.sample config.js $ vim config.js ... ``` @@ -46,7 +46,7 @@ $ docker restart slackbot In addition, if your want to specify expose port, remember to use `-p` argument replace `-P` ## Configuration -Explain configuration in config.sample.js with comment. +Explain configuration in config.js.sample with comment. ```javascript var config = { // Require item diff --git a/config.sample.js b/config.js.sample similarity index 100% rename from config.sample.js rename to config.js.sample From 8141b4a2103db3d259fc84c85370ed44ec1ee0fb Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sun, 16 Aug 2015 00:59:52 +0800 Subject: [PATCH 17/24] Add Chinese documentation --- README_zh-tw.md | 124 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 README_zh-tw.md diff --git a/README_zh-tw.md b/README_zh-tw.md new file mode 100644 index 0000000..2bb5f5d --- /dev/null +++ b/README_zh-tw.md @@ -0,0 +1,124 @@ +# Slack IRC Syncbot + +同步 [Slack](http://slack.com)、[IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) 兩者之間的訊息。 + +## 1. 直接使用 node.js 執行 + +### 1-1. 前置需求 +- `git` +- `node.js` & `npm` + +### 1-2. 步驟 + +```bash +$ git clone https://github.com/fntsrlike/slack-irc-syncbot.git +$ cd slack-irc-syncbot +$ npm install +``` + +參考 `config.js.sample` 編寫您所需要的設定檔,設定值詳細的意義請參考下面的「設定」章節。然後將設定值儲存至專案根目錄(檔名通常是 `config.js`)。然後輸入下面的指令: + + $ node <設定檔名> + +之後就會運行機器人,掛載 IRC 頻道可能會需要一段時間,當完成時,即會顯示如下的訊息: + +``` +$ node config.js +.............done! +Server running at http://localhost:8080/ +``` + +## 2. 透過 Docker-Compose 執行 + +這個專案是支援 `Docker` 的,只要您的電腦有 `Docker` 和 `docker-compose`,您就不用刻意去安裝 `node.js`。 + +### 2-1. 前置需求 +- `git` +- `docker` +- `docker-compose` + +### 2-2. 步驟 + +在你修改玩設定檔後,可以在修改 `docker-compose.yml` 的 `volumes` 和 `ports` 去決定有使用的設定檔或輸出的 port。然後就可以執行下列指令 + +```shell +$ docker-compose up -d +``` + +`docker-compose` 就會去建立該 `image` 然後自動在背景執行程式。 + + +## 3. 設定檔詳解 + +在這個章節我們會透過講解 `config.js.sample` 裡面項目,幫助您要如何撰寫您專屬的 `config.js`。 + +```javascript +'use strict'; + +var App = require('./lib/app'); + +// -- 從這邊開始進行設定 + +// 關於機器人的基本設定值 +// var config = { +// nick: '', +// username: '', +// password: '', +// token: '', +// incomeUrl: ''], +// serverPort: 80 +// }; + +var config = { + nick: 'slackbot', + username: 'slackbot-username', + token: 'XXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXX', + incomeUrl: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX', + outgoingToken: ['XXXXXXXXXXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXXXXXXXXXXX'], + serverPort: 80 +}; + +// 機器人要同步的頻道,前後分別為 IRC Server 和 Slack 的 Channel 名稱。 +config.channels = { + '# [頻道密碼、選填]': '#', + '#sample' : '#general' +}; + +// 使用者暱稱、頭像同步,前後分別為 IRC Server 和 Slack 的 username。 +config.users = { + '': '', + 'ircuser': 'slackuser' +}; + +// -- 到此行結束設定。 + +App( config ).start(); +``` + +### 3-1. 必填的屬性 +- `nick`: IRC 帳號的暱稱。每個暱稱在 IRC Server 都是不可重複的。若是重複,程式會自動加上數字遞疊。 +- `username`: IRC 帳號的使用者名稱。 +- `token`: Slack 的 API token。 +- `incomeUrl`: Slack Incoming WebHooks Integrations 提供的網址。 +- `outgoingToken`: Slack Outgoing WebHooks Integrations 提供的 `token`。若同步多個頻道,則會有多個 token,以 Array 的形式儲存。 + +### 3-2. 選填的屬性 +#### 3-2-1. 屬性 +- `server`: IRC server 位址,預設是 `irc.freenode.com`。 +- `iconUrl`: IRC 同步到 Slack 訊息顯示預設頭像的網址。48 * 48 的長寬是比較推薦的。 +- `iconEmoji`: 同上,但是是輸入 emoji code。效果會被 `iconUrl` 覆蓋。 +- `serverPort`: 接收 Slack 訊息用的網頁所使用的 port。預設是 `80` port。 +- `initializeTimeoutLimit`: 設定初始化時,判定超時、失敗的秒數。 +- `listUpdatedPeriod`: 設定定期更新使用者名單的秒數。 + +#### 3-2-2. 開關 +- `isSilent`: 設成 `true` 去對機器人在 IRC 上靜音。預設是 `false`。 +- `isSystemSilent`: 同上。不過特別針對系統訊息。 +- `isUsersTracking`: 設成 `true` 去追蹤 IRC 上使用者的暱稱。預設是 `true`。 +- `isAutoTildeAdded`: 設成 `true` 去讓雙平台使用者名稱綁定的 IRC 名稱前,加上 `~` 作為前綴。預設是 `false`。 +- `isShowSlackChannel`: 設成 `true` 讓同步到 Slack 訊息的使用者名稱前加上 IRC Channel 的名稱。預設是 `false`, +- `isMapName`: 設成 `true` 決定是否開啟暱稱同步的功能。預設為 `true`。 +- `isMapAvatar`:設成 `true` 決定是否開啟頭像同步的功能。預設為 `true`。 + +其他關於程式的設定,可以參考 [node-irc](https://github.com/martynsmith/node-irc/blob/0.3.x/lib/irc.js)。 From bf75a98503546bde66022b853f86b3fd088eb187 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sun, 16 Aug 2015 07:07:36 +0800 Subject: [PATCH 18/24] Improve README.md --- README.md | 117 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 93a6711..30db865 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,108 @@ # Slack IRC Syncbot Synchronize messages between [Slack](http://slack.com) and [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat). -## Usage +## 1. Usage for node.js +### 1-1. Requirments +- `git` +- `node.js` & `npm` + +### 1-2. Steps ```bash -git clone https://github.com/fntsrlike/slack-irc-syncbot.git -cd slack-irc-syncbot -npm install +$ git clone https://github.com/fntsrlike/slack-irc-syncbot.git +$ cd slack-irc-syncbot +$ npm install ``` -Write your own configuration file (Refer `config.js.sample`) is a good starting point for building your own. The details can refer Configure part in below. +Refer `config.js.sample` to write your own configuration. Meaning of setting detail could refer the section "Configuration". After create your configuration to project root as `config.js`, execute the command: -Save this to a file in the root of the project then run your bot with: +```bash +$ node <設定檔名> +``` - node your-config +It will execute program. To join IRC channel may need for a while. When finished setup progress, it will display messages as following: -This will launch the bot in your terminal based on provided configuration. +```bash +$ node config.js +.............done! +Server running at http://localhost:8080/ +``` -## Usage for Docker +## 2. Usage for Docker-Compose -This project also support docker. you can clone the project and configure it. BTW, your config file should be named `config.js`. -```shell -$ git clone https://github.com/fntsrlike/slack-irc-syncbot.git -$ cd slack-irc-syncbot -$ cp config.js.sample config.js -$ vim config.js -... -``` +This project also support docker. If you have install docker and docker-compose, you can excute project without installing node.js in your local. -Then build image and run. -```shell -$ docker build --tag="slack-irc-syncbot" ./ -... -$ docker run -d -P slack-irc-syncbot -``` +### 2-1. Requirements +- `git` +- `docker` +- `docker-compose` -If you don't want to rebuild images after editing config file, just use volume to sync config and restart container. -```shell -$ docker run -d -P -v $PWD/config.js:/app/config.js --name="slackbot" slack-irc-syncbot -$ vim config.js -... -$ docker restart slackbot +### 2-2. Steps + +After you create your own configuration as `config.js` in project root, edit `docker-compose.yml` to setting arguments of docker, usually we will set volumes and ports. At last, execute command: + +```bash +$ docker-compose up -d ``` -In addition, if your want to specify expose port, remember to use `-p` argument replace `-P` +`docker` will create image and container to execute program in background. + +## 3. Configuration + +In thie section, we will explain how to set configuration with `config.js.sample`. -## Configuration -Explain configuration in config.js.sample with comment. ```javascript +'use strict'; + +var App = require('./lib/app'); + +// -- Setting form this line + +// Basic configuration of IRCBot +// var config = { +// nick: '', +// username: '', +// password: '', +// token: '', +// incomeUrl: ''], +// serverPort: 80 +// }; + var config = { - // Require item nick: 'slackbot', username: 'slackbot-username', token: 'XXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXX', incomeUrl: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX', - outgoingToken: ['XXXXXXXXXXXXXXXXXXXXXXXX'], + outgoingToken: ['XXXXXXXXXXXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXXXXXXXXXXX'], + serverPort: 80 }; -// Channels map +// The channels wanna be sync messages. config.channels = { - '#irc-channel password(optional)': '#slack-channel' + '# [password, option]': '#', + '#sample' : '#general' }; -// Users map -// Index is not nick, but account name at IRC. It could be get by `/whois`. -// Value is slack's username. +// To sync nicks and avatar of user config.users = { - 'ircAccount': 'slackUser' + '': '', + 'ircuser': 'slackuser' }; + +// -- Setting end on this line + +App( config ).start(); ``` -### Requirements +### 3-1. Requirements - `nick`: IRCbot's nick, it should be unique on IRC Server - `username`: IRC bot's username - `token`: Slack's API token - `incomeUrl`: From Incoming WebHooks of Integrations - `outgoingToken`: From Outgoing WebHooks of Integrations -- `channels`: Channels map. Decide to sync which IRC chanel to Slack channel -- `users`: Users map. Let messages sync from IRC could dislpay usesname of Slack -### Options +### 3-2. Options - `server`: IRC server, default is `irc.freenode.com` - `iconUrl`: Default ICON for messages from IRC to Slack by url. 48*48 size is better - `iconEmoji`: As iconUrl but by emoji code. It will override by iconUrl @@ -87,13 +110,13 @@ config.users = { - `initializeTimeoutLimit`: Set seconds to be limit time of initialization. - `listUpdatedPeriod`: Set seconds to update user list -### Flags +### 3-3. Flags - `isSilent`: Set true to stop IRC bot from speaking into the channel - `isSystemSilent`: Set true to stop speak any bot's system messages - `isUsersTracking`: Set true to tracking IRC users' nick. Otherwise, user mapping will be turn off. - `isAutoTildeAdded`: Set true to add tilde prefix on IRC nicks - `isShowSlackChannel`: Set true to display channel name of slack on IRC channel -- `isMapName`: -- `isMapAvatar`: +- `isMapName`: Set true to sync nicks. +- `isMapAvatar`: Set true to sync avatar Other config options about IRCBot, can refer [node-irc](https://github.com/martynsmith/node-irc/blob/0.3.x/lib/irc.js) From 8e675fea9bbc52c89a808cfb726451f3791fa69f Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sun, 16 Aug 2015 23:36:10 +0800 Subject: [PATCH 19/24] Add prototype of https connection support --- README.md | 2 ++ README_zh-tw.md | 2 ++ lib/slack-to-irc.js | 40 +++++++++++++++++++++++++++++++++++++--- ssl/.gitkeep | 0 4 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 ssl/.gitkeep diff --git a/README.md b/README.md index 30db865..bf14547 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ App( config ).start(); - `iconUrl`: Default ICON for messages from IRC to Slack by url. 48*48 size is better - `iconEmoji`: As iconUrl but by emoji code. It will override by iconUrl - `serverPort`: The port of web application to get post request from slack. default is 80 +- `httpsServerPort`: As `serverPort` but in https connection. default is 443. - `initializeTimeoutLimit`: Set seconds to be limit time of initialization. - `listUpdatedPeriod`: Set seconds to update user list @@ -118,5 +119,6 @@ App( config ).start(); - `isShowSlackChannel`: Set true to display channel name of slack on IRC channel - `isMapName`: Set true to sync nicks. - `isMapAvatar`: Set true to sync avatar +- `isHttpsConnecttion' Set `true` to turn on https connection. Other config options about IRCBot, can refer [node-irc](https://github.com/martynsmith/node-irc/blob/0.3.x/lib/irc.js) diff --git a/README_zh-tw.md b/README_zh-tw.md index 2bb5f5d..5b7c050 100644 --- a/README_zh-tw.md +++ b/README_zh-tw.md @@ -109,6 +109,7 @@ App( config ).start(); - `iconUrl`: IRC 同步到 Slack 訊息顯示預設頭像的網址。48 * 48 的長寬是比較推薦的。 - `iconEmoji`: 同上,但是是輸入 emoji code。效果會被 `iconUrl` 覆蓋。 - `serverPort`: 接收 Slack 訊息用的網頁所使用的 port。預設是 `80` port。 +- `httpsServerPort`: 同上,但是在 https 的連線狀況。預設是 `443` port。 - `initializeTimeoutLimit`: 設定初始化時,判定超時、失敗的秒數。 - `listUpdatedPeriod`: 設定定期更新使用者名單的秒數。 @@ -120,5 +121,6 @@ App( config ).start(); - `isShowSlackChannel`: 設成 `true` 讓同步到 Slack 訊息的使用者名稱前加上 IRC Channel 的名稱。預設是 `false`, - `isMapName`: 設成 `true` 決定是否開啟暱稱同步的功能。預設為 `true`。 - `isMapAvatar`:設成 `true` 決定是否開啟頭像同步的功能。預設為 `true`。 +- `isHttpsConnecttion' 設成 `true` 去開啟 https 連線服務。 其他關於程式的設定,可以參考 [node-irc](https://github.com/martynsmith/node-irc/blob/0.3.x/lib/irc.js)。 diff --git a/lib/slack-to-irc.js b/lib/slack-to-irc.js index b6ac81c..87542ea 100644 --- a/lib/slack-to-irc.js +++ b/lib/slack-to-irc.js @@ -2,6 +2,7 @@ var _ = require('underscore'); var http = require('http'); +var https = require('https'); var querystring = require('querystring'); var SlackMsgDecoder = require('./slack-msg-decoder'); @@ -13,8 +14,13 @@ var SlackToIRC = function(config) { this.config = _.defaults(config, { showSlackChannel: false, - serverPort: 80 + serverPort: 80, + httpsServerPort: 443, + isHttpsConnecttion: false }); + + // TODO: Check Ports are free or not + // TODO: Check SSL Keys are exist or not }; SlackToIRC.prototype.setIrcBot = function(bot) { @@ -29,9 +35,17 @@ SlackToIRC.prototype.setSlackRes = function(resource) { SlackToIRC.prototype.listen = function() { this.config.avatarMap = this.slackRes.getAvatarMap(); + this._server().listen(this.config.serverPort); - console.log('Server running at ' + - 'http://localhost:' + this.config.serverPort + '/'); + console.log('HTTP Web Server running at ' + + 'http://localhost:' + this.config.serverPort + '/'); + + if (this.config.isHttpsConnecttion) { + console.log('this.config.httpsServerPort: ' + this.config.httpsServerPort); + this._httpsServer().listen(this.config.httpsServerPort); + console.log('HTTPS Web Server running at ' + + 'https://localhost:' + this.config.httpsServerPort + '/'); + } return this; }; @@ -47,6 +61,26 @@ SlackToIRC.prototype._server = function() { return server; }; +SlackToIRC.prototype._httpsServer = function() { + var options; + var server; + + options = { + key: fs.readFileSync('ssl/key.pem'), + cert: fs.readFileSync('ssl/cert.pem') + }; + + server = https.createServer(options, function (req, res) { + if (req.method === 'POST') { + this._requestHandler(req, res); + } else { + res.end('Recieved request (not post).'); + } + }.bind(this)); + + return server; +}; + SlackToIRC.prototype._requestHandler = function(req, res) { req.on('data', function(data) { var payload = querystring.parse(data.toString()); diff --git a/ssl/.gitkeep b/ssl/.gitkeep new file mode 100644 index 0000000..e69de29 From c421f1ad73b690ed259aa06629834cdd8dbce955 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 29 Aug 2015 10:32:36 +0800 Subject: [PATCH 20/24] Fix fs module not require issue --- lib/slack-to-irc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/slack-to-irc.js b/lib/slack-to-irc.js index 87542ea..ab176c6 100644 --- a/lib/slack-to-irc.js +++ b/lib/slack-to-irc.js @@ -1,6 +1,7 @@ 'use strict'; var _ = require('underscore'); +var fs = require('fs'); var http = require('http'); var https = require('https'); var querystring = require('querystring'); From e07b8d6747b9ceea31a10f10720b11c2fadf3b4d Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 29 Aug 2015 10:40:58 +0800 Subject: [PATCH 21/24] Add IRC Banned Nicks feature --- README.md | 6 ++++++ README_zh-tw.md | 6 ++++++ config.js.sample | 4 ++++ lib/irc-to-slack.js | 5 +++++ 4 files changed, 21 insertions(+) diff --git a/README.md b/README.md index bf14547..d3ce1fb 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,12 @@ config.users = { 'ircuser': 'slackuser' }; +// Baned list of IRC Nicks +config.bannedIRCNicks = [ + '', + 'ircNick' +]; + // -- Setting end on this line App( config ).start(); diff --git a/README_zh-tw.md b/README_zh-tw.md index 5b7c050..126d68d 100644 --- a/README_zh-tw.md +++ b/README_zh-tw.md @@ -91,6 +91,12 @@ config.users = { 'ircuser': 'slackuser' }; +// IRC 暱稱黑名單 +config.bannedIRCNicks = [ + '', + 'ircNick' +]; + // -- 到此行結束設定。 App( config ).start(); diff --git a/config.js.sample b/config.js.sample index e501d5e..5ba43ee 100644 --- a/config.js.sample +++ b/config.js.sample @@ -19,4 +19,8 @@ config.users = { 'ircAccount': 'slackUser' }; +config.bannedIRCNicks = [ + 'ircNick' +]; + App( config ).start(); diff --git a/lib/irc-to-slack.js b/lib/irc-to-slack.js index 9cd52cc..10163e0 100644 --- a/lib/irc-to-slack.js +++ b/lib/irc-to-slack.js @@ -10,6 +10,7 @@ var IrcToSlack = function(config) { } this.config = _.defaults(config, { + 'bannedIRCNicks': [] }); return this; @@ -29,6 +30,10 @@ IrcToSlack.prototype._sentToSlack = function(type, from, to, message) { var hasAvatar = false; var isNickExist = !!this.nameMap.getSlackNameByIrcNick(from); + if (_.contains(this.config.bannedIRCNicks, username)) { + return; + } + if (this.config.isMapName && isNickExist) { username = this.nameMap.getSlackNameByIrcNick(from); hasAvatar = typeof avatars[username] !== 'undefined'; From b485576516a440acb19e8e9fe786c38a4800e11d Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 29 Aug 2015 12:15:50 +0800 Subject: [PATCH 22/24] Add index display public info feature --- README.md | 1 + README_zh-tw.md | 1 + lib/slack-to-irc.js | 38 +++++++++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d3ce1fb..8dc7b73 100644 --- a/README.md +++ b/README.md @@ -126,5 +126,6 @@ App( config ).start(); - `isMapName`: Set true to sync nicks. - `isMapAvatar`: Set true to sync avatar - `isHttpsConnecttion' Set `true` to turn on https connection. +- `isDisplayInfo' Set true to let index display some public information. Other config options about IRCBot, can refer [node-irc](https://github.com/martynsmith/node-irc/blob/0.3.x/lib/irc.js) diff --git a/README_zh-tw.md b/README_zh-tw.md index 126d68d..1ce5ba7 100644 --- a/README_zh-tw.md +++ b/README_zh-tw.md @@ -128,5 +128,6 @@ App( config ).start(); - `isMapName`: 設成 `true` 決定是否開啟暱稱同步的功能。預設為 `true`。 - `isMapAvatar`:設成 `true` 決定是否開啟頭像同步的功能。預設為 `true`。 - `isHttpsConnecttion' 設成 `true` 去開啟 https 連線服務。 +- `isDisplayInfo' 設成 `true` 讓首頁顯示可公開資訊。預設為 `true`。 其他關於程式的設定,可以參考 [node-irc](https://github.com/martynsmith/node-irc/blob/0.3.x/lib/irc.js)。 diff --git a/lib/slack-to-irc.js b/lib/slack-to-irc.js index ab176c6..d28ea07 100644 --- a/lib/slack-to-irc.js +++ b/lib/slack-to-irc.js @@ -17,6 +17,7 @@ var SlackToIRC = function(config) { showSlackChannel: false, serverPort: 80, httpsServerPort: 443, + isDisplayInfo: true, isHttpsConnecttion: false }); @@ -55,7 +56,7 @@ SlackToIRC.prototype._server = function() { if (req.method === 'POST') { this._requestHandler(req, res); } else { - res.end('Recieved request (not post).'); + res.end(this.config.isDisplayInfo ? this._getIndexHtml() : 'Recieved request (not post).'); } }.bind(this)); @@ -117,4 +118,39 @@ SlackToIRC.prototype._decodeMessage = function(text) { .decodeAngel().encodeAmpersand().toString(); }; +SlackToIRC.prototype._getIndexHtml = function() { + var html = ''; + + html += '' + + 'Slack IRC Messages Syncbot' + + '' + + '' + + '

Slack IRC Messages Syncbot

' + + '

Sync Channels

' + + '' + + '' + + '' + this._objectToHtmlTr(this.config.channels) + '' + + '
IRC ChannelSlack Channel
' + + '

Binding Users

' + + '' + + '' + + '' + this._objectToHtmlTr(this.config.users) + '' + + '
IRC AcoountSlack Account
' + + '

Banned IRC Nicks

' + this.config.bannedIRCNicks.join(', ') + '

' + + '

[Github]

' + + ''; + + return html; +} + +SlackToIRC.prototype._objectToHtmlTr = function(object) { + var html = ''; + + for (var key in object) { + html += '' + key + '' + object[key] + ''; + } + + return html; +} + module.exports = SlackToIRC; From 29cfffe23f681d6130edacd8a88af59689deb89e Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 29 Aug 2015 14:42:09 +0800 Subject: [PATCH 23/24] Add banned keywords feature --- README.md | 9 +++++++-- README_zh-tw.md | 5 +++++ config.js.sample | 4 ++++ lib/irc-to-slack.js | 10 +++++++++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8dc7b73..68b98a9 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ var config = { serverPort: 80 }; -// The channels wanna be sync messages. +// The channels wanna be sync messages. config.channels = { '# [password, option]': '#', '#sample' : '#general' @@ -90,12 +90,17 @@ config.users = { 'ircuser': 'slackuser' }; -// Baned list of IRC Nicks +// Baned list of IRC Nicks. Usually are bots. config.bannedIRCNicks = [ '', 'ircNick' ]; +// To filter messages has bad word or dirty word +config.bannedKeywords = [ + 'keyword' +]; + // -- Setting end on this line App( config ).start(); diff --git a/README_zh-tw.md b/README_zh-tw.md index 1ce5ba7..bec33ef 100644 --- a/README_zh-tw.md +++ b/README_zh-tw.md @@ -97,6 +97,11 @@ config.bannedIRCNicks = [ 'ircNick' ]; +// 關鍵字黑名單,擁有以下關鍵字的訊息將會被篩選掉。 +config.bannedKeywords = [ + 'keyword' +]; + // -- 到此行結束設定。 App( config ).start(); diff --git a/config.js.sample b/config.js.sample index 5ba43ee..312e135 100644 --- a/config.js.sample +++ b/config.js.sample @@ -23,4 +23,8 @@ config.bannedIRCNicks = [ 'ircNick' ]; +config.bannedKeywords = [ + // 'keyword' +]; + App( config ).start(); diff --git a/lib/irc-to-slack.js b/lib/irc-to-slack.js index 10163e0..7a31a73 100644 --- a/lib/irc-to-slack.js +++ b/lib/irc-to-slack.js @@ -10,7 +10,8 @@ var IrcToSlack = function(config) { } this.config = _.defaults(config, { - 'bannedIRCNicks': [] + 'bannedIRCNicks': [], + 'bannedKeywords': [] }); return this; @@ -29,11 +30,18 @@ IrcToSlack.prototype._sentToSlack = function(type, from, to, message) { var avatars = this.config.avatarMap; var hasAvatar = false; var isNickExist = !!this.nameMap.getSlackNameByIrcNick(from); + var bannedKeywords = this.config.bannedKeywords; if (_.contains(this.config.bannedIRCNicks, username)) { return; } + for (var i=0, len=bannedKeywords.length; i < len; i++) { + if (message.toLowerCase().indexOf(bannedKeywords[i].toLowerCase()) > -1) { + return; + } + } + if (this.config.isMapName && isNickExist) { username = this.nameMap.getSlackNameByIrcNick(from); hasAvatar = typeof avatars[username] !== 'undefined'; From 4d2942e8b44baccc867899f1e1e4a8691ad6a055 Mon Sep 17 00:00:00 2001 From: "Ruoshi.Ling" Date: Sat, 29 Aug 2015 14:56:28 +0800 Subject: [PATCH 24/24] Make banned nicks and keywords case-insensitive --- lib/irc-to-slack.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/irc-to-slack.js b/lib/irc-to-slack.js index 7a31a73..b981262 100644 --- a/lib/irc-to-slack.js +++ b/lib/irc-to-slack.js @@ -14,6 +14,9 @@ var IrcToSlack = function(config) { 'bannedKeywords': [] }); + this.config.bannedIRCNicks = this.config.bannedIRCNicks.join('|').toLowerCase().split('|'); + this.config.bannedKeywords = this.config.bannedKeywords.join('|').toLowerCase().split('|'); + return this; }; @@ -32,12 +35,12 @@ IrcToSlack.prototype._sentToSlack = function(type, from, to, message) { var isNickExist = !!this.nameMap.getSlackNameByIrcNick(from); var bannedKeywords = this.config.bannedKeywords; - if (_.contains(this.config.bannedIRCNicks, username)) { + if (_.contains(this.config.bannedIRCNicks, username.toLowerCase())) { return; } for (var i=0, len=bannedKeywords.length; i < len; i++) { - if (message.toLowerCase().indexOf(bannedKeywords[i].toLowerCase()) > -1) { + if (message.toLowerCase().indexOf(bannedKeywords[i]) > -1) { return; } }