Created
August 30, 2012 22:35
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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