Question

I keep getting the following error when running the following ruby script. If anyone can help me fix this it would be greatly appreciated. I've removed any sensitive data such as API keys.

Code:

#!/usr/bin/env ruby
require "tweetstream"
require "mongo"
require "time"

TweetStream.configure do |config|
  config.consumer_key       = 'KEY'
  config.consumer_secret    = 'SECRET'
  config.oauth_token        = 'TOKEN'
  config.oauth_token_secret = 'TOKEN_SECRET'
  config.auth_method        = :oauth
end

db = Mongo::Connection.new("ds045037.mongolab.com", 45037).db("tweets")
auth = db.authenticate("DB_USERNAME", "DB_PASSWORD")
tweets = db.collection("tweetdata")

TweetStream::Daemon.new("TWITTER_USERNAME", "TWITTER_PASSWORD").track("TERM") do |status|
  # Do things when nothing's wrong
  data = {"created_at" => Time.parse(status.created_at), "text" => status.text, "geo" => status.geo, "coordinates" => status.coordinates, "id" => status.id, "id_str" => status.id_str}
  tweets.insert({"data" => data});
end

Command to start the script:

ruby tweetscrape.rb

Ruby version:

ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-linux]

ruby -c tweetscrape.rb produces:

Syntax OK

Error Message:

/usr/local/rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons.rb:184:in `[]=': can't convert Symbol into Integer (TypeError)
    from /usr/local/rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons.rb:184:in `run_proc'
    from /usr/local/rvm/gems/ruby-1.9.3-p429/gems/tweetstream-2.5.0/lib/tweetstream/daemon.rb:48:in `start'
    from /usr/local/rvm/gems/ruby-1.9.3-p429/gems/tweetstream-2.5.0/lib/tweetstream/client.rb:131:in `filter'
    from /usr/local/rvm/gems/ruby-1.9.3-p429/gems/tweetstream-2.5.0/lib/tweetstream/client.rb:98:in `track'
    from tweetscrape.rb:19:in `<main>'

EDIT: I now have no errors using the below but nothing is entered in to the mongodb:

#!/usr/bin/env ruby
require "tweetstream"
require "mongo"
require "time"

TweetStream.configure do |config|
  config.consumer_key       = 'gfdsgfdsgfdsgfdsgfdsgfds'
  config.consumer_secret    = 'gfsdgfdsgfdsgfdsgfsdgfd'
  config.oauth_token        = 'gfdgfdsgfsdgfdsgfsdgf'
  config.oauth_token_secret = 'hsgfsdgfsdgfsdgfds'
  config.auth_method        = :oauth
end

db = Mongo::Connection.new("ds045037.mongolab.com", 45037).db("tweets")
auth = db.authenticate("gfsdgfdsgfsd", "gfdsgfdsgfdsgfsd")
tweets = db.collection("tweetdata")

TweetStream::Client.new.track('TERM') do |status|
  puts status.text
  data = {"created_at" => Time.parse(status.created_at), "text" => status.text, "geo" => status.geo, "coordinates" => status.coordinates, "id" => status.id, "id_str" => status.id_str}
  tweets.insert({"data" => data})
end

Tweets show on screen through puts though...

Was it helpful?

Solution

The initial error you were getting with the Daemon class is because you're not passing the correct parameters to the constructor. The contructor takes a string and a hash.

Moving on from that , the insert failed because:

  1. parsing status.datetime throws an exception (its already a Time object).
  2. status.coordinate throws an exception if there's no coordinate.

The following code works for me (note : I added growl so you can see the tweets):

#!/usr/bin/env ruby
require "tweetstream"
require "mongo"
require "time"
require 'growl'

DESIRED = %w{created_at text geo coordinates id id_str}
host= ENV["MONGO_HOST"]  || 'localhost'
port = ENV["MONGO_PORT"]  || 27017
username = ENV["MONGO_USERNAME"]
password = ENV["MONGO_PASSWORD"]

term = ARGV[1] || 'TERM'

begin
  TweetStream.configure do |config|
    config.consumer_key       = ENV["TWEET_CONSUMER_KEY"]
    config.consumer_secret    = ENV["TWEET_CONSUMER_SECRET"]
    config.oauth_token        = ENV["TWEET_OAUTH_TOKEN"]
    config.oauth_token_secret = ENV["TWEET_OAUTH_TOKEN_SECRET"]
    config.auth_method        = :oauth
  end

  db = Mongo::Connection.new(host, port).db("tweets")
  db.authenticate(username, password)
  tweets = db.collection("tweetdata")

  puts "about to start tracking term #{term}"
  TweetStream::Daemon.new('tracker').track(term) do |status|
    Growl.notify status.text, :title => status.user.screen_name

    #
    # filter out nil values
    # filter out all keys not in the desired array
    #
    data = status.attrs.select{|k,v| !v.nil? && DESIRED.include?(k.to_s)}
    tweets.insert({"data" => data});
  end

rescue Mongo::ConnectionFailure
  puts "Connection Error :  #{$!}"
rescue Mongo::AuthenticationError
  puts "Auth Error :  #{$!}"
rescue Mongo::MongoDBError
  puts "Unexpected Error :  #{$!}"
end

You'll need to setup your environment with the following correct values :

export MONGO_USERNAME="..."
export MONGO_PASSWORD="..."
export TWEET_CONSUMER_KEY="..."
export TWEET_CONSUMER_SECRET="..."
export TWEET_OAUTH_TOKEN="..."
export TWEET_OAUTH_TOKEN_SECRET="..."

Then you can start the daemon with something like (in this case we'll search for yankees):

ruby tweetscrape.rb start yankees
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top