Question

I'm trying to integrate my app with twitter API.

here are my steps:

1: installed the twitter gem: gem 'twitter

2:grabbed this code from the twitter gem documentation and placed it inside my controller. I also tried placing the code in a helper.

require 'twitter'

@client = Twitter::REST::Client.new do |config|
  config.consumer_key    = ENV["CONSUMER_KEY"]
  config.consumer_secret = ENV["CONSUMER_SECRET"]
  config.access_token        = ENV["ACCESS_TOKEN"]
  config.access_token_secret = ENV["ACCESS_SECRET"]
end

3) registered my app with twitter and got the consumer_key (AKA: API key), consumer_secret (AKA:API secret), access_token, and access_token_secret.

I used a config/application.yml to store access tokens. is that correct way of doing it? I hope so.

4) in views, I have <%= @client.user.username %>.

I'm doing this in development (localhost3000). my callback url is http://127.0.0.1/

I also tried to organize my code as this answer suggests to no avail.

I'm using Rails 4.0.2

I tested the code in the console and is working perfectly. I tried several queries including the one shown above: <%= @client.user.username %> and they are all working.

but when I run my code in development i get this error:

undefined method `user'` for nil:NilClass. 

I understand what the error means. but how is it possible that @client is nil? when I run it in the console, it is not nil. Did I forget something? I would appreciate any suggestions. Please let me know if you would like me to provide more info/code. Thanks.

EDIT: Also, tried to move the above code that start with @client to a config/initializers/twitter.rb. Getting same error message.

Was it helpful?

Solution 3

I tried both solutions outlined here by @Pramod Shinde and @Peeyush, but none of them seemed to work for me. Here is how I solved the problem.

What I needed to do is to wrap a method action around the following code which I had inside my controller. Like this:

def tweets
  @client = Twitter::REST::Client.new do |config|
    config.consumer_key        = ENV["CONSUMER_KEY"]
    config.consumer_secret     = ENV["CONSUMER_SECRET"]
    config.access_token        = ENV["ACCESS_TOKEN"]
    config.access_token_secret = ENV["ACCESS_SECRET"]
  end
end

I created a new file, config/application.yml to store my twitter API credentials, and added the file to .gitignore to avoid it being commited to github. The above code uses ENV[] to access the credentials stored in config/application.yml.

config/application.yml:

CONSUMER_KEY: "1234"
CONSUMER_SECRET: "1234"
ACCESS_TOKEN: "1234"
ACCESS_SECRET: "1234"  

This is a YAML file. So beware of the indentation.

Then inside my routes.rb, I created a route that maps to the above action:

get "/tweets", to: "posts#tweets"

Obviously, if you wanted to post tweets instead of fetching them, you'd have to create a POST route. You may also consider moving the above action to it's own TweetsController. Or encapsulate it in it's own class.

To complete the convention, I created a view file which maps to the tweets action:

tweets.html.erb

The reason why I was getting this error message:

undefined method `user' for nil:NilClass

is because I didn't have a route, controller action, and a view file that map to each.

Up until this point, everything is working fine when in development.

when I pushed the app to heroku, I got the following error:

ActionView::Template::Error (Unable to verify your credentials):

Solution: install gem 'figaro' (actually this gem creates for you config/application.yml file and automatically appends it to .gitignore.

To solve the heroku error, all you have to do is run: rake figaro:heroku. See this tutorial about using the figaro gem to keep the environment variables private

OTHER TIPS

This may be because your controller code is trying to access CONSUMER_KEY etc. from environment variable but you have not set it in development mode.

You can use rails_config gem and let it create the settings.yml file for you in config/ with appropriate configurations. ] Now, store you twitter details in it as follows:

twitter:
  CONSUMER_KEY: 'your_consumer_key_here'
  CONSUMER_SECRET: 'your_consumer_secret_here'
  ACCESS_TOKEN: 'your_access_token_here'
  ACCESS_SECRET:'your_access_secret_here'

Then, modify your controller code to use those values as follows:

account = Settings['twitter']

@client = Twitter::REST::Client.new do |config|
  config.consumer_key        = account["CONSUMER_KEY"]
  config.consumer_secret     = account["CONSUMER_SECRET"]
  config.access_token        = account["ACCESS_TOKEN"]
  config.access_token_secret = account["ACCESS_SECRET"]
end

You can add settings.yml to .gitignore so that the file is not commited by git.

Or, you can use the approach described Here.

You can read this if you are thinking of setting ENV variables in development.

I think your keys are not getting loaded properly

your config/settings.yml should look like this

development:
  twitter:  
    CONSUMER_KEY: 'your_consumer_key_here'
    CONSUMER_SECRET: 'your_consumer_secret_here'
    ACCESS_TOKEN: 'your_access_token_here'
    ACCESS_SECRET:'your_access_secret_here'

make this file as per your environments

Then Load this as

def get_twitter_client 
  oauth_config = YAML::load(File.open("#{Rails.root}/config/settings.yml"))

  @client = Twitter::REST::Client.new do |config|
    config.consumer_key        = oauth_config[Rails.env]['twitter']["CONSUMER_KEY"]
    config.consumer_secret     = oauth_config[Rails.env]['twitter']["CONSUMER_SECRET"]
    config.access_token        = oauth_config[Rails.env]['twitter']["ACCESS_TOKEN"]
    config.access_token_secret = oauth_config[Rails.env]['twitter']["ACCESS_SECRET"]
  end
end

Also if you look at Twitter gem @client has method user(user show API) which accepts user_id or twitter_username/handle/screen_name

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top