Actions: | Security

AllGoodBits.org

Navigation: Home | Services | Tools | Articles | Other

IRC with irssi

I've been using, for several years, an irssi config that I built based on much work by carina.org.uk, it just works for my usage which is inside screen(1) on a server somewhere. Here is a redacted version that connects to 2 IRC networks, freenode and perl.org, identifying and autojoining a couple of channels (one of which is "fake"), sets up some aliases, a highlight and a statusbar.

To make it your own, search for TODO and change to your own nick and your own password, respectively and then change the values in the channels and windows sections so that you get windows for and join channels that you want.

#THIS SECTION DEALS WITH THE SERVERS YOU CONNECT TO

servers = (
  {
    address = "irc.freenode.net";
    chatnet = "freenode";
    port = "6667";
    autoconnect = "yes";
  },
  {
    address = "irc.perl.org";
    chatnet = "perl";
    port = "6667";
    autoconnect = "yes";
  },
);

#THIS SECTION DEALS WITH THE COMMANDS THAT ARE SENT WHEN YOU JOIN A SERVER
chatnets = {
  freenode = {
    type = "IRC";
    autosendcmd = "/msg nickserv identify MYNICKTODO MYPASSWORDTODO";
    max_kicks = "4";
    max_modes = "3";
    max_msgs = "5";
    max_whois = "4";
  };

};

#THIS SECTION DEALS WITH THE CHANNELS THAT YOU WANT TO JOIN ON CONNECT
channels = (
  { name = "#help"; chatnet = "freenode"; autojoin = "yes"; },
  { name = "#morehelp"; chatnet = "freenode"; autojoin = "yes"; },
  );

#THIS SECTION DEALS WITH ALIASES
aliases = {
  J = "join";
  WJOIN = "join -window";
  WQUERY = "query -window";
  LEAVE = "part";
  BYE = "quit";
  EXIT = "quit";
  SIGNOFF = "quit";
  DESCRIBE = "action";
  DATE = "time";
  HOST = "userhost";
  LAST = "lastlog";
  SAY = "msg *";
  WI = "whois";
  WII = "whois $0 $0";
  WW = "whowas";
  W = "who";
  N = "names";
  M = "msg";
  T = "topic";
  C = "clear";
  CL = "clear";
  K = "kick";
  KB = "kickban";
  KN = "knockout";
  BANS = "ban";
  B = "ban";
  MUB = "unban *";
  UB = "unban";
  IG = "ignore";
  UNIG = "unignore";
  SB = "scrollback";
  UMODE = "mode $N";
  WC = "window close";
  WN = "window new hide";
  SV = "say Irssi $J ($V) - http://irssi.org/";
  GOTO = "sb goto";
  CHAT = "dcc chat";
  RUN = "SCRIPT LOAD";
  UPTIME = "eval exec - expr `date +%s` - \\$F | awk '{print \"Irssi uptime: \"int(\\\\\\$1/3600/24)\"d \"int(\\\\\\$1/3600%24)\"h \"int(\\\\\\$1/60%60)\"m \"int(\\\\\\$1%60)\"s\" }'";
  CALC = "exec - if which bc &>/dev/null\\; then echo '$*' | bc | awk '{print \"$*=\"$$1}'\\; else echo bc was not found\\; fi";
  SBAR = "STATUSBAR";
  INVITELIST = "mode $C +I";
  Q = "QUERY";
  ec = "window close";
  em = "me";
  nixk = "nick";
  mw = "me";
  mne = "me";
  wm = "window move";
  awat = "away";
  nme = "me";
};

#THIS SECTION DEALS WITH YOUR STATUSBAR - DO NOT CHANGE THIS UNLESS YOU ARE SURE WHAT YOU ARE DOING
statusbar = {
  # formats:
  # when using {templates}, the template is shown only if it's argument isn't
  # empty unless no argument is given. for example {sb} is printed always,
  # but {sb $T} is printed only if $T isn't empty.

  items = {
    # start/end text in statusbars
    barstart = "{sbstart}";
    barend = "{sbend}";

    topicbarstart = "{topicsbstart}";
    topicbarend = "{topicsbend}";

    # treated "normally", you could change the time/user name to whatever
    time = "{sb $Z}";
    user = "{sb $cumode$N{sbmode $usermode}{sbaway $A}}";

    # treated specially .. window is printed with non-empty windows,
    # window_empty is printed with empty windows
    window = "{sb $winref:$itemname{sbmode $M}}";
    window_empty = "{sb $winref{sbservertag $tag}}";
    prompt = "{prompt $[.15]itemname}";
    prompt_empty = "{prompt $winname}";
    topic = " $topic";
    topic_empty = " Irssi v$J - http://irssi.org/help/";

    # all of these treated specially, they're only displayed when needed
    lag = "{sb Lag: $0-}";
    act = "{sb Act: $0-}";
    more = "-- more --";
  };

  # there's two type of statusbars. root statusbars are either at the top
  # of the screen or at the bottom of the screen. window statusbars are at
  # the top/bottom of each split window in screen.
  default = {
    # the "default statusbar" to be displayed at the bottom of the window.
    # contains all the normal items.
    window = {
      disabled = "no";

      # window, root
      type = "window";
      # top, bottom
      placement = "bottom";
      # number
      position = "1";
      # active, inactive, always
      visible = "active";

      # list of items in statusbar in the display order
      items = {
        barstart = { priority = "100"; };
        time = { };
        user = { };
        window = { };
        window_empty = { };
        lag = { priority = "-1"; };
        act = { priority = "10"; };
        more = { priority = "-1"; alignment = "right"; };
        barend = { priority = "100"; alignment = "right"; };
      };
    };

    # statusbar to use in inactive split windows
    window_inact = {
      type = "window";
      placement = "bottom";
      position = "1";
      visible = "inactive";
      items = {
        barstart = { priority = "100"; };
        window = { };
        window_empty = { };
        more = { priority = "-1"; alignment = "right"; };
        barend = { priority = "100"; alignment = "right"; };
      };
    };

    # we treat input line as yet another statusbar :) It's possible to
    # add other items before or after the input line item.
    prompt = {
      type = "root";
      placement = "bottom";
      # we want to be at the bottom always
      position = "100";
      visible = "always";
      items = {
        prompt = { priority = "-1"; };
        prompt_empty = { priority = "-1"; };
        # treated specially, this is the real input line.
        input = { priority = "10"; };
      };
    };

    # topicbar
    topic = {
      type = "root";
      placement = "top";
      position = "1";
      visible = "always";
      items = {
        topicbarstart = { priority = "100"; };
        topic = { };
        topic_empty = { };
        topicbarend = { priority = "100"; alignment = "right"; };
      };
    };
  };
};

#THIS SECTION DEALS WITH SETTINGS SUCH AS YOUR NAME AND TIMESTAMP FORMAT
settings = {
  core = {
    real_name = "MYNICKTODO";
    user_name = "MYNICKTODO";
    nick = "MYNICKTODO";
    timestamp_format = "%H:%M:%S";
  };
  "fe-text" = { scrollback_time = "48h"; };
  "fe-common/core" = { autolog = "yes"; };
};

#THIS SECTION DEALS WITH YOUR HILIGHTS
hilights = (
  { text = "MYNICKTODO"; nick = "no"; word = "no"; },

);

logs = { };
ignores = ( );

#THIS SECTIONS DEALS WITH YOUR CHANNELS.  THE NUMBER IS THE WINDOW NUMBER
#A CHANNEL WILL APPEAR IN.
windows = {
  1 = { immortal = "yes"; name = "(status)"; level = "ALL"; };
  2 = {
    items = (
      {
        type = "CHANNEL";
        chat_type = "IRC";
        name = "#help";
        tag = "freenode";
      }
    );
  };
  3 = {
    items = (
      {
        type = "CHANNEL";
        chat_type = "IRC";
        name = "#morehelp";
        tag = "freenode";
      }
    );
  };
};
mainwindows = { 1 = { first_line = "1"; lines = "22"; }; };

jtrucks, a freenode staffer amongst other awesomeness, posted the following snippet. The basic idea is that you create windows, join channels, message people and then run this and it will save everything for you so you can recreate it at will:

/alias immortalize /foreach window /window immortal on
/alias stickum /foreach window /window stick on
/alias addallchannels script exec foreach my \$channel (Irssi::channels()) { Irssi::command("channel add -auto \$channel->{name} \$channel->{server}->{tag} \$channel->{key}")\;}
/alias preserve /immortalize; /stickum;/addallchannels;/layout save;/save

which in the aliases section of .irssi/config would look like:

ADDALLCHAN = "script exec foreach my \\$channel (Irssi::channels()) { Irssi::command(\"channel add -auto \\$channel->{name} \\$channel->{server}->{tag} \\$channel->{key}\")\\;}";
immortalize = "/foreach window /window immortal on";
stickum = "   /foreach window /window stick on";
preserve = "  /immortalize; /stickum;/addallchannels;/layout save;/save";