soapy_cake 2.1.0 → 2.1.1
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/.rubocop_todo.yml +16 -0
- data/Gemfile +2 -1
- data/circle.yml +2 -0
- data/lib/soapy_cake.rb +3 -0
- data/lib/soapy_cake/admin.rb +2 -2
- data/lib/soapy_cake/admin_addedit.rb +5 -50
- data/lib/soapy_cake/campaigns.rb +104 -0
- data/lib/soapy_cake/client.rb +5 -5
- data/lib/soapy_cake/helper.rb +14 -9
- data/lib/soapy_cake/modification_type.rb +45 -0
- data/lib/soapy_cake/version.rb +1 -1
- data/spec/fixtures/vcr_cassettes/SoapyCake_AdminAddedit/campaigns/edits_a_campaign.yml +18 -5
- data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_create/creates_campaigns.yml +60 -0
- data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_create/raises_an_error_if_the_creation_was_unsuccessful.yml +60 -0
- data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_get/gets_campaigns.yml +1205 -0
- data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_patch/different_pre-existing_values/does_not_change_anything_unintentionally_attribute_set_0_.yml +380 -0
- data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_patch/different_pre-existing_values/does_not_change_anything_unintentionally_attribute_set_1_.yml +383 -0
- data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_patch/updates_a_campaign.yml +454 -0
- data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_update/raises_an_error_if_the_update_was_unsuccessful.yml +82 -0
- data/spec/fixtures/vcr_cassettes/SoapyCake_Campaigns/_update/updates_campaigns.yml +82 -0
- data/spec/integration/soapy_cake/admin_addedit_spec.rb +0 -31
- data/spec/integration/soapy_cake/campaigns_spec.rb +175 -0
- data/spec/lib/soapy_cake/admin_spec.rb +0 -1
- data/spec/lib/soapy_cake/campaigns_spec.rb +127 -0
- data/spec/lib/soapy_cake/modification_type_spec.rb +59 -0
- data/spec/spec_helper.rb +3 -3
- metadata +27 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffa62a533e0dbfd1cd366b024b007c9a923d4a12
|
4
|
+
data.tar.gz: 5b47bba259aa0ccaafcd0eb6ffb10384b3ea4030
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb9a9ceabe4b5733bec4d5b56a2dc33f47564322d92c96af2beda789b9c376fb6aa4dc2e6b1f6bd05e01b2eff16cdeba1d6c7b9ab1b7373a0a974e2b322105a1
|
7
|
+
data.tar.gz: f204021e63684c64c838bb03d45addb6098e0ffb6142cf6fda723c0d97440af1a875b0dcecaf99b5240737240a01afe2be550c262b42a17e56df99b0ffc399b9
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2016-11-11 15:36:42 +0100 using RuboCop version 0.43.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 1
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 27
|
12
|
+
|
13
|
+
# Offense count: 1
|
14
|
+
# Configuration parameters: CountComments.
|
15
|
+
Metrics/MethodLength:
|
16
|
+
Max: 20
|
data/Gemfile
CHANGED
data/circle.yml
CHANGED
data/lib/soapy_cake.rb
CHANGED
@@ -23,6 +23,9 @@ require 'soapy_cake/admin_addedit'
|
|
23
23
|
require 'soapy_cake/admin_track'
|
24
24
|
require 'soapy_cake/affiliate'
|
25
25
|
|
26
|
+
require 'soapy_cake/modification_type'
|
27
|
+
require 'soapy_cake/campaigns'
|
28
|
+
|
26
29
|
module SoapyCake
|
27
30
|
API_CONFIG = YAML.load(File.read(File.expand_path('../../api.yml', __FILE__)))
|
28
31
|
NET_TIMEOUT = 600
|
data/lib/soapy_cake/admin.rb
CHANGED
@@ -37,7 +37,7 @@ module SoapyCake
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def creatives(opts = {})
|
40
|
-
opts = translate_values(opts
|
40
|
+
opts = translate_values(opts)
|
41
41
|
|
42
42
|
run Request.new(:admin, :export, :creatives, opts)
|
43
43
|
end
|
@@ -80,7 +80,7 @@ module SoapyCake
|
|
80
80
|
|
81
81
|
def caps(opts)
|
82
82
|
require_params(opts, %i(start_date end_date))
|
83
|
-
opts = translate_values(opts
|
83
|
+
opts = translate_values(opts)
|
84
84
|
|
85
85
|
run Request.new(:admin, :reports, :caps, opts)
|
86
86
|
end
|
@@ -70,29 +70,6 @@ module SoapyCake
|
|
70
70
|
offer_contract_is_default use_fallback_targeting
|
71
71
|
).freeze
|
72
72
|
|
73
|
-
REQUIRED_NEW_CAMPAIGN_PARAMS = %i(
|
74
|
-
affiliate_id offer_id account_status_id payout
|
75
|
-
redirect_404 clear_session_on_conversion paid_upsells
|
76
|
-
).freeze
|
77
|
-
|
78
|
-
CAMPAIGN_UPDATE_DEFAULT_OPTIONS = {
|
79
|
-
account_status_id: :no_change,
|
80
|
-
auto_disposition_delay_hours: 0,
|
81
|
-
clear_session_on_conversion: 'no_change',
|
82
|
-
currency_id: 0,
|
83
|
-
expiration_date_modification_type: 'do_not_change',
|
84
|
-
media_type_id: 0,
|
85
|
-
paid: 'no_change',
|
86
|
-
paid_redirects: 'no_change',
|
87
|
-
paid_upsells: 'no_change',
|
88
|
-
postback_delay_ms: -1,
|
89
|
-
redirect_404: 'no_change',
|
90
|
-
redirect_offer_contract_id: 0,
|
91
|
-
review: 'no_change',
|
92
|
-
use_offer_contract_payout: 'no_change',
|
93
|
-
payout_update_option: 'do_not_change'
|
94
|
-
}.freeze
|
95
|
-
|
96
73
|
def add_offer(opts)
|
97
74
|
require_params(opts, REQUIRED_NEW_OFFER_PARAMS)
|
98
75
|
|
@@ -164,7 +141,7 @@ module SoapyCake
|
|
164
141
|
def update_caps(opts)
|
165
142
|
require_params(opts, %i(cap_type_id cap_interval_id cap_amount send_alert_only))
|
166
143
|
|
167
|
-
opts = translate_values(opts
|
144
|
+
opts = translate_values(opts)
|
168
145
|
|
169
146
|
run Request.new(:admin, :addedit, :caps, opts)
|
170
147
|
end
|
@@ -172,7 +149,7 @@ module SoapyCake
|
|
172
149
|
def remove_caps(opts)
|
173
150
|
require_params(opts, %i(cap_type_id))
|
174
151
|
|
175
|
-
opts = translate_values(opts
|
152
|
+
opts = translate_values(opts)
|
176
153
|
|
177
154
|
opts = opts.merge(cap_interval_id: 0, cap_amount: -1, send_alert_only: false)
|
178
155
|
run Request.new(:admin, :addedit, :caps, opts)
|
@@ -196,25 +173,13 @@ module SoapyCake
|
|
196
173
|
run Request.new(:admin, :addedit, :advertiser, opts.merge(advertiser_id: 0))
|
197
174
|
end
|
198
175
|
|
199
|
-
def add_campaign(opts)
|
200
|
-
require_params(opts, REQUIRED_NEW_CAMPAIGN_PARAMS)
|
201
|
-
addedit_campaign(opts.merge(campaign_id: 0, expiration_date: future_expiration_date))
|
202
|
-
end
|
203
|
-
|
204
|
-
def edit_campaign(opts)
|
205
|
-
require_params(opts, %i(campaign_id))
|
206
|
-
validate_id(opts, :campaign_id)
|
207
|
-
|
208
|
-
addedit_campaign(CAMPAIGN_UPDATE_DEFAULT_OPTIONS.merge(opts))
|
209
|
-
end
|
210
|
-
|
211
176
|
private
|
212
177
|
|
213
178
|
def addedit_offer_tier(add_edit_option, opts)
|
214
179
|
require_params(opts, %i(offer_id tier_id price_format_id offer_contract_id status_id))
|
215
180
|
|
216
181
|
opts = opts.merge(redirect_offer_contract_id: -1, add_edit_option: add_edit_option)
|
217
|
-
opts = translate_values(opts
|
182
|
+
opts = translate_values(opts)
|
218
183
|
|
219
184
|
run Request.new(:admin, :addedit, :offer_tiers, opts)
|
220
185
|
end
|
@@ -252,26 +217,16 @@ module SoapyCake
|
|
252
217
|
|
253
218
|
opts = translate_booleans(opts)
|
254
219
|
opts = apply_tag_opts(opts)
|
255
|
-
opts = translate_values(opts
|
256
|
-
currency_id offer_status_id offer_type_id price_format_id
|
257
|
-
conversion_cap_behavior conversion_behavior_on_redirect
|
258
|
-
))
|
220
|
+
opts = translate_values(opts)
|
259
221
|
|
260
222
|
run(Request.new(:admin, :addedit, :offer, default_offer_options.merge(opts)))[:success_info]
|
261
223
|
end
|
262
224
|
|
263
225
|
def addedit_offer_contract(opts)
|
264
226
|
require_params(opts, REQUIRED_OFFER_CONTRACT_PARAMS)
|
265
|
-
opts = translate_values(opts
|
227
|
+
opts = translate_values(opts)
|
266
228
|
|
267
229
|
run Request.new(:admin, :addedit, :offer_contract, opts)
|
268
230
|
end
|
269
|
-
|
270
|
-
def addedit_campaign(opts)
|
271
|
-
opts = translate_booleans(opts)
|
272
|
-
opts = translate_values(opts, %i(account_status_id))
|
273
|
-
opts = opts.reverse_merge(display_link_type_id: 1)
|
274
|
-
run Request.new(:admin, :addedit, :campaign, opts)
|
275
|
-
end
|
276
231
|
end
|
277
232
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module SoapyCake
|
3
|
+
class Campaigns
|
4
|
+
include Helper
|
5
|
+
|
6
|
+
# TODO: Figure out what `static_suppression` is for and whether it needs to
|
7
|
+
# be in the list.
|
8
|
+
ALL_PARAMS = %i(
|
9
|
+
account_status_id affiliate_id auto_disposition_delay_hours campaign_id
|
10
|
+
clear_session_on_conversion currency_id display_link_type_id
|
11
|
+
expiration_date expiration_date_modification_type media_type_id
|
12
|
+
offer_contract_id offer_id paid paid_redirects paid_upsells payout
|
13
|
+
payout_update_option pixel_html postback_delay_ms postback_url
|
14
|
+
redirect_404 redirect_domain redirect_offer_contract_id review test_link
|
15
|
+
third_party_name unique_key_hash use_offer_contract_payout
|
16
|
+
).freeze
|
17
|
+
|
18
|
+
NO_CHANGE_VALUES = {
|
19
|
+
account_status_id: 0,
|
20
|
+
expiration_date_modification_type: ModificationType::DO_NOT_CHANGE,
|
21
|
+
currency_id: 0,
|
22
|
+
use_offer_contract_payout: 'no_change',
|
23
|
+
payout_update_option: ModificationType::DO_NOT_CHANGE,
|
24
|
+
paid: 'no_change',
|
25
|
+
paid_redirects: 'no_change',
|
26
|
+
paid_upsells: 'no_change',
|
27
|
+
review: 'no_change',
|
28
|
+
auto_disposition_delay_hours: 0,
|
29
|
+
redirect_offer_contract_id: 0,
|
30
|
+
redirect_404: 'no_change',
|
31
|
+
clear_session_on_conversion: 'no_change',
|
32
|
+
postback_delay_ms: -1
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
delegate :read_only?, to: :client
|
36
|
+
|
37
|
+
def get(opts = {})
|
38
|
+
client.run Request.new(:admin, :export, :campaigns, opts)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create(opts = {})
|
42
|
+
response = addedit_campaign(opts.merge(campaign_id: 0))
|
43
|
+
response.fetch(:success_info).fetch(:campaign_id)
|
44
|
+
end
|
45
|
+
|
46
|
+
def update(campaign_id, opts = {})
|
47
|
+
opts = opts.merge(campaign_id: campaign_id)
|
48
|
+
opts = opts.merge(payout.options(opts))
|
49
|
+
opts = opts.merge(expiration_date.options(opts))
|
50
|
+
opts = NO_CHANGE_VALUES.merge(opts)
|
51
|
+
require_params(opts, ALL_PARAMS)
|
52
|
+
addedit_campaign(opts)
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def patch(campaign_id, opts = {})
|
57
|
+
campaign = get(campaign_id: campaign_id).first
|
58
|
+
opts = NO_CHANGE_VALUES
|
59
|
+
.merge(
|
60
|
+
affiliate_id: campaign.fetch(:affiliate).fetch(:affiliate_id),
|
61
|
+
# Only present in production:
|
62
|
+
display_link_type_id: campaign.dig(:link_display_type, :link_display_type_id) || 1,
|
63
|
+
media_type_id: campaign.fetch(:media_type).fetch(:media_type_id),
|
64
|
+
offer_contract_id: campaign.fetch(:offer_contract).fetch(:offer_contract_id),
|
65
|
+
offer_id: campaign.fetch(:offer).fetch(:offer_id),
|
66
|
+
payout: campaign.fetch(:payout).fetch(:amount),
|
67
|
+
payout_update_option: 'do_not_change',
|
68
|
+
pixel_html: campaign.dig(:pixel_info, :pixel_html) || '',
|
69
|
+
postback_url: campaign.dig(:pixel_info, :postback_url) || '',
|
70
|
+
redirect_domain: campaign.fetch(:redirect_domain, ''),
|
71
|
+
test_link: campaign[:test_link] || '',
|
72
|
+
unique_key_hash: campaign.dig(:pixel_info, :hash_type, :hash_type_id) || 'none',
|
73
|
+
third_party_name: campaign.fetch(:third_party_name, '')
|
74
|
+
)
|
75
|
+
.merge(opts)
|
76
|
+
update(campaign_id, opts)
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def payout
|
83
|
+
ModificationType.new(:payout, :payout_update_option, 0)
|
84
|
+
end
|
85
|
+
|
86
|
+
def expiration_date
|
87
|
+
ModificationType.new(
|
88
|
+
:expiration_date,
|
89
|
+
:expiration_date_modification_type,
|
90
|
+
Time.utc(1970, 1, 1)
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
def addedit_campaign(opts)
|
95
|
+
opts = translate_booleans(opts)
|
96
|
+
opts = translate_values(opts)
|
97
|
+
client.run Request.new(:admin, :addedit, :campaign, opts)
|
98
|
+
end
|
99
|
+
|
100
|
+
def client
|
101
|
+
@client ||= Client.new
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/soapy_cake/client.rb
CHANGED
@@ -22,10 +22,6 @@ module SoapyCake
|
|
22
22
|
!write_enabled
|
23
23
|
end
|
24
24
|
|
25
|
-
protected
|
26
|
-
|
27
|
-
attr_reader :domain, :api_key, :time_converter, :opts, :logger, :retry_count, :write_enabled
|
28
|
-
|
29
25
|
def run(request)
|
30
26
|
check_write_enabled!(request)
|
31
27
|
request.api_key = api_key
|
@@ -37,6 +33,10 @@ module SoapyCake
|
|
37
33
|
end
|
38
34
|
end
|
39
35
|
|
36
|
+
protected
|
37
|
+
|
38
|
+
attr_reader :domain, :api_key, :time_converter, :opts, :logger, :retry_count, :write_enabled
|
39
|
+
|
40
40
|
private
|
41
41
|
|
42
42
|
def fetch_opt(key, fallback = nil)
|
@@ -49,7 +49,7 @@ module SoapyCake
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def with_retries(&block)
|
52
|
-
opts = { tries: retry_count + 1, on: [RateLimitError, SocketError], sleep: ->
|
52
|
+
opts = { tries: retry_count + 1, on: [RateLimitError, SocketError], sleep: ->(n) { 3**n } }
|
53
53
|
Retryable.retryable(opts, &block)
|
54
54
|
end
|
55
55
|
|
data/lib/soapy_cake/helper.rb
CHANGED
@@ -5,9 +5,9 @@ module SoapyCake
|
|
5
5
|
return nil if obj == {}
|
6
6
|
|
7
7
|
case obj
|
8
|
-
when Hash
|
8
|
+
when Hash, Saxerator::Builder::HashElement
|
9
9
|
obj.map { |hk, hv| [hk, walk_tree(hv, hk, &block)] }.to_h
|
10
|
-
when Array
|
10
|
+
when Array, Saxerator::Builder::ArrayElement
|
11
11
|
obj.map { |av| walk_tree(av, &block) }
|
12
12
|
else
|
13
13
|
yield(obj, key)
|
@@ -20,7 +20,7 @@ module SoapyCake
|
|
20
20
|
|
21
21
|
def require_params(opts, params)
|
22
22
|
params.each do |param|
|
23
|
-
raise Error, "Parameter '#{param}' missing!"
|
23
|
+
raise Error, "Parameter '#{param}' missing!" if opts[param].nil?
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -34,17 +34,22 @@ module SoapyCake
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def translate_values(opts
|
37
|
+
def translate_values(opts)
|
38
38
|
opts.map do |k, v|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
id_key = :"#{k}_id"
|
40
|
+
|
41
|
+
if Const::CONSTS.key?(id_key)
|
42
|
+
[id_key, const_lookup(id_key, v)]
|
43
|
+
elsif Const::CONSTS.key?(k) && !v.is_a?(Integer)
|
44
|
+
[k, const_lookup(k, v)]
|
45
|
+
else
|
46
|
+
[k, v]
|
47
|
+
end
|
43
48
|
end.to_h
|
44
49
|
end
|
45
50
|
|
46
51
|
def const_lookup(type, key)
|
47
|
-
Const::CONSTS
|
52
|
+
Const::CONSTS.fetch(type).fetch(key) do
|
48
53
|
raise ArgumentError, "#{key} is not a valid value for #{type}"
|
49
54
|
end
|
50
55
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module SoapyCake
|
3
|
+
class ModificationType
|
4
|
+
CHANGE = 'change'
|
5
|
+
REMOVE = 'remove'
|
6
|
+
DO_NOT_CHANGE = 'do_not_change'
|
7
|
+
|
8
|
+
def initialize(key, modification_type_key, default)
|
9
|
+
@key = key
|
10
|
+
@modification_type_key = modification_type_key
|
11
|
+
@default = default
|
12
|
+
end
|
13
|
+
|
14
|
+
def options(input_opts)
|
15
|
+
validate_input(input_opts)
|
16
|
+
|
17
|
+
input_opts.merge(
|
18
|
+
key => value(input_opts),
|
19
|
+
modification_type_key => modification_type(input_opts)
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :key, :modification_type_key, :default
|
26
|
+
|
27
|
+
def value(input_opts)
|
28
|
+
input_opts.fetch(key, default)
|
29
|
+
end
|
30
|
+
|
31
|
+
def modification_type(input_opts)
|
32
|
+
input_opts.fetch(modification_type_key) do
|
33
|
+
input_opts[key] ? CHANGE : REMOVE
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_input(input_opts)
|
38
|
+
return unless input_opts[key].nil? && input_opts[modification_type_key] == CHANGE
|
39
|
+
raise InvalidInput,
|
40
|
+
"`#{modification_type_key}` was '#{CHANGE}', but no `#{key}` was provided to change it to"
|
41
|
+
end
|
42
|
+
|
43
|
+
InvalidInput = Class.new(StandardError)
|
44
|
+
end
|
45
|
+
end
|
data/lib/soapy_cake/version.rb
CHANGED
@@ -17,6 +17,7 @@ http_interactions:
|
|
17
17
|
<cake:auto_disposition_delay_hours>0</cake:auto_disposition_delay_hours>
|
18
18
|
<cake:clear_session_on_conversion>no_change</cake:clear_session_on_conversion>
|
19
19
|
<cake:currency_id>0</cake:currency_id>
|
20
|
+
<cake:expiration_date>1970-01-01T01:00:00</cake:expiration_date>
|
20
21
|
<cake:expiration_date_modification_type>do_not_change</cake:expiration_date_modification_type>
|
21
22
|
<cake:media_type_id>1</cake:media_type_id>
|
22
23
|
<cake:paid>no_change</cake:paid>
|
@@ -28,16 +29,28 @@ http_interactions:
|
|
28
29
|
<cake:review>no_change</cake:review>
|
29
30
|
<cake:use_offer_contract_payout>no_change</cake:use_offer_contract_payout>
|
30
31
|
<cake:payout_update_option>do_not_change</cake:payout_update_option>
|
31
|
-
<cake:campaign_id>
|
32
|
+
<cake:campaign_id>23727</cake:campaign_id>
|
32
33
|
<cake:affiliate_id>1</cake:affiliate_id>
|
33
34
|
<cake:offer_id>8910</cake:offer_id>
|
34
35
|
<cake:payout>1.23</cake:payout>
|
36
|
+
<cake:offer_contract_id>767</cake:offer_contract_id>
|
37
|
+
<cake:pixel_html><></cake:pixel_html>
|
38
|
+
<cake:postback_url>http://examle.com/postback</cake:postback_url>
|
39
|
+
<cake:redirect_domain>trk_ad2games.cakemarketing.net</cake:redirect_domain>
|
40
|
+
<cake:test_link>http://example.com/test</cake:test_link>
|
41
|
+
<cake:unique_key_hash>none</cake:unique_key_hash>
|
35
42
|
</cake:Campaign>
|
36
43
|
</env:Body>
|
37
44
|
</env:Envelope>
|
38
45
|
headers:
|
39
46
|
Content-Type:
|
40
47
|
- application/soap+xml;charset=UTF-8
|
48
|
+
Accept-Encoding:
|
49
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
50
|
+
Accept:
|
51
|
+
- "*/*"
|
52
|
+
User-Agent:
|
53
|
+
- Ruby
|
41
54
|
response:
|
42
55
|
status:
|
43
56
|
code: 200
|
@@ -54,15 +67,15 @@ http_interactions:
|
|
54
67
|
X-Powered-By:
|
55
68
|
- ASP.NET
|
56
69
|
Date:
|
57
|
-
-
|
70
|
+
- Thu, 03 Nov 2016 16:08:18 GMT
|
58
71
|
Content-Length:
|
59
|
-
- '
|
72
|
+
- '631'
|
60
73
|
body:
|
61
74
|
encoding: UTF-8
|
62
75
|
string: <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
|
63
76
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><CampaignResponse
|
64
77
|
xmlns="http://cakemarketing.com/api/3/"><CampaignResult><success>true</success><message>Campaign
|
65
|
-
Updated</message><success_info><campaign_id>
|
78
|
+
Updated</message><success_info><campaign_id>23727</campaign_id><affiliate_id>13978</affiliate_id><offer_id>7704</offer_id><offer_contract_id>767</offer_contract_id><media_type_id>1</media_type_id><original>true</original></success_info></CampaignResult></CampaignResponse></soap:Body></soap:Envelope>
|
66
79
|
http_version:
|
67
80
|
recorded_at: Tue, 17 Feb 2015 12:00:00 GMT
|
68
|
-
recorded_with: VCR 3.0.
|
81
|
+
recorded_with: VCR 3.0.3
|