Custom Audio Notifications in Campfire

Continuous integration is great. What’s even better is knowing immediately when the build is broken. The past couple of weeks we’ve been using the Jenkins Campfire Plugin to shoot a message into our team campfire room to let us know the status of our builds.

This was our first ‘bot’ in the room, and it felt a little weird. My teammate Ray created a persona for the Jenkins bot by associating it with the one and only Leroy Jenkins, changing the name of the bot from “Jenkins” to “Leeerrroooy J”. We also changed the sender name of the emails that Jenkins delivers to match.

But something was missing. Every time Leeerrroooy J. popped into our chat room with something to say, we’d all scream “Leeerrroooy Jenkins!”. I thought it would be awesome if we could have Campfire do this for us! But sadly, I couldn’t find any scripts to play audio in Campfire in response to a certain message.

So, I created one. Now, every time Leeerrroooy J. lets us know the status of a build, this will play. Makes me laugh every time.

Realizing this script could be useful in other contexts, I made it a tad more configurable, and put it on github. Right now, you can setup the script to play the sound at a given URL any time a specific word is said in the room, or when a certain user posts a message.

Hope you enjoy it as much as I do.

Script for Creating and Fetching Database Backups on Heroku

Heroku recently announced a new database backup solution, PG Backups, to replace their previous one, bundles. The basic plan allows you to store two database backups on Heroku’s servers for free. Since I already have a backup solution which allows me to store any number of backups, I decided to write a script to create database backups on Heroku, download them, and back them up using my existing solution. PG Backups is incredibly easy to use, and does all of the heavy lifting.

Kudos to Heroku for continuing to find ways to make their platform easier to use.

The script is below. Hope you find it useful.

Bugzilla and SMTP Authentication

The last few months I’ve been helping out in an effort to upgrade Shotokan Karate of America‘s membership management system. They’re rewriting the system from scratch, as the old system has grown to be unmaintainable. The code for the new system was about 85% complete when I signed up, so I offered to start testing the system while the sole developer working on the project finished up the code. There were no unit tests, so I figured that would be a good place to start. This naturally brought up the issue of how we would communicate problems and fixes, so I offered to install Bugzilla on my Linux box and suggested we use that.

It wasn’t until later that I found out that Bugzilla and SMTP Authentication do not get along (although I see that there is a fix in the pipeline). Bugzilla supports SMTP, but without authentication. It also supports sendmail, but my ISP isn’t too keen on people running their own mail servers, making the use of sendmail difficult. Since my ISP has a SMTP server for me to use, I figured I would use that. But, authentication is required on that server.

I toyed around with some ideas in an attempt to keep me from hacking the Bugzilla code. One involved parsing the data/mailer.testfile file (where mail is sent when the “testfile” mail option is set) for the To address and the email body, and sending the email via a custom script. But, that brought up some interesting race conditions if multiple users made a change that triggered an email at approximately the same time. We would need to periodically read that file to send the email, wiping out the contents afterward to avoid resending the same messages. If the timing was right, we could potentially wipe out a message that was never sent.

I took a look at the Bugzilla code, and found the module that was responsible for sending the email. The code was clean, and pretty easy to follow, even though I know very little perl. I found the point in the module where it calls out to the Mail Transport Agent to deliver the mail. I figured I could easily insert a call to a script to deliver the mail, using SMTP Authentication. That is exactly what I did. I modified BugMail.pm to include the “system” call below.

sub MessageToMTA {
    ....

    # --- Begin New Lines ---
    system('send-bugzilla-email.rb', $msg);
    # --- End New Lines ---

    $mailer->open($headers->header_hashref);
    print $mailer $body;
    $mailer->close;
}

$msg is a variable that contains the SMTP message to send. That message includes the To address, the subject of the email, and the body of the email. In other words, everything we would need to send the mail ourselves. I then wrote a ruby script to parse the message, and send the email. Here’s the script.

#!/usr/bin/ruby

require 'net/smtp'

from_address = 'username@my_isp.com'

# Break the message up into an array of strings
message_array = ARGV.first.split("\n")

# Pull out the To address and the subject
message_array[1] =~ /^To: (.*)$/
to_address = $1

message_array[2] =~ /^Subject: (.*)$/
subject = $1

# Delete some crap that we do not care about
4.times { |i| message_array.delete_at(0) }

# Combine what remains back into the body
body = message_array.join("\n")

message =  "From: Bugzilla <#{from_address}>\n"
message << "To: #{to_address}\n"
message << "Subject: #{subject}\n"
message << body

# Send the email
Net::SMTP.start('smtp.my_isp.com', 25, 'my_isp.com', 'username', 'password', :login) do |smtp|
  smtp.send_message message, from_address, to_address
end

File.open('/var/log/bugzilla_email.log', 'a+') do |file|
  file.puts("\n-----------------------------------------\n")
  file.puts(message)
end

Although not ideal, it does the job. And, if I do say so myself, it works quite well. I’ll be looking forward to upgrading to the new version of Bugzilla once it supports SMTP authentication. In the meantime, this will keep things rolling.