In this tutorial I Will show how you can post twitter feeds using rails, but not required to be rails as it’s just a simple ruby class. Mostly it’s about how to use the Twitter gem.
It will cache the feeds in memcached. It does not do any database hit for performance.
Only queries twitter once an hour, which you can set default_ttl on the class object.
This is based on a Rails 3.2.7 App with Dalli as memcached backend.
Added to Gemfile:
gem ‘twitter’
gem ‘dalli’
Then Create an initializer file containing your twitter credentials:
1 2 3 4 5 6 7 8 9 | # config/initializers/twitter.rb Twitter.configure do |config| config.consumer_key = ENV["TWITTER_CONSUMER_KEY"] config.consumer_secret = ENV["TWITTER_CONSUMER_SECRET"] config.oauth_token = ENV["TWITTER_OAUTH_TOKEN_SECRET"] config.oauth_token_secret = ENV["TWITTER_OAUTH_TOKEN_SECRET"] end |
This is the model that does all the work. It fetches the timeline then stores in memcached.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | # app/models/twitter_status.rb class TwitterStatus attr_accessor :default_ttl attr_accessor :user # if no user is initialized, then use own screen_name from Twitter def user @user || Twitter.user.screen_name end # refresh time def default_ttl @default_ttl || 1.hour end def timeline unless is_fresh? reload end read_timeline end # Re-fetch timeline from twitter and saves it to the cache again def reload set_timeline set_timestamp end private def cache_key "twitter_timeline_#{user.to_s}" end def cache_timestamp "twitter_timestamp_#{user.to_s}" end def fetched_at Rails.cache.read(cache_key) end def read_timeline Rails.cache.read(cache_key) end def set_timestamp Rails.cache.write(cache_timestamp, Time.now, timeToLive: default_ttl) end def set_timeline Rails.cache.write(cache_key, Twitter.user_timeline(user, include_entities: true)) rescue Rails.logger.info("Error: Cannot connect to twitter or network down") Rails.cache.write(cache_key, []) end def is_fresh? fetched_at && fetched_at.is_a?(Time) && ((fetched_at + default_ttl) > Time.now) end end |
How to use it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # Initialize object > my_timeline = TwitterStatus.new => #<TwitterStatus:0x007ff70dc50da8> # Default Time to store on memcached is 1 hour > my_timeline.default_ttl => 3600 seconds # Change the update interval to 10 minutes. > my_timeline.default_ttl = 10.minutes => 600 seconds # Get Array of recent tweets for Own Timeline > my_timeline.timeline => [#<Twitter::Status:0x007ff70da00468 @attrs={. . . . # Get latest single tweet on your timeline: > my_timeline.timeline.first.text => "Hello world http://t.co/123456" # Get timeline of another user > user_timeline = TwitterStatus.new => #<TwitterStatus:0x007ff70dc98860> > user_timeline.user = "fred_on_rails" => "fred_on_rails" # Get fred's last tweet from timeline 1.9.3-p194 :039 > user_timeline.timeline.first.text => "Rainwater Crimes: Man gets jail and fines for collecting on his own land http://t.co/Qzn5NWpS" # Force reload, it refetches from twitter and saves it to the cache again > user_timeline.reload => true |
In the views you could display like this:
1 2 3 4 5 6 7 | # app/helpers/twitter_helper.rb module TwitterHelper def url_for_twit(user,status_id) "https://twitter.com/#{user}/status/#{status_id}" end end |
In a controller action (example for a logged in user profile page)
1 2 3 | @twitter_status = TwitterStatus.new @twitter_status.user = current_user.twitter_screen_name @twitter_status.default_ttl = 30.minutes |
Erb view:
1 2 3 4 5 6 7 8 9 10 11 | <h3>Twitter Updates</h3> <ul> <% @twitter_status.timeline[0..5].each do |status| %> <li> <%= link_to(status.text, url_for_twit(@twitter_status.user, status.id), target: 'blank') %> <span class="twitter-feed-date"> <%= time_ago_in_words status.created_at %> ago </span> </li> <% end %> </ul> |
