Skip to content
This repository has been archived by the owner on Jun 8, 2023. It is now read-only.

Bing v13 API upgrade #17

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
8 changes: 4 additions & 4 deletions bing-ads.gemspec
Expand Up @@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]

spec.add_dependency 'savon', '~> 2.11'
spec.add_dependency 'activesupport', '~> 5.0'
spec.add_dependency 'activesupport', '~> 6.0'
spec.add_dependency 'persey', '~> 1.0.0'

spec.add_development_dependency "bundler", "~> 1.15"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.0"
spec.add_development_dependency "bundler", "~> 2.3"
spec.add_development_dependency "rake", "~> 13.0"
spec.add_development_dependency "rspec", "~> 3.9"
end
8 changes: 4 additions & 4 deletions lib/bing/ads.rb
Expand Up @@ -8,14 +8,14 @@
require 'bing/ads/api/errors'
require 'bing/ads/api/soap_client'
require 'bing/ads/api/http_client'
require 'bing/ads/api/v11'
require 'bing/ads/api/v11/constants'
require 'bing/ads/api/v11/data'
require 'bing/ads/api/v11/services'
require 'bing/ads/api/v12'
require 'bing/ads/api/v12/constants'
require 'bing/ads/api/v12/data'
require 'bing/ads/api/v12/services'
require 'bing/ads/api/v13'
require 'bing/ads/api/v13/constants'
require 'bing/ads/api/v13/data'
require 'bing/ads/api/v13/services'

require 'bing/ads/utils'
require 'bing/ads/version'
Expand Down
29 changes: 0 additions & 29 deletions lib/bing/ads/api/v11/constants.rb

This file was deleted.

10 changes: 0 additions & 10 deletions lib/bing/ads/api/v11/constants/wsdl.yml

This file was deleted.

38 changes: 0 additions & 38 deletions lib/bing/ads/api/v11/services/bulk.rb

This file was deleted.

4 changes: 2 additions & 2 deletions lib/bing/ads/api/v12/data/report_request.rb
Expand Up @@ -27,7 +27,7 @@ class << self
def prepare(type, report_request_raw)
report_request_raw[:columns] = prepare_columns(
columns: report_request_raw[:columns],
type: type.to_s.classify
type: type.to_s.camelcase
)

report_request_raw[:scope] = prepare_scope(
Expand All @@ -48,7 +48,7 @@ def prepare(type, report_request_raw)
:attributes! => {
report_request: {
"xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance",
"i:type" => "#{namespace_identifier}:#{type.to_s.classify}ReportRequest"
"i:type" => "#{namespace_identifier}:#{type.to_s.camelcase}ReportRequest"
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/bing/ads/api/v12/services/reporting.rb
Expand Up @@ -35,6 +35,9 @@ def report_url(report_request_id)
end

def report_body(report_request_id)
report_url = report_url(report_request_id)
return if report_url.nil?

HttpClient.download(report_url(report_request_id))
end

Expand Down
6 changes: 3 additions & 3 deletions lib/bing/ads/api/v11.rb → lib/bing/ads/api/v13.rb
@@ -1,9 +1,9 @@
module Bing
module Ads
module API
# Bing::Ads::API::V11
module V11
NAMESPACE_IDENTIFIER = :v11
# Bing::Ads::API::V13
module V13
NAMESPACE_IDENTIFIER = :v13

def self.constants
@_config || fail('Error loading bing ads gem')
Expand Down
31 changes: 31 additions & 0 deletions lib/bing/ads/api/v13/constants.rb
@@ -0,0 +1,31 @@
# frozen_string_literal: true

module Bing
module Ads
module API
# Bing::Ads::API::V13::Constants
module Constants
root_v13_path = File.expand_path('../', __FILE__)

campaign_management_path = File.join(root_v13_path, 'constants', 'campaign_management.yml')
bulk_path = File.join(root_v13_path, 'constants', 'bulk.yml')
languages_path = File.join(root_v13_path, 'constants', 'languages.yml')
limits_path = File.join(root_v13_path, 'constants', 'limits.yml')
time_zones_path = File.join(root_v13_path, 'constants', 'time_zones.yml')
wsdl_path = File.join(root_v13_path, 'constants', 'wsdl.yml')

Persey.init(:default) do
source :yaml, campaign_management_path, :campaign_management
source :yaml, bulk_path, :bulk
source :yaml, languages_path, :languages
source :yaml, limits_path, :limits
source :yaml, time_zones_path, :time_zones
source :yaml, wsdl_path, :wsdl
env :default
end

Bing::Ads::API::V13.constants = Persey.config
end
end
end
end
5 changes: 5 additions & 0 deletions lib/bing/ads/api/v13/constants/bulk.yml
@@ -0,0 +1,5 @@
download_entities:
campaigns: 1
ad_groups: 2
ads: 3
keywords: 4
Expand Up @@ -52,9 +52,6 @@ campaign_status:
budget_paused: BudgetPaused
budget_and_manual_paused: BudgetAndManualPaused
deleted: Deleted
pricing_model:
cpc: Cpc
cpm: Cpm
keyword_editorial_statuses:
active: Active
disapproved: Disapproved
Expand All @@ -66,7 +63,6 @@ keyword_statuses:
inactive: Inactive
match_types:
broad: Broad
content: Content
exact: Exact
phrase: Phrase
network:
Expand Down
@@ -1,7 +1,7 @@
abu_dhabi_muscat: 'AbuDhabiMuscat'
adelaide: 'Adelaide'
alaska: 'Alaska'
almaty_novosibirsk: 'Almaty_Novosibirsk'
almaty_novosibirsk: 'AlmatyNovosibirsk'
amsterdam_berlin_bern_rome_stockholm_vienna: 'AmsterdamBerlinBernRomeStockholmVienna'
arizona: 'Arizona'
astana_dhaka: 'AstanaDhaka'
Expand Down Expand Up @@ -51,11 +51,11 @@ kathmandu: 'Kathmandu'
krasnoyarsk: 'Krasnoyarsk'
kuala_lumpur_singapore: 'KualaLumpurSingapore'
kuwait_riyadh: 'KuwaitRiyadh'
magadan_solomon_island_new_caledonia: 'MagadanSolomonIslandNewCaledonia'
solomon_island_new_caledonia: 'SolomonIslandNewCaledonia'
mid_atlantic: 'MidAtlantic'
midway_islandand_samoa: 'MidwayIslandand_Samoa'
midway_islandand_samoa: 'MidwayIslandAndSamoa'
moscow_st_petersburg_volgograd: 'MoscowStPetersburgVolgograd'
mountain_time_u_s_canada: 'MountainTime_US_Canada'
mountain_time_u_s_canada: 'MountainTimeUSCanada'
nairobi: 'Nairobi'
newfoundland: 'Newfoundland'
nukualofa: 'Nukualofa'
Expand Down
10 changes: 10 additions & 0 deletions lib/bing/ads/api/v13/constants/wsdl.yml
@@ -0,0 +1,10 @@
sandbox:
customer_management: "https://clientcenter.api.sandbox.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl"
campaign_management: "https://campaign.api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/CampaignManagementService.svc?singleWsdl"
reporting: "https://reporting.api.sandbox.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc?singleWsdl"
bulk: 'https://bulk.api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/BulkService.svc?singleWsdl'
production:
customer_management: "https://clientcenter.api.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl"
campaign_management: "https://campaign.api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/CampaignManagementService.svc?singleWsdl"
reporting: "https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc?singleWsdl"
bulk: 'https://bulk.api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/BulkService.svc?singleWsdl'
Expand Up @@ -3,3 +3,4 @@
require_relative './data/campaign'
require_relative './data/keyword'
require_relative './data/report_request'
require_relative './data/bulk_request'
@@ -1,43 +1,42 @@
module Bing
module Ads
module API
module V11
module V13
module Data
# Bing::Ads::API::V11::Data::AdGroup
# Bing::Ads::API::V13::Data::AdGroup
class AdGroup

# @order
# https://msdn.microsoft.com/en-us/library/bing-ads-campaign-management-adgroup.aspx
KEYS_ORDER = [
:ad_distribution,
:ad_rotation,
:bidding_scheme,
:content_match_bid,
:end_date,
:forward_compatibility_map,
:id,
:language,
:name,
:native_bid_adjustment,
:network,
:pricing_model,
:remarketing_targeting_setting,
:search_bid,
:settings,
:start_date,
:status,
:tracking_url_template,
:url_custom_parameters
# Alphabetical
]
# Alphabetical
KEYS_ORDER = %i[
ad_distribution
ad_rotation
bidding_scheme
content_match_bid
end_date
forward_compatibility_map
id
language
name
native_bid_adjustment
network
remarketing_targeting_setting
search_bid
settings
start_date
status
tracking_url_template
url_custom_parameter
].freeze

def self.prepare(ad_group_raw)
ad_group_raw[:ad_rotation] = { type: ad_group_raw[:ad_rotation] } if ad_group_raw[:ad_rotation]
if ad_group_raw[:bidding_scheme]
# TODO support MaxClicksBiddingScheme, MaxConversionsBiddingScheme and TargetCpaBiddingScheme
ad_group_raw[:bidding_scheme] = {
type: ad_group_raw[:bidding_scheme],
'@xsi:type' => "#{Bing::Ads::API::V11::NAMESPACE_IDENTIFIER}:#{ad_group_raw[:bidding_scheme]}"
'@xsi:type' => "#{Bing::Ads::API::V13::NAMESPACE_IDENTIFIER}:#{ad_group_raw[:bidding_scheme]}"
}
end
ad_group_raw[:content_match_bid] = { amount: ad_group_raw[:content_match_bid] } if ad_group_raw[:content_match_bid]
Expand Down
52 changes: 52 additions & 0 deletions lib/bing/ads/api/v13/data/bulk_request.rb
@@ -0,0 +1,52 @@
module Bing
module Ads
module API
module V13
module Data
class BulkRequest

KEYS_ORDER = %i[
account_ids
compression_type
data_scope
download_entities
download_file_type
format_version
last_sync_time_in_utc
].freeze

class << self
def prepare(bulk_request_row)
bulk_request_row[:account_ids] = prepare_account_ids(
account_ids: bulk_request_row[:account_ids]
)
bulk_request_row[:download_entities] =
prepare_download_entities(
levels: bulk_request_row.delete(:levels)
)
bulk_request_row.except!(:levels)
bulk_request = Bing::Ads::Utils.sort_keys(bulk_request_row, KEYS_ORDER)
Bing::Ads::Utils.camelcase_keys(bulk_request)
end

private

def prepare_account_ids(account_ids:)
{
'a1:long' => account_ids,
'@xmlns:a1' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'
}
end

def prepare_download_entities(levels:)
levels = %w[campaign] if levels.nil? || levels.empty?
entities = levels.map(&:pluralize).map(&:camelcase)
{ download_entity: entities }
end
end
end
end
end
end
end
end