Skip to content

Instantly share code, notes, and snippets.

@mhagerty
Created December 5, 2012 19:39
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhagerty/4218820 to your computer and use it in GitHub Desktop.
Save mhagerty/4218820 to your computer and use it in GitHub Desktop.
A sample Ruby script utilizing Mechanize to navigate Oauth authentication for Yahoo Sports API
# Author: Mike Hagerty, 11/28/2012
# The purpose of this script is to pull data from the Yahoo Sports API. I tried to document the steps as thoroughly as possible, as I had a
# tough time navigating this process
# Yahoo Sports requires Oauth authentication for personal team-related data. This requirement complicates the automation of pulling data, as Oauth in general requires user interaction to complete the authentication process.
# Mechanize is used to automate the user interaction steps required to authenticated via Oauth.
# This script also has example code for storing the data in a mongodb at the end
#!/usr/bin/ruby
require 'oauth'
require 'mongo'
require 'uri'
require 'json'
require 'mechanize'
# EDIT THESE USER VALUES FOR YOUR SPECIFIC SCRIPT
# Yahoo Oauth Variables
# Yahoo Consumer Secret
@consumer_key = "your consumer key"
# Yahoo Consumer Secret
@consumer_secret = "your consumer secret"
# Yahoo User Credentials
# Yahoo User ID
@yahoo_user_id = 'Your Yahoo ID'
# Yahoo User Password
@yahoo_password = 'Your Yahoo Password'
# Mongo HQ DB settings
# Mongo DB URL, with username and password
@mongo_connect_url = 'Your MongoHQ connect URL with username and password'
# Mongo DB Collection name, specifically for league transactions
@mongo_collection_name = 'Your MongoDB Collection Name'
# End Mongo HQ DB settings
# End Setting Variables
# DONE EDITING USER VALUES
# DO NOT EDIT THESE VALUES
# Oauth variables
# Yahoo Oauth Request Token Path
@yahoo_oauth_request_token_path = '/oauth/v2/get_request_token'
# Yahoo Oauth Access Token Path
@yahoo_oauth_access_token_path = '/oauth/v2/get_token'
# Yahoo Oauth Authorize Path
@yahoo_oauth_authorize_path = '/oauth/v2/request_auth'
# Eng Yahoo Oauth Variables
# Yahoo URLs
# Yahoo User Login Settings
# Yahoo User Login URL
@yahoo_user_login_url = "https://login.yahoo.com/"
# Yahoo Sport API Oauth URL
@yahoo_oauth_url = "https://api.login.yahoo.com"
# End Yahoo User Login Settings
# Mechanize Settings for Yahoo
# Yahoo Login form name, found through browser inspection
@yahoo_login_form_name = 'login_form'
# Yahoo Login Username Field Name, found through browser inspection
@yahoo_login_username_fieldname = 'login'
# Yahoo Login Password Field Name, found through browser inspection
@yahoo_login_password_fieldname = 'passwd'
# Yahoo Agreement Page Acceptance form name, found through browser inspection
@yahoo_acceptance_form_name = 'rcForm'
# Name of verifier span name, found through browser inspection
@verifier_code_span_name = 'shortCode'
# End Mechanize Settings for Yahoo
# Logs into Yahoo using Mechanize, sets session cookies, authenticates and grabs access token for oauth, grabs json and converts to json object hash
def retrieve_yahoo_data()
# Sets up parameters to grab Oauth request token
@auth_consumer=OAuth::Consumer.new @consumer_key,
@consumer_secret, {
:site => @yahoo_oauth_url,
:scheme => :query_string,
:request_token_path => @yahoo_oauth_request_token_path,
:access_token_path => @yahoo_oauth_access_token_path,
:authorize_path => @yahoo_oauth_authorize_path
}
# Set request token
@request_token = @auth_consumer.get_request_token
# initiate Mechanize agent
myagent = Mechanize.new
# disregard SSL certs, this causes a problem on Windows
myagent.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
# LOGIN TO YAHOO AND SET REQUIRED COOKIES
newpage1 = myagent.get @yahoo_user_login_url
# puts "Going to Yahoo Login Page"
temp_jar = myagent.cookie_jar
#puts temp_jar.inspect # prints cookies
submit_form = newpage1.form_with(name: @yahoo_login_form_name) # find form name of form that submits the login
submit_form.field_with(name: @yahoo_login_username_fieldname).value = @yahoo_user_id
submit_form.field_with(name: @yahoo_login_password_fieldname).value = @yahoo_password
newpage2 = submit_form.click_button
myagent.cookie_jar = temp_jar
#puts temp_jar.inspect #prints cookies
#END LOGIN PROCESS
# MAKE OAUTH REQUEST
# Gets authentication page first when requesting auth_url
agreement_page = myagent.get(@request_token.authorize_url)
# puts "Going to Agreement Page"
# Find form to be submitted when you click Agree
agreement_form = agreement_page.form_with(name: @yahoo_acceptance_form_name)
#Set Verifier Page by accepting the default Accept form
verifier_code_page = agreement_form.click_button # clicks first submit button
# puts "Going to Verifier Code Page"
verifier_code_html = verifier_code_page.search('//span[starts-with(@id, @verifier_code_span_name)]') # returns span html
verifier_code = verifier_code_html.children.text # Nokogiri, the embedded parser within Mechanize, returns the full span text, but calling children will put the text of the span
# puts "Verifier Code is: " + verifier_code #
@access_token=@request_token.get_access_token(:oauth_verifier => verifier_code)
# puts "Access Token is: " + @access_token.token
# use the token to make the GET request to retrieve the data. The access_token instance can issue network requests.
# Pass the Yahoo URL, with the alreasy created auth token, to get the results from the Yahoo API
@json_response = @access_token.request(:get, @yahoo_sports_url) # returns a Net::HTTPOK object, which needs to be converted to a JSON hash to be imported into Mongo
@json_hash = JSON.parse(@json_response.body) # converts the Net object to a Hash
end
# Establish connection to MongoHQ, delete existing transaction json document, and upload new transaction document
def push_data_to_mongo
return @db_connection if @db_connection
db = URI.parse(@mongo_connect_url)
db_name = db.path.gsub(/^\//, '')
@db_connection = Mongo::Connection.new(db.host, db.port).db(db_name)
@db_connection.authenticate(db.user, db.password) unless (db.user.nil? || db.user.nil?)
@db_connection
# stuff json hash into connected db
transactions_collection = @db_connection.collection(@mongo_collection_name)
transactions_collection.remove() # remove all existing documents from existing db collection
transactions_collection.insert(@json_hash)
end
retrieve_yahoo_data
push_data_to_mongo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment