Skip to content


Subversion checkout URL

You can clone with
Download ZIP
IRC Bot Framework for Node.js
Pull request Compare This branch is 172 commits behind master.

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.

Build Status

Tennu is an IRC bot framework written in Node.js


Note: Modules are going to be renamed to plugins. The only breaking change in code is that the config property will be changed and you'll have to move your private plugins from tennu_modules to tennu_plugins. The code for now will say 'modules', while the documentation says 'plugins'. They are synonomous.

Basic Usage

With Tennu, you create an irc client, require your modules or subscribe to your event listeners, and then connect.

var tennu = require('tennu');
var network = require('../config/myNetwork.json'); // See next section
var myClient = tennu.Client(network);

Before connecting, add listeners to events from irc & users, or load modules.

// Do something when a nick, perhaps yourself, joins a channel
myClient.on('join', function (message) {
    this.say(, + " joined!");

// Do something when a user emits a command, in this case, join the specified channel.
myClient.on('!join', function (command) {

// Load a module.

// Or just use a module from tennu_modules/%f or node_modules/tennu-%f
myClient.use(['admin', 'last-seen']);



A network configuration object has the following properties:

  • server - IRC server to connect to. Example:
  • port - Port to connect to. Defaults to 6667.
  • secure - Use a TLS socket (Throws away the NetSocket)
  • ipv6 - Whether you are connecting over ipv6 or not.
  • localAddress - See net.Socket documentation. ;)
  • capab - IRC3 CAP support. (Untested)
  • password - Password for IRC Network (most networks do not have a password)
  • nickname - Nickname the bot will use. Defaults to "tennubot"
  • username - Username the bot will use. Defaults to "user"
  • realname - Realname for the bot. Defaults to "tennu v0.3"
  • password - Password for identifying to services.
  • nickserv - Nickname of nickserv service. Defaults to "nickserv".
  • trigger - Command character to trigger commands with. By default, '!'.
  • channels - Array of channels to autojoin. Example: ["#help", "#tennu"]
  • modules - An array of module names that the bot requires.
  • disable-help - Disables the built-in help plugin.

Password is listed twice. That is a bug that will be fixed in v0.9.0.

Other plugins may add additional properties.

Configuration objects are JSON encodable.


The following properties will be renamed:

  • user -> username
  • nick -> nickname
  • trigger -> command-trigger
  • password -> auth-password (or something better...)
  • modules -> plugins

Dependency Management

The second (optional) parameter to tennu.Client is an object of factories to replace the factories that the Client uses by default.

  • NetSocket
  • IrcSocket
  • IrcOutputSocket [0.9.0 - Will be removed in favor of the 'actions' plugin]
  • MessageHandler
  • CommandHandler
  • Modules [0.9.0 - Will be renamed to Plugins]
  • BiSubscriber
  • Logger

These functions will always be called as constructors (with new).


Of these, the only one you will probably care about is Logger. The object returned by the Logger function must implement the following methods:

debug, info, notice, warn, error, crit, alert, emerg

Base Tennu will only use debug through error, but other modules and event emitters may use crit through emerg.

Event Handling

Note: Tennu uses a custom event handler. Listeners are placed at the end of the event queue, insead of happening right away. Errors are currently logged to console, but otherwise swallowed.

Respond Functionality

Commands and Messages that have a channel property take a return value. Currently, the return value must be a string or array that is then said to the channel the message originated in.

// Simple echobot.
tennu.on('privmsg', function (privmsg) {
    return privmsg.message;

// Equivalent to:
tennu.on('privmsg', function (privmsg) {
    tennu.say(, privmsg.message);

Subscribing Options

Subscribing to events in Tennu is more flexible than most event listeners.

You register a single handler on multiple events at once by separating the events with a space, for example .on("x y", fn) is equivalent to .on('x', fn); .on('y', fn). Furthermore, an object can be passed, where each key is passed as the first parameter and its value, the second.

// Examples

on("irc_event", listener)
on("!user-command", listener)
on("join quit", listener)
    "part": part_listener,
    "join": join_listener,
    "!hi !bye": talk_listener

Listener Parameters

Listeners are passed either a message or command object.


Messages are passed by irc events.

Messages are immutable, as are their args. Make sure to copy the args array before trying to manipulate it.

All messages have the following fields:

  • receiver - Receiver of the message. A reference to the Client object.
  • prefix - The prefix is either a hostmask of the format "nickname!username@hostname", or the server you are connected to.
  • command - Message command type. For example, 'privmsg' or 'nick'.
  • params - Array of sent parameters.
  • tags - IRC3 tags sent with message.

Some messages have extended information. See Message Properties.


Commands are passed for user commands.

Commands are an extension of Messages with the command type of 'privmsg'. They have all properties, plus the following properties:

  • args - Array of words after the command name.
  • command - The command name.

For example, a command of "!do-it ARG1 ARG2" will have args be ["ARG1", "ARG2"] and command be 'do-it'.


All of the following are methods on Tennu that can be used once connected.

These methods are also available on the client's 'out' property. In Tennu 0.9.0, the 'out' property will go away, and the 'actions' module will export these methods.

say(channel, message)

  • channel is either a channel ("#chan") or a user ("nick").
  • message is either a string or array of strings. Given an array, say each individual element on its own line.

Has the bot say the message(s) to the specific channel/user.

/* Output (IRC)
(botnick) This is a message!
tennu.say('#example', "This is a message!");

/* Output (IRC)
(botnick) Hi there.
(botnick) Bye there.
tennu.say('#example', ["Hi there.", "Bye there."]);

act(channel, message)

As per say, but as an action (/me)

/* Output (IRC)
botnick does something!
tennu.act('#example', "does something!");

ctcp(channel, type, message)

tennu.ctcp('havvy', 'ping', 'PINGMESSAGE');


Change the bots nickname.


Joins the specified channel.

tennu.join("#keyed-channel channel-key");
tennu.join("0"); // Part all channels.

part(channel, reason)

Parts the specified channel with the given reason.


Quits the server with the given reason.

whois(users, server)

Server is optional, and you'll probably not need it. Look at RFC 1459 for what benefit it gives you.

users is either a string or an array of strings.


Retrieves the userhost of the user(s).


For actions that are lacking a command, you can use raw to perform them. You must either pass an array of arguments (and the multiword argument must be in a single index without the colon) or pass the full string.

If you find yourself using raw(), please file an issue.

rawf(format, args...)


As raw(message), but the arguments are passed through util.format() first.

Plugin System

Tennu has its own plugin system, loosely based off of Node's module system. You can read about it at

You may access the module system's methods via the Client.modules property or by using one of the following methods:

  • client.require()
  • client.getModule()
  • client.getRole()
  • client.use()
  • client.initializeModule()
  • client.isModuleInitializable()

Creating Your Own Modules

See Creating Your Own Modules.

See Getting Started.

Built-In Modules

Only the help module is currently implemented.



Sets the command !help.

See Help Module Documentation.


If you don't want this functionality, set disable-help to true in your configuration object.





This module has a single method exported: isIdentifedAs(nickname, nickname_identified, callback)

See User Module Documentation.



[0.4.x and below]

Information about the server. For now, the only thing this module offers is a capabilities map listing the information from the 005 raw numeric.

var server = tennu.use("server");

The capabilities object looks like this for the Mibbit network.

  UHNAMES: true,
  NAMESX: true,
  SAFELIST: true,
  HCN: true,
  CHANLIMIT: '#:40',
  MAXLIST: 'b:120,e:120,I:120',
  NICKLEN: '30',
  TOPICLEN: '307',
  KICKLEN: '307',
  AWAYLEN: '307',
  WALLCHOPS: true,
  WATCH: '128',
  SILENCE: '15',
  MODES: '12',
  PREFIX: '(qaohv)~&@%+',
  CHANMODES: 'beI,kfL,lj,psmntirRcOAQKVCuzNSMTG',
  NETWORK: 'Mibbit',
  CASEMAPPING: 'ascii',
  EXTBAN: '~,cqnr',
  STATUSMSG: '~&@%+',
  EXCEPTS: true,
  INVEX: true

Command Line Utility

Note: Don't listen to this. Instead, keep tennu in your bot's dependencies, and run ./node_modules/tennu/bin/cli.js.

Install Tennu globally, and you'll gain access to the tennu command line tool.

> pwd
> ls
node_modules/ tennu_modules/ config.json
> tennu config.json

The tennu command takes two optional argument, -v (--verbose) and -d (--debug), for adding a Logger that logs to the console (info level and above without -d).

Other Objects

The following other objects can be obtained from the Tennu module:

  • Message
  • OutputSocket
  • MessageParser
  • CommandParser
  • Bisubscriber

Documentation for these objects in isolation is currently unavailable.


npm test

Between all projects (tennu, tennu-plugins, irc-socket, after-events), there are over 100 tests, but more are always appreciated, especially if they are failing with an actual bug. ;)

See Also

Something went wrong with that request. Please try again.