Skip to content
This repository was archived by the owner on Jun 8, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a4165cd
camelcase instead of classify
abhishekgupta5 Dec 11, 2018
16622bf
Merge pull request #2 from abhishekgupta5/report-type
prvithani Dec 11, 2018
124e729
Handle the case when the url is nil for no data from bing
prvithani Mar 4, 2019
c8c6044
Merge pull request #3 from adwyze/handle-empty-url
prvithani Mar 4, 2019
a3132af
Bing API v13 upgrade
ssrva Oct 23, 2019
3c78353
Bing API v13 upgrade (#4)
prvithani Oct 24, 2019
2cfb9fe
Updated dependency close to rails 6
anantprsd5 Jan 20, 2020
8ae266c
Update `activesupport` dependency version to allow minor version upgrade
prvithani May 31, 2020
605a7b9
Add format_version as a valid parameter in report_request
iamrahil Mar 16, 2023
2648571
Merge pull request #6 from adwyze/add_format_version
prvithani Mar 16, 2023
2fd9109
Bump gem version
iamrahil Mar 16, 2023
0461acb
Upgrade bundler/rspec/rake for SOC2
ankuriitk Jan 29, 2024
7c6f6ca
fix(int, bing): categorize CallRateExceeded error as rate limit error
vmuneeb May 29, 2025
17f16cf
feat(bing): Add retry for ratelimit errors
vmuneeb May 29, 2025
1bd933f
Merge pull request #8 from clarisights/categorize-rate-limit-error
vmuneeb May 29, 2025
9edf55f
fix(bing): fix syntax error
vmuneeb May 29, 2025
71356c0
Bump gem version to 13.0.2
vmuneeb May 29, 2025
0b0ddfa
Merge pull request #9 from clarisights/fix-syntax-error
vmuneeb May 29, 2025
6defb59
fix(int, bing): Improve SOAP client error handling and retry logic
vmuneeb Jun 3, 2025
568530c
Merge pull request #10 from clarisights/handle-bulk-api-rate-limit
vmuneeb Jun 4, 2025
9164f12
Bump gem version to 13.0.3
vmuneeb Sep 15, 2025
24819f6
Merge pull request #11 from clarisights/version-upgrade
vmuneeb Sep 18, 2025
fa5a642
chore(deps): relax active support dependency
killbotXD Nov 5, 2025
8dbee24
Merge pull request #12 from clarisights/relax-active-support-dependency
OPhamster Dec 3, 2025
a571b03
feat: Treat AccountNotAuthorized as a typed exception
anmolarora Jun 16, 2026
703ec99
fix: Treat UserIsNotAuthorized as a typed exception
vijuSR Jun 22, 2026
7affd7a
Merge pull request #14 from clarisights/sc-53652/oncall-bing-failure-…
vijuSR Jun 23, 2026
368e2c0
fix: Bump gem version post user perms error classification change
vijuSR Jun 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions bing-ads.gemspec
Original file line number Diff line number Diff line change
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', '< 8.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
Original file line number Diff line number Diff line change
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
20 changes: 20 additions & 0 deletions lib/bing/ads/api/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,26 @@ def initialize(operation, limit, type)
super("can not #{operation} more than #{limit} #{type.to_s.humanize.downcase.pluralize} in a single call")
end
end

# Bing::Ads::API::Errors::RateLimitError
class RateLimitError < RuntimeError
def initialize(message = "Rate limit exceeded. Please try again later.")
super(message)
end
end

# Bing::Ads::API::Errors::RateLimitError
class BulkApiRateLimitError < RuntimeError
def initialize(message = "Bulk API Rate limit exceeded. Please try again later.")
super(message)
end
end

# Bing::Ads::API::Errors::AccountNotAuthorized
class AccountNotAuthorized < RuntimeError; end;

# Bing::Ads::API::Errors::UserIsNotAuthorized
class UserIsNotAuthorized < RuntimeError; end;
end
end
end
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
download_entities:
campaigns: 1
ad_groups: 2
ads: 3
keywords: 4
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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'
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
require_relative './data/campaign'
require_relative './data/keyword'
require_relative './data/report_request'
require_relative './data/bulk_request'
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Loading