Friday, November 21, 2008

Give a Twitter spot to your website

Saturday, April 21, 2007, 19:38
This news item was posted in Ruby On Rails category and has 1 Comment so far.

Long time, no blog, but it’s changing… My little experiment with Ruby On Rails, heardontv.com, is doing well.. well let’s say there are users registering every day and contributing to the site through new songs, comments, rating, link submission…

I’ve configured the site to receive an email every time a new user register, a comment is posted. It allows the moderators to monitor the content posted by the users and I can keep an eye on the activity (fortunately today email clients have good rule system to route these emails to a specific mailbox).

This activity is not top-secret information and I wanted to have it available to everyone. Sure I could have just put in place a page on the site with a log of the activity for everyone to look at but I decided to follow an other path.

Tracking the activity of a website is a bit like asking your website “hey you, what are your doing?” and today there is one place where tons of people answer this question every day, twitter. And so I decided heardontv will have its own twitter space and will be micro-blogging its activity on twitter.

And here comes the Rails twitter library doing exactly this. I based the code on two articles, the twitter API and a good article about twittering from Ruby.

Whenever there is something interesting to be twittered in heardontv, I just do something like:

  Twitter::status(comment.author_or_user + " says " + comment.comment + " in " +
      @episode.tvshow.name + " at " +
      url_for(episode_url(:name => @episode.tvshow.name, :season => @episode.season, :title => @episode.title), :only_path => false))

The message does not get twittered immediately but gets added to a queue. There is a cron process set up on the server to process the messages (see the twitter.rb script below) at regular intervals.

The result is here. Now I - every one indeed - can track heardontv activity. To be honest not everything makes it to twitter, there is some randomness to decide if we “twit” or not.

Here are the files making the plugin so you can give a twitter spot to your website :)

vendor/plugins/twitter_status/lib/twitter.rb

require 'net/http'
require 'uri'

module Twitter

  def self.init(config_file = 'twitter.yml')
    @@config = YAML::load_file("#{RAILS_ROOT}/config/#{config_file}")
  end

  # store a new twitter status in the database
  def self.status(message)
    status = TwitterMessage.new
    status.message = message
    status.save
  end

  # publish the most recent messages
  # publishing stops if one error occurs while publishing
  def self.publish
    messages = TwitterMessage.find(
                                   :all,
                                   :conditions => 'published = false',
    :order => 'created_at ASC')
    TwitterMessage.logger.info("Twitter::starting to publish " + messages.size.to_s + " messages")
    messages.each do | message |
      if (!process(message))
        message.logger.info "Twitter::stopping publishing after error"
        break
      end
    end
    TwitterMessage.logger.info("Twitter::publish completed")
  end

  # process a single message
  # mark the message as published
  def self.process(message)
    begin
      message.logger.info "Twitter::process(" + message.message + ")"
      url = URI.parse('http://twitter.com/statuses/update.xml')
      req = Net::HTTP::Post.new(url.path)
      req.basic_auth config['email'], config['password']
      req.set_form_data({ "status" => message.message })

      begin
        res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }

        case res
        when Net::HTTPSuccess, Net::HTTPRedirection
          if res.body.empty?
            # Twitter is not responding properly
            message.logger.info "Twitter::process error EMPTY BODY"
            return false
          else
            # Twitter update succeeded
            message.published = true
            message.save
            message.logger.info "Twitter::process success"
            message.destroy
            return true
          end

        else
          # Twitter update failed for an unknown reason
          message.logger.info "Twitter::process error UNKNOWN " + res.value
          return false
        end

      rescue
        # Twitter update failed - check username/password
        message.logger.info "Twitter::process error FAILED"
        return false
      end

    rescue SocketError
      # Twitter is currently unavailable
      message.logger.info "Twitter::process error UNAVAILABLE"
      return false
    end
  end

  protected
  def self.config
    @@config
  end
end

vendor/plugins/twitter_status/lib/twitter_message.rb

class TwitterMessage < ActiveRecord::Base
end

vendor/plugins/twitter_status/init.rb

require 'twitter'

Twitter.init

config/twitter.yml

email: theemailyouregisteredwith@twitter.com
password: thepasswordyouuse

script/twitter.rb

#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/environment'

Twitter.publish

the database migration

class AddTwitter < ActiveRecord::Migration
  def self.up
    create_table :twitter_messages, :force => true do |t|
      t.column :message, :text
      t.comµçVÖâ§V&Æ—6†VB¦&ööÆVâ¦FVfVÇBÓâfÇ6P¢Bæ6öÇVÖâ¦7&VFVEöB¦FFWF–ÖR¦çVÆÂÓâfÇ6P¢Væ@¢Væ@ ¢FVb6VÆbæF÷và¢G&÷÷F&ÆR§Gv—GFW%öÖW76vW0¢Væ@¦Væ@

You can leave a response, or trackback from your own site.

One Response to “Give a Twitter spot to your website”

  1. Andrea said on Monday, April 23, 2007, 15:47

    That’s really nice! I didn’t think about using Twitter in this way.

    Thanks.

Leave a Reply