Blog

Download you twitter feed using Ruby on Rails with OAuth

Jonathon Horsman Jun 28 18 comments

Twitter provides an easy to use API allowing you to display your tweets on another web site or inside another application.

This article explains how to do this in a Ruby on Rails application using the new OAuth authentication mechanism.

It assumes you already have a Ruby on Rails application. I’m not going to go into tedious OAuth implementation details, just the results!

Register your application on the Twitter developer site

Create your application on Twitter, go to http://dev.twitter.com and click Register an app. Fill in the details giving it a name such as “My site tweet feed” and make it read only. The values you enter don’t really matter since no one else will be using your application, so long as a basic description and application website are set.

Copy your consumer key and consumer secret

After registration you should see your Twitter application settings page:

Twitter API settings page

Take note of the Consumer key and Consumer secret values, you will need to copy these into your application later.

Copy your access token

Click the My Access Token link on the right.

Twitter Client Token settings page

Note the Access Token and Access Token Secret, you will also need to copy these later.

Now you’re ready to modify your Ruby on Rails application to connect to the Twitter API.

Install the gem

There are a number of Ruby gems available for connecting to the API. I’ve had success with Grackle so that’s what we’ll use.

Install the Grackle gem:

gem install grackle

Create a table for storing tweets

Create a migration which will create a table for storing your tweets:

script/generation migration CreateTweets

Edit that migration, creating the table with 2 fields:

class CreateTweets < ActiveRecord::Migration
  def self.up
    create_table :tweets do |t|
      t.string :content
      t.datetime :created
    end
  end

  def self.down
    drop_table :tweets
  end
end

Create a model for the new table

Create a Tweet model, and add a method for downloading and storing the tweets:

require 'grackle'

class Tweet < ActiveRecord::Base

  MY_APPLICATION_NAME = "arctickiwi"
  
  """Connect to the Twitter API and pull down the latest tweets"""
  def self.get_latest
    tweets = client.statuses.user_timeline? :screen_name => MY_APPLICATION_NAME # hit the API
    tweets.each do |t|
      created = DateTime.parse(t.created_at)
      # create the tweet if it doesn't already exist
      unless Tweet.exists?(["created=?", created])
        Tweet.create({:content => t.text, :created => created })
       end
    end
  end
  
  private
  def self.client
    Grackle::Client.new(:auth=>{
      :type=>:oauth,
      :consumer_key=>'copy_from_twitter_consumer_key',
      :consumer_secret=>'copy_from_twitter_consumer_secret',
      :token=>"copy_from_twitter_access_token",
      :token_secret=>"copy_from_twitter_access_token_seceret"
    })

  end
end

Make sure you update your MY_APPLICATION_NAME, unless you want to get our tweets. Also enter your consumer key, consumer secret, token and token secret.

See if it works

You should now be able to download your latest tweets and store them in the database:

On the command line, run script/console

Tweet.get_latest

You should see a whole lot of text flash past the screen as the client hits the API, downloads the tweets and sticks them in the database.

If you get an error like this:

Grackle::TwitterError: get http://api.twitter.com/1/statuses/user_timeline.json?screen_name=arctickiwi => 
401: {"request":"/1/statuses/user_timeline.json?screen_name=arctickiwi","error":"Invalid / expired Token"}

it means one of your keys or secrets is wrong.

If it worked and you’re still in the console, you can see all your tweets now in the database:

Tweet.all

Display your tweets

As with any other model in Rails you can do whatever you want with them, like display them on a web page.

You will probably want links in your tweets to be real clickable links on your site, so here’s a helper method for to wrap links with anchor tags (in app/helpers/application_helper.rb)

module ApplicationHelper
  def display_content_with_links(tweet)
    tweet.content.gsub(/(http:\/\/[a-zA-Z0-9\/\.\+\-_:?&=]+)/) {|a| "<a href=\"#{a}\">#{a}</a>"}
  end
end

Create a cron job

You will want your tweets downloaded automatically all the time. I call a rake task from cron job which runs every 10 minutes for this.

In lib/tasks create a file called download_tweets.rake

task :download_tweets => :environment do
  Tweet.get_latest
end

and inside cron:

0,10,20,30,40,50 * * * * cd /path/to/my/app && RAILS_ENV=production /usr/bin/env rake download_tweets >> /path/to/my/app/log/cron.log 2>&1

I output to a log file so if something goes wrong one day I can see why.

FYI using the whenever gem is great for automatically creating cron jobs in conjunction with Capistrano

Good luck, and please leave a comment if you find this useful.

Comments //

Jon

Jon Sep 30

Any ideas how to run a cron job for a ASP.Net MVC site?

Jonathon Horsman

Jonathon Horsman Sep 30

Hi Jon

We don't use Windows or develop in ASP, but I think you want the Windows Scheduler under Control Panel.

HTH

nayak

nayak Nov 26

Hi ,
Thanks for this nice article

i am using twitter api for my site it was working fine but from past 1 week tweets are not displaying in my site when i checked the log file its showing fetching data from people which i have requested but it is not storing into my database i dont known where i am going wrong it is not displaying any error message also can u help me

Jonathon Horsman

Jonathon Horsman Nov 29

Hi Nayak

What happens when you run Tweet.get_latest in the Rails console?

I'd suggest posting your question on stackoverflow.com if you're having problems. You'll need to include your code and the log output too.

Jonno

Jon G

Jon G Jan 24

The line "unless Tweet.exists?(["created=?", created])" doesn't seem to be working for me. When I run "Tweet.get_latest" in the console, it creates the same tweet twice. Any reasons why this could be?

I think the problem is I don't really understand the breakdown of the line. What does the "created=?" (checks to see if it's already been created I'd imagine?) but then what does the ", created" do after it?

Jonathon Horsman

Jonathon Horsman Jan 24

Hi Jon

That "exists" line checks if a tweet has already been created with the same date/time (created is a timestamp), since that's how I'm uniquely identifying tweets.

However you could probably use the id_str parameter instead since that's probably more appropriate for uniquely identifying tweets.

Hope this help

Jonno

Tyler Breland

Tyler Breland Feb 10

Hi, I loved the post, but I am having an issue grabbing the profile_image_url. What I've done is just added a new migration which created an :avatar column in the Tweet table then I added :avatar => t.profile_image_url, in the create! hash. Grackle isn't pulling it, and according to the api, I am using the right method. Any thoughts? I don't see why this wouldn't work.
-Tyler

Jonathon Horsman

Jonathon Horsman Feb 11

Hi Tyler

Looks like the profile_image_url belongs to the 'user' associated with the tweet.

So in order to get the profile image URL you need to do :avatar => t.user.profile_image_url

Hope this helps

Jonno

geof

geof Jul 06

very nice tutorial! I also saw another related gem, tweetstream which looks very promising.

Stephen McCurry

Stephen McCurry Apr 13

Very helpful thanks. I used the Twitter Gem but was able to follow this example easily and adapt. It is surprising how few good examples there are of doing this basic Twitter integration.

dress an evening wedding

dress an evening wedding Oct 05

Espousals melody is all a passage out of taste. picking a vast melody using the rig or rite is very transverse that you pulling of your celebration with out a stick! There are very several completely different factors to some marriage celebration rite and marriage celebration reception which make secure it is out and out. The few should look in any way factors from the great day time to have a title to the force to make certain which they have every little thing fitted to go. just one this species of outcome that should disentangle to be determined upon former in the direction of characteristic celebration could it may be be the species of marriage celebration melody that will most in all probability be uncompounded body from the day. The drawn out-confine bride and valet will need to look at marriage celebration Dressesmusic for equally the marriage celebration rite and marriage celebration reception.

sac longchamp 4 x 4

sac longchamp 4 x 4 Oct 17

Quand le jour des enfants arrivent, beaucoup d'enfants demandent à leurs parents pour le longchamp mickey comme Mickey gifts.Both ainsi que Assailant sur le nez est s?r de devenir buddie votre enfant de bord de coupe optimales., Généré par le bien-connu créateur jouet qui couine. En conséquence, peuvent éprouver le moindre doute au sein de la haute qualité provenant de la marchandise. Boogie luminary de cinéma de Mickey a été faite par tout simplement des frais de fisher, et aussi Pricking l'exacte Longchamp sac 18 roues a été con?u par un bare Mattel. Très, il est facile de déclarer que la présente pourrait certainement être parmi les lutte contre une paire de makers.Are film cadeau que vous again avoir dérouté? Qui ont été con?us pour être trouvé parmi Transfert Super Mickey étoiles et même puissante tous les véhicules sac Longchamp? En conséquence, A c?té de ce point les avantages et les inconvénients de chaque élément. Regardez liste below.Odiferous tous les avantages Longchamp Van sac, en plus de consPros :: Préparé à couler, converser en, sacs chanel prix, indiquent les fissures, en vocalisant, avec séance d'exercice. Ninety composite keyword phrases.">Plut?t excitant: Préparé à-woful quelque chose en utilisant> Quatre-vingt dix phrases de mots clés complexes. Votre fils ou votre fille ne s'ennuie pas aussi extrêmement rapide à l'information ce processus automatique de robot regular.longchamp pas chere et puissante susceptible de "manger" petit produit que vous choisissez et insérer sur le composant droit à cette forme est, et puis aussi il sera probablement pinard l'avenir l'putting on à travers la part de nouveau form.Swindles body of troops de l'homme: 2. Stinky tout simplement joué boogie à travers des destinations.Longchamp Pas ChereL'homme n'a jamais errer près de la fracture, même si un Stinky leg.For cherche à être populaire uniquement à titre d'hommes, néanmoins Zumba Superstar Mickey sont également souhaitée par ladies.League aspects Super Mickey étoiles positifs et en plus disadvantagesPros:; Il est vraiment Mickey mouse , la kindness générée par Walt Disney. Un peu d'individus peut-être témoigné que chaque jeune fille ou un gar?on bare dans votre univers possèdent objectif qui sera affiché en utilisant Mickey. Vos enfants pourraient être vraiment tout à fait heureux dans le cas où ils deviendront ce play.pl of child spécifiques comme ce manner of writing, et ce marché est un gros gateau, le longchamp fait un bon travail.

Emilio Pucci Tunic Printed Single Sleeve Knit Silk Dress Orange Outlet

Emilio Pucci Tunic Printed Single Sleeve Knit Silk Dress Orange Outlet Oct 17

(real) Hong Kong family make straight up as if they come out from Practice, Elle magazines. Everyone make straight up elegantly in different styles. Fortunately, Hong Kong family take receive that they are union of multi cultures so there is no march of phraseology and all can be approved. We can see Hip Hop horde, sporty trend, big Nike T-shirt with limited issue Adidas shoes and skateboard go on foot along with hi-so girls who to the full covered by fire-brand names, Dolce-Gabbana skin-firmly held together make straight, Emilio Pucci brief coat|jacket}, serpent-skinned Jimmy Choo shoe and latest season Gucci handbag without any diverting melting.

Emilio Pucci Abstract Boat Neck Seven Sleeves Dress Royalblue Outlet

Emilio Pucci Abstract Boat Neck Seven Sleeves Dress Royalblue Outlet Oct 17

Hong Kong has been exposed on the make cultures from both Westerners and Easterners along with ruling fire-brand names like Louis Vuitton, Gucci, Prada, Bally, Loewe, Dolce-Gabbana, Balenciaga and also the brands from limited designers. These top global brands all have their branches in Hong Kong. Shopping areas can be found on almost every street as shopping can be started right away after coming out from any rail place. For instigation, Admiralty clime|realm|territory|domain|circle|area} is filled of make shops and big province stores which need more than a week to complete exploring.

emilio pucci dress gwyneth paltrow

emilio pucci dress gwyneth paltrow Oct 17

With the holidays approaching, there are maniple of pieces to originate you really perceive sexier as well as a formidable offer more mirthful than a ribbons align. These wonderful emilio pucci appears within a ribbons {clothes|align|vesture|outfit|suit|apparel} are characteristic to strike your fancy and might have your married man or boyfriend executing a coupled-take when you waltz in to the extension this hibernate!

multisite wordpress

multisite wordpress Jan 30

always i used to read smaller posts which as well clear their motive, and that is also
happening with this article which I am reading at this time.

Ayush

Ayush Feb 28

Hey I am getting this error when I enter Tweet.all in console

NameError: undefined local variable or method `wt' for main:Object
        from (irb):1
        from c:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-4.0.3
/lib/rails/commands/console.rb:90:in `start'

and when i enter Tweet.get_latest

NameError: undefined local variable or method `e' for main:Object
        from (irb):4
        from c:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-4.0.3
/lib/rails/commands/console.rb:90:in `start'

Ayush Gupta

Ayush Gupta Feb 28

And I am getting this error of SSL certificate which I am unable to resolve:

Grackle::TwitterError: get http://api.twitter.com/1.1/statuses/user_timeline.jso
n?screen_name=Test_App_OSM => 403: {"errors":[{"message":"SSL is required","code
":92}]}

Post a comment

  1. optional

Recent Tweets

Blog: The monumental Myspace cock-up: http://bit.ly/emgRKV
Tweeted on Friday at 09:43

Awww railsapi, delete some logs: http://bit.ly/htBNDH
Tweeted on Wednesday at 16:15