Skip to content

Instantly share code, notes, and snippets.

@adsr
Created April 26, 2019 03:55
Show Gist options
  • Select an option

  • Save adsr/db827dc0b9fb4712af451b43a059c0bc to your computer and use it in GitHub Desktop.

Select an option

Save adsr/db827dc0b9fb4712af451b43a059c0bc to your computer and use it in GitHub Desktop.
diff --git a/lib/irslackd.js b/lib/irslackd.js
index 05c998b..a17a211 100644
--- a/lib/irslackd.js
+++ b/lib/irslackd.js
@@ -20,40 +20,41 @@ class Irslackd {
self.ircd = self.getNewIrcd(self.config.tlsOpts);
const requireInit = true;
const noRequireInit = false;
new Map([
[ 'AWAY', self.makeIrcHandler(self.onIrcAway, requireInit) ],
[ 'INVITE', self.makeIrcHandler(self.onIrcInvite, requireInit) ],
[ 'JOIN', self.makeIrcHandler(self.onIrcJoin, requireInit) ],
[ 'KICK', self.makeIrcHandler(self.onIrcKick, requireInit) ],
[ 'LIST', self.makeIrcHandler(self.onIrcList, requireInit) ],
[ 'MODE', self.makeIrcHandler(self.onIrcMode, noRequireInit) ],
[ 'NICK', self.makeIrcHandler(self.onIrcNick, noRequireInit) ],
[ 'PART', self.makeIrcHandler(self.onIrcPart, requireInit) ],
[ 'PASS', self.makeIrcHandler(self.onIrcPass, noRequireInit) ],
[ 'PING', self.makeIrcHandler(self.onIrcPing, noRequireInit) ],
[ 'PRIVMSG', self.makeIrcHandler(self.onIrcPrivmsg, requireInit) ],
[ 'QUIT', self.makeIrcHandler(self.onIrcQuit, requireInit) ],
[ 'TOPIC', self.makeIrcHandler(self.onIrcTopic, requireInit) ],
[ 'USER', self.makeIrcHandler(self.onIrcUser, noRequireInit) ],
[ 'WHOIS', self.makeIrcHandler(self.onIrcWhois, requireInit) ],
[ 'WHO', self.makeIrcHandler(self.onIrcWho, requireInit) ],
+ [ 'SLACK', self.makeIrcHandler(self.onIrcSlack, requireInit) ],
[ 'ircLine', self.makeIrcHandler(self.onIrcLine, noRequireInit) ],
[ 'ircError', self.makeIrcHandler(self.onIrcError, noRequireInit) ],
[ 'ircClose', self.makeIrcHandler(self.onIrcClose, noRequireInit) ],
[ 'ircConnect', (socket) => { self.onIrcConnect(socket); } ],
]).forEach((handler, cmd, map) => {
self.ircd.on(cmd, handler);
});
self.ircd.listen(self.config.port, self.config.host);
}
async onIrcConnect(socket) {
this.socketMap.set(socket, new IrcUser(socket));
}
async onIrcClose(ircUser, hadError) {
console.log('irc_out', 'Disconnecting client');
try {
if (ircUser.socket) {
ircUser.socket.destroy();
this.socketMap.delete(ircUser.socket);
}
if (ircUser.slackRtm) {
@@ -694,40 +695,95 @@ class Irslackd {
let slackUser = ircUser.ircToSlack.get(ircNick);
if (!slackUser) return;
try {
let user = await ircUser.slackWeb.apiCallOrThrow('users.info', { user: slackUser });
this.ircd.write(ircUser.socket, 'irslackd', '311', [
ircUser.ircNick,
ircNick,
ircNick,
'irslackd',
'*',
':' + (user.user.real_name || user.user.profile.display_name || user.user.name),
]);
} catch (e) {
this.ircd.write(ircUser.socket, 'irslackd', '401', [
ircUser.ircNick,
ircNick,
':No such nick/channel',
]);
}
}
+ async onIrcSlack(ircUser, msg) {
+ const self = this;
+ const cmd = (msg.args[0] || '').toLowerCase();
+ let ircChan;
+ let slackChan;
+ let results = [];
+ let ircMethod;
+ let ircTarget;
+ switch (cmd) {
+ case 'history':
+ ircChan = msg.args[1];
+ slackChan = ircUser.ircToSlack.get(ircChan);
+ if (!slackChan) return;
+ const history = await ircUser.slackWeb.apiCallOrThrow('conversations.history', {
+ channel: slackChan,
+ limit: +msg.args[2] || 20,
+ });
+ results = history.messages;
+ ircMethod = 'NOTICE';
+ ircTarget = ircChan;
+ break;
+ case 'stat':
+ ircChan = msg.args[1];
+ slackChan = ircUser.ircToSlack.get(ircChan);
+ if (!slackChan) return;
+ let ts = msg.args[2];
+ if (ts.substr(0, 1) === '@') ts = ts.substr(1);
+ if (ts.substr(0, 7) === 'thread-') ts = ts.substr(7);
+ const replies = await ircUser.slackWeb.apiCallOrThrow('conversations.replies', {
+ channel: slackChan,
+ ts: ts,
+ limit: 1,
+ });
+ results = replies.messages;
+ ircMethod = 'NOTICE';
+ ircTarget = ircChan;
+ break;
+ case 'search':
+ const messages = await ircUser.slackWeb.apiCallOrThrow('search.messages', {
+ query: msg.args.slice(1).join(' '),
+ count: 20,
+ });
+ results = messages.messages.matches;
+ ircMethod = 'PRIVMSG';
+ ircTarget = ircUser.ircNick;
+ break;
+ }
+ results.forEach(async (res) => {
+ let channel = ircTarget;
+ if (res.channel) channel = await self.resolveSlackChannel(ircUser, res.channel.id);
+ const nick = '@' + ((await self.resolveSlackUser(ircUser, res.user)) || res.user || 'unknown');
+ const line = channel + ' @' + res.ts + ' <' + nick + '> ' + self.ircizeText(ircUser, self.decodeEntities(res.text));
+ self.ircd.write(ircUser.socket, 'irslackd', ircMethod, [ ircTarget, line ]);
+ });
+ }
onIrcDebugPrivmsg(ircUser, msg) {
let cmd = msg.args[0];
let out = null;
const iOpts = { depth: 3, showHidden: true };
switch (cmd) {
case 'dump_server': out = util.inspect(this, iOpts); break;
case 'dump_user': out = util.inspect(ircUser, iOpts); break;
case 'dump_rtm': out = util.inspect(ircUser.slackRtm, iOpts); break;
case 'dump_web': out = util.inspect(ircUser.slackWeb, iOpts); break;
}
if (out) console.log('debug', cmd, out);
}
onIrcDebugJoin(ircUser) {
this.sendIrcChannelJoin(ircUser, debugChannel, 'irslackd debug', [ ircUser.ircNick ]);
}
onIrcDebugPart(ircUser) {
this.sendIrcChannelPart(ircUser, debugChannel);
}
async onIrcLine(ircUser, line) {
console.log('irc_in', line);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment