Skip to content

Instantly share code, notes, and snippets.

@hendricius
Created February 26, 2014 10:18
Show Gist options
  • Save hendricius/a14868d939ef0e34ef9f to your computer and use it in GitHub Desktop.
Save hendricius/a14868d939ef0e34ef9f to your computer and use it in GitHub Desktop.
# Retrieves (and saves) keyword estimates
def get_estimates(keywords, no_save = false)
@api = get_adwords_api
# If the refresh option is selected, by default all keywords will be
# be updated with estimates from the adwords api.
if !AdwordsConfig.config[:refresh_keywords]
keywords = keywords.find_all{|keyword| !keyword.up_to_date? }
end
keywords.uniq! {|keyword| keyword.name.slice(0, 80)}
# Abort if there are no keywords
return if keywords.empty?
service = @api.service(:TargetingIdeaService)
keywords.each_slice(800) do |keywords| # Max 800 keywords per request allowed
objects = keywords
keywords = keywords.map{|keyword| keyword.name.slice(0, 80)}
selector = {
:idea_type => 'KEYWORD',
:request_type => 'STATS',
:requested_attribute_types => ['COMPETITION', 'AVERAGE_CPC', 'SEARCH_VOLUME', 'KEYWORD_TEXT'],
:search_parameters => [
{
:xsi_type => 'RelatedToQuerySearchParameter',
:queries => keywords
},
{
:xsi_type => 'LocationSearchParameter',
:locations => [{:id => AdwordsConfig.config[:target_location]}]
},
{
:xsi_type => "NetworkSearchParameter",
:network_setting => {
:target_google_search => true,
:target_search_network => false,
:target_content_network => false
}
},
],
:paging => {
:start_index => 0,
:number_results => 800
}
}
data = service.get(selector)
objects.each do |object|
result = data[:entries].detect{|entry| entry[:data]['KEYWORD_TEXT'][:value] == object.name}
if result && result[:data]['COMPETITION'] && result[:data]['COMPETITION'][:value]
competition = (result[:data]['COMPETITION'][:value].to_f * 3).ceil
object.competition = competition > 0 ? competition : 1
object.competition_real = result[:data]['COMPETITION'][:value].to_f
else
object.competition = 1
end
if result && result[:data]['AVERAGE_CPC'] && result[:data]['AVERAGE_CPC'][:value]
object.cpc = result[:data]['AVERAGE_CPC'][:value][:micro_amount].to_f / 1000000
else
object.cpc = 0.0
end
if result && result[:data]['SEARCH_VOLUME'] && result[:data]['SEARCH_VOLUME'][:value]
object.impressions = result[:data]['SEARCH_VOLUME'][:value]
else
object.impressions = 0
end
end
if objects.count == 800 # Loop not done
sleep(@@RETRY_INTERVAL)
end
end
service = @api.service(:TrafficEstimatorService)
keywords.each_slice(2000) do |keywords| # Max 2k keywords per request allowed
estimate_cpc = keywords.map{|keyword| keyword.cpc * keyword.impressions}.inject(:+) / 20
objects = keywords
keywords = keywords.map do |keyword|
{
:xsi_type => 'Keyword',
:text => keyword.name.slice(0, 80),
:match_type => AdwordsConfig.config[:estimate_match]
}
end
keywords = keywords.map{|keyword| {:keyword => keyword}}
ad_group = {
:keyword_estimate_requests => keywords,
:max_cpc => {
:micro_amount => (1000000 * estimate_cpc).to_i
}
}
campaign = {
:ad_group_estimate_requests => [ad_group],
:criteria => [
{:xsi_type => 'Location', :id => AdwordsConfig.config[:target_location]}
],
:network_setting => {
:target_google_search => true,
:target_search_network => false,
:target_content_network => false
}
}
selector = {:campaign_estimate_requests => [campaign]}
response = service.get(selector)
if response and response[:campaign_estimates]
keyword_estimates = response[:campaign_estimates].first[:ad_group_estimates].first[:keyword_estimates]
keyword_estimates.each_with_index do |estimate, index|
object = objects.at(index)
object.clicks = ((estimate[:min][:clicks_per_day] + estimate[:max][:clicks_per_day]) / 2 * 30).to_i
#object.cpc = ((estimate[:min][:average_cpc][:micro_amount].to_f / 1000000) + (estimate[:max][:average_cpc][:micro_amount].to_f / 1000000)) / 2
object.ctr = (estimate[:min][:click_through_rate] + estimate[:max][:click_through_rate]) / 2
#object.impressions = (estimate[:min][:impressions_per_day] + estimate[:max][:impressions_per_day]) / 2 * 30
object.conversion = AdwordsConfig.config[:magic_conversion]
end
end
if objects.count == 2000 # Loop not done
sleep(@@RETRY_INTERVAL)
end
end
if !no_save
ActiveRecord::Base.transaction do
keywords.each{|keyword| keyword.save}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment