Monday, May 28, 2012

IRC backlog in Pidgin using ZNC

For a while now I've been complaining about missing out on IRC conversations when I'm not connected to Pidgin. Finally, I set out to solve the problem. This post walks you through the solution I came up with.
I decided to use an IRC bouncer to keep me connected and then relay the backlog to Pidgin when it connects. This, of course, implies that your bouncer needs to be running some place where it is always connected. I chose to use ZNC as the bouncer. I heard good things about it on the Internets. As you can tell by the name of my blog I like Linux, so, these installation instructions are for the Ubuntu distro both for the server and the client.

Server setup

We will start by installing ZNC and runit, which we will use later to run ZNC as a daemon, on the server.
sudo aptitude install znc runit

When this is done, we are ready to configure ZNC. There biggest thing you have to remember here is to not start ZNC when the configuration is done. We will start ZNC as a daemon with runit later. I also chose not to keep the buffers after replay since Pidgin will write the replay to its logs and to enable SSL for the ZNC server. You should also make your ZNC user an admin and enable the webadmin console if you want to make changes to the configuration more easily. If you don't know what I'm talking about you should read the ZNC Configuration first. When you are ready run:
znc --makeconf
Now we are going to install a runit service which allows a non-root user to create runit services because ZNC strongly advices not to run ZNC as root, and for good reason. If this sounds confusing see runit user-specific services.
mkdir -p ~/service/service ~/service/sv
cd /etc/sv
sudo mkdir -p runsvdir-$USER/log/main
cd runsvdir-$USER/
sudo -E sh -c 'echo "#!/bin/sh -e\nexec 2>&1\nexec chpst -u$SUDO_USER runsvdir $HOME/service/service" > run'
sudo -E sh -c 'echo "#!/bin/sh -e\nexec chpst -u$SUDO_USER svlogd -tt ./main" > log/run'
sudo chmod 755 run log/run
sudo chown $USER:$USER log/main
sudo ln -s /etc/sv/runsvdir-$USER /etc/service
# Wait for service to start
sleep 5
sudo sv status runsvdir-$USER
If everything went OK you will get a message saying the service is running. Now we can install a runit service which runs ZNC as our user.
cd ~/service/sv
mkdir -p znc/log/main
cd znc
sh -c 'echo "#!/bin/sh -e\nexec 2>&1\nexec znc -f" > run'
sh -c 'echo "#!/bin/sh -e\nexec svlogd -tt ./main" > log/run'
chmod 755 run log/run
ln -s ~/service/sv/znc ~/service/service/znc
# Wait for service to start
sleep 5
sv status ~/service/service/znc
Again, If everything went OK you will get a message saying the service is running. We are now done with the server setup unless you want to follow the process for removing duplicate timestamps described below.

Pidgin setup

Now we need to add the account created in ZNC to pidgin. Since ZNC requires a username for every IRC server you connect to, I chose freenode as the username for the account that is going to connect to irc.freenode.com. Start Pidgin and go to Accounts->Manage Accounts->Add. You will see a screen like this:



Fill in the fields accordingly. Username is the ZNC username you created (freenode in my case), Server is the domain name or IP address of the ZNC server, and password is the password for the user just described. Check the 'Remember password' option if you want to make your life easier but slightly less secure. Next click on Advanced. You will see a screen like this:


Again, fill in the fields accordingly. Port is the port where your ZNC server runs and Username is the same username you used for the previous step (freenode in my case.) If you enabled SSL in your ZNC server check 'Use SSL.' Click Save. If everything worked you will now be connected to the the IRC server you chose in your ZNC configuration (irc.freenode.com in my case) and any chat rooms you setup for that server will open up automagically in Pidgin.

Removing duplicate timestamps

Eventually, as you log on to Pidgin and see the replay of the backlog, you will see that the messages from ZNC come back with timestamps. This gets annoying since Pidgin also prints out timestamps and now you have two sets of timestamps for every line in the replay. Fortunately, there's a Pidgin plugin that fixes this problem. There are two steps for setting this up.

Server setup

First, let's change the timestamp format in the ZNC configuration. It turns out that this plugin only recognizes ZNC timestamps that are in the format [%Y-%m-%d %H:%M:%S], and, at least for me, the default timestamp format in the ZNC configuration is [%H:%M:%S]. To correct this use the webadmin interface provided with ZNC. In your browser go to http(s)://<znc_server>:<znc_port>. After logging in with your admin user go to 'Your Settings' and scroll all the way to the bottom. Change the 'Timestamp Format' field to [%Y-%m-%d %H:%M:%S] and check the option 'Append Timestamps.' If 'Prepend Timestamps' is checked then uncheck it. When you are done, it should look something like this:


Click Save to accept the changes.


Client setup

The second step is to setup the Pidgin plugin on the client machine. Start by adding the plugin's PPA and installing the plugin.
sudo add-apt-repository ppa:konradgraefe/pidgin-plugins
sudo aptitude update
sudo aptitude install pidgin-znchelper
Now restart Pidgin and go to Tools->Plugins. Scroll to the bottom and check the box next to 'ZNC Helper'. Next, click on 'Configure Plugin'. You will see a screen like this:


Check the box next to your ZNC user to activate the plugin for it and click Close twice.

That's it. Feel free to comment, complain and tell me where I went wrong.