bing_ads_ruby_sdk 0.0.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +6 -1
- data/.rspec +3 -1
- data/Gemfile +0 -3
- data/LICENSE.txt +1 -1
- data/README.md +70 -9
- data/Rakefile +2 -0
- data/bin/setup +1 -3
- data/bing_ads_ruby_sdk.gemspec +17 -22
- data/changelog.md +19 -0
- data/lib/bing_ads_ruby_sdk.rb +32 -3
- data/lib/bing_ads_ruby_sdk/api.rb +81 -0
- data/lib/bing_ads_ruby_sdk/augmented_parser.rb +79 -0
- data/lib/bing_ads_ruby_sdk/configuration.rb +26 -0
- data/lib/bing_ads_ruby_sdk/errors/error_handler.rb +65 -0
- data/lib/bing_ads_ruby_sdk/errors/errors.rb +192 -0
- data/lib/bing_ads_ruby_sdk/header.rb +44 -0
- data/lib/bing_ads_ruby_sdk/http_client.rb +65 -0
- data/lib/bing_ads_ruby_sdk/log_message.rb +57 -0
- data/lib/bing_ads_ruby_sdk/oauth2/authorization_handler.rb +94 -0
- data/lib/bing_ads_ruby_sdk/oauth2/fs_store.rb +34 -0
- data/lib/bing_ads_ruby_sdk/postprocessors/cast_long_arrays.rb +35 -0
- data/lib/bing_ads_ruby_sdk/postprocessors/snakize.rb +35 -0
- data/lib/bing_ads_ruby_sdk/preprocessors/camelize.rb +45 -0
- data/lib/bing_ads_ruby_sdk/preprocessors/order.rb +58 -0
- data/lib/bing_ads_ruby_sdk/services/ad_insight.rb +10 -0
- data/lib/bing_ads_ruby_sdk/services/base.rb +83 -0
- data/lib/bing_ads_ruby_sdk/services/bulk.rb +26 -0
- data/lib/bing_ads_ruby_sdk/services/campaign_management.rb +116 -0
- data/lib/bing_ads_ruby_sdk/services/customer_billing.rb +10 -0
- data/lib/bing_ads_ruby_sdk/services/customer_management.rb +26 -0
- data/lib/bing_ads_ruby_sdk/services/reporting.rb +10 -0
- data/lib/bing_ads_ruby_sdk/soap_client.rb +143 -0
- data/lib/bing_ads_ruby_sdk/string_utils.rb +23 -0
- data/lib/bing_ads_ruby_sdk/version.rb +4 -1
- data/lib/bing_ads_ruby_sdk/wsdl/v12/production/ad_insight.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/production/bulk.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/production/campaign_management.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/production/customer_billing.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/production/customer_management.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/production/reporting.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/sandbox/ad_insight.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/sandbox/bulk.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/sandbox/campaign_management.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/sandbox/customer_billing.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/sandbox/customer_management.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/sandbox/reporting.xml +1 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/test/ad_insight.xml +3065 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/test/bulk.xml +1424 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/test/campaign_management.xml +9949 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/test/customer_billing.xml +899 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/test/customer_management.xml +3966 -0
- data/lib/bing_ads_ruby_sdk/wsdl/v12/test/reporting.xml +3742 -0
- data/lib/bing_ads_ruby_sdk/wsdl/wsdl_source.txt +25 -0
- data/lib/bing_ads_ruby_sdk/wsdl_operation_wrapper.rb +39 -0
- data/tasks/bing_ads_ruby_sdk.rake +28 -0
- metadata +137 -38
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'signet/oauth_2/client'
|
2
|
+
require 'bing_ads_ruby_sdk/oauth2/fs_store'
|
3
|
+
|
4
|
+
module BingAdsRubySdk
|
5
|
+
module OAuth2
|
6
|
+
# Adds some useful methods to Signet::OAuth2::Client
|
7
|
+
class AuthorizationHandler
|
8
|
+
|
9
|
+
# @param developer_token
|
10
|
+
# @param client_id
|
11
|
+
# @param store [Store]
|
12
|
+
def initialize(developer_token:, client_id:, store:)
|
13
|
+
@client = build_client(developer_token, client_id)
|
14
|
+
@store = store
|
15
|
+
refresh_from_store
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String] unless client.client_id url is nil interpolated url.
|
19
|
+
# @return [nil] if client.client_id is nil.
|
20
|
+
def code_url
|
21
|
+
return nil if client.client_id.nil?
|
22
|
+
"https://login.live.com/oauth20_authorize.srf?client_id=#{client.client_id}&scope=bingads.manage&response_type=code&redirect_uri=https://login.live.com/oauth20_desktop.srf"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Once you have completed the oauth process in your browser using the code_url
|
26
|
+
# copy the url your browser has been redirected to and use it as argument here
|
27
|
+
def fetch_from_url(url)
|
28
|
+
codes = extract_codes(url)
|
29
|
+
|
30
|
+
return false if codes.none?
|
31
|
+
fetch_from_code(codes.last)
|
32
|
+
rescue Signet::AuthorizationError, URI::InvalidURIError
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
# Get or fetch an access token.
|
37
|
+
# @return [String] The access token.
|
38
|
+
def fetch_or_refresh
|
39
|
+
if client.expired?
|
40
|
+
client.refresh!
|
41
|
+
store.write(token_data)
|
42
|
+
end
|
43
|
+
client.access_token
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :client, :store
|
49
|
+
|
50
|
+
# Refresh existing authorization token
|
51
|
+
# @return [Signet::OAuth2::Client] if everything went well.
|
52
|
+
# @return [nil] if the token can't be read from the store.
|
53
|
+
def refresh_from_store
|
54
|
+
ext_token = store.read
|
55
|
+
client.update_token!(ext_token) if ext_token
|
56
|
+
end
|
57
|
+
|
58
|
+
# Request the Api to exchange the code for the access token.
|
59
|
+
# Save the access token through the store.
|
60
|
+
# @param [String] code authorization code from bing's ads.
|
61
|
+
# @return [#store.write] store's write output.
|
62
|
+
def fetch_from_code(code)
|
63
|
+
client.code = code
|
64
|
+
client.fetch_access_token!
|
65
|
+
store.write(token_data)
|
66
|
+
end
|
67
|
+
|
68
|
+
def extract_codes(url)
|
69
|
+
url = URI.parse(url)
|
70
|
+
query_params = URI.decode_www_form(url.query)
|
71
|
+
query_params.find { |arg| arg.first.casecmp("CODE").zero? }
|
72
|
+
end
|
73
|
+
|
74
|
+
def build_client(developer_token, client_id)
|
75
|
+
Signet::OAuth2::Client.new({
|
76
|
+
authorization_uri: 'https://login.live.com/oauth20_authorize.srf',
|
77
|
+
token_credential_uri: 'https://login.live.com/oauth20_token.srf',
|
78
|
+
redirect_uri: 'https://login.live.com/oauth20_desktop.srf',
|
79
|
+
developer_token: developer_token,
|
80
|
+
client_id: client_id
|
81
|
+
})
|
82
|
+
end
|
83
|
+
|
84
|
+
def token_data
|
85
|
+
{
|
86
|
+
access_token: client.access_token,
|
87
|
+
refresh_token: client.refresh_token,
|
88
|
+
issued_at: client.issued_at,
|
89
|
+
expires_in: client.expires_in
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module BingAdsRubySdk
|
4
|
+
module OAuth2
|
5
|
+
# Oauth2 token default non-encrypted File System store
|
6
|
+
class FsStore
|
7
|
+
# @param filename [String] the uniq filename to identify filename storing data.
|
8
|
+
def initialize(filename)
|
9
|
+
@filename = filename
|
10
|
+
end
|
11
|
+
|
12
|
+
# Writes the token to file
|
13
|
+
# @return [File] if the file was written (doesn't mean the token is).
|
14
|
+
# @return [self] if the filename don't exist.
|
15
|
+
def write(value)
|
16
|
+
return nil unless filename
|
17
|
+
File.open(filename, 'w') { |f| JSON.dump(value, f) }
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Reads the token from file
|
22
|
+
# @return [Hash] if the token information that was stored.
|
23
|
+
# @return [nil] if the file doesn't exist.
|
24
|
+
def read
|
25
|
+
return nil unless File.file?("./#{filename}")
|
26
|
+
JSON.parse(IO.read(filename))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :filename
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BingAdsRubySdk
|
4
|
+
module Postprocessors
|
5
|
+
class CastLongArrays
|
6
|
+
|
7
|
+
def initialize(params)
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
process(@params)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def process(obj)
|
18
|
+
return unless obj.is_a?(Hash)
|
19
|
+
|
20
|
+
obj.each do |k, v|
|
21
|
+
case v
|
22
|
+
when Hash
|
23
|
+
if v[:long].is_a?(Array)
|
24
|
+
obj[k] = v[:long].map(&:to_i)
|
25
|
+
else
|
26
|
+
process(v)
|
27
|
+
end
|
28
|
+
when Array
|
29
|
+
v.each {|elt| process(elt) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BingAdsRubySdk
|
4
|
+
module Postprocessors
|
5
|
+
class Snakize
|
6
|
+
|
7
|
+
def initialize(params)
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
process(@params)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# NOTE: there is a potential for high memory usage here as we're using recursive method calling
|
18
|
+
def process(obj)
|
19
|
+
return obj unless obj.is_a?(Hash)
|
20
|
+
|
21
|
+
obj.each_with_object({}) do |(k, v), h|
|
22
|
+
case v
|
23
|
+
when Hash then v = process(v)
|
24
|
+
when Array then v = v.map {|elt| process(elt) }
|
25
|
+
end
|
26
|
+
h[snakize(k)] = v
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def snakize(string)
|
31
|
+
BingAdsRubySdk::StringUtils.snakize(string)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BingAdsRubySdk
|
4
|
+
module Preprocessors
|
5
|
+
class Camelize
|
6
|
+
|
7
|
+
def initialize(params)
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
process(@params)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# NOTE: there is a potential for high memory usage here as we're using recursive method calling
|
18
|
+
def process(obj)
|
19
|
+
return obj unless obj.is_a?(Hash)
|
20
|
+
|
21
|
+
obj.each_with_object({}) do |(k, v), h|
|
22
|
+
case v
|
23
|
+
when Hash then v = process(v)
|
24
|
+
when Array then v = v.map {|elt| process(elt) }
|
25
|
+
end
|
26
|
+
h[transform_key(k.to_s)] = v
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def transform_key(key)
|
31
|
+
if BLACKLIST.include?(key)
|
32
|
+
key
|
33
|
+
else
|
34
|
+
camelize(key)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def camelize(string)
|
39
|
+
BingAdsRubySdk::StringUtils.camelize(string)
|
40
|
+
end
|
41
|
+
|
42
|
+
BLACKLIST = %w(long string)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BingAdsRubySdk
|
4
|
+
module Preprocessors
|
5
|
+
class Order
|
6
|
+
|
7
|
+
def initialize(wsdl_wrapper, params)
|
8
|
+
@wrapper = wsdl_wrapper
|
9
|
+
@params = params
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
process(params, wrapper.request_namespace_type)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :wrapper, :params
|
19
|
+
|
20
|
+
# NOTE: there is a potential for high memory usage here as we're using recursive method calling
|
21
|
+
def process(obj, namespace_type)
|
22
|
+
return obj unless obj.is_a?(Hash)
|
23
|
+
|
24
|
+
allowed_attributes = wrapper.ordered_fields_hash(namespace_type)
|
25
|
+
|
26
|
+
order(obj, allowed_attributes).tap do |ordered_hash|
|
27
|
+
ordered_hash.each do |type_name, value|
|
28
|
+
ordered_hash[type_name] = ordered_value(allowed_attributes, type_name, value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def ordered_value(allowed_attributes, type_name, value)
|
34
|
+
case value
|
35
|
+
when Hash
|
36
|
+
namespace_type = wrapper.namespace_and_type_from_name(allowed_attributes, type_name)
|
37
|
+
process(value, namespace_type)
|
38
|
+
when Array
|
39
|
+
value.map do |elt|
|
40
|
+
namespace_type = wrapper.namespace_and_type_from_name(allowed_attributes, type_name)
|
41
|
+
process(elt, namespace_type)
|
42
|
+
end
|
43
|
+
else value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def ordered_params(namespace_type)
|
48
|
+
wrapper.ordered_fields_hash(namespace_type)
|
49
|
+
end
|
50
|
+
|
51
|
+
def order(hash, allowed_attributes)
|
52
|
+
array = allowed_attributes.keys
|
53
|
+
# basically order by index in reference array
|
54
|
+
Hash[ hash.sort_by { |k, _| array.index(wrapper.base_type_name(allowed_attributes, k)) || k.ord } ]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bing_ads_ruby_sdk/preprocessors/camelize'
|
4
|
+
require 'bing_ads_ruby_sdk/preprocessors/order'
|
5
|
+
require 'bing_ads_ruby_sdk/postprocessors/snakize'
|
6
|
+
require 'bing_ads_ruby_sdk/postprocessors/cast_long_arrays'
|
7
|
+
|
8
|
+
|
9
|
+
module BingAdsRubySdk
|
10
|
+
module Services
|
11
|
+
class Base
|
12
|
+
|
13
|
+
def initialize(soap_client)
|
14
|
+
@soap_client = soap_client
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(operation_name, message = {})
|
18
|
+
camelized_name = BingAdsRubySdk::StringUtils.camelize(operation_name.to_s)
|
19
|
+
response = soap_client.call(
|
20
|
+
camelized_name,
|
21
|
+
preprocess(message, camelized_name),
|
22
|
+
)
|
23
|
+
postprocess(response)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.service
|
27
|
+
raise 'implement me'
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :soap_client
|
33
|
+
|
34
|
+
def call_wrapper(action, message, *response_nesting)
|
35
|
+
response = call(action, message)
|
36
|
+
wrap_array(dig_response(response, response_nesting))
|
37
|
+
end
|
38
|
+
|
39
|
+
def preprocess(message, operation_name)
|
40
|
+
order(
|
41
|
+
soap_client.wsdl_wrapper(operation_name),
|
42
|
+
camelize(message)
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def postprocess(message)
|
47
|
+
cast_long_arrays(
|
48
|
+
snakize(message)
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def order(wrapper, hash)
|
53
|
+
::BingAdsRubySdk::Preprocessors::Order.new(wrapper, hash).call
|
54
|
+
end
|
55
|
+
|
56
|
+
def camelize(hash)
|
57
|
+
::BingAdsRubySdk::Preprocessors::Camelize.new(hash).call
|
58
|
+
end
|
59
|
+
|
60
|
+
def snakize(hash)
|
61
|
+
::BingAdsRubySdk::Postprocessors::Snakize.new(hash).call
|
62
|
+
end
|
63
|
+
|
64
|
+
def cast_long_arrays(hash)
|
65
|
+
::BingAdsRubySdk::Postprocessors::CastLongArrays.new(hash).call
|
66
|
+
end
|
67
|
+
|
68
|
+
def dig_response(response, keys)
|
69
|
+
response.dig(*keys)
|
70
|
+
rescue StandardError => e
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def wrap_array(arg)
|
75
|
+
case arg
|
76
|
+
when Array then arg
|
77
|
+
when nil, "" then []
|
78
|
+
else [arg]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module BingAdsRubySdk
|
2
|
+
module Services
|
3
|
+
class Bulk < Base
|
4
|
+
|
5
|
+
def download_campaigns_by_account_ids(message)
|
6
|
+
call(__method__, message)
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_bulk_download_status(message)
|
10
|
+
call(__method__, message)
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_bulk_upload_url(message)
|
14
|
+
call(__method__, message)
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_bulk_upload_status(message)
|
18
|
+
call(__method__, message)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.service
|
22
|
+
:bulk
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module BingAdsRubySdk
|
2
|
+
module Services
|
3
|
+
class CampaignManagement < Base
|
4
|
+
|
5
|
+
|
6
|
+
def add_ad_extensions(message)
|
7
|
+
call(__method__, message)
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_conversion_goals(message)
|
11
|
+
call(__method__, message)
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_shared_entity(message)
|
15
|
+
call(__method__, message)
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_uet_tags(message)
|
19
|
+
call(__method__, message)
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_ad_extensions_associations(message)
|
23
|
+
call(__method__, message)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def update_conversion_goals(message)
|
28
|
+
call(__method__, message)
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_uet_tags(message)
|
32
|
+
call(__method__, message)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def get_ad_extensions_associations(message)
|
37
|
+
wrap_array(
|
38
|
+
call(__method__, message)
|
39
|
+
.dig(:ad_extension_association_collection, :ad_extension_association_collection)
|
40
|
+
.first
|
41
|
+
.dig(:ad_extension_associations, :ad_extension_association)
|
42
|
+
)
|
43
|
+
rescue
|
44
|
+
[]
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_ad_extension_ids_by_account_id(message)
|
48
|
+
call_wrapper(__method__, message, :ad_extension_ids)
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_ad_extensions_by_ids(message)
|
52
|
+
call_wrapper(__method__, message, :ad_extensions, :ad_extension)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_ad_groups_by_ids(message)
|
56
|
+
call_wrapper(__method__, message, :ad_groups, :ad_group)
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_ad_groups_by_campaign_id(message)
|
60
|
+
call_wrapper(__method__, message, :ad_groups, :ad_group)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_ads_by_ad_group_id(message)
|
64
|
+
call_wrapper(__method__, message, :ads, :ad)
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_budgets_by_ids(message= {})
|
68
|
+
call_wrapper(__method__, message, :budgets, :budget)
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_campaigns_by_account_id(message)
|
72
|
+
call_wrapper(__method__, message, :campaigns, :campaign)
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_campaigns_by_ids(message)
|
76
|
+
call_wrapper(__method__, message, :campaigns, :campaign)
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_campaign_criterions_by_ids(message)
|
80
|
+
call_wrapper(__method__, message, :campaign_criterions, :campaign_criterion)
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_conversion_goals_by_ids(message)
|
84
|
+
call_wrapper(__method__, message, :conversion_goals, :conversion_goal)
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_keywords_by_ad_group_id(message)
|
88
|
+
call_wrapper(__method__, message, :keywords, :keyword)
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_keywords_by_editorial_status(message)
|
92
|
+
call_wrapper(__method__, message, :keywords, :keyword)
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_keywords_by_ids(message)
|
96
|
+
call_wrapper(__method__, message, :keywords, :keyword)
|
97
|
+
end
|
98
|
+
|
99
|
+
def get_shared_entities_by_account_id(message)
|
100
|
+
call_wrapper(__method__, message, :shared_entities, :shared_entity)
|
101
|
+
end
|
102
|
+
|
103
|
+
def get_uet_tags_by_ids(message = {})
|
104
|
+
call_wrapper(__method__, message, :uet_tags, :uet_tag)
|
105
|
+
end
|
106
|
+
|
107
|
+
def get_shared_entity_associations_by_entity_ids(message)
|
108
|
+
call_wrapper(__method__, message, :associations, :shared_entity_association)
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.service
|
112
|
+
:campaign_management
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|