Posts Tagged ‘bitlbee’

Bitlbee and Emacs

Friday, October 16th, 2009

As part of switching to bitlbee as my primary IM client, I ended up making a lot of customizations to my erc configuration, both for general use and for bitlbee-specific stuff. I didn’t really have any beforehand, since I don’t use IRC very much, but these make it a lot more usable with bitlbee. Bitlbee can be pretty annoying at the start; these help to make it much less so. Most of the general ERC customizations came from the emacs-Viki, but most of the bitlbee-related code is mine.

The first customization I made was to set the header-line of disconnected buffers to be a different face than normal. The header line is just the top line of the buffer; some modes, such as ERC, use it for displaying information about the current context. This just makes it easier to tell which ERC buffers are still connected to the server.

(defface erc-header-line-disconnected
  '((t (:foreground "black" :background "indianred")))
  "Face to use when ERC has been disconnected.")
 
(defun erc-update-header-line-show-disconnected ()
  "Use a different face in the header-line when disconnected."
  (erc-with-server-buffer
    (cond ((erc-server-process-alive) 'erc-header-line)
          (t 'erc-header-line-disconnected))))
          (setq erc-header-line-face-method 'erc-update-header-line-show-disconnected)
 
(setq erc-header-line-face-method 'erc-update-header-line-show-disconnected)

I like to log my IM messages. I often have useful discussions with people, or receive information from them, that I want to refer to later. The following sets my log directory and updates them whenever the ERC buffer is updated, ensuring I never lose information.

(setq erc-log-channels-directory "~/.emacs.d/logs/")
(setq erc-save-buffer-on-part nil)
(setq erc-save-queries-on-quit nil
      erc-log-write-after-send t
      erc-log-write-after-insert t)

IRC in general will give a lot of messages that you don’t care about, and there are some bitlbee-specific ones as well. erc-hide-list is a list of types of messages that ERC will hide, and erc-ignore-unimportant is a function I wrote to suppress other information I don’t want to see. This includes mode changes for people and reconnection attempts when an account is already online.

(setq erc-hide-list '("MODE"))
(defun erc-ignore-unimportant (msg)
  (if (or (string-match "*** localhost has changed mode for &bitlbee to" msg)
          (string-match "Account already online" msg)
          (string-match "Unknown error while loading configuration" msg))
      (setq erc-insert-this nil)))
(add-hook 'erc-insert-pre-hook 'erc-ignore-unimportant)

Speaking of reconnection attempts when an account is online, I have ERC automatically connect me to my accounts whenever I log on as well as every 60 seconds. This simulates the behaviour of other IM clients, which will auto-reconnect when disconnected.

(defvar bitlbee-password "<SECRET>")
(defun bitlbee-identify ()
  "If we're on the bitlbee server, send the identify command to the
 &bitlbee channel."
  (when (and (string= "localhost" erc-session-server)
             (string= "&bitlbee" (buffer-name)))
    (erc-message "PRIVMSG" (format "%s identify %s"
                                   (erc-default-target)
                                   bitlbee-password))))
(add-hook 'erc-join-hook 'bitlbee-identify)
 
(defun bitlbee-connect ()
  (interactive)
  (save-window-excursion
    (when (get-buffer "&bitlbee")
      (switch-to-buffer "&bitlbee")
      (erc-message "PRIVMSG" (concat (erc-default-target) " identify " bitlbee-password))
      (erc-message "PRIVMSG" (concat (erc-default-target) " account on 0")
      (erc-message "PRIVMSG" (concat (erc-default-target) " account on 1"))))))
(setq bitlbee-reconnect-timer (run-with-timer 0 60 'bitlbee-connect))

The ‘blist’ command for bitlbee will list your buddies and their statuses. However, by it doesn’t do any color-coding for your Friends who are online vs who are away, so I had to add this. It isn’t very difficult; erc-keywords is a list of keyword-face pairs that the keyword is matched with. All you need to do to perform any type of highlighting is be able to match the message you want highlighted with a regular expression.

(setq erc-keywords '((".*Online.*" (:foreground "green"))
                     (".*Busy" (:foreground "red"))
                     (".*Away" (:foreground "red"))
                     (".*Idle" (:foreground "orange"))
                     ))

One of the reasons I switched from Pidgin to Bitlbee was that Pidgin was no longer notifying me of new messages; I decided to try seeing if I could implement this for bitlbee. It actually turned out to be pretty easy, although there is one problem: it only occurs for messages sent to the public channel, not private messages, so it won’t inform me when someone starts a conversation with me. I’m still looking into how to fix this.

(defun erc-notify-on-msg (msg)
  (if (string-match "nflath:" msg)
      (shell-command (concat "notify-send \"" msg "\""))))
(add-hook 'erc-insert-pre-hook 'erc-notify-on-msg)

The last customization I have to bitlbee is so that I don’t have to type the user I’m addressing each time in the public channel. Usually, you have to prepend each message with user: in order for it to be sent to them; this code will auto-prepend messages with the last user you addressed. It’s a work in progress, as a lot of cases I don’t want this to happen - for example, when I’m listing my buddies - but it’s pretty good right now.

(setq bitlbee-target "")
(defun bitlbee-update-target (msg)
  (if (string-match "\\([^:]*: \\)" msg)
      (setq bitlbee-target (match-string 1 msg))
    (if (not (or
              (string-match "account" msg)
              (string-match "help" msg)
              (string-match "identify" msg)
              (string-match "blist" msg)))
        (setq str (concat bitlbee-target msg)))))
(add-hook 'erc-send-pre-hook 'bitlbee-update-target)

I generally want to be logged into IM, so I just start it up on emacs start.

(erc :server "localhost" :port "6667" :nick "nflath" :password bitlbee-password)

If you have any other customizations or improvements to suggest, please let me know in the comments.

Bitlbee

Friday, October 2nd, 2009

I usually use pidgin for my instant messaging, but recently it has stopped alerting me when I get messages. I wasn’t entirely sure why, but it meant I kept missing messages from people and was incredibly annoying. A combination of this and the fact that I wished to be able to stick in Emacs for chatting sent me out on a search for a new messaging program.

Emacs itself has a few packages that claim to do instant messaging support, bust most are either in early stages, flat-out don’t work, or don’t support the protocols I need. TNT, for example, works quite well - but only for AIM. Since in most cases I use either MSN or Gmail, that strikes TNT out. Unfortunately, it seemed I was going to have to either switch to another external IM client or just keep using Pidgin. Then a friend of mine told me about Bitlbee.

Bitlbee is a program that will create an IRC server that you can use to communicate via MSN, Jabber, and a few other protocols. You can use it to MSN via a terminal running IRSSI; I decided to use ERC, Emacs’ built-in IRC client. The bitlbee we page is located here; go there if you need to report a bug, or want more information than is provided in this post.

Installing Bitlbee is easy, if you are on Ubuntu. A simple ’sudo apt-get install bitlbee’ will install it. I’m not entirely sure how to do it on other operating systems, but the source is provided so in the worst case scenario you can just build it yourself. Once this is done, the command ’sudo /etc/init.d/bitlbee start’ will start the IRC server. Connect to this on localhost:6667 and you are ready to go.

Once you join the IRC server, you will need to register your account. Do this by sending the message ‘register pass’, where pass is your desired password. After this, you can start adding accounts. Adding a MSN account is done by ‘account add msn username@userdomain pass’. Gmail accounts require two commands to add: The first is ‘account add jabber user@gmail.com pass’ and the second is ‘account set 1/server talk.google.com’ The 1 in the previous command may differ in your case: find which number you should be using by sending ‘account list’. Connecting to your accounts is done with ‘account on #’. Once you are logged in, you probably want to save your configuration with ’save’.

Once you have connected to your accounts, you can see all your buddies and their statuses with ‘blist’. Messaging them can be done in two ways, the first of which is to prefix the message to them with ‘username: ‘. In this case, replies they send to you will appear in this main channel. If you want a private message to be opened, you can message them using the standard ‘/msg user’ command. This is probably what most users will want; I haven’t used bitlbee with ERC enough to know which I prefer.

Of course, you will probably want to add new contacts eventually. This is done with the ‘add’ command. To use it, just ‘add # user’, where # is the number of the connection you want to add the user to and user is their username. The other command you’ll want to know aobut at the start is ‘rename’, which will allow you to alias users with ‘rename user alias’. Since many people have usernames that don’t make it obvious who they are, this command is pretty much required for a chat application.

That is everything I needed to do to get set up with Bitlbee and start chatting. To access its help system, use ‘help’ in the bitlbee server. There are a few other things I want to investigate that aren’t a huge priority for me: the ability to merge users and to export my aliases are two of them. It doesn’t look like there is a way to export data from bitlbee, although there is a bug report filed. The ability to merge users is probably not possible in bitlbee itself, but it’s not a big deal and I can probably just code something in elisp to handle that case.