The
37signals blog points out a simply Ruby
script for KDE that will give you a visual notification when a new message is posted to a
Campfire chat room.
I have modified that script to work for Gnome as well as KDE, and additionally a text console. I also made a few other additions such as:
- Allow you to specify a specific chat room(s) as a command line argument
- Multiple chats rooms can be monitored concurrently using threading
- Added the Campfire logo to the notifications
- Added some initial status messages to display login status, room topic, and current people in the room
- Display of the last 3 messages of the current day's transcript so you know what's going on without need to login
- Filter out ads
Here is my version of the script:
#!/usr/bin/env ruby
# == Synopsis
# Program to monitor a campfire chat room
# Modified from code provided at: http://www.snailbyte.com/2007/09/13/campfire-activity-notifier-for-kde/
#
# == Usage
# campfireMonitor [roomName] [roomName] ...
#
# == Author
# Steven Pothoven and Snailbyte Ltd.
require 'rubygems'
require 'tinder'
require "cgi"
class App
VERSION = '0.1.1'
def initialize arguments, stdin
# default settings
campfireSubdomain = 'mySubdomain'
campfireUsername = 'user@email.com'
campfirePassword = 'password'
roomNames = ['Room1', 'Room2']
if arguments.length > 0
roomNames = arguments
end
@ui = 'gnome'
@campfireIconPath = '/path/to/campfire-logo.png'
# define you favorite audio player and audio file here for audio notifications
@soundCommand = 'mplayer /usr/share/sounds/pop.wav'
@campfire = Tinder::Campfire.new campfireSubdomain
if @campfire.login campfireUsername, campfirePassword
alert nil, "CampfireMonitor", "Successfully logged in #{campfireUsername}"
@rooms = roomNames.collect { |roomName| @campfire.find_room_by_name roomName }
# remove any invalid rooms
@rooms.delete(nil);
@rooms.each do |room|
notify room, "CampfireMonitor", "Entered room."
notify room, "CampfireMonitor", "Topic is: #{room.topic}.".gsub("'","")
notify room, "CampfireMonitor", "Current users are: #{room.users}.".gsub("'","")
end
else
alert nil, "CampfireMonitor", "Failed to log in #{campfireUsername}"
end
end
# display notifcation message
def notify room, user, msg
if msg and msg.size > 0
msg = CGI.unescapeHTML(msg);
if @ui == 'kde'
system "dcop knotify default notify eventname \'#{user}\' \'#{''+@campfire.uri.to_s+'/room/'+room.id+'/'+room.name+': ' unless room.nil?} #{msg}\' '' '' 16 2"
elsif @ui == 'gnome'
system "notify-send -i #{@campfireIconPath} '#{user}' '#{''+@campfire.uri.to_s+'/room/'+room.id+'/'+room.name+': ' unless room.nil?} #{msg}'"
else
puts "#{room.name+':' unless room.nil?}#{user} - #{msg}"
end
end
end
# notify with sound
def alert room, user, msg
notify room, user, msg
if @soundCommand and @soundCommand.length > 0
system @soundCommand
end
end
def run
# first get any missed messages for today
threads = []
@rooms.each do |room|
thread = Thread.new do
room.transcript(Date.today).last(3).each do |m|
if !m.nil? and m[:message] and m[:message].size > 1
notify room, m[:person], m[:message].gsub("'","")
end
end
end
threads << thread
end
threads.each { |thread| thread.join}
# listen for more messages
threads = []
@rooms.each do |room|
thread = Thread.new do
notify room, "CampfireMonitor", "Waiting for messages..."
room.listen do |m|
if !m.nil? and m[:message].size > 1
unless m[:person] == "Ad"
alert room, m[:person], m[:message].gsub("'","")
end
end
end
end
threads << thread
end
threads.each { |thread| thread.join}
end
end
app = App.new(ARGV, STDIN)
app.run
I'm sure you can think of plenty more customizations such as command-line options for all the default settings, etc. But I wanted to keep it fairly simple.
One last thing, here is the cropped version of the Campfire logo I use for my notifications (campfire-logo.png):