Last active
September 9, 2019 18:00
-
-
Save klmansel/090541647b135417510af237fd70f3d1 to your computer and use it in GitHub Desktop.
ApiMetrics module created to track Google Ads API calls
This file contains 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
class AdwordsApiService::AdGroupGateway < AdwordsApiService::Base | |
def find(ad_group_id) | |
selector = { | |
fields: ad_group_fields, | |
predicates: [ | |
{ | |
field: "Id", | |
operator: "EQUALS", | |
values: [ad_group_id] | |
} | |
] | |
} | |
begin | |
response = api_service.get(selector) | |
if response[:total_num_entries] > 0 | |
AdGroupSerializer.deserialize(response[:entries].first) | |
else | |
raise AdwordsApiService::Error, "Ad Group not found" | |
end | |
rescue TypeError | |
raise AdwordsApiService::Error, "Ad Group not found" | |
end | |
end | |
def find_by_campaign_id(campaign_id) | |
selector = { | |
fields: ad_group_fields, | |
predicates: [ | |
{ | |
field: "CampaignId", | |
operator: "EQUALS", | |
values: [campaign_id] | |
} | |
] | |
} | |
begin | |
response = api_service.get(selector) | |
if response && response[:entries] | |
AdGroupSerializer.deserialize(response[:entries]) | |
else | |
[] | |
end | |
rescue AdwordsApi::Errors::ApiException => error | |
raise AdwordsApiService::Error, error.message | |
end | |
end | |
def create(ad_group) | |
serialized_ad_group = AdGroupSerializer.serialize(ad_group) | |
operation = { | |
operator: "ADD", | |
operand: serialized_ad_group | |
} | |
mutate(operation) | |
end | |
def update(ad_group) | |
serialized_ad_group = AdGroupSerializer.serialize(ad_group) | |
operation = { | |
operator: "SET", | |
operand: serialized_ad_group | |
} | |
mutate(operation) | |
end | |
def link_audience_to_ad_group(ad_group_id, audience_id) | |
operation = { | |
operator: "ADD", | |
operand: { | |
xsi_type: "BiddableAdGroupCriterion", | |
ad_group_id: ad_group_id, | |
criterion: { | |
xsi_type: "CriterionUserList", | |
user_list_id: audience_id | |
} | |
} | |
} | |
begin | |
response = @api_service ||= configure_api_service(:AdGroupCriterionService).mutate([operation]) | |
response[:value].first | |
rescue AdwordsApi::Errors::ApiException => error | |
raise AdwordsApiService::Error, error.message | |
rescue AdsCommon::Errors::UnexpectedParametersError | |
raise AdwordsApiService::Error, "Invalid request" | |
end | |
end | |
private | |
def mutate(operation) | |
response = api_service.mutate([operation]) | |
response[:value].first | |
rescue AdwordsApi::Errors::ApiException => error | |
raise AdwordsApiService::Error, error.message | |
end | |
def api_service | |
@api_service ||= configure_api_service(:AdGroupService) | |
end | |
def ad_group_fields | |
[ | |
"Id", "Name", "Status", "CampaignId", "BiddingStrategySource", "CpcBid", "CpmBid" | |
] | |
end | |
end |
This file contains 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
class Admin::ApiCallsController < AdminController | |
def index | |
@api_calls = policy_scope(ApiCall).where("created_at > ?", 30.days.ago) | |
@daily_calls = @api_calls.group_by_day(:created_at).count | |
@weekly_calls = @api_calls.group_by_week(:created_at, time_zone: "Eastern Time (US & Canada)").count | |
@last_hour_calls = policy_scope(ApiCall).where("created_at > ?", 1.hour.ago).count | |
end | |
end |
This file contains 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
# services/adwords_api_service/base.rb | |
class AdwordsApiService::Base | |
# The ApiMetrics module creates an ApiCall record for each | |
# get and mutate operation. This module must prepend an AdwordsApi::Api | |
# instance and is used in gateways by chaining 'class.prepend ApiMetrics' | |
# to API service instantiation | |
# @author [karamansel] | |
module ApiMetrics | |
RECORDED_METHODS = [:mutate, :get].freeze | |
RECORDED_METHODS.each do |method| | |
define_method method do |*args| | |
super(*args) do |header| | |
header[:operations].times do | |
ApiCall.create!( | |
service_name: header[:service_name], | |
method_name: header[:method_name] | |
) | |
end | |
end | |
end | |
end | |
end | |
include CustomExceptions | |
API_VERSION = :v201809 | |
def initialize(oauth2_token, client_customer_id = nil) | |
# unrelated code removed | |
end | |
# The only Adwords endpoint that does not require a customer's Adwords Customer ID | |
# Used when they Oauth with our application to fetch their Customer ID. | |
def ads_accounts | |
# unrelated code removed | |
end | |
private | |
def authentication_headers | |
# unrelated code removed | |
end | |
# log level options in order of least to most logging: | |
# FATAL, ERROR, WARN, INFO, DEBUG | |
def environment_based_log_level | |
# unrelated code removed | |
end | |
protected | |
def configure_api_service(service_name) | |
service = @adwords.service(service_name) | |
service.class.prepend ApiMetrics unless Rails.env.development? | |
service | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment