Class: Adapi::Api
- Inherits:
-
Object
- Object
- Adapi::Api
- Extended by:
- ActiveModel::Naming
- Includes:
- ActiveModel::Conversion, ActiveModel::Validations
- Defined in:
- lib/adapi/api.rb
Direct Known Subclasses
Ad, AdGroup, AdGroupCriterion, AdParam, BudgetOrder, Campaign, CampaignCriterion, CampaignTarget, ConstantData, Location, ManagedCustomer
Defined Under Namespace
Classes: AdGroupError, ApiError, CampaignError
Constant Summary collapse
- LOGGER =
Config.setup_logger
- API_EXCEPTIONS =
[ AdsCommon::Errors::ApiException, AdsCommon::Errors::HttpError, AdwordsApi::Errors::ApiException ]
Instance Attribute Summary collapse
-
#adwords ⇒ Object
Returns the value of attribute adwords.
-
#id ⇒ Object
Returns the value of attribute id.
-
#params ⇒ Object
Returns the value of attribute params.
-
#service ⇒ Object
Returns the value of attribute service.
-
#status ⇒ Object
Returns the value of attribute status.
-
#version ⇒ Object
Returns the value of attribute version.
-
#xsi_type ⇒ Object
Returns the value of attribute xsi_type.
Class Method Summary collapse
- .create(params = {}) ⇒ Object
-
.to_micro_units(x) ⇒ Object
convert number to micro units (unit * one million).
-
.update(params = {}) ⇒ Object
done mostly for campaign, probably won’t work pretty much anywhere else which can be easily fixed creating by self.update method for specific class.
Instance Method Summary collapse
-
#[](k) ⇒ Object
FIXME hotfix, should be able to sort it out better through ActiveModel.
- #[]=(k, v) ⇒ Object
-
#attributes ⇒ Object
(also: #to_hash)
Returns hash of attributes for a model instance.
-
#check_for_errors(adapi_instance, options = {}) ⇒ Object
Deals with campaign exceptions encountered during complex operations over AdWords API.
-
#initialize(params = {}) ⇒ Api
constructor
A new instance of Api.
-
#mutate(operation) ⇒ Object
wrap AdWords add/update/destroy actions and deals with errors PS: Keyword and Ad models have their own wrappers because of PolicyViolations.
-
#new? ⇒ Boolean
detects whether the instance has been saved already.
- #persisted? ⇒ Boolean
-
#store_errors(failed_instance, error_prefix = nil) ⇒ Object
Shortcut for pattern used in Campaign#update method When partial update fails, store errors in main campaign instance.
- #to_param ⇒ Object
Constructor Details
#initialize(params = {}) ⇒ Api
Returns a new instance of Api.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/adapi/api.rb', line 42 def initialize(params = {}) params.symbolize_keys! raise "Missing Service Name" unless params[:service_name] @adwords = params[:adwords_api_instance] # REFACTOR unless @adwords @adwords = AdwordsApi::Api.new(Adapi::Config.read) authentication_method = Adapi::Config.read[:authentication][:method].to_s.upcase case authentication_method when "CLIENTLOGIN", "OAUTH" warn "#{authentication_method} is nearly obsolete, please update to OAuth2" when "OAUTH2_JWT" raise "OAUTH2_JWT is not yet implemented, please use OAUTH2 instead" # authorize to oauth2 when "OAUTH2" oauth2_token = Adapi::Config.read[:authentication][:oauth2_token] if oauth2_token.nil? || oauth2_token.class != Hash raise "Missing or invalid OAuth2 token" end @adwords.({:oauth2_verification_code => $token}) end end @adwords.logger = LOGGER if LOGGER @version = API_VERSION @service = @adwords.service(params[:service_name].to_sym, @version) @params = params end |
Instance Attribute Details
#adwords ⇒ Object
Returns the value of attribute adwords.
30 31 32 |
# File 'lib/adapi/api.rb', line 30 def adwords @adwords end |
#id ⇒ Object
Returns the value of attribute id.
30 31 32 |
# File 'lib/adapi/api.rb', line 30 def id @id end |
#params ⇒ Object
Returns the value of attribute params.
30 31 32 |
# File 'lib/adapi/api.rb', line 30 def params @params end |
#service ⇒ Object
Returns the value of attribute service.
30 31 32 |
# File 'lib/adapi/api.rb', line 30 def service @service end |
#status ⇒ Object
Returns the value of attribute status.
30 31 32 |
# File 'lib/adapi/api.rb', line 30 def status @status end |
#version ⇒ Object
Returns the value of attribute version.
30 31 32 |
# File 'lib/adapi/api.rb', line 30 def version @version end |
#xsi_type ⇒ Object
Returns the value of attribute xsi_type.
30 31 32 |
# File 'lib/adapi/api.rb', line 30 def xsi_type @xsi_type end |
Class Method Details
.create(params = {}) ⇒ Object
103 104 105 106 107 108 109 110 |
# File 'lib/adapi/api.rb', line 103 def self.create(params = {}) # FIXME deep symbolize_keys, probably through ActiveSupport params.symbolize_keys! if params.is_a?(Hash) api_instance = self.new(params) api_instance.create api_instance end |
.to_micro_units(x) ⇒ Object
convert number to micro units (unit * one million)
227 228 229 |
# File 'lib/adapi/api.rb', line 227 def self.to_micro_units(x) (x.to_f * 1e6).to_i end |
.update(params = {}) ⇒ Object
done mostly for campaign, probably won’t work pretty much anywhere else which can be easily fixed creating by self.update method for specific class
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/adapi/api.rb', line 116 def self.update(params = {}) params.symbolize_keys! # PS: updating campaign without finding it is much faster api_instance = self.new() api_instance.id = params.delete(:id) api_instance.errors.add('id', 'is missing') unless api_instance.id api_instance.update(params) api_instance end |
Instance Method Details
#[](k) ⇒ Object
FIXME hotfix, should be able to sort it out better through ActiveModel
87 88 89 |
# File 'lib/adapi/api.rb', line 87 def [](k) self.send(k) end |
#[]=(k, v) ⇒ Object
91 92 93 |
# File 'lib/adapi/api.rb', line 91 def []=(k,v) self.send("#{k}=", v) end |
#attributes ⇒ Object Also known as: to_hash
Returns hash of attributes for a model instance
This is an implementation of ActiveRecord::Base#attributes method. Children of API model customize this method for their own attributes.
38 39 40 |
# File 'lib/adapi/api.rb', line 38 def attributes { status: status, xsi_type: xsi_type } end |
#check_for_errors(adapi_instance, options = {}) ⇒ Object
Deals with campaign exceptions encountered during complex operations over AdWords API
Parameters: store_errors (default: true) - add errors to self.error collection raise_errors (default: false) - raises exception CampaignError (after optional saving errors)
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/adapi/api.rb', line 186 def check_for_errors(adapi_instance, = {}) .merge!( store_errors: true, raise_errors: false ) # don't store errors in this case, because errors are already there # and loop in store_errors method would cause application to hang [:store_errors] = false if (adapi_instance == self) unless adapi_instance.errors.empty? store_errors(adapi_instance, [:prefix]) if [:store_errors] if [:raise_errors] exception_type = case adapi_instance.xsi_type when "Campaign" then CampaignError when "AdGroup" then AdGroupError else ApiError end raise exception_type end end end |
#mutate(operation) ⇒ Object
wrap AdWords add/update/destroy actions and deals with errors PS: Keyword and Ad models have their own wrappers because of PolicyViolations
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/adapi/api.rb', line 132 def mutate(operation) operation = [operation] unless operation.is_a?(Array) # fix to save space during specifyng operations operation = operation.map do |op| op[:operand].delete(:status) if op[:operand][:status].nil? op end begin response = @service.mutate(operation) rescue *API_EXCEPTIONS => e unless e.respond_to?(:errors) self.errors.add(:base, e.) return false end e.errors.each do |error| if (error[:xsi_type] == 'PolicyViolationError') || (error[:api_error_type] == 'PolicyViolationError') # return exemptable PolicyViolations errors in custom format so we can request exemptions # see adwords-api gem example for details: handle_policy_violation_error.rb # so far, this applies only for keywords and ads if error[:is_exemptable] self.errors.add( :PolicyViolationError, error[:key].merge( :operation_index => AdwordsApi::Utils.operation_index_for_error(error) ) ) end # besides PolicyViolations errors in custom format, return all errors also in regular format self.errors.add(:base, "violated %s policy: \"%s\" on \"%s\"" % [ error[:is_exemptable] ? 'exemptable' : 'non-exemptable', error[:key][:policy_name], error[:key][:violating_text] ]) else self.errors.add(:base, e.) end end # of errors.each false end response end |
#new? ⇒ Boolean
detects whether the instance has been saved already
99 100 101 |
# File 'lib/adapi/api.rb', line 99 def new? self.id.blank? end |
#persisted? ⇒ Boolean
82 83 84 |
# File 'lib/adapi/api.rb', line 82 def persisted? false end |
#store_errors(failed_instance, error_prefix = nil) ⇒ Object
Shortcut for pattern used in Campaign#update method When partial update fails, store errors in main campaign instance
211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/adapi/api.rb', line 211 def store_errors(failed_instance, error_prefix = nil) raise "#{failed_instance.xsi_type}#store_errors: Invalid object instance" unless failed_instance.respond_to?(:errors) error_prefix ||= failed_instance.respond_to?(:xsi_type) ? failed_instance.xsi_type : nil failed_instance.errors..each_pair do |k, v| k = "#{error_prefix}::#{k}" if error_prefix and (k != :base) Array(v).each do |x| self.errors.add(k, x) end end end |
#to_param ⇒ Object
78 79 80 |
# File 'lib/adapi/api.rb', line 78 def to_param self[:id] end |