Mcabber notifications

Mcabber is a great console based xmpp client with e2e (pgp and otr). By default the only way to see that you got a new message is the urgent hint set by mcabber and shown by awesome if configured correctly. I used gajim before and liked the notifications via naughty. This text is about enhancing your mcabber and awesome to inform you about your latest chat messages and status changes of your contacts. So lets get naughty ;)

mcabber configuration
mcabber has support for an external hook invoked if something happened. We use this for our notification. The relevant parts are the following:

set events_command = ~/.mcabber/event.sh set events_ignore_active_window = 0 set event_log_files = 1 set event_log_dir = /tmp

As you can see we need a shellscript wrapper that pushes the bits to awesome.

~/.mcabber/event.sh echo "mcabber_event_hook('$1', '$2', '$3', '$4')" | awesome-client
 * 1) !/bin/sh

Just an information about security. The shellscript above can easily be exploited locally e.g.: ./event.sh "');awful.util.spawn('xterm'); --"

However the data sent by mcabber cannot contain the tick char (') that would be needed for this exploit. The only possible data chunk may containing illegal data would be the node of the jid, but again the tick char is forbidden.

Anyway if you really dont trust incoming data you could replace the tick char everywhere with a sed command e.g. echo "mcabber_event_hook('`echo $1 | sed -e "s/'/_/g"`', ...

awesome configuration
Next you have to set up your rc.lua

First add the profiles for status changes naughty.config.presets.online = { bg = "#1f880e80", fg = "#ffffff", } naughty.config.presets.chat = naughty.config.presets.online naughty.config.presets.away = { bg = "#eb4b1380", fg = "#ffffff", } naughty.config.presets.xa = { bg = "#65000080", fg = "#ffffff", } naughty.config.presets.dnd = { bg = "#65340080", fg = "#ffffff", } naughty.config.presets.invisible = { bg = "#ffffff80", fg = "#000000", } naughty.config.presets.offline = { bg = "#64636380", fg = "#ffffff", } naughty.config.presets.requested = naughty.config.presets.offline naughty.config.presets.error = { bg = "#ff000080", fg = "#ffffff", }

After that we add the function that handles the mcabber hook events. You have to change the variable "muc_nick" if you want awesome to hide your own MUC messages but only incoming messages.

muc_nick = "your_muc_nickname"

function mcabber_event_hook(kind, direction, jid, msg) if kind == "MSG" then if direction == "IN" or direction == "MUC" then local filehandle = io.open(msg) local txt = filehandle:read("*all") filehandle:close awful.util.spawn("rm "..msg) if direction == "MUC" and txt:match("^<" .. muc_nick .. ">") then return end naughty.notify{ icon = "chat_msg_recv", text = awful.util.escape(txt), title = jid }       end elseif kind == "STATUS" then local mapping = { [ "O" ] = "online", [ "F" ] = "chat", [ "A" ] = "away", [ "N" ] = "xa", [ "D" ] = "dnd", [ "I" ] = "invisible", [ "_" ] = "offline", [ "?" ] = "error", [ "X" ] = "requested" }       local status = mapping[direction] local iconstatus = status if not status then status = "error" end if jid:match("icq") then iconstatus = "icq/" .. status end naughty.notify{ preset = naughty.config.presets[status], text = jid, icon = iconstatus }   end end

As you can see I use the gajim icons for the notifications, you may also want to use them. In the script above I also match for "icq" which is my icq transport, so the icq icons will be used but not the xmpp ones.

Icons
Add this to your rc.lua naughty.config.icon_dirs = { os.getenv("HOME") .. ".config/awesome/naughtyicons/", "/usr/share/pixmaps/" }

Create the directory ~/.config/awesome/naughtyicons/ extract the contents of the tarball (this link does not work) there.

Event Alternative
A basic alternative is the following MCabber event script:

--Pnevma 05:51, 29 March 2010 (UTC) Warning: This was made by a user with minimum understanding of Bash and LUA, it may do something bad! Could a more adept user check it and remove this warning/script if necessary? I've been using it for a while and everything seems fine.
 * 1) !/bin/sh

if [ $1 = "MSG" ]; then case "$2" in   IN)      if [ -n "$4" -a -f "$4" ]; then        message="$(cat $4)"        echo 'naughty.notify({title = "'$3'", text = "'"$1: $message"'"})' | awesome-client        rm $4      fi      ;;    MUC) if [ -n "$4" && -f "$4" ]; then message="$(cat $4)" echo 'naughty.notify({title = "'$3'", text = "'"$1: $message"'"})' | awesome-client rm $4 fi     ;; OUT)       echo > /dev/null      ;;  esac elif [ $1 = "STATUS" ]; then  case "$2" in    _) echo 'naughty.notify({title = "'$3'", text = "'"$1: has signed off."'"})' | awesome-client ;;   O)      echo 'naughty.notify({title = "'$3'", text = "'"$1: is now online."'"})' | awesome-client     ;;    F)      echo 'naughty.notify({title = "'$3'", text = "'"$1: is chatty."'"})' | awesome-client ;;   A)      echo 'naughty.notify({title = "'$3'", text = "'"$1: has gone away."'"})' | awesome-client     ;;    N)      echo 'naughty.notify({title = "'$3'", text = "'"$1: is now extended away."'"})' | awesome-client ;;   D)     echo 'naughty.notify({title = "'$3'", text = "'"$1: does not want to be disturbed."'"})' | awesome-client     ;;    I)      echo 'naughty.notify({title = "'$3'", text = "'"$1: is now invisible."'"})' | awesome-client ;;   ?)      echo 'naughty.notify({title = "'ERROR'", text = "'"Something broke."'"})' | awesome-client     ;;    X)      echo 'naughty.notify({title = "'$3'", text = "'"$1: has a request."'"})' | awesome-client ;; esac elif [ $1 = "UNREAD" ]; then echo 'naughty.notify({title = "'$1'", text = "'"There are $2 new messages."'"})' | awesome-client fi