google-ads-googleads 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +2 -0
  3. data/README.md +107 -0
  4. data/Rakefile +7 -0
  5. data/googleads_config.rb +10 -0
  6. data/lib/google/ads/googleads.rb +25 -0
  7. data/lib/google/ads/googleads/config.rb +42 -0
  8. data/lib/google/ads/googleads/errors.rb +40 -0
  9. data/lib/google/ads/googleads/field_mask_util.rb +159 -0
  10. data/lib/google/ads/googleads/googleads_client.rb +177 -0
  11. data/lib/google/ads/googleads/patches.rb +45 -0
  12. data/lib/google/ads/googleads/path_lookup_util.rb +84 -0
  13. data/lib/google/ads/googleads/proto_lookup_util.rb +249 -0
  14. data/lib/google/ads/googleads/v0/common/ad_pb.rb +80 -0
  15. data/lib/google/ads/googleads/v0/common/bidding_pb.rb +71 -0
  16. data/lib/google/ads/googleads/v0/common/criteria_pb.rb +25 -0
  17. data/lib/google/ads/googleads/v0/common/custom_parameter_pb.rb +24 -0
  18. data/lib/google/ads/googleads/v0/common/metrics_pb.rb +65 -0
  19. data/lib/google/ads/googleads/v0/common/policy_pb.rb +24 -0
  20. data/lib/google/ads/googleads/v0/common/value_pb.rb +28 -0
  21. data/lib/google/ads/googleads/v0/enums/ad_group_ad_status_pb.rb +29 -0
  22. data/lib/google/ads/googleads/v0/enums/ad_group_criterion_status_pb.rb +29 -0
  23. data/lib/google/ads/googleads/v0/enums/ad_group_status_pb.rb +29 -0
  24. data/lib/google/ads/googleads/v0/enums/ad_group_type_pb.rb +27 -0
  25. data/lib/google/ads/googleads/v0/enums/ad_network_type_pb.rb +31 -0
  26. data/lib/google/ads/googleads/v0/enums/ad_serving_optimization_status_pb.rb +31 -0
  27. data/lib/google/ads/googleads/v0/enums/ad_type_pb.rb +32 -0
  28. data/lib/google/ads/googleads/v0/enums/advertising_channel_sub_type_pb.rb +28 -0
  29. data/lib/google/ads/googleads/v0/enums/advertising_channel_type_pb.rb +27 -0
  30. data/lib/google/ads/googleads/v0/enums/bid_source_pb.rb +29 -0
  31. data/lib/google/ads/googleads/v0/enums/bidding_strategy_type_pb.rb +36 -0
  32. data/lib/google/ads/googleads/v0/enums/budget_delivery_method_pb.rb +28 -0
  33. data/lib/google/ads/googleads/v0/enums/budget_status_pb.rb +28 -0
  34. data/lib/google/ads/googleads/v0/enums/campaign_serving_status_pb.rb +31 -0
  35. data/lib/google/ads/googleads/v0/enums/campaign_status_pb.rb +29 -0
  36. data/lib/google/ads/googleads/v0/enums/criterion_type_pb.rb +27 -0
  37. data/lib/google/ads/googleads/v0/enums/day_of_week_pb.rb +33 -0
  38. data/lib/google/ads/googleads/v0/enums/device_pb.rb +29 -0
  39. data/lib/google/ads/googleads/v0/enums/google_ads_field_category_pb.rb +30 -0
  40. data/lib/google/ads/googleads/v0/enums/google_ads_field_data_type_pb.rb +36 -0
  41. data/lib/google/ads/googleads/v0/enums/keyword_match_type_pb.rb +29 -0
  42. data/lib/google/ads/googleads/v0/enums/page_one_promoted_strategy_goal_pb.rb +28 -0
  43. data/lib/google/ads/googleads/v0/enums/quality_score_bucket_pb.rb +29 -0
  44. data/lib/google/ads/googleads/v0/enums/slot_pb.rb +32 -0
  45. data/lib/google/ads/googleads/v0/errors/ad_customizer_error_pb.rb +31 -0
  46. data/lib/google/ads/googleads/v0/errors/ad_error_pb.rb +154 -0
  47. data/lib/google/ads/googleads/v0/errors/ad_group_ad_error_pb.rb +34 -0
  48. data/lib/google/ads/googleads/v0/errors/ad_group_criterion_error_pb.rb +63 -0
  49. data/lib/google/ads/googleads/v0/errors/ad_group_error_pb.rb +38 -0
  50. data/lib/google/ads/googleads/v0/errors/ad_sharing_error_pb.rb +29 -0
  51. data/lib/google/ads/googleads/v0/errors/adx_error_pb.rb +27 -0
  52. data/lib/google/ads/googleads/v0/errors/authentication_error_pb.rb +47 -0
  53. data/lib/google/ads/googleads/v0/errors/authorization_error_pb.rb +30 -0
  54. data/lib/google/ads/googleads/v0/errors/bidding_error_pb.rb +46 -0
  55. data/lib/google/ads/googleads/v0/errors/bidding_strategy_error_pb.rb +30 -0
  56. data/lib/google/ads/googleads/v0/errors/campaign_budget_error_pb.rb +40 -0
  57. data/lib/google/ads/googleads/v0/errors/campaign_criterion_error_pb.rb +36 -0
  58. data/lib/google/ads/googleads/v0/errors/campaign_error_pb.rb +60 -0
  59. data/lib/google/ads/googleads/v0/errors/collection_size_error_pb.rb +28 -0
  60. data/lib/google/ads/googleads/v0/errors/criterion_error_pb.rb +106 -0
  61. data/lib/google/ads/googleads/v0/errors/date_error_pb.rb +34 -0
  62. data/lib/google/ads/googleads/v0/errors/date_range_error_pb.rb +31 -0
  63. data/lib/google/ads/googleads/v0/errors/distinct_error_pb.rb +28 -0
  64. data/lib/google/ads/googleads/v0/errors/errors_pb.rb +154 -0
  65. data/lib/google/ads/googleads/v0/errors/feed_attribute_reference_error_pb.rb +29 -0
  66. data/lib/google/ads/googleads/v0/errors/field_mask_error_pb.rb +30 -0
  67. data/lib/google/ads/googleads/v0/errors/function_error_pb.rb +42 -0
  68. data/lib/google/ads/googleads/v0/errors/function_parsing_error_pb.rb +37 -0
  69. data/lib/google/ads/googleads/v0/errors/id_error_pb.rb +27 -0
  70. data/lib/google/ads/googleads/v0/errors/image_error_pb.rb +63 -0
  71. data/lib/google/ads/googleads/v0/errors/internal_error_pb.rb +28 -0
  72. data/lib/google/ads/googleads/v0/errors/list_operation_error_pb.rb +28 -0
  73. data/lib/google/ads/googleads/v0/errors/media_bundle_error_pb.rb +48 -0
  74. data/lib/google/ads/googleads/v0/errors/media_error_pb.rb +50 -0
  75. data/lib/google/ads/googleads/v0/errors/multiplier_error_pb.rb +38 -0
  76. data/lib/google/ads/googleads/v0/errors/mutate_error_pb.rb +31 -0
  77. data/lib/google/ads/googleads/v0/errors/new_resource_creation_error_pb.rb +29 -0
  78. data/lib/google/ads/googleads/v0/errors/not_empty_error_pb.rb +27 -0
  79. data/lib/google/ads/googleads/v0/errors/null_error_pb.rb +27 -0
  80. data/lib/google/ads/googleads/v0/errors/operation_access_denied_error_pb.rb +35 -0
  81. data/lib/google/ads/googleads/v0/errors/operator_error_pb.rb +27 -0
  82. data/lib/google/ads/googleads/v0/errors/query_error_pb.rb +72 -0
  83. data/lib/google/ads/googleads/v0/errors/quota_error_pb.rb +28 -0
  84. data/lib/google/ads/googleads/v0/errors/range_error_pb.rb +28 -0
  85. data/lib/google/ads/googleads/v0/errors/region_code_error_pb.rb +27 -0
  86. data/lib/google/ads/googleads/v0/errors/request_error_pb.rb +41 -0
  87. data/lib/google/ads/googleads/v0/errors/resource_access_denied_error_pb.rb +27 -0
  88. data/lib/google/ads/googleads/v0/errors/resource_count_limit_exceeded_error_pb.rb +33 -0
  89. data/lib/google/ads/googleads/v0/errors/setting_error_pb.rb +43 -0
  90. data/lib/google/ads/googleads/v0/errors/string_format_error_pb.rb +28 -0
  91. data/lib/google/ads/googleads/v0/errors/string_length_error_pb.rb +28 -0
  92. data/lib/google/ads/googleads/v0/errors/url_field_error_pb.rb +70 -0
  93. data/lib/google/ads/googleads/v0/resources/ad_group_ad_pb.rb +28 -0
  94. data/lib/google/ads/googleads/v0/resources/ad_group_criterion_pb.rb +64 -0
  95. data/lib/google/ads/googleads/v0/resources/ad_group_pb.rb +38 -0
  96. data/lib/google/ads/googleads/v0/resources/bidding_strategy_pb.rb +36 -0
  97. data/lib/google/ads/googleads/v0/resources/campaign_budget_pb.rb +32 -0
  98. data/lib/google/ads/googleads/v0/resources/campaign_criterion_pb.rb +32 -0
  99. data/lib/google/ads/googleads/v0/resources/campaign_pb.rb +70 -0
  100. data/lib/google/ads/googleads/v0/resources/customer_pb.rb +29 -0
  101. data/lib/google/ads/googleads/v0/resources/google_ads_field_pb.rb +38 -0
  102. data/lib/google/ads/googleads/v0/resources/keyword_view_pb.rb +22 -0
  103. data/lib/google/ads/googleads/v0/services/ad_group_ad_service_client.rb +262 -0
  104. data/lib/google/ads/googleads/v0/services/ad_group_ad_service_client_config.json +36 -0
  105. data/lib/google/ads/googleads/v0/services/ad_group_ad_service_pb.rb +47 -0
  106. data/lib/google/ads/googleads/v0/services/ad_group_ad_service_services_pb.rb +51 -0
  107. data/lib/google/ads/googleads/v0/services/ad_group_criterion_service_client.rb +262 -0
  108. data/lib/google/ads/googleads/v0/services/ad_group_criterion_service_client_config.json +36 -0
  109. data/lib/google/ads/googleads/v0/services/ad_group_criterion_service_pb.rb +47 -0
  110. data/lib/google/ads/googleads/v0/services/ad_group_criterion_service_services_pb.rb +51 -0
  111. data/lib/google/ads/googleads/v0/services/ad_group_service_client.rb +262 -0
  112. data/lib/google/ads/googleads/v0/services/ad_group_service_client_config.json +36 -0
  113. data/lib/google/ads/googleads/v0/services/ad_group_service_pb.rb +47 -0
  114. data/lib/google/ads/googleads/v0/services/ad_group_service_services_pb.rb +51 -0
  115. data/lib/google/ads/googleads/v0/services/bidding_strategy_service_client.rb +263 -0
  116. data/lib/google/ads/googleads/v0/services/bidding_strategy_service_client_config.json +36 -0
  117. data/lib/google/ads/googleads/v0/services/bidding_strategy_service_pb.rb +47 -0
  118. data/lib/google/ads/googleads/v0/services/bidding_strategy_service_services_pb.rb +52 -0
  119. data/lib/google/ads/googleads/v0/services/campaign_budget_service_client.rb +263 -0
  120. data/lib/google/ads/googleads/v0/services/campaign_budget_service_client_config.json +36 -0
  121. data/lib/google/ads/googleads/v0/services/campaign_budget_service_pb.rb +47 -0
  122. data/lib/google/ads/googleads/v0/services/campaign_budget_service_services_pb.rb +52 -0
  123. data/lib/google/ads/googleads/v0/services/campaign_criterion_service_client.rb +262 -0
  124. data/lib/google/ads/googleads/v0/services/campaign_criterion_service_client_config.json +36 -0
  125. data/lib/google/ads/googleads/v0/services/campaign_criterion_service_pb.rb +47 -0
  126. data/lib/google/ads/googleads/v0/services/campaign_criterion_service_services_pb.rb +51 -0
  127. data/lib/google/ads/googleads/v0/services/campaign_service_client.rb +262 -0
  128. data/lib/google/ads/googleads/v0/services/campaign_service_client_config.json +36 -0
  129. data/lib/google/ads/googleads/v0/services/campaign_service_pb.rb +47 -0
  130. data/lib/google/ads/googleads/v0/services/campaign_service_services_pb.rb +51 -0
  131. data/lib/google/ads/googleads/v0/services/credentials.rb +33 -0
  132. data/lib/google/ads/googleads/v0/services/customer_service_client.rb +214 -0
  133. data/lib/google/ads/googleads/v0/services/customer_service_client_config.json +31 -0
  134. data/lib/google/ads/googleads/v0/services/customer_service_pb.rb +24 -0
  135. data/lib/google/ads/googleads/v0/services/customer_service_services_pb.rb +49 -0
  136. data/lib/google/ads/googleads/v0/services/google_ads_field_service_client.rb +285 -0
  137. data/lib/google/ads/googleads/v0/services/google_ads_field_service_client_config.json +36 -0
  138. data/lib/google/ads/googleads/v0/services/google_ads_field_service_pb.rb +36 -0
  139. data/lib/google/ads/googleads/v0/services/google_ads_field_service_services_pb.rb +51 -0
  140. data/lib/google/ads/googleads/v0/services/google_ads_service_client.rb +242 -0
  141. data/lib/google/ads/googleads/v0/services/google_ads_service_client_config.json +31 -0
  142. data/lib/google/ads/googleads/v0/services/google_ads_service_pb.rb +72 -0
  143. data/lib/google/ads/googleads/v0/services/google_ads_service_services_pb.rb +49 -0
  144. data/lib/google/ads/googleads/v0/services/keyword_view_service_client.rb +216 -0
  145. data/lib/google/ads/googleads/v0/services/keyword_view_service_client_config.json +31 -0
  146. data/lib/google/ads/googleads/v0/services/keyword_view_service_pb.rb +24 -0
  147. data/lib/google/ads/googleads/v0/services/keyword_view_service_services_pb.rb +49 -0
  148. data/lib/google/ads/googleads/version.rb +25 -0
  149. data/lib/google/ads/googleads/wrapper_util.rb +48 -0
  150. 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
@@ -0,0 +1,2 @@
1
+ 0.1.0:
2
+ - Initial release with support for Google Ads API V0.
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
@@ -0,0 +1,7 @@
1
+ # -*- ruby -*-
2
+ require 'bundler/gem_tasks'
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.test_files = FileList['test/**/test_*.rb']
7
+ end
@@ -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