google-ads-googleads 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog +8 -0
- data/google_ads_config.rb +6 -0
- data/lib/google/ads/google_ads/api_versions.rb +8 -0
- data/lib/google/ads/google_ads/config.rb +2 -0
- data/lib/google/ads/google_ads/google_ads_client.rb +37 -66
- data/lib/google/ads/google_ads/logging_interceptor.rb +108 -36
- data/lib/google/ads/google_ads/lookup_util.rb +105 -0
- data/lib/google/ads/google_ads/partial_failure_error_decoder.rb +24 -0
- data/lib/google/ads/google_ads/utils/v0/proto_lookup_util.rb +4 -1
- data/lib/google/ads/google_ads/utils/v1/path_lookup_util.rb +11 -1
- data/lib/google/ads/google_ads/utils/v1/proto_lookup_util.rb +39 -6
- data/lib/google/ads/google_ads/v1/common/ad_asset_pb.rb +12 -0
- data/lib/google/ads/google_ads/v1/common/ad_type_infos_pb.rb +39 -0
- data/lib/google/ads/google_ads/v1/common/asset_types_pb.rb +34 -0
- data/lib/google/ads/google_ads/v1/common/bidding_pb.rb +4 -0
- data/lib/google/ads/google_ads/v1/common/criteria_pb.rb +4 -0
- data/lib/google/ads/google_ads/v1/common/policy_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/common/segments_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/enums/ad_group_criterion_approval_status_pb.rb +23 -0
- data/lib/google/ads/google_ads/v1/enums/ad_group_type_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/enums/ad_type_pb.rb +3 -0
- data/lib/google/ads/google_ads/v1/enums/advertising_channel_sub_type_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/enums/advertising_channel_type_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/enums/app_campaign_app_store_pb.rb +21 -0
- data/lib/google/ads/google_ads/v1/enums/app_campaign_bidding_strategy_goal_type_pb.rb +23 -0
- data/lib/google/ads/google_ads/v1/enums/asset_type_pb.rb +22 -0
- data/lib/google/ads/google_ads/v1/enums/bidding_source_pb.rb +2 -2
- data/lib/google/ads/google_ads/v1/enums/budget_type_pb.rb +21 -0
- data/lib/google/ads/google_ads/v1/enums/conversion_adjustment_type_pb.rb +21 -0
- data/lib/google/ads/google_ads/v1/enums/legacy_app_install_ad_app_store_pb.rb +24 -0
- data/lib/google/ads/google_ads/v1/enums/payment_mode_pb.rb +21 -0
- data/lib/google/ads/google_ads/v1/enums/recommendation_type_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/errors/asset_error_pb.rb +23 -0
- data/lib/google/ads/google_ads/v1/errors/authorization_error_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/errors/bidding_error_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/errors/campaign_error_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/errors/conversion_adjustment_upload_error_pb.rb +28 -0
- data/lib/google/ads/google_ads/v1/errors/conversion_upload_error_pb.rb +6 -0
- data/lib/google/ads/google_ads/v1/errors/criterion_error_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/errors/errors_pb.rb +4 -0
- data/lib/google/ads/google_ads/v1/errors/media_upload_error_pb.rb +11 -0
- data/lib/google/ads/google_ads/v1/errors/mutate_error_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/errors/policy_validation_parameter_error_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/errors/recommendation_error_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/errors/request_error_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/errors/youtube_video_registration_error_pb.rb +11 -0
- data/lib/google/ads/google_ads/v1/resources/ad_group_criterion_pb.rb +3 -0
- data/lib/google/ads/google_ads/v1/resources/ad_pb.rb +3 -0
- data/lib/google/ads/google_ads/v1/resources/asset_pb.rb +26 -0
- data/lib/google/ads/google_ads/v1/resources/campaign_budget_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/resources/campaign_criterion_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/resources/campaign_pb.rb +23 -11
- data/lib/google/ads/google_ads/v1/resources/extension_feed_item_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/resources/mutate_job_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/resources/recommendation_pb.rb +21 -8
- data/lib/google/ads/google_ads/v1/resources/shared_criterion_pb.rb +1 -0
- data/lib/google/ads/google_ads/v1/services/ad_group_criterion_service_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/services/asset_service_client.rb +267 -0
- data/lib/google/ads/google_ads/v1/services/asset_service_client_config.json +36 -0
- data/lib/google/ads/google_ads/v1/services/asset_service_pb.rb +35 -0
- data/lib/google/ads/google_ads/v1/services/asset_service_services_pb.rb +42 -0
- data/lib/google/ads/google_ads/v1/services/conversion_adjustment_upload_service_client.rb +222 -0
- data/lib/google/ads/google_ads/v1/services/conversion_adjustment_upload_service_client_config.json +31 -0
- data/lib/google/ads/google_ads/v1/services/conversion_adjustment_upload_service_pb.rb +56 -0
- data/lib/google/ads/google_ads/v1/services/conversion_adjustment_upload_service_services_pb.rb +40 -0
- data/lib/google/ads/google_ads/v1/services/conversion_upload_service_client.rb +53 -0
- data/lib/google/ads/google_ads/v1/services/conversion_upload_service_client_config.json +5 -0
- data/lib/google/ads/google_ads/v1/services/conversion_upload_service_pb.rb +27 -0
- data/lib/google/ads/google_ads/v1/services/conversion_upload_service_services_pb.rb +2 -0
- data/lib/google/ads/google_ads/v1/services/google_ads_service_pb.rb +5 -0
- data/lib/google/ads/google_ads/v1/services/recommendation_service_pb.rb +5 -0
- data/lib/google/ads/google_ads/v1/services/shopping_performance_view_service_client.rb +19 -6
- data/lib/google/ads/google_ads/version.rb +1 -1
- data/lib/google/ads/google_ads/wrapper_util.rb +4 -0
- data/lib/google/ads/google_ads.rb +4 -0
- metadata +27 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4cf7ec45c64d8e3b15c113cedc904e46d667d301740608146d0985537f6e3e44
|
|
4
|
+
data.tar.gz: 0a33073c1cf8401df2388172f6026d4c0cbe3a4f8f8e81b5da710ac57766dc01
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d36f3d385b11ce0efa43e7c4008af8569f4b3f1133d8c151eb1cf472958c50489c3dbd43c8180935588a21ef47413fea5135785187b84297a3ab27b28f2d012
|
|
7
|
+
data.tar.gz: 7c42c6b2bc5edb4f5b795ffe5b5316d0e5a539a6ceaa5dd1a913b5c7f1c54a61c4bc5f0873ea3ac8c215ebe8599699a54df712dd962a94fc3b9c6e50725bc945
|
data/ChangeLog
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
1.1.0:
|
|
2
|
+
- Adding support for Google Ads API v1_1.
|
|
3
|
+
- Refactored proto and path lookup utils to be accessible before client
|
|
4
|
+
instantiation.
|
|
5
|
+
- Numerous fixes to logging, including support for logging large images and
|
|
6
|
+
partial failure errors.
|
|
7
|
+
- New partial failure decoder utility.
|
|
8
|
+
|
|
1
9
|
1.0.0:
|
|
2
10
|
- Adding support for Google Ads API v1.
|
|
3
11
|
- Adding support for versioned path and proto lookup utils.
|
data/google_ads_config.rb
CHANGED
|
@@ -31,4 +31,10 @@ Google::Ads::GoogleAds::Config.new do |c|
|
|
|
31
31
|
# You can provide a filename as a String, an IO object like STDOUT or STDERR,
|
|
32
32
|
# or an open file.
|
|
33
33
|
c.log_target = STDOUT
|
|
34
|
+
|
|
35
|
+
# Instead of specifying logging through level and target, you can also
|
|
36
|
+
# pass a logger directly (for e.g. passing Rails.logger in a
|
|
37
|
+
# config/initializer). The passed logger will override log_level and
|
|
38
|
+
# log_target
|
|
39
|
+
# c.logger = Logger.new(STDOUT)
|
|
34
40
|
end
|
|
@@ -28,6 +28,7 @@ module Google
|
|
|
28
28
|
|
|
29
29
|
attr_accessor :log_level
|
|
30
30
|
attr_accessor :log_target
|
|
31
|
+
attr_accessor :logger
|
|
31
32
|
|
|
32
33
|
def initialize(&block)
|
|
33
34
|
@refresh_token = nil
|
|
@@ -38,6 +39,7 @@ module Google
|
|
|
38
39
|
|
|
39
40
|
@log_level = nil
|
|
40
41
|
@log_target = nil
|
|
42
|
+
@logger = nil
|
|
41
43
|
yield self if block_given?
|
|
42
44
|
end
|
|
43
45
|
|
|
@@ -55,6 +55,7 @@ require 'googleauth'
|
|
|
55
55
|
require 'google/ads/google_ads/patches'
|
|
56
56
|
require 'google/ads/google_ads/config'
|
|
57
57
|
require 'google/ads/google_ads/field_mask_util'
|
|
58
|
+
require 'google/ads/google_ads/lookup_util'
|
|
58
59
|
require 'google/ads/google_ads/wrapper_util'
|
|
59
60
|
require 'google/ads/google_ads/logging_interceptor'
|
|
60
61
|
|
|
@@ -69,12 +70,12 @@ module Google
|
|
|
69
70
|
module Ads
|
|
70
71
|
module GoogleAds
|
|
71
72
|
class GoogleAdsClient
|
|
72
|
-
DEFAULT_API_VERSION = :V1
|
|
73
|
-
KNOWN_API_VERSIONS = [:V0, :V1]
|
|
74
73
|
|
|
75
74
|
DEFAULT_CONFIG_FILENAME = 'google_ads_config.rb'
|
|
76
75
|
|
|
77
76
|
attr_reader :logger
|
|
77
|
+
# Allow setting the lookup_util manually for users who use it before creating the client.
|
|
78
|
+
attr_writer :lookup_util
|
|
78
79
|
|
|
79
80
|
def initialize(config_path = nil, &block)
|
|
80
81
|
if block_given?
|
|
@@ -103,8 +104,6 @@ module Google
|
|
|
103
104
|
end
|
|
104
105
|
@config = eval_result
|
|
105
106
|
end
|
|
106
|
-
@proto_lookup_utils = {}
|
|
107
|
-
@path_lookup_utils = {}
|
|
108
107
|
|
|
109
108
|
begin
|
|
110
109
|
@logger = create_default_logger
|
|
@@ -122,21 +121,24 @@ module Google
|
|
|
122
121
|
# :Campaign will return an instantiated CampaignServiceClient.
|
|
123
122
|
#
|
|
124
123
|
# Raises ArgumentError if no service can be found for the provided type.
|
|
125
|
-
def service(name, version =
|
|
124
|
+
def service(name, version = default_api_version)
|
|
126
125
|
service_path = ENV['GOOGLEADS_SERVICE_PATH']
|
|
127
126
|
|
|
128
127
|
# We need a local reference to refer to from within the class block
|
|
129
128
|
# below.
|
|
130
129
|
logger = @logger
|
|
131
130
|
|
|
132
|
-
class_to_return =
|
|
131
|
+
class_to_return = lookup_util.raw_service(name, version)
|
|
133
132
|
class_to_return = Class.new(class_to_return) do
|
|
134
133
|
unless service_path.nil? || service_path.empty?
|
|
135
134
|
const_set('SERVICE_ADDRESS', service_path.freeze)
|
|
136
135
|
end
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
|
|
137
|
+
if logger
|
|
138
|
+
logging_interceptor =
|
|
139
|
+
Google::Ads::GoogleAds::LoggingInterceptor.new(logger)
|
|
140
|
+
const_set('GRPC_INTERCEPTORS', [logging_interceptor])
|
|
141
|
+
end
|
|
140
142
|
end
|
|
141
143
|
|
|
142
144
|
headers = {
|
|
@@ -144,7 +146,7 @@ module Google
|
|
|
144
146
|
}
|
|
145
147
|
if @config.login_customer_id
|
|
146
148
|
login_customer_id = @config.login_customer_id
|
|
147
|
-
if !login_customer_id.is_a?
|
|
149
|
+
if !login_customer_id.is_a?(Integer) || login_customer_id <= 0 ||
|
|
148
150
|
login_customer_id > 9_999_999_999
|
|
149
151
|
raise sprintf('Invalid login_customer_id. Must be an integer ' \
|
|
150
152
|
'0 < x <= 9,999,999,999. Got %s', login_customer_id)
|
|
@@ -162,16 +164,16 @@ module Google
|
|
|
162
164
|
# example, passing :Campaign will return an instantiated Campaign.
|
|
163
165
|
#
|
|
164
166
|
# Raises ArgumentError if no entity can be found for the provided type.
|
|
165
|
-
def resource(name, version =
|
|
166
|
-
|
|
167
|
+
def resource(name, version = default_api_version)
|
|
168
|
+
lookup_util.resource(name, version)
|
|
167
169
|
end
|
|
168
170
|
|
|
169
171
|
# Return an operation for the provided entity type. For example, passing
|
|
170
172
|
# :Campaign will return an instantiated CampaignOperation.
|
|
171
173
|
#
|
|
172
174
|
# Raises ArgumentError if no entity can be found for the provided type.
|
|
173
|
-
def operation(name, version =
|
|
174
|
-
|
|
175
|
+
def operation(name, version = default_api_version)
|
|
176
|
+
lookup_util.operation(name, version)
|
|
175
177
|
end
|
|
176
178
|
|
|
177
179
|
# Return a reference to the enum class for the provided enum type. For
|
|
@@ -179,8 +181,8 @@ module Google
|
|
|
179
181
|
# CampaignStatusEnum.
|
|
180
182
|
#
|
|
181
183
|
# Raises ArgumentError if no enum can be found for the provided type.
|
|
182
|
-
def enum(name, version =
|
|
183
|
-
|
|
184
|
+
def enum(name, version = default_api_version)
|
|
185
|
+
lookup_util.enum(name, version)
|
|
184
186
|
end
|
|
185
187
|
|
|
186
188
|
# Returns a reference to the FieldMaskUtil class for ease of access.
|
|
@@ -194,8 +196,8 @@ module Google
|
|
|
194
196
|
end
|
|
195
197
|
|
|
196
198
|
# Returns a reference to the PathLookupUtil to generate resource names.
|
|
197
|
-
def path(version =
|
|
198
|
-
|
|
199
|
+
def path(version = default_api_version)
|
|
200
|
+
lookup_util.path(version)
|
|
199
201
|
end
|
|
200
202
|
|
|
201
203
|
# Set the logger to use. This will only take effect on services fetched
|
|
@@ -204,6 +206,13 @@ module Google
|
|
|
204
206
|
@logger = logger
|
|
205
207
|
end
|
|
206
208
|
|
|
209
|
+
# Decode a partial failure error from a response.
|
|
210
|
+
# See Google::Ads::GoogleAds::PartialFailureErrorDecoder for full
|
|
211
|
+
# documentation.
|
|
212
|
+
def decode_partial_failure_error(pfe)
|
|
213
|
+
PartialFailureErrorDecoder.decode(pfe)
|
|
214
|
+
end
|
|
215
|
+
|
|
207
216
|
private
|
|
208
217
|
|
|
209
218
|
ERROR_TRANSFORMER = Proc.new do |gax_error|
|
|
@@ -249,59 +258,21 @@ module Google
|
|
|
249
258
|
|
|
250
259
|
# Create the default logger, useful if the user hasn't defined one.
|
|
251
260
|
def create_default_logger()
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
KNOWN_API_VERSIONS.include?(version)
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
# Load up the proto lookup util for the given version, storing a copy
|
|
262
|
-
# of it if this is the first time we needed it.
|
|
263
|
-
def proto_lookup_util(version)
|
|
264
|
-
unless valid_version?(version)
|
|
265
|
-
raise sprintf('Unknown version %s', version)
|
|
266
|
-
end
|
|
267
|
-
if @proto_lookup_utils[version].nil?
|
|
268
|
-
path_version = version.downcase
|
|
269
|
-
require sprintf('google/ads/google_ads/utils/%s/proto_lookup_util',
|
|
270
|
-
path_version)
|
|
271
|
-
class_path = sprintf(
|
|
272
|
-
'Google::Ads::GoogleAds::Utils::%s::ProtoLookupUtil',
|
|
273
|
-
version
|
|
274
|
-
)
|
|
275
|
-
@proto_lookup_utils[version] = class_for_path(class_path).new
|
|
261
|
+
if @config.logger.nil?
|
|
262
|
+
logger = Logger.new(@config.log_target)
|
|
263
|
+
logger.level = Logger.const_get(@config.log_level)
|
|
264
|
+
logger
|
|
265
|
+
else
|
|
266
|
+
@config.logger
|
|
276
267
|
end
|
|
277
|
-
@proto_lookup_utils[version]
|
|
278
268
|
end
|
|
279
269
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
def path_lookup_util(version)
|
|
283
|
-
unless valid_version?(version)
|
|
284
|
-
raise sprintf('Unknown version %s', version)
|
|
285
|
-
end
|
|
286
|
-
if @path_lookup_utils[version].nil?
|
|
287
|
-
path_version = version.downcase
|
|
288
|
-
require sprintf('google/ads/google_ads/utils/%s/path_lookup_util',
|
|
289
|
-
path_version)
|
|
290
|
-
class_path = sprintf(
|
|
291
|
-
'Google::Ads::GoogleAds::Utils::%s::PathLookupUtil',
|
|
292
|
-
version
|
|
293
|
-
)
|
|
294
|
-
@path_lookup_utils[version] = class_for_path(class_path).new(
|
|
295
|
-
proto_lookup_util(version))
|
|
296
|
-
end
|
|
297
|
-
@path_lookup_utils[version]
|
|
270
|
+
def lookup_util
|
|
271
|
+
@lookup_util ||= Google::Ads::GoogleAds::LookupUtil.new
|
|
298
272
|
end
|
|
299
273
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
path.split('::').inject(Kernel) do |scope, const_name|
|
|
303
|
-
scope.const_get(const_name)
|
|
304
|
-
end
|
|
274
|
+
def default_api_version
|
|
275
|
+
Google::Ads::GoogleAds::DEFAULT_API_VERSION
|
|
305
276
|
end
|
|
306
277
|
end
|
|
307
278
|
end
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
#
|
|
17
17
|
# Interceptor to log outgoing requests and incoming responses.
|
|
18
18
|
|
|
19
|
+
require 'google/ads/google_ads/api_versions'
|
|
20
|
+
require 'google/ads/google_ads/partial_failure_error_decoder'
|
|
19
21
|
require 'grpc/generic/interceptors'
|
|
20
22
|
require 'json'
|
|
21
23
|
|
|
@@ -23,56 +25,126 @@ module Google
|
|
|
23
25
|
module Ads
|
|
24
26
|
module GoogleAds
|
|
25
27
|
class LoggingInterceptor < GRPC::ClientInterceptor
|
|
28
|
+
INTERESTING_ERROR_CLASSES = ::Google::Ads::GoogleAds::KNOWN_API_VERSIONS.map { |v|
|
|
29
|
+
require "google/ads/google_ads/#{v.downcase}/errors/errors_pb"
|
|
30
|
+
const_get("Google::Ads::GoogleAds::#{v}::Errors::GoogleAdsFailure")
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
def initialize(logger)
|
|
34
|
+
# Don't propagate args, parens are necessary
|
|
27
35
|
super()
|
|
28
36
|
@logger = logger
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
def request_response(request:, call:, method:, metadata: {})
|
|
40
|
+
begin
|
|
41
|
+
response = yield
|
|
42
|
+
|
|
43
|
+
@logger.info(build_summary_message(request, call, method, false))
|
|
44
|
+
@logger.debug(build_request_message(metadata, request))
|
|
45
|
+
@logger.debug(build_success_response_message(response))
|
|
46
|
+
if response.respond_to?(:partial_failure_error) && response.partial_failure_error
|
|
47
|
+
@logger.warn(build_partial_failure_message(response))
|
|
48
|
+
end
|
|
49
|
+
response
|
|
50
|
+
rescue Exception
|
|
51
|
+
@logger.warn(build_summary_message(request, call, method, true))
|
|
52
|
+
@logger.info(build_request_message(metadata, request))
|
|
53
|
+
@logger.info(build_error_response_message)
|
|
54
|
+
raise
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def build_partial_failure_message(response)
|
|
61
|
+
errors = PartialFailureErrorDecoder.decode(
|
|
62
|
+
response.partial_failure_error
|
|
63
|
+
)
|
|
64
|
+
errors.reduce("Partial failure errors: ") do |accum, error|
|
|
65
|
+
accum += error.to_json + "\n"
|
|
66
|
+
accum
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def build_error_response_message
|
|
71
|
+
# this looks like "magic", but the Google::Gax::GaxError grabs
|
|
72
|
+
# the current exception as its cause, and then parses details
|
|
73
|
+
# out of that exception. So this sets it up so that
|
|
74
|
+
# most_recent_error.status_details contains useful information about
|
|
75
|
+
# our failure
|
|
76
|
+
most_recent_error = Google::Gax::GaxError.new('')
|
|
77
|
+
response_message = "Incoming response (errors): \n"
|
|
78
|
+
|
|
79
|
+
formatted_details = case most_recent_error.status_details
|
|
80
|
+
when nil
|
|
81
|
+
""
|
|
82
|
+
when String
|
|
83
|
+
most_recent_error.status_details
|
|
84
|
+
when Array
|
|
85
|
+
most_recent_error.status_details.select { |detail|
|
|
86
|
+
INTERESTING_ERROR_CLASSES.include?(detail.class)
|
|
87
|
+
}.map { |detail|
|
|
88
|
+
response_error_from_detail(detail)
|
|
89
|
+
}.join("\n")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
response_message += formatted_details
|
|
93
|
+
response_message
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def build_success_response_message(response)
|
|
97
|
+
"Incoming response: Payload: #{response.to_json}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def build_request_message(metadata, request)
|
|
101
|
+
# calling #to_json on some protos (specifically those with non-UTF8
|
|
102
|
+
# encodable byte values) causes a segfault, however #inspect works
|
|
103
|
+
# so we check if the proto contains a bytevalue, and if it does
|
|
104
|
+
# we #inspect instead of #to_json
|
|
105
|
+
request_inspect = if use_bytes_inspect?(request)
|
|
106
|
+
request.inspect
|
|
107
|
+
else
|
|
108
|
+
request.to_json
|
|
109
|
+
end
|
|
110
|
+
"Outgoing request: Headers: #{metadata.to_json} Payload: #{request_inspect}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def build_summary_message(request, call, method, is_fault)
|
|
32
114
|
customer_id = "N/A"
|
|
33
115
|
customer_id = request.customer_id if request.respond_to?(:customer_id)
|
|
34
116
|
# CustomerService get requests have a different format.
|
|
35
117
|
if request.respond_to?(:resource_name)
|
|
36
118
|
customer_id = request.resource_name.split('/').last
|
|
37
119
|
end
|
|
38
|
-
summary_message =
|
|
39
|
-
sprintf("CID: %s, Host: %s, Method: %s",
|
|
40
|
-
customer_id,
|
|
41
|
-
call.instance_variable_get('@wrapped').peer,
|
|
42
|
-
method
|
|
43
|
-
)
|
|
44
|
-
request_message = sprintf("Outgoing request: Headers: %s Payload: %s",
|
|
45
|
-
metadata.to_json, request.to_json)
|
|
46
|
-
begin
|
|
47
|
-
response = yield
|
|
48
|
-
summary_message += ", IsFault: no"
|
|
49
|
-
response_message = sprintf("Incoming response: Payload: %s",
|
|
50
|
-
response.to_json)
|
|
51
|
-
|
|
52
|
-
@logger.info(summary_message)
|
|
53
|
-
@logger.debug(request_message)
|
|
54
|
-
@logger.debug(response_message)
|
|
55
|
-
return response
|
|
56
|
-
rescue Exception => e
|
|
57
|
-
summary_message += sprintf(", IsFault: yes")
|
|
58
|
-
response_message = "Incoming response (errors): \n"
|
|
59
|
-
|
|
60
|
-
most_recent_error = Google::Gax::GaxError.new('')
|
|
61
|
-
most_recent_error.status_details && most_recent_error.status_details.each do |detail|
|
|
62
|
-
if detail.is_a?(
|
|
63
|
-
Google::Ads::GoogleAds::V0::Errors::GoogleAdsFailure)
|
|
64
|
-
detail.errors.each_with_index do |error, i|
|
|
65
|
-
response_message +=
|
|
66
|
-
sprintf("Error %d: %s\n", i + 1, error.to_json)
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
120
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
121
|
+
is_fault_string = if is_fault
|
|
122
|
+
"yes"
|
|
123
|
+
else
|
|
124
|
+
"no"
|
|
75
125
|
end
|
|
126
|
+
|
|
127
|
+
[
|
|
128
|
+
"CID: #{customer_id}",
|
|
129
|
+
"Host: #{call.instance_variable_get('@wrapped').peer}",
|
|
130
|
+
"Method: #{method}",
|
|
131
|
+
"IsFault: #{is_fault_string}",
|
|
132
|
+
].join(", ")
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def response_error_from_detail(detail)
|
|
136
|
+
detail.errors.map.with_index { |error, i|
|
|
137
|
+
"Error #{i + 1}: #{error.to_json}"
|
|
138
|
+
}.join("\n")
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def use_bytes_inspect?(request)
|
|
142
|
+
contains_bytes_field?(request.class.descriptor)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def contains_bytes_field?(descriptor)
|
|
146
|
+
return false if descriptor.nil?
|
|
147
|
+
descriptor.map { |x| x.type == :bytes || (x.type == :message && contains_bytes_field?(x.subtype)) }.any?
|
|
76
148
|
end
|
|
77
149
|
end
|
|
78
150
|
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
module Google
|
|
2
|
+
module Ads
|
|
3
|
+
module GoogleAds
|
|
4
|
+
class LookupUtil
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@proto_lookup_utils = {}
|
|
8
|
+
@path_lookup_utils = {}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Return a resource or common entity for the provided entity type. For
|
|
12
|
+
# example, passing :Campaign will return an instantiated Campaign.
|
|
13
|
+
#
|
|
14
|
+
# Raises ArgumentError if no entity can be found for the provided type.
|
|
15
|
+
def resource(name, version)
|
|
16
|
+
proto_lookup_util(version).resource(name).new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Return an operation for the provided entity type. For example, passing
|
|
20
|
+
# :Campaign will return an instantiated CampaignOperation.
|
|
21
|
+
#
|
|
22
|
+
# Raises ArgumentError if no entity can be found for the provided type.
|
|
23
|
+
def operation(name, version)
|
|
24
|
+
proto_lookup_util(version).operation(name).new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Return a reference to the enum class for the provided enum type. For
|
|
28
|
+
# example, passing :CampaignStatus will return a reference to the
|
|
29
|
+
# CampaignStatusEnum.
|
|
30
|
+
#
|
|
31
|
+
# Raises ArgumentError if no enum can be found for the provided type.
|
|
32
|
+
def enum(name, version)
|
|
33
|
+
proto_lookup_util(version).enum(name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Return a service for the provided entity type. For example, passing
|
|
37
|
+
# :Campaign will return an instantiated CampaignServiceClient.
|
|
38
|
+
#
|
|
39
|
+
# Raises ArgumentError if no service can be found for the provided type.
|
|
40
|
+
def raw_service(name, version)
|
|
41
|
+
proto_lookup_util(version).service(name)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns a reference to the PathLookupUtil to generate resource names.
|
|
45
|
+
def path(version)
|
|
46
|
+
path_lookup_util(version)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
attr_reader :proto_lookup_utils, :path_lookup_utils
|
|
52
|
+
|
|
53
|
+
# Load up the proto lookup util for the given version, storing a copy
|
|
54
|
+
# of it if this is the first time we needed it.
|
|
55
|
+
def proto_lookup_util(version)
|
|
56
|
+
unless valid_version?(version)
|
|
57
|
+
raise sprintf('Unknown version %s', version)
|
|
58
|
+
end
|
|
59
|
+
if proto_lookup_utils[version].nil?
|
|
60
|
+
path_version = version.downcase
|
|
61
|
+
require sprintf('google/ads/google_ads/utils/%s/proto_lookup_util',
|
|
62
|
+
path_version)
|
|
63
|
+
class_path = sprintf(
|
|
64
|
+
'Google::Ads::GoogleAds::Utils::%s::ProtoLookupUtil',
|
|
65
|
+
version
|
|
66
|
+
)
|
|
67
|
+
proto_lookup_utils[version] = class_for_path(class_path).new
|
|
68
|
+
end
|
|
69
|
+
proto_lookup_utils[version]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Load up the path lookup util for the given version, storing a copy
|
|
73
|
+
# of it if this is the first time we needed it.
|
|
74
|
+
def path_lookup_util(version)
|
|
75
|
+
unless valid_version?(version)
|
|
76
|
+
raise sprintf('Unknown version %s', version)
|
|
77
|
+
end
|
|
78
|
+
if path_lookup_utils[version].nil?
|
|
79
|
+
path_version = version.downcase
|
|
80
|
+
require sprintf('google/ads/google_ads/utils/%s/path_lookup_util',
|
|
81
|
+
path_version)
|
|
82
|
+
class_path = sprintf(
|
|
83
|
+
'Google::Ads::GoogleAds::Utils::%s::PathLookupUtil',
|
|
84
|
+
version
|
|
85
|
+
)
|
|
86
|
+
path_lookup_utils[version] = class_for_path(class_path).new(
|
|
87
|
+
proto_lookup_util(version))
|
|
88
|
+
end
|
|
89
|
+
path_lookup_utils[version]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Converts complete class path into class object.
|
|
93
|
+
def class_for_path(path)
|
|
94
|
+
path.split('::').inject(Kernel) do |scope, const_name|
|
|
95
|
+
scope.const_get(const_name)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def valid_version?(version)
|
|
100
|
+
Google::Ads::GoogleAds.valid_version?(version)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Google
|
|
2
|
+
module Ads
|
|
3
|
+
module GoogleAds
|
|
4
|
+
class PartialFailureErrorDecoder
|
|
5
|
+
# decodes a partial_failure_error (Google::Rpc::Status instance) to
|
|
6
|
+
# an array of meaningful error protos
|
|
7
|
+
#
|
|
8
|
+
# Return an Array of protobuf objects, typed depending on what was
|
|
9
|
+
# in the passed object (which will mostly be Google::Protobuf::Any,
|
|
10
|
+
# so the types could be any valid protobuf type)
|
|
11
|
+
def self.decode(partial_failure_error)
|
|
12
|
+
partial_failure_error.details.select { |detail|
|
|
13
|
+
Google::Protobuf::Any === detail
|
|
14
|
+
}.map { |detail|
|
|
15
|
+
type = Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
|
16
|
+
detail.type_name
|
|
17
|
+
).msgclass
|
|
18
|
+
detail.unpack(type)
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -272,7 +272,10 @@ module Google
|
|
|
272
272
|
KeywordParameters: ['services', 'recommendation_service_pb', 'ApplyRecommendationOperation::KeywordParameters'],
|
|
273
273
|
TargetCpaOptInParameters: ['services', 'recommendation_service_pb', 'ApplyRecommendationOperation::TargetCpaOptInParameters'],
|
|
274
274
|
LocationNames: ['services', 'geo_target_constant_service_pb', 'SuggestGeoTargetConstantsRequest::LocationNames'],
|
|
275
|
-
GeoTargets: ['services', 'geo_target_constant_service_pb', 'SuggestGeoTargetConstantsRequest::GeoTargets']
|
|
275
|
+
GeoTargets: ['services', 'geo_target_constant_service_pb', 'SuggestGeoTargetConstantsRequest::GeoTargets'],
|
|
276
|
+
KeywordAndUrlSeed: ['services', 'keyword_plan_idea_service_pb', 'KeywordAndUrlSeed'],
|
|
277
|
+
KeywordSeed: ['services', 'keyword_plan_idea_service_pb', 'KeywordSeed'],
|
|
278
|
+
UrlSeed: ['services', 'keyword_plan_idea_service_pb', 'UrlSeed']
|
|
276
279
|
}.freeze
|
|
277
280
|
|
|
278
281
|
ENUMS = {
|
|
@@ -137,6 +137,13 @@ module Google
|
|
|
137
137
|
)
|
|
138
138
|
end
|
|
139
139
|
|
|
140
|
+
def asset(customer_id, asset_id)
|
|
141
|
+
@proto_lookup_util.service(:Asset).asset_path(
|
|
142
|
+
customer_id.to_s,
|
|
143
|
+
asset_id.to_s
|
|
144
|
+
)
|
|
145
|
+
end
|
|
146
|
+
|
|
140
147
|
def bidding_strategy(customer_id, bidding_strategy_id)
|
|
141
148
|
@proto_lookup_util.service(:BiddingStrategy).
|
|
142
149
|
bidding_strategy_path(
|
|
@@ -601,7 +608,10 @@ module Google
|
|
|
601
608
|
end
|
|
602
609
|
|
|
603
610
|
def shopping_performance_view(customer_id)
|
|
604
|
-
|
|
611
|
+
@proto_lookup_util.service(:ShoppingPerformanceView).
|
|
612
|
+
shopping_performance_view_path(
|
|
613
|
+
customer_id.to_s
|
|
614
|
+
)
|
|
605
615
|
end
|
|
606
616
|
|
|
607
617
|
def topic_constant(vertical_id)
|