Skip to content

Instantly share code, notes, and snippets.

@tomharrisonjr
Created August 30, 2012 22:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomharrisonjr/3543368 to your computer and use it in GitHub Desktop.
Save tomharrisonjr/3543368 to your computer and use it in GitHub Desktop.
Example Ruby on Rails library for Google API, Google Analytics Network (GAN), events/list API, as well as others using Installed Applications approach
module GoogleApi
# Inspired by http://www.ericnagel.com/how-to-tips/google-affiliate-network-api.html
require 'rest-client'
require 'active_support'
# Google Affiliate Network
class GAN
# These values obtained from https://code.google.com/apis/console, creating a client ID for Installed Applications
CLIENT_ID = '<your-value>.apps.googleusercontent.com'
CLIENT_SECRET = '<your-value>'
REDIRECT_URI = '<your-value>'
# URLs needed to get the authorization
OAUTH_BASE_URL = 'https://accounts.google.com/o/oauth2'
OAUTH_AUTH_URL = OAUTH_BASE_URL + '/auth'
OAUTH_TOKEN_URL = OAUTH_BASE_URL + '/token'
# Get this value by using the setup routine, after which the process can run without user interaction
REFRESH_TOKEN = '<your-value>' # see setup method below
# URL for getting GAN events. Other GAN APIs should follow a similar pattern
API_SCOPE = 'https://www.googleapis.com/auth/gan.readonly'
PUBLISHER_ID = '<your-value>' # e.g. K123456
GAN_EVENT_URL = "https://www.googleapis.com/gan/v1beta1/publishers/#{PUBLISHER_ID}/events"
# calls the GAN API with a fresh access token to return event data from the given date range (ruby dates)
def list_events(access_token, start_date, end_date)
params = {
:eventDateMin => date_to_format(start_date),
:eventDateMax => date_to_format(end_date),
}
oauth_url = "#{GAN_EVENT_URL}?#{params.to_query}"
puts "Listing events with URL: #{oauth_url}\n"
response = RestClient.get(oauth_url, :authorization => "OAuth #{access_token}")
if response.code != 200
puts "ERROR: list_events GET failed with code #{response.code} and response\n#{response}\n"
return
end
events = ActiveSupport::JSON.decode(response)
parse_events(events)
end
# sample of how to parse the events response
def parse_events(events)
events['items'].each do |item|
date_str = item['eventDate']
order_total = item['commissionableSales']['amount']
order_id = item['orderId']
advertiser_name = item['advertiserName']
user_id_proxy = item['memberId']
commission = item['earnings']['amount']
puts "#{date_from_format(date_str)}: order: #{order_id} total: $#{order_total} from: #{advertiser_name} by: #{user_id_proxy} commission: #{commission}"
end
nil
end
# for testing from rails console, for example
def self.execute
refresh_token = REFRESH_TOKEN
gan = GoogleApi::GAN.new
access_token = gan.access_token(refresh_token)
start_date = Date.parse("2012-08-01")
end_date = Date.today
gan.list_events(access_token, start_date, end_date)
end
# two step process for getting a refresh token:
# first run without arg -- prints URL to use to get an auth code
# second, pass auth code to get a refresh token that is valid in some context for some lifetime.
def self.setup(auth_code = nil)
if auth_code.nil?
self.application_auth_code_url
# value returned in browser, e.g. '4/noBm-KAYLdGcES_8KYkbSZwMnGxx.8i1iPOKc-zYXaDn_6y0ZQNiUXSDvcgI'
else
self.refresh_token(auth_code)
end
end
# Generates a URL to Google that we'll go to to get an auth code via browser (might be able to automate if needed)
def self.application_auth_code_url
params = {
:response_type => 'code',
:client_id => CLIENT_ID,
:redirect_uri => REDIRECT_URI,
:scope => API_SCOPE,
}
# build auth URL with params
oauth_url = "#{OAUTH_AUTH_URL}?#{params.to_query}"
puts "Go to #{oauth_url} and set the variable auth_code to the value provided"
oauth_url
end
# Gets a refresh token given an authorization code. This appears to last indefinitely.
def self.refresh_token(auth_code)
params = {
:code => auth_code,
:client_id => CLIENT_ID,
:client_secret => CLIENT_SECRET,
:redirect_uri => REDIRECT_URI,
:grant_type => 'authorization_code'
}
oauth_url = OAUTH_TOKEN_URL
puts "Posting to #{oauth_url} with params #{params}"
response = RestClient.post(oauth_url, params)
if response.code != 200
puts "ERROR: refresh_token POST failed with code #{response.code} and response\n#{response}\n"
return
end
data = ActiveSupport::JSON.decode(response)
puts "Set refresh token from values:\n"
puts data
end
# returns an access token given a refresh token, which at least says it is volatile -- lasting for an hour
def access_token(refresh_token)
oauth_url = OAUTH_TOKEN_URL
params = {
:client_secret => CLIENT_SECRET,
:grant_type => 'refresh_token',
:refresh_token => refresh_token,
:client_id => CLIENT_ID,
}
puts "Posting to #{oauth_url} with params #{params}"
response = RestClient.post(oauth_url, params)
if response.code != 200
puts "ERROR: access_token POST failed with code #{response.code} and response\n#{response}\n"
return
end
data = ActiveSupport::JSON.decode(response)
access_token = data["access_token"]
access_token
end
private
# Format of dates accepted as inputs is 2012-08-30T13:15:01.009Z
def date_to_format(date)
date.strftime("%FT%T.%LZ")
end
# Parses GAN's date format to a ruby datetime
def date_from_format(date_str)
DateTime.parse(date_str)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment