google-ads-googleads 0.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 +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
|