google-ads-googleads 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ChangeLog +2 -0
- data/README.md +107 -0
- data/Rakefile +7 -0
- data/googleads_config.rb +10 -0
- data/lib/google/ads/googleads.rb +25 -0
- data/lib/google/ads/googleads/config.rb +42 -0
- data/lib/google/ads/googleads/errors.rb +40 -0
- data/lib/google/ads/googleads/field_mask_util.rb +159 -0
- data/lib/google/ads/googleads/googleads_client.rb +177 -0
- data/lib/google/ads/googleads/patches.rb +45 -0
- data/lib/google/ads/googleads/path_lookup_util.rb +84 -0
- data/lib/google/ads/googleads/proto_lookup_util.rb +249 -0
- data/lib/google/ads/googleads/v0/common/ad_pb.rb +80 -0
- data/lib/google/ads/googleads/v0/common/bidding_pb.rb +71 -0
- data/lib/google/ads/googleads/v0/common/criteria_pb.rb +25 -0
- data/lib/google/ads/googleads/v0/common/custom_parameter_pb.rb +24 -0
- data/lib/google/ads/googleads/v0/common/metrics_pb.rb +65 -0
- data/lib/google/ads/googleads/v0/common/policy_pb.rb +24 -0
- data/lib/google/ads/googleads/v0/common/value_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/enums/ad_group_ad_status_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/enums/ad_group_criterion_status_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/enums/ad_group_status_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/enums/ad_group_type_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/enums/ad_network_type_pb.rb +31 -0
- data/lib/google/ads/googleads/v0/enums/ad_serving_optimization_status_pb.rb +31 -0
- data/lib/google/ads/googleads/v0/enums/ad_type_pb.rb +32 -0
- data/lib/google/ads/googleads/v0/enums/advertising_channel_sub_type_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/enums/advertising_channel_type_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/enums/bid_source_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/enums/bidding_strategy_type_pb.rb +36 -0
- data/lib/google/ads/googleads/v0/enums/budget_delivery_method_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/enums/budget_status_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/enums/campaign_serving_status_pb.rb +31 -0
- data/lib/google/ads/googleads/v0/enums/campaign_status_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/enums/criterion_type_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/enums/day_of_week_pb.rb +33 -0
- data/lib/google/ads/googleads/v0/enums/device_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/enums/google_ads_field_category_pb.rb +30 -0
- data/lib/google/ads/googleads/v0/enums/google_ads_field_data_type_pb.rb +36 -0
- data/lib/google/ads/googleads/v0/enums/keyword_match_type_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/enums/page_one_promoted_strategy_goal_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/enums/quality_score_bucket_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/enums/slot_pb.rb +32 -0
- data/lib/google/ads/googleads/v0/errors/ad_customizer_error_pb.rb +31 -0
- data/lib/google/ads/googleads/v0/errors/ad_error_pb.rb +154 -0
- data/lib/google/ads/googleads/v0/errors/ad_group_ad_error_pb.rb +34 -0
- data/lib/google/ads/googleads/v0/errors/ad_group_criterion_error_pb.rb +63 -0
- data/lib/google/ads/googleads/v0/errors/ad_group_error_pb.rb +38 -0
- data/lib/google/ads/googleads/v0/errors/ad_sharing_error_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/errors/adx_error_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/errors/authentication_error_pb.rb +47 -0
- data/lib/google/ads/googleads/v0/errors/authorization_error_pb.rb +30 -0
- data/lib/google/ads/googleads/v0/errors/bidding_error_pb.rb +46 -0
- data/lib/google/ads/googleads/v0/errors/bidding_strategy_error_pb.rb +30 -0
- data/lib/google/ads/googleads/v0/errors/campaign_budget_error_pb.rb +40 -0
- data/lib/google/ads/googleads/v0/errors/campaign_criterion_error_pb.rb +36 -0
- data/lib/google/ads/googleads/v0/errors/campaign_error_pb.rb +60 -0
- data/lib/google/ads/googleads/v0/errors/collection_size_error_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/errors/criterion_error_pb.rb +106 -0
- data/lib/google/ads/googleads/v0/errors/date_error_pb.rb +34 -0
- data/lib/google/ads/googleads/v0/errors/date_range_error_pb.rb +31 -0
- data/lib/google/ads/googleads/v0/errors/distinct_error_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/errors/errors_pb.rb +154 -0
- data/lib/google/ads/googleads/v0/errors/feed_attribute_reference_error_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/errors/field_mask_error_pb.rb +30 -0
- data/lib/google/ads/googleads/v0/errors/function_error_pb.rb +42 -0
- data/lib/google/ads/googleads/v0/errors/function_parsing_error_pb.rb +37 -0
- data/lib/google/ads/googleads/v0/errors/id_error_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/errors/image_error_pb.rb +63 -0
- data/lib/google/ads/googleads/v0/errors/internal_error_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/errors/list_operation_error_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/errors/media_bundle_error_pb.rb +48 -0
- data/lib/google/ads/googleads/v0/errors/media_error_pb.rb +50 -0
- data/lib/google/ads/googleads/v0/errors/multiplier_error_pb.rb +38 -0
- data/lib/google/ads/googleads/v0/errors/mutate_error_pb.rb +31 -0
- data/lib/google/ads/googleads/v0/errors/new_resource_creation_error_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/errors/not_empty_error_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/errors/null_error_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/errors/operation_access_denied_error_pb.rb +35 -0
- data/lib/google/ads/googleads/v0/errors/operator_error_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/errors/query_error_pb.rb +72 -0
- data/lib/google/ads/googleads/v0/errors/quota_error_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/errors/range_error_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/errors/region_code_error_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/errors/request_error_pb.rb +41 -0
- data/lib/google/ads/googleads/v0/errors/resource_access_denied_error_pb.rb +27 -0
- data/lib/google/ads/googleads/v0/errors/resource_count_limit_exceeded_error_pb.rb +33 -0
- data/lib/google/ads/googleads/v0/errors/setting_error_pb.rb +43 -0
- data/lib/google/ads/googleads/v0/errors/string_format_error_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/errors/string_length_error_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/errors/url_field_error_pb.rb +70 -0
- data/lib/google/ads/googleads/v0/resources/ad_group_ad_pb.rb +28 -0
- data/lib/google/ads/googleads/v0/resources/ad_group_criterion_pb.rb +64 -0
- data/lib/google/ads/googleads/v0/resources/ad_group_pb.rb +38 -0
- data/lib/google/ads/googleads/v0/resources/bidding_strategy_pb.rb +36 -0
- data/lib/google/ads/googleads/v0/resources/campaign_budget_pb.rb +32 -0
- data/lib/google/ads/googleads/v0/resources/campaign_criterion_pb.rb +32 -0
- data/lib/google/ads/googleads/v0/resources/campaign_pb.rb +70 -0
- data/lib/google/ads/googleads/v0/resources/customer_pb.rb +29 -0
- data/lib/google/ads/googleads/v0/resources/google_ads_field_pb.rb +38 -0
- data/lib/google/ads/googleads/v0/resources/keyword_view_pb.rb +22 -0
- data/lib/google/ads/googleads/v0/services/ad_group_ad_service_client.rb +262 -0
- data/lib/google/ads/googleads/v0/services/ad_group_ad_service_client_config.json +36 -0
- data/lib/google/ads/googleads/v0/services/ad_group_ad_service_pb.rb +47 -0
- data/lib/google/ads/googleads/v0/services/ad_group_ad_service_services_pb.rb +51 -0
- data/lib/google/ads/googleads/v0/services/ad_group_criterion_service_client.rb +262 -0
- data/lib/google/ads/googleads/v0/services/ad_group_criterion_service_client_config.json +36 -0
- data/lib/google/ads/googleads/v0/services/ad_group_criterion_service_pb.rb +47 -0
- data/lib/google/ads/googleads/v0/services/ad_group_criterion_service_services_pb.rb +51 -0
- data/lib/google/ads/googleads/v0/services/ad_group_service_client.rb +262 -0
- data/lib/google/ads/googleads/v0/services/ad_group_service_client_config.json +36 -0
- data/lib/google/ads/googleads/v0/services/ad_group_service_pb.rb +47 -0
- data/lib/google/ads/googleads/v0/services/ad_group_service_services_pb.rb +51 -0
- data/lib/google/ads/googleads/v0/services/bidding_strategy_service_client.rb +263 -0
- data/lib/google/ads/googleads/v0/services/bidding_strategy_service_client_config.json +36 -0
- data/lib/google/ads/googleads/v0/services/bidding_strategy_service_pb.rb +47 -0
- data/lib/google/ads/googleads/v0/services/bidding_strategy_service_services_pb.rb +52 -0
- data/lib/google/ads/googleads/v0/services/campaign_budget_service_client.rb +263 -0
- data/lib/google/ads/googleads/v0/services/campaign_budget_service_client_config.json +36 -0
- data/lib/google/ads/googleads/v0/services/campaign_budget_service_pb.rb +47 -0
- data/lib/google/ads/googleads/v0/services/campaign_budget_service_services_pb.rb +52 -0
- data/lib/google/ads/googleads/v0/services/campaign_criterion_service_client.rb +262 -0
- data/lib/google/ads/googleads/v0/services/campaign_criterion_service_client_config.json +36 -0
- data/lib/google/ads/googleads/v0/services/campaign_criterion_service_pb.rb +47 -0
- data/lib/google/ads/googleads/v0/services/campaign_criterion_service_services_pb.rb +51 -0
- data/lib/google/ads/googleads/v0/services/campaign_service_client.rb +262 -0
- data/lib/google/ads/googleads/v0/services/campaign_service_client_config.json +36 -0
- data/lib/google/ads/googleads/v0/services/campaign_service_pb.rb +47 -0
- data/lib/google/ads/googleads/v0/services/campaign_service_services_pb.rb +51 -0
- data/lib/google/ads/googleads/v0/services/credentials.rb +33 -0
- data/lib/google/ads/googleads/v0/services/customer_service_client.rb +214 -0
- data/lib/google/ads/googleads/v0/services/customer_service_client_config.json +31 -0
- data/lib/google/ads/googleads/v0/services/customer_service_pb.rb +24 -0
- data/lib/google/ads/googleads/v0/services/customer_service_services_pb.rb +49 -0
- data/lib/google/ads/googleads/v0/services/google_ads_field_service_client.rb +285 -0
- data/lib/google/ads/googleads/v0/services/google_ads_field_service_client_config.json +36 -0
- data/lib/google/ads/googleads/v0/services/google_ads_field_service_pb.rb +36 -0
- data/lib/google/ads/googleads/v0/services/google_ads_field_service_services_pb.rb +51 -0
- data/lib/google/ads/googleads/v0/services/google_ads_service_client.rb +242 -0
- data/lib/google/ads/googleads/v0/services/google_ads_service_client_config.json +31 -0
- data/lib/google/ads/googleads/v0/services/google_ads_service_pb.rb +72 -0
- data/lib/google/ads/googleads/v0/services/google_ads_service_services_pb.rb +49 -0
- data/lib/google/ads/googleads/v0/services/keyword_view_service_client.rb +216 -0
- data/lib/google/ads/googleads/v0/services/keyword_view_service_client_config.json +31 -0
- data/lib/google/ads/googleads/v0/services/keyword_view_service_pb.rb +24 -0
- data/lib/google/ads/googleads/v0/services/keyword_view_service_services_pb.rb +49 -0
- data/lib/google/ads/googleads/version.rb +25 -0
- data/lib/google/ads/googleads/wrapper_util.rb +48 -0
- metadata +248 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 786e9754852be58af6ed81928f5c2eb75784d4d24090479912ad3dd376a57d57
|
4
|
+
data.tar.gz: 21ef46bf2d76bc7085ca8ed1f2b6a63eb4becf92d61c0a8d970f926156c3cf4d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 55349a21aad338d63dcce98df2511a4372e7f36a00a9d25b74f83feba241c074579a29b22061ccb013afad1184e68737f1cd76b3167802fd80c482eda9fb1793
|
7
|
+
data.tar.gz: '0178da13bafbfd1c9b61e684397d76e2d02065f3ba53f2fd5345cc1d6f0a0ab29b30a8bdb0bbd70185515ea3875996b00824f6a97c9a73134746f541f32d055c'
|
data/ChangeLog
ADDED
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# Google Ads Client Library for Ruby
|
2
|
+
|
3
|
+
`google-ads-googleads` uses [Google API extensions][google-gax] to provide an
|
4
|
+
easy-to-use client library for the [Google Ads API][].
|
5
|
+
|
6
|
+
[google-gax]: https://github.com/googleapis/gax-ruby
|
7
|
+
[Google Ads API]: https://developers.google.com/google-ads/api
|
8
|
+
|
9
|
+
# Documentation for Users
|
10
|
+
|
11
|
+
## Getting started
|
12
|
+
|
13
|
+
`google-ads-googleads` will allow you to connect to the
|
14
|
+
[Google Ads API][] and access all its methods.
|
15
|
+
|
16
|
+
In order to achieve so you need to set up authentication as well as install the
|
17
|
+
library locally.
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
Install this library using gem:
|
22
|
+
|
23
|
+
$ [sudo] gem install google-ads-googleads
|
24
|
+
|
25
|
+
Alternatively, if you prefer not to or can't use the hosted gem on RubyGems, you
|
26
|
+
can download the gem from the [Releases][] page and install it from the local
|
27
|
+
file:
|
28
|
+
|
29
|
+
$ [sudo] gem install google-ads-googleads-[version].gem
|
30
|
+
|
31
|
+
Or you can build it yourself from the source. After cloning the GitHub repo,
|
32
|
+
navigate to the `google-ads-ruby` folder and run:
|
33
|
+
|
34
|
+
$ rake build
|
35
|
+
$ gem install pkg/google-ads-googleads-[version].gem
|
36
|
+
|
37
|
+
[Releases]: https://github.com/googleads/google-ads-ruby/releases
|
38
|
+
|
39
|
+
## Set Up Authentication
|
40
|
+
|
41
|
+
To authenticate your API calls, you need to specify your client ID, client
|
42
|
+
secret, refresh token, and developer token to the library in one of a few ways.
|
43
|
+
|
44
|
+
If you don't have a client ID or client secret yet, please see the
|
45
|
+
[Authorization guide][] to get those set up. Once you have those, the Ruby
|
46
|
+
library can help you use those to generate a refresh token.
|
47
|
+
|
48
|
+
See and run the [Authentication example][] to generate your refresh token.
|
49
|
+
Once this is generated, you can provide it to the library in a few different
|
50
|
+
ways.
|
51
|
+
|
52
|
+
The simplest is to copy the [adwords_config.rb][] to your home directory and
|
53
|
+
simply modify it to include the client ID, client secret, and refresh token.
|
54
|
+
The library will automatically read it from the home directory if instantiated
|
55
|
+
with no arguments:
|
56
|
+
|
57
|
+
adwords = Google::Ads::Googleads::GoogleadsClient.new
|
58
|
+
|
59
|
+
Alternatively, if you prefer to keep the file elsewhere, you can instantiate the
|
60
|
+
library by passing the path to where you keep this file:
|
61
|
+
|
62
|
+
adwords = Google::Ads::Googleads::GoogleadsClient.new('path/to/file.rb')
|
63
|
+
|
64
|
+
If you prefer not to store this information in a file at all, and would rather
|
65
|
+
pass the information programmatically at runtime, you can accomplish that this
|
66
|
+
way:
|
67
|
+
|
68
|
+
adwords = Google::Ads::Googleads::GoogleadsClient.new do |config|
|
69
|
+
config.client_id = 'INSERT_CLIENT_ID_HERE'
|
70
|
+
config.client_secret = 'INSERT_CLIENT_SECRET_HERE'
|
71
|
+
config.refresh_token = 'INSERT_REFRESH_TOKEN_HERE'
|
72
|
+
config.developer_token = 'INSERT_DEVELOPER_TOKEN_HERE'
|
73
|
+
end
|
74
|
+
|
75
|
+
You can also modify these properties after instantiation by using the
|
76
|
+
`configure` method on the `AdwordsClient`, using the same structure as above.
|
77
|
+
|
78
|
+
[Authorization guide]: https://developers.google.com/google-ads/api/docs/oauth/
|
79
|
+
[Authentication example]: https://github.com/googleads/google-ads-ruby/blob/master/examples/authentication/authenticate_in_standalone_application.rb
|
80
|
+
[adwords_config.rb]: https://github.com/googleads/google-ads-ruby/blob/master/googleads_config.rb
|
81
|
+
|
82
|
+
## Usage
|
83
|
+
|
84
|
+
To include the gem in your code:
|
85
|
+
|
86
|
+
require 'google/ads/googleads'
|
87
|
+
|
88
|
+
To fetch a specific service, for example CampaignService:
|
89
|
+
|
90
|
+
adwords = Google::Ads::Googleads::GoogleadsClient.new
|
91
|
+
campaign_service = adwords.service(:Campaign)
|
92
|
+
|
93
|
+
See the provided [examples][] for more detailed demonstrations of how to use the
|
94
|
+
library.
|
95
|
+
|
96
|
+
[examples]: https://github.com/googleads/google-ads-ruby/blob/master/examples
|
97
|
+
|
98
|
+
# Authors
|
99
|
+
|
100
|
+
Author:
|
101
|
+
|
102
|
+
- Danial Klimkin
|
103
|
+
- Michael Cloonan
|
104
|
+
|
105
|
+
Maintainer:
|
106
|
+
|
107
|
+
- Michael Cloonan
|
data/Rakefile
ADDED
data/googleads_config.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# This is an example configuration file for the Google Ads API Ruby client
|
2
|
+
# library.
|
3
|
+
# Please fill in the required fields and copy it to your home directory.
|
4
|
+
|
5
|
+
Google::Ads::Googleads::Config.new do |c|
|
6
|
+
c.client_id = 'INSERT_CLIENT_ID_HERE'
|
7
|
+
c.client_secret = 'INSERT_CLIENT_SECRET_HERE'
|
8
|
+
c.refresh_token = 'INSERT_REFRESH_TOKEN_HERE'
|
9
|
+
c.developer_token = 'INSERT_DEVELOPER_TOKEN_HERE'
|
10
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright:: Copyright 2017, Google Inc. All Rights Reserved.
|
4
|
+
#
|
5
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
14
|
+
# implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'google/ads/googleads/googleads_client'
|
19
|
+
|
20
|
+
module Google
|
21
|
+
module Ads
|
22
|
+
module Googleads
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright 2018 Google LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
# Configuration setup for and storage for the API.
|
18
|
+
|
19
|
+
module Google
|
20
|
+
module Ads
|
21
|
+
module Googleads
|
22
|
+
class Config
|
23
|
+
attr_accessor :refresh_token
|
24
|
+
attr_accessor :client_id
|
25
|
+
attr_accessor :client_secret
|
26
|
+
attr_accessor :developer_token
|
27
|
+
|
28
|
+
def initialize(&block)
|
29
|
+
@refresh_token = nil
|
30
|
+
@client_id = nil
|
31
|
+
@client_secret = nil
|
32
|
+
@developer_token = nil
|
33
|
+
yield self if block_given?
|
34
|
+
end
|
35
|
+
|
36
|
+
def configure(&block)
|
37
|
+
yield self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright 2018 Google LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
# File for all errors that will be used by the Google Ads API Library.
|
18
|
+
|
19
|
+
module Google
|
20
|
+
module Ads
|
21
|
+
module Googleads
|
22
|
+
module Errors
|
23
|
+
|
24
|
+
# Generic error class for non-specific errors.
|
25
|
+
class Error < ::StandardError
|
26
|
+
end
|
27
|
+
|
28
|
+
# Raised when encountering an API-specific error, such as an entity
|
29
|
+
# not found or a malformed query.
|
30
|
+
class GoogleAdsError < Error
|
31
|
+
attr_reader :failure
|
32
|
+
|
33
|
+
def initialize(failure)
|
34
|
+
@failure = failure
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright 2018 Google LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
# Utility for constructing field masks, which are necessary for update
|
18
|
+
# operations.
|
19
|
+
|
20
|
+
require "google/protobuf"
|
21
|
+
|
22
|
+
module Google
|
23
|
+
module Ads
|
24
|
+
module Googleads
|
25
|
+
# Utility for constructing FieldMask objects.
|
26
|
+
#
|
27
|
+
# Copied from C# implementation courtesy of jonskeet@google.com
|
28
|
+
class FieldMaskUtil
|
29
|
+
# Construct a field mask containing any changes to the object made
|
30
|
+
# in the given block.
|
31
|
+
#
|
32
|
+
# Example:
|
33
|
+
#
|
34
|
+
# obj = MyObject.new
|
35
|
+
# obj.some_property = 1
|
36
|
+
#
|
37
|
+
# mask = FieldMaskUtil.with obj do
|
38
|
+
# obj.other_property = 2
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # the mask will contain the changed property "other_property"
|
42
|
+
# api_client.mutate obj, mask
|
43
|
+
#
|
44
|
+
# @param obj [Object] the object to watch
|
45
|
+
# @yield block used for determining changes to the object
|
46
|
+
# @return [Google::Protobuf::FieldMask] the computed mask
|
47
|
+
def self.with(obj)
|
48
|
+
raise 'nil cannot be compared' if obj.nil?
|
49
|
+
original = obj.class.decode(obj.class.encode(obj))
|
50
|
+
yield
|
51
|
+
compare original, obj
|
52
|
+
end
|
53
|
+
|
54
|
+
# Construct a field mask containing any fields set on the given object.
|
55
|
+
#
|
56
|
+
# Example:
|
57
|
+
#
|
58
|
+
# obj = MyObject.new
|
59
|
+
# obj.some_property = 1
|
60
|
+
# obj.other_property = 2
|
61
|
+
#
|
62
|
+
# mask = FieldMaskUtil.all_set_fields_of obj
|
63
|
+
#
|
64
|
+
# # the mask will contain the present properties "some_property" and
|
65
|
+
# # "other_property"
|
66
|
+
# api_client.mutate obj, mask
|
67
|
+
#
|
68
|
+
# @param obj [Object] the object to watch
|
69
|
+
# return [Google::Protobuf::FieldMask] the computed mask
|
70
|
+
def self.all_set_fields_of(obj)
|
71
|
+
new_instance = obj.class.new
|
72
|
+
compare_obj(Google::Protobuf::FieldMask.new, '', new_instance, obj)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Creates Google::Protobuf::FieldMask objects based on the
|
76
|
+
# difference between two objects.
|
77
|
+
#
|
78
|
+
# @param original
|
79
|
+
# @param modified
|
80
|
+
# @return [Google::Protobuf::FieldMask] the computed mask
|
81
|
+
def self.compare(original, modified)
|
82
|
+
raise 'nil cannot be compared' if original.nil? || modified.nil?
|
83
|
+
raise 'objects of different types cannot be compared' if original.class != modified.class
|
84
|
+
compare_obj(Google::Protobuf::FieldMask.new, '', original, modified)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.compare_obj(mask, current_field, original, modified)
|
88
|
+
descriptor = original.class.descriptor
|
89
|
+
|
90
|
+
descriptor.entries.each do |field|
|
91
|
+
field_path = get_path current_field, field.name
|
92
|
+
|
93
|
+
# extract values
|
94
|
+
original_value = original[field.name]
|
95
|
+
modified_value = modified[field.name]
|
96
|
+
|
97
|
+
if is_repeated?(original_value) || is_repeated?(modified_value)
|
98
|
+
# repeated fields - must match exactly or add the field
|
99
|
+
mask.paths << field_path unless original_value == modified_value
|
100
|
+
else
|
101
|
+
case field.type
|
102
|
+
when :message
|
103
|
+
if original_value != modified_value
|
104
|
+
# wrappers - do not include the .value part of the path
|
105
|
+
if is_wrapper? [original_value, modified_value]
|
106
|
+
mask.paths << field_path
|
107
|
+
elsif original_value.nil?
|
108
|
+
# new message, make a blank instance and then compare
|
109
|
+
# against it
|
110
|
+
original_value = modified[field.name].class.new
|
111
|
+
compare_obj mask, field_path, original_value, modified_value
|
112
|
+
elsif modified_value.nil?
|
113
|
+
# just emit the deleted field name
|
114
|
+
mask.paths << field_path
|
115
|
+
else
|
116
|
+
compare_obj mask, field_path, original_value, modified_value
|
117
|
+
end
|
118
|
+
end
|
119
|
+
else # primitive types
|
120
|
+
mask.paths << field_path unless original_value == modified_value
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
mask
|
126
|
+
end
|
127
|
+
|
128
|
+
# Construts path string
|
129
|
+
def self.get_path(path, field)
|
130
|
+
path.nil? || path == '' ? field : "#{path}.#{field}"
|
131
|
+
end
|
132
|
+
|
133
|
+
WRAPPER_TYPES = [Google::Protobuf::DoubleValue,
|
134
|
+
Google::Protobuf::FloatValue,
|
135
|
+
Google::Protobuf::Int64Value,
|
136
|
+
Google::Protobuf::UInt64Value,
|
137
|
+
Google::Protobuf::Int32Value,
|
138
|
+
Google::Protobuf::UInt32Value,
|
139
|
+
Google::Protobuf::BoolValue,
|
140
|
+
Google::Protobuf::StringValue,
|
141
|
+
Google::Protobuf::BytesValue].freeze
|
142
|
+
|
143
|
+
# Checks if the object is a wrapper type
|
144
|
+
def self.is_wrapper?(obj)
|
145
|
+
obj = [obj] unless obj.is_a?(Array)
|
146
|
+
obj.any? { |x| WRAPPER_TYPES.count { |klass| klass == x.class } > 0 }
|
147
|
+
end
|
148
|
+
|
149
|
+
# Checks if the object is a repeated field
|
150
|
+
def self.is_repeated?(obj)
|
151
|
+
obj.is_a?(Google::Protobuf::RepeatedField)
|
152
|
+
end
|
153
|
+
|
154
|
+
private_class_method :compare_obj, :get_path, :is_wrapper?,
|
155
|
+
:is_repeated?
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright 2018 Google LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
# Googleads client class to configure settings and fetch services.
|
18
|
+
|
19
|
+
require 'googleauth'
|
20
|
+
|
21
|
+
require 'google/ads/googleads/patches'
|
22
|
+
require 'google/ads/googleads/config'
|
23
|
+
require 'google/ads/googleads/field_mask_util'
|
24
|
+
require 'google/ads/googleads/wrapper_util'
|
25
|
+
require 'google/ads/googleads/proto_lookup_util'
|
26
|
+
require 'google/ads/googleads/path_lookup_util'
|
27
|
+
|
28
|
+
require 'google/ads/googleads/errors'
|
29
|
+
require 'google/ads/googleads/v0/errors/errors_pb'
|
30
|
+
|
31
|
+
require 'google/gax'
|
32
|
+
|
33
|
+
module Google
|
34
|
+
module Ads
|
35
|
+
module Googleads
|
36
|
+
class GoogleadsClient
|
37
|
+
API_VERSION = :V0
|
38
|
+
|
39
|
+
DEFAULT_CONFIG_FILENAME = 'googleads_config.rb'
|
40
|
+
|
41
|
+
def initialize(config_path = nil, &block)
|
42
|
+
if block_given?
|
43
|
+
@config = Google::Ads::Googleads::Config.new
|
44
|
+
|
45
|
+
yield @config
|
46
|
+
else
|
47
|
+
if config_path.nil?
|
48
|
+
config_path = File.join(ENV['HOME'], DEFAULT_CONFIG_FILENAME)
|
49
|
+
end
|
50
|
+
|
51
|
+
unless File.exist?(config_path)
|
52
|
+
raise ArgumentError,
|
53
|
+
sprintf('No configuration file found at location "%s"',
|
54
|
+
config_path)
|
55
|
+
end
|
56
|
+
file = File.read(config_path)
|
57
|
+
|
58
|
+
eval_result = eval(file, binding, config_path)
|
59
|
+
unless eval_result.instance_of?(Google::Ads::Googleads::Config)
|
60
|
+
raise ArgumentError, sprintf(
|
61
|
+
'Configuration file did not produce expected type ' +
|
62
|
+
'Google::Ads::Googleads::Config, got "%s" instead',
|
63
|
+
eval_result.class
|
64
|
+
)
|
65
|
+
end
|
66
|
+
@config = eval_result
|
67
|
+
end
|
68
|
+
@proto_lookup_util =
|
69
|
+
Google::Ads::Googleads::ProtoLookupUtil.new(API_VERSION)
|
70
|
+
@path_lookup_util =
|
71
|
+
Google::Ads::Googleads::PathLookupUtil.new(@proto_lookup_util)
|
72
|
+
end
|
73
|
+
|
74
|
+
def configure(&block)
|
75
|
+
yield @config
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return a service for the provided entity type. For example, passing
|
79
|
+
# :Campaign will return an instantiated CampaignServiceClient.
|
80
|
+
#
|
81
|
+
# Raises ArgumentError if no service can be found for the provided type.
|
82
|
+
def service(name)
|
83
|
+
service_path = ENV['GOOGLEADS_SERVICE_PATH']
|
84
|
+
|
85
|
+
class_to_return = @proto_lookup_util.service(name)
|
86
|
+
unless service_path.nil? || service_path.empty?
|
87
|
+
class_to_return = Class.new(class_to_return) do
|
88
|
+
const_set('SERVICE_ADDRESS', service_path.freeze)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
return class_to_return.new(
|
93
|
+
credentials: get_updater_proc(),
|
94
|
+
metadata: {:"developer-token" => @config.developer_token},
|
95
|
+
exception_transformer: ERROR_TRANSFORMER
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Return a resource or common entity for the provided entity type. For
|
100
|
+
# example, passing :Campaign will return an instantiated Campaign.
|
101
|
+
#
|
102
|
+
# Raises ArgumentError if no entity can be found for the provided type.
|
103
|
+
def resource(name)
|
104
|
+
@proto_lookup_util.resource(name).new
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return an operation for the provided entity type. For example, passing
|
108
|
+
# :Campaign will return an instantiated CampaignOperation.
|
109
|
+
#
|
110
|
+
# Raises ArgumentError if no entity can be found for the provided type.
|
111
|
+
def operation(name)
|
112
|
+
@proto_lookup_util.operation(name).new
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return a reference to the enum class for the provided enum type. For
|
116
|
+
# example, passing :CampaignStatus will return a reference to the
|
117
|
+
# CampaignStatusEnum.
|
118
|
+
#
|
119
|
+
# Raises ArgumentError if no enum can be found for the provided type.
|
120
|
+
def enum(name)
|
121
|
+
@proto_lookup_util.enum(name)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns a reference to the FieldMaskUtil class for ease of access.
|
125
|
+
def field_mask()
|
126
|
+
Google::Ads::Googleads::FieldMaskUtil
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns a reference to the WrapperUtil class for ease of access.
|
130
|
+
def wrapper()
|
131
|
+
Google::Ads::Googleads::WrapperUtil
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns a reference to the PathLookupUtil to generate resource names.
|
135
|
+
def path()
|
136
|
+
@path_lookup_util
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
ERROR_TRANSFORMER = Proc.new do |gax_error|
|
142
|
+
begin
|
143
|
+
gax_error.status_details.each do |failure|
|
144
|
+
# If there is an underlying GoogleAdsFailure, throw that one.
|
145
|
+
if failure.is_a?(
|
146
|
+
Google::Ads::Googleads::V0::Errors::GoogleAdsFailure)
|
147
|
+
raise Google::Ads::Googleads::Errors::GoogleAdsError.new(
|
148
|
+
failure)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
rescue Google::Ads::Googleads::Errors::GoogleAdsError
|
152
|
+
# If we raised this, bubble it out.
|
153
|
+
raise
|
154
|
+
rescue NoMethodError
|
155
|
+
# Sometimes status_details is just a String; in that case, we should
|
156
|
+
# just raise the original exception.
|
157
|
+
end
|
158
|
+
# If we don't find an error of the correct type, or if we run into an
|
159
|
+
# error while processing, just throw the original.
|
160
|
+
raise gax_error
|
161
|
+
end
|
162
|
+
|
163
|
+
# Provides the service a method by which to obtain an access token to
|
164
|
+
# authenticate API requests.
|
165
|
+
def get_updater_proc()
|
166
|
+
return Signet::OAuth2::Client.new(
|
167
|
+
token_credential_uri: 'https://www.googleapis.com/oauth2/v3/token',
|
168
|
+
client_id: @config.client_id,
|
169
|
+
client_secret: @config.client_secret,
|
170
|
+
refresh_token: @config.refresh_token,
|
171
|
+
scope: ['https://www.googleapis.com/auth/adwords']
|
172
|
+
).updater_proc
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|