Gw

Ruby on Rails Facebooker Notifications using Cron

January 18, 2010


For those of you who don’t know, Facebooker is a Ruby wrapper over the Facebook REST API. Thanks to its contributors, building Facebook applications in Ruby has been made exceedingly simple.

The goal of this post is to send a notification to your Facebook application’s users using Facebooker and running cron jobs. Let’s get started.

Assumptions

1) You’ve got a Facebook application up and running using Facebooker
2) Your app requires access to a Facebook user’s profile
3) Your running OSX 10.5 or higher

If I’ve assumed too much, there is an exceptional Facebooker tutorial that walks you through how to install and initiate a Facebook application using Facebooker that can be found here: http://apps.facebook.com/facebooker_tutorial/

Setup

Install a gem called whenever:


# config/environment.rb
config.gem 'javan-whenever', :lib => false, :source => 'http://gems.github.com'

$ cd /my/rails/app
$ sudo rake gems:install

For most of us, writing cron jobs isn’t terribly exciting nor is the syntax particularly friendly. The whenever gem allows you to write cron jobs using a clean Ruby syntax.

Next, we’ll want to “wheneverize” our application. All this does is create an initial RAILS_ROOT/config/schedule.rb file for us to work from, complete with some great examples.


$ cd /my/rails/app
$ wheneverize .

Sending Facebook Notifications from Your Rails Application

There are two ways a Facebook application can send notifications: user-to-user and application-to-user. For our purposes, we’ll be working with application-to-user notifications. As the Facebook developer wiki notes, these are sent on the application’s behalf and do not require an active session.

Okay, moving on. Next, we’ll need to create a class method in the model you’d like to send notifications from.

Facebooker provides us with a method called send_notification that we’ll use to send our notifications. It takes two parameters: user_ids (an array) and some fbml. I’ll be using an Assignment model that reminds students of upcoming deadlines for a given course:


#app/models/assignment.rb

class Assignment < ActiveRecord::Base
  belongs_to :course  

  def self.send_assignment_deadline
    Facebooker::Session.create.send_notification([User.all.map(&:facebook_id).split(',')],"Holy Smokes, something is due today!")
  end
end

It’s more than likely that you’ll want your message to be dynamic, so here’s how to do that:


#app/models/assignment.rb
  def self.send_assignment_deadline
    self.each do |a|
      Facebooker::Session.create.send_notification([User.all.map(&:facebook_id).split(',')], "#{a.title} is due in #{a.course.title} on <b>#{a.due_date.to_date}</b>.")
    end
  end
 

Alright, lets load script/console and test this method.


$ script/console
>> Assignment.send_assignment_deadline
=> [#<Assignment id: 38, title: "Et Aliquam", due_date: "2010-01-16 07:03:47", course_id: 4, created_at: "2010-01-17 18:31:36", updated_at: "2010-01-17 18:31:36">]

Awesome, moving on.

Next, we’ll want to schedule some cron jobs to run using the RAILS_ROOT/config/schedule.rb file that wheneverize gave us.

At the top of your schedule.rb file, you have the option of setting the path to your Rails application. However, if you choose not to, the RAILS_ROOT will be used automatically.

Let’s write a cron job using the Ruby syntax provided by the whenever gem and I’ll explain it in a moment:


#config/schedule.rb
set :environment, RAILS_ENV 

every :monday, :at => "12:00 am" do
  runner "Assignment.send_assignment_deadline"
end

The every block is used to indicate how often you’d like your job to run. This can be set in seconds, minutes, hours, days, weeks, whatever you’d like. For example if I wanted the same job to run daily, I could define an every block that looks like this:


#config/schedule.rb
set :environment, RAILS_ENV 

every 1.day, :at => '12:00 am' do
  runner "Assignment.send_assignment_deadline"
end

Inside the block you’re able to define multiple command, rake, and runner tasks appropriately.

After your happy with your awesome job, execute the following command to update your local crontab file:


$ whenever --update-crontab rails_app_name

You can check its contents by running:


$ crontab -l

Note: If your trying to run this in production, you’ll want to update your crontab accordingly. To do this:


$ whenever --update-crontab rails_app_name --set environment=production

To edit the file, or create one if you don’t already have one, run:


$ crontab -e

And that’s it.

Your job(s) will run according to the specifications you’ve set out and be pushed to the users who have signed up for your Facebook application.

Notes

There are limitations put in place by Facebook as to the number of notifications you can send a user in a given week. You can get these details for your Rails applications details by running the Facebooker public instance method:


  get_allocation(integration_point)
  # Integration points include.. 
  # :notifications_per_day, :requests_per_day, :emails_per_day, :email_disable_message_location

Hopefully you’ve found this post useful in your endeavors to conquer the Ruby on Rails + Facebook world.

Credits:

Ryan Bates: Cron in Ruby
Whenever

2 Comments


Tyler Brown says:

Hmmm... I thought Facebook is doing away with app-to-user notifications?


Derrick Bradley says:

Hi Tyler.

Yes, you're correct. According to Facebook's developer roadmap, starting March 1, 2010, application-to-user and user-to-user notifications will be removed.

This post will be updated with alternative methods of sending information to users.


New Comment