UNPKG

tennu

Version:

Tennu - Modular IRC Bot Framework for Node.js

113 lines (98 loc) 4.35 kB
const format = require("util").format; const Promise = require("bluebird"); const ResultCtors = require("r-result"); const Ok = ResultCtors.Ok; const Fail = ResultCtors.Fail; module.exports = function (client, rawf, emitter) { return function (channel) { return new Promise(function (resolve, reject) { if (channel === undefined || channel === "") { reject(new Error("No channel given to join action.")); return; } const joinInfo = { names: [], channel: channel, nickname: client.nickname(), topic: {} }; // Only listen to events for the channel we care about. const forChannel = function (handler) { return function (message) { if (message.channel === channel) { try { handler(message); } catch (e) { reject(e); } } }; }; const formatc = function (formatstr) { return format(formatstr, channel); }; // const onJoin = forChannel(function (join) { // // There's no actual data we need on the JOIN event itself. // }); const onTopic = forChannel(function (topic) { client.debug("PluginAction", formatc("Handling RPL_TOPIC for %s.")); joinInfo.topic.topic = topic.topic; }); const onTopicWhoTime = forChannel(function (topicWhoTime) { client.debug("PluginAction", formatc("Handling RPL_TOPICWHOTIME for %s.")); joinInfo.topic.setter = topicWhoTime.who; joinInfo.topic.timestamp = topicWhoTime.timestamp; }); const onNames = forChannel(function (names) { client.debug("PluginAction", formatc("Handling RPL_NAMREPLY for %s.")); joinInfo.names = joinInfo.names.concat(names.nicknames); }); const onNamesEnd = forChannel(function () { client.debug("PluginAction", formatc("Handling RPL_ENDOFNAMES for %s.")); unsubscribe(); resolve(Ok(joinInfo)); }); const onJoinFail = forChannel(function (failMessage) { client.debug("PluginAction", formatc("Handling Join Error for %s.")); client.debug("PluginAction", require('util').inspect(failMessage)); unsubscribe(); client.debug("PluginAction", formatc("Resolving Ok(...) for %s.")) resolve(Fail(failMessage)); }); const handlers = { //join: onJoin, rpl_topic: onTopic, rpl_topicwhotime: onTopicWhoTime, rpl_namreply: onNames, rpl_endofnames: onNamesEnd, err_nosuchchannel: onJoinFail, err_unavailresource: onJoinFail, err_channelisfull: onJoinFail, err_toomanychannels: onJoinFail, err_inviteonlychan: onJoinFail, err_bannedfromchan: onJoinFail, err_badchannelkey: onJoinFail, err_needreggednick: onJoinFail, err_operonly: onJoinFail }; client.debug("PluginAction", formatc("Registering handlers for JOIN %s.")); client.on(handlers); // Assume failure in an hour. var timeout = setTimeout(function () { unsubscribe(); client.error(formatc("Attempt to join %s failed.")); reject(new Error(formatc("Join attempt timed out for channel %s."))); }, 3600 * 1000); var unsubscribe = function () { client.debug("PluginAction", formatc("Unsubscribing events for JOIN %s")); client.off(handlers); clearTimeout(timeout); }; client.debug("PluginAction", formatc("Attempting to join %s.")); rawf("JOIN :%s", channel); }) .tap(function (result) { emitter.emit("join", result); }); }; };