Build Monitoring Widgets with Ruby and BitBar

By Jonathan Cutrell


Ruby developers are used to finding incredibly useful open source projects packaged as gems. In this tutorial, we’ll take a look at BitBar, an open source project that isn’t built in Ruby, but when combined with a small bit of Ruby can be incredibly powerful.

While the original project is no longer actively maintained, an updated fork of the project can be found here:

BitBar provides Mac OS X users an easy way to create a menu bar item from the standard output of a script. I’ll show you how to create a simple site ping monitor, and then we’ll create a Twitter follower counter.

Installing BitBar

To install BitBar, visit the GitHub repository at Download the zip file (the button to download is in the righthand sidebar). Inside the archived folder, you will find a “Releases” folder, which holds the file. Put this in your Applications directory. Opening this application launches BitBar.

How BitBar Works: File Structure

BitBar is a simple application that runs all shell scripts in a given directory on an interval that is determined by the filename. Of course, you should be very careful when adding scripts to BitBar, especially if you are adding a low interval time.

To run a given file every 5 minutes, the naming structure would look something like this:

Of course, you will also want to make your scripts executable. Note that BitBar refers to these scripts as “plugins” in their documentation.

How BitBar Works: Script Output

In order to add visible text to your BitBar plugin, you will need to send output to STDOUT. In Ruby, this is simply the output of puts. By default, BitBar will cycle through each line of the output, unless you output the specific string “—“; anything after this line will show up in a dropdown after you click the BitBar item in the menu bar.

BitBar also allows changing the text color and responding to clicks. Clicks can either open a URL or trigger another shell script, and can be set to do so in the background.

Here’s a simple Ruby script that would create a link to StackOverflow in BitBar:

url = ""
puts "Go to StackOverflow | href=#{url}"

Notice the | separating the outputted text and the parameters for clicking. The href parameter tells BitBar to open this URL when clicked. Here’s a more complex example, showing some red text that triggers another executable script:

puts "Run My Script | color=#ff0000 bash=/path/to/your/"

Of course, once again, you’ll want that script to be set to be executable using chmod.

Finally, if the script takes parameters, you can add them using param1, param2, and param3. If you would like to execute the bash script in the background on click, set the parameter terminal= to false. For example, you might want to use the current time as a parameter for a script that runs in the background:

current_time =
puts "Run My Script | color=#ff0000 bash=/path/to/your/ terminal=false param1=#{current_time}"

Creating a Site Monitor

Now that we know how BitBar works, let’s create a site monitor in Ruby that we can then use with BitBar. As a disclaimer, you should know that only checking a site’s status from your own computer may not give you the full picture. To really know if your sites are down, use monitoring services and sites like But this little widget will provide a quick glance and signal potential problems as they occur.

The required behavior is a bullet point that is red or green, depending on the status of a list of sites. I want to be able to keep that list of sites in an easy-to-update YAML file. When one of the sites goes down, I want to be able to click the bullet point in my menu bar and see the failing site. I also want to be able to click that menu item to visit the site in my browser.

Let’s get started with some Ruby!

The Site Checker Class

First, we’ll create a simple class called SiteChecker:

# /path/to/bitbar_plugins/site_checker/site_checker.rb
require 'yaml'
require 'net/http'

class SiteChecker

  def initialize(sites)
    @sites = sites

  def up?(server, port=80)
    http = Net::HTTP.start(server, port, {open_timeout: 5, read_timeout: 5})
    response = http.head("/")
    response.code == "200"
  rescue Timeout::Error, SocketError

  def run
    results = {} {|s| results[s] = up?(s) }

Great! Now we have a simple Ruby class that can check any given site, can be initialized with a list of sites to check, and returns a hash of results.

Next, let’s write the actual BitBar plugin that will use the SiteChecker class. Add a folder to the BitBar plugins folder called site_checker and save the site_checker.rb file there. Next, create a file called, and place it in the BitBar plugins directory. Here’s what that file looks like:

#!/usr/bin/env ruby
# Note: the ruby path above should point to your Ruby installation.
# You can verify this by checking `which ruby`
$:.unshift File.dirname(__FILE__)
require 'site_checker/site_checker.rb'
require 'yaml'
def run
  sites = YAML.load_file(File.join(__dir__, 'site_checker/sites.yml'))["sites"]
  site_checker =
  results =
  if results.values.include? false
    puts "• | color=#ff0000"
    puts "---" {|key, val| val == false }.keys.each do |site|
      puts "#{site} down | href=http://#{site}"
    puts "• | color=#82B021"

This simple script formats the output of our SiteChecker class for BitBar to use. Finally, we need to make sure we’ve added our sites.yml file inside our site_checker directory:

  - ""
  - ""
  - ""

Make sure your site uses only its domain name (without any protocols).

The final step is to make the script executable. You can do this by running chmod +x The resulting file structure should look like this:

├── site_checker
│   ├── site_checker.rb
│   └── sites.yml

Twitter Follower Count

Next, let’s do something a bit more involved. We’ll show how many users we are following and how many users are following us on Twitter.

The first step is to register an application with Twitter. Once you’ve followed the steps and successfully created your project, you will need to locate the API keys and access tokens for the application.

Next, create a folder inside your BitBar plugins directory called twitter_counter, and an associated plugin file called

Inside of the newly created twitter_counter folder, create an account_detail.rb file. We will use this to create a simple class that will return follow count information for a Twitter account.

The AccountDetail class looks like this:

require 'twitter'
class AccountDetail
  attr_accessor :user

  def initialize(username)
    @client = create_client
    @user = @client.user(username)

  def followers
  def followings


  def create_client do |config|
      config.consumer_key        = "YOUR CONSUMER KEY"
      config.consumer_secret     = "YOUR CONSUMER SECRET"
      config.access_token        = "YOUR ACCESS TOKEN"
      config.access_token_secret = "YOUR ACCESS TOKEN SECRET"

Make sure you run gem install twitter if you have not already. In the previous example, we used built-in libraries. Twitter is a third-party gem that must be installed before this class will work.

The AccountDetail class essentially wraps a very small subsection of the Twitter gem for our use case. Next, edit the file to look like this:


$:.unshift File.dirname(__FILE__)
require 'twitter_counter/account_detail'

def run
  @account_detail ='your_twitter_name')
  puts "#{@account_detail.followers} followers"
  puts "#{@account_detail.followings} following"

Finally, edit the permissions on the script to make it executable. As long as everything is set up correctly, you should see a simple widget in the menu that cycles between your “follower” count and your “following” count. Of course, we could use much more of the Twitter API to do even more interesting things!


While this tool may not be used in a project you are intending to ship to your clients, it certainly can be a useful and fun tool to create your own native applications. Here are some ideas for more projects using BitBar:

  • Build status indicator (integrating with something like CircleCI or Codeship)
  • Stripe sales ticker
  • A simple easy-to-access action list for performing common scriptable tasks or macro-functions
  • Visual graphing of things with something like (Spark)[]

Share your ideas with us here! Happy hacking!



Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in Ruby, once a week, for free.