Blog

Download you twitter feed using Ruby on Rails with OAuth

Jonathon Horsman Jun 28 39 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}]}

france galop longchamp

france galop longchamp May 05

I'm curious to find out what blog system you happen to be using?
I'm experiencing some small security problems with my latest
website and I would like to find something more risk-free.
Do you have any recommendations?
Hello, i think that i saw you visited my site thus i
came to “return the favor”.I am attempting to find things to improve my website!I suppose its ok to use a few of your ideas!!

\

webhosting

webhosting May 12

This is really attention-grabbing, You're an overly professional blogger.
I've joined your feed and sit up for seeking more off your magnificent post.
Also, I've shared your site in my social networks

Jacob

Jacob May 25

I'm truly enjoying the design and layout of your blog.
It's a very easy on the eyes which makes it much more enjoyable for me to come here and visit more
often. Did you hire out a developer to create your theme?
Fantastic work!

Castle Age HD Hack Cheats

Castle Age HD Hack Cheats Jun 04

Have you ever thought about adding a little bit more than just your articles?
I mean, what you say is fundamental and everything.
Nevertheless think about if you added some great photos or videos to give your posts more, "pop"!

Your content is excellent but with images and clips, this
site could definitely be one of the best in its field. Awesome blog!

vrushti

vrushti Jun 08

how to run Tweet.get_update in console?
It shows 'Tweet.get_latest: command not found' . I m using ubuntu.

golf star hack tool android

golf star hack tool android Jun 25

Excellent way of telling, and fastidious post to take facts
about my presentation topic, which i am going to present in institution of higher education.

oakley sunglasses uae

oakley sunglasses uae Jul 08

<a href="http://i-optic.co.il/file/canada-goose-outlet/sweden-down-jacket-men.asp">sweden down jacket men</a> <a href="http://popdee.com/input/canada-goose-outlet/Might-be-you-can-Canada-Goose-Parka.asp">Might be you can Canada Goose Parka</a> <a href="http://sirdodisha.org/SIRDWEBSITE/userfiles/file/LV/vintage-replica-louis-vuitton-key-ring.asp">vintage replica louis vuitton key ring</a> <a href="http://cmind.dk/pics/CL/christian-louboutin-mens-boots-cheap-still-kit.asp">christian louboutin mens boots cheap still kit</a> <a href="http://alhenthaguesthouse.co.za/famersxy/michael-kors/michael-kors-totes-quilted-coats-for-men.asp">michael kors totes quilted coats for men</a> <a href="http://faststad.se/pages/CL/christian-louboutin-macarena-wedge.asp">christian louboutin macarena wedge</a> <a href="http://www.mediability.it/clienti/oakley-sungless/oakley-radarlock-glasses.asp">oakley radarlock glasses</a> <a href="http://columbia.se/pages/oakley/oakley-glasses-dictate-4-0-parts.asp">oakley glasses dictate 4.0 parts</a> <a href="http://aarhussymfoniskeorgelfestival.dk/personer/michael-kors/michael-kors-totes-mens-quilted-coats.asp">michael kors totes mens quilted coats</a> <a href="http://tryckhuset.se/news/canada-goose-outlet/Where-To-Buy-A-Canada-Goose-Jacket-Toronto.asp">Where To Buy A Canada Goose Jacket Toronto</a> <a href="http://cmind.dk/pics/LV/lv-bag-white-grey.asp">lv bag white grey</a> <a href="http://agricolagiardina.it/images/CL/christian-louboutin-macarena-wedges-sandals-shoes.asp">christian louboutin macarena wedges sandals shoes</a> <a href="http://globalexchange.com.br/imagens/canada-goose-outlet/Solaris-Parka.asp">Solaris Parka</a> <a href="http://webbsystem.se/Old/pages/CL/christian-louboutin-macarena-wedge-sandals-cheap-c.asp">christian louboutin macarena wedge sandals cheap c</a> <a href="http://alsen.saknet.dk/shadow/north-face-outlet/the-north-face-100k.asp">the north face 100k</a> <a href="http://www.legge196.net/acquisti/north-face-outlet/the-north-face-vietnam-website.asp">the north face vietnam website</a> <a href="http://scarabeo.ne-ws.it/images/oakley-sungless/oakley-sunglasses-0089.asp">oakley sunglasses 0089</a> <a href="http://www.fair-research.eu/include/oakley-sungless/oakley-sunglasses-50.asp">oakley sunglasses 50$</a> <a href="http://www.4traffic.it/old/north-face-outlet/the-north-face-cyber-monday.asp">the north face cyber monday</a> <a href="http://www.kentneriva.com/neriva/canada-goose-outlet/That-could-be-Ladies-Canada-Goose.asp">That could be Ladies Canada Goose</a>

genuine louis vuitton bags

genuine louis vuitton bags Jul 08

Lovely shoes, right size thank you very much for such a quick delivery!!!very lovely shoes but for this order ,shipment time is very longToo bad the form is slightly smaller number asking for 8 and 8 would use 37 to 36 in the case in Brazil

wikidot.com

wikidot.com Jul 11

Currently it seems like BlogEngine is the top blogging platform out
there right now. (from what I've read) Is that what you're
using on your blog?

ugg boots black friday

ugg boots black friday Jul 19

<a href="http://www.guccihandbagsoutletonline.com/">gucci outlet</a> z <a href="http://www.burberryblackfridaysale.com/">burberry black friday</a> v <a href="http://www.kobebryantshoesforsale.com/">kobe bryant shoes</a> v <a href="http://www.kobebryantshoesforsale.com/">kobe bryant shoes</a> v <a href="http://www.kobebryantshoesforsale.com/">kobe bryant shoes</a> v <a href="http://www.kobebryantshoesforsale.com/">kobe bryant shoes</a> s <a href="http://louisvuittonoutletonlinereal.com/">louis vuitton outlet</a> e <a href="http://www.kd6sneakersforsale.com/">kd vi</a> e <a href="http://www.kd6sneakersforsale.com/">kd vi</a> e <a href="http://www.kd6sneakersforsale.com/">kd vi</a> u <a href="http://www.katespadebagsoutletsales.net/">kate spade bags</a> u <a href="http://www.katespadebagsoutletsales.net/">kate spade bags</a> u <a href="http://www.katespadebagsoutletsales.net/">kate spade bags</a> u <a href="http://www.katespadebagsoutletsales.net/">kate spade bags</a> m <a href="http://www.burberryoutletstoresonline.biz/">burberry handbags</a> m <a href="http://www.burberryoutletstoresonline.biz/">burberry handbags</a> m <a href="http://www.burberryoutletstoresonline.biz/">burberry handbags</a> m <a href="http://www.burberryoutletstoresonline.biz/">burberry handbags</a> m <a href="http://www.burberryoutletstoresonline.biz/">burberry handbags</a> g <a href="http://cheapuggboots.azonline.net/">uggs for cheap</a> g <a href="http://cheapuggboots.azonline.net/">uggs for cheap</a> g <a href="http://cheapuggboots.azonline.net/">uggs for cheap</a> g <a href="http://cheapuggboots.azonline.net/">uggs for cheap</a> q <a href="http://www.michaelkorshandbagsoutletclearance.com/">michael kors bags</a> q <a href="http://www.michaelkorshandbagsoutletclearance.com/">michael kors bags</a> q <a href="http://www.michaelkorshandbagsoutletclearance.com/">michael kors bags</a> q <a href="http://www.michaelkorshandbagsoutletclearance.com/">michael kors bags</a> q <a href="http://www.michaelkorshandbagsoutletclearance.com/">michael kors bags</a> q <a href="http://www.michaelkorshandbagsoutletclearance.com/">michael kors handbags</a> y <a href="http://www.katespadeoutletstoreonline.com/">kate spade handbags</a>

gry maszyny na pieniadze

gry maszyny na pieniadze Jul 23

maszyny do grania na pieniadze

slblog.dk

slblog.dk Jul 24

potrójne ryzyko w rozrywka jest kogoś wykonać,
akt , i taniec

online shopping

online shopping Jul 26

Link exchange is nothing else however it is just placing the other person's weblog link
on your page at proper place and other person will
also do similar for you.

www.outdoornutcoupons.com

www.outdoornutcoupons.com Jul 28

The spectacular sights allow it to be a beautiful spot to take a family member
and enjoy an intimate vacation in France. You will discover this country provides incredible
opportunities to really make the the majority
of a hiking encounter, within the inclines, inside the
mountains, across the water, about the seashore
and more.

magicofmaking.wikidot.com

magicofmaking.wikidot.com Aug 03

I am regular reader, how are you everybody? This paragraph posted at this
web site is truly fastidious.

Madonna

Madonna Aug 09

Its not my first time to pay a quick visit this web
site, i am visiting this website dailly and obtain nice information from here everyday.

domain

domain Aug 14

Amazing blog! Do you have any tips for aspiring writers?

I'm hoping to start my own blog soon but I'm a little lost on everything.
Would you advise starting with a free platform like Wordpress or go for a paid option? There are so many choices out there that I'm completely overwhelmed ..
Any recommendations? Kudos!

Recommended Online site

Recommended Online site Aug 15

I really like your blog.. very nice colors & theme.
Did you make this website yourself or did you hire someone to
do it for you? Plz answer back as I'm looking
to design my own blog and would like to
know where u got this from. thanks

Shelton

Shelton Aug 16

I've been exploring for a little for any high-quality articles or blog posts
in this sort of space . Exploring in Yahoo I at last stumbled
upon this site. Reading this information So i am happy to convey
that I have a very good uncanny feeling I discovered exactly what I
needed. I so much surely will make sure to don?t fail to remember
this web site and give it a look regularly.

Cheap authentic jordan shoes for sales

Cheap authentic jordan shoes for sales Aug 16

cheap nike jordans

Google

Google Aug 23

It will also increase the ranking of your website on search engines and will drive more traffic to your website.
* Let you know there are things you can do to improve y0ur ranking.
Any time you create new content or share new links
on your website or blog, be sure to do so
by diversifying all of the link and anchor text you implement, regardless
of the market you represent or the industry you are working in.

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