fuelsdk_json_bump 0.0.5
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 +7 -0
- data/.gitignore +26 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +91 -0
- data/Guardfile +8 -0
- data/LICENSE.md +13 -0
- data/README.md +127 -0
- data/Rakefile +1 -0
- data/fuelsdk.gemspec +30 -0
- data/lib/fuelsdk.rb +74 -0
- data/lib/fuelsdk/client.rb +282 -0
- data/lib/fuelsdk/http_request.rb +116 -0
- data/lib/fuelsdk/objects.rb +757 -0
- data/lib/fuelsdk/rest.rb +122 -0
- data/lib/fuelsdk/soap.rb +288 -0
- data/lib/fuelsdk/targeting.rb +58 -0
- data/lib/fuelsdk/utils.rb +47 -0
- data/lib/fuelsdk/version.rb +39 -0
- data/lib/new.rb +1240 -0
- data/samples/sample-AddSubscriberToList.rb +56 -0
- data/samples/sample-CreateAndStartDataExtensionImport.rb +29 -0
- data/samples/sample-CreateAndStartListImport.rb +27 -0
- data/samples/sample-CreateContentAreas.rb +48 -0
- data/samples/sample-CreateDataExtensions.rb +54 -0
- data/samples/sample-CreateProfileAttributes.rb +48 -0
- data/samples/sample-SendEmailToDataExtension.rb +23 -0
- data/samples/sample-SendEmailToList.rb +23 -0
- data/samples/sample-SendTriggeredSends.rb +30 -0
- data/samples/sample-bounceevent.rb +70 -0
- data/samples/sample-campaign.rb +211 -0
- data/samples/sample-clickevent.rb +71 -0
- data/samples/sample-contentarea.rb +122 -0
- data/samples/sample-dataextension.rb +209 -0
- data/samples/sample-directverb.rb +55 -0
- data/samples/sample-email.rb +122 -0
- data/samples/sample-email.senddefinition.rb +134 -0
- data/samples/sample-folder.rb +143 -0
- data/samples/sample-import.rb +104 -0
- data/samples/sample-list.rb +105 -0
- data/samples/sample-list.subscriber.rb +97 -0
- data/samples/sample-openevent.rb +70 -0
- data/samples/sample-profileattribute.rb +57 -0
- data/samples/sample-sentevent.rb +70 -0
- data/samples/sample-subscriber.rb +136 -0
- data/samples/sample-triggeredsend.rb +130 -0
- data/samples/sample-unsubevent.rb +72 -0
- data/samples/sample_helper.rb.template +8 -0
- data/spec/client_spec.rb +200 -0
- data/spec/helper_funcs_spec.rb +11 -0
- data/spec/http_request_spec.rb +36 -0
- data/spec/objects_helper_spec.rb +32 -0
- data/spec/objects_spec.rb +484 -0
- data/spec/rest_spec.rb +48 -0
- data/spec/soap_spec.rb +140 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/targeting_spec.rb +39 -0
- metadata +250 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2013 ExactTarget, Inc.
|
3
|
+
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
7
|
+
|
8
|
+
following conditions are met:
|
9
|
+
|
10
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
11
|
+
|
12
|
+
following disclaimer.
|
13
|
+
|
14
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
15
|
+
|
16
|
+
following disclaimer in the documentation and/or other materials provided with the distribution.
|
17
|
+
|
18
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
|
19
|
+
|
20
|
+
products derived from this software without specific prior written permission.
|
21
|
+
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
23
|
+
|
24
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
25
|
+
|
26
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
27
|
+
|
28
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
|
30
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
31
|
+
|
32
|
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
33
|
+
|
34
|
+
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
35
|
+
=end
|
36
|
+
|
37
|
+
module FuelSDK
|
38
|
+
module_function
|
39
|
+
def format_name_value_pairs attributes
|
40
|
+
attrs = []
|
41
|
+
attributes.each do |name, value|
|
42
|
+
attrs.push 'Name' => name, 'Value' => value
|
43
|
+
end
|
44
|
+
|
45
|
+
attrs
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2013 ExactTarget, Inc.
|
3
|
+
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
7
|
+
|
8
|
+
following conditions are met:
|
9
|
+
|
10
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
11
|
+
|
12
|
+
following disclaimer.
|
13
|
+
|
14
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
15
|
+
|
16
|
+
following disclaimer in the documentation and/or other materials provided with the distribution.
|
17
|
+
|
18
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
|
19
|
+
|
20
|
+
products derived from this software without specific prior written permission.
|
21
|
+
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
23
|
+
|
24
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
25
|
+
|
26
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
27
|
+
|
28
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
|
30
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
31
|
+
|
32
|
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
33
|
+
|
34
|
+
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
35
|
+
=end
|
36
|
+
|
37
|
+
module FuelSDK
|
38
|
+
VERSION = "0.0.5"
|
39
|
+
end
|
data/lib/new.rb
ADDED
@@ -0,0 +1,1240 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2013 ExactTarget, Inc.
|
3
|
+
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
7
|
+
|
8
|
+
following conditions are met:
|
9
|
+
|
10
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
11
|
+
|
12
|
+
following disclaimer.
|
13
|
+
|
14
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
15
|
+
|
16
|
+
following disclaimer in the documentation and/or other materials provided with the distribution.
|
17
|
+
|
18
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
|
19
|
+
|
20
|
+
products derived from this software without specific prior written permission.
|
21
|
+
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
23
|
+
|
24
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
25
|
+
|
26
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
27
|
+
|
28
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
|
30
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
31
|
+
|
32
|
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
33
|
+
|
34
|
+
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
35
|
+
=end
|
36
|
+
|
37
|
+
require "fuelsdk/version"
|
38
|
+
|
39
|
+
require 'rubygems'
|
40
|
+
require 'open-uri'
|
41
|
+
require 'savon'
|
42
|
+
require 'date'
|
43
|
+
require 'json'
|
44
|
+
require 'yaml'
|
45
|
+
require 'jwt'
|
46
|
+
|
47
|
+
|
48
|
+
def indifferent_access key, hash
|
49
|
+
hash[key.to_sym] || hash[key.to_s]
|
50
|
+
end
|
51
|
+
|
52
|
+
module FuelSDK
|
53
|
+
|
54
|
+
class Soap
|
55
|
+
def client
|
56
|
+
'soap'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Rest
|
61
|
+
def client
|
62
|
+
'rest'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Client
|
67
|
+
attr_reader :id, :secret, :signature
|
68
|
+
|
69
|
+
def initialize params={}, debug=false
|
70
|
+
@debug = debug
|
71
|
+
@id = indifferent_access :clientid, params
|
72
|
+
@secret = indifferent_access :clientsecret, params
|
73
|
+
@signature = indifferent_access :appsignature, params
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class SoapClient < Client
|
78
|
+
def initialize getWSDL=true, params={}, debug=false
|
79
|
+
super params, debug
|
80
|
+
@wsdl = params["defaultwsdl"]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class RestClient < Client
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# parse response
|
89
|
+
class ET_Constructor
|
90
|
+
attr_accessor :status, :code, :message, :results, :request_id, :moreResults
|
91
|
+
|
92
|
+
def initialize(response = nil, rest = false)
|
93
|
+
@results = []
|
94
|
+
if !response.nil? && !rest then
|
95
|
+
envelope = response.hash[:envelope]
|
96
|
+
@@body = envelope[:body]
|
97
|
+
|
98
|
+
if ((!response.soap_fault?) or (!response.http_error?)) then
|
99
|
+
@code = response.http.code
|
100
|
+
@status = true
|
101
|
+
elsif (response.soap_fault?) then
|
102
|
+
@code = response.http.code
|
103
|
+
@message = @@body[:fault][:faultstring]
|
104
|
+
@status = false
|
105
|
+
elsif (response.http_error?) then
|
106
|
+
@code = response.http.code
|
107
|
+
@status = false
|
108
|
+
end
|
109
|
+
elsif
|
110
|
+
@code = response.code
|
111
|
+
@status = true
|
112
|
+
if @code != "200" then
|
113
|
+
@status = false
|
114
|
+
end
|
115
|
+
|
116
|
+
begin
|
117
|
+
@results = JSON.parse(response.body)
|
118
|
+
rescue
|
119
|
+
@message = response.body
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class ET_CreateWSDL
|
127
|
+
|
128
|
+
def initialize(path)
|
129
|
+
# Get the header info for the correct wsdl
|
130
|
+
response = HTTPI.head(@wsdl)
|
131
|
+
if response and (response.code >= 200 and response.code <= 400) then
|
132
|
+
header = response.headers
|
133
|
+
# Check when the WSDL was last modified
|
134
|
+
modifiedTime = Date.parse(header['last-modified'])
|
135
|
+
p = path + '/ExactTargetWSDL.xml'
|
136
|
+
# Check if a local file already exists
|
137
|
+
if (File.file?(p) and File.readable?(p) and !File.zero?(p)) then
|
138
|
+
createdTime = File.new(p).mtime.to_date
|
139
|
+
|
140
|
+
# Check if the locally created WSDL older than the production WSDL
|
141
|
+
if createdTime < modifiedTime then
|
142
|
+
createIt = true
|
143
|
+
else
|
144
|
+
createIt = false
|
145
|
+
end
|
146
|
+
else
|
147
|
+
createIt = true
|
148
|
+
end
|
149
|
+
|
150
|
+
if createIt then
|
151
|
+
res = open(@wsdl).read
|
152
|
+
File.open(p, 'w+') { |f|
|
153
|
+
f.write(res)
|
154
|
+
}
|
155
|
+
end
|
156
|
+
@status = response.code
|
157
|
+
else
|
158
|
+
@status = response.code
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class ET_Client < ET_CreateWSDL
|
164
|
+
attr_accessor :auth, :ready, :status, :debug, :authToken
|
165
|
+
attr_reader :authTokenExpiration,:internalAuthToken, :wsdlLoc, :clientId,
|
166
|
+
:clientSecret, :soapHeader, :authObj, :path, :appsignature, :stackID, :refreshKey
|
167
|
+
|
168
|
+
def initialize(getWSDL = true, debug = false, params = nil)
|
169
|
+
config = YAML.load_file("config.yaml")
|
170
|
+
@clientId = config["clientid"]
|
171
|
+
@clientSecret = config["clientsecret"]
|
172
|
+
@appsignature = config["appsignature"]
|
173
|
+
@wsdl = config["defaultwsdl"]
|
174
|
+
@debug = debug
|
175
|
+
|
176
|
+
begin
|
177
|
+
@path = File.dirname(__FILE__)
|
178
|
+
|
179
|
+
#make a new WSDL
|
180
|
+
if getWSDL then
|
181
|
+
super(@path)
|
182
|
+
end
|
183
|
+
|
184
|
+
if params && params.has_key?("jwt") then
|
185
|
+
jwt = JWT.decode(params["jwt"], @appsignature, true);
|
186
|
+
@authToken = jwt['request']['user']['oauthToken']
|
187
|
+
@authTokenExpiration = Time.new + jwt['request']['user']['expiresIn']
|
188
|
+
@internalAuthToken = jwt['request']['user']['internalOauthToken']
|
189
|
+
@refreshKey = jwt['request']['user']['refreshToken']
|
190
|
+
|
191
|
+
self.determineStack
|
192
|
+
|
193
|
+
@authObj = {'oAuth' => {'oAuthToken' => @internalAuthToken}}
|
194
|
+
@authObj[:attributes!] = { 'oAuth' => { 'xmlns' => 'http://exacttarget.com' }}
|
195
|
+
|
196
|
+
myWSDL = File.read(@path + '/ExactTargetWSDL.xml')
|
197
|
+
@auth = Savon.client(
|
198
|
+
soap_header: @authObj,
|
199
|
+
wsdl: myWSDL,
|
200
|
+
endpoint: @endpoint,
|
201
|
+
wsse_auth: ["*", "*"],
|
202
|
+
raise_errors: false,
|
203
|
+
log: @debug,
|
204
|
+
open_timeout:180,
|
205
|
+
read_timeout: 180
|
206
|
+
)
|
207
|
+
else
|
208
|
+
self.refreshToken
|
209
|
+
end
|
210
|
+
|
211
|
+
rescue
|
212
|
+
raise
|
213
|
+
end
|
214
|
+
|
215
|
+
if ((@auth.operations.length > 0) and (@status >= 200 and @status <= 400)) then
|
216
|
+
@ready = true
|
217
|
+
else
|
218
|
+
@ready = false
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def debug=(value)
|
223
|
+
@debug = value
|
224
|
+
end
|
225
|
+
|
226
|
+
def refreshToken(force = nil)
|
227
|
+
#If we don't already have a token or the token expires within 5 min(300 seconds), get one
|
228
|
+
if ((@authToken.nil? || Time.new + 300 > @authTokenExpiration) || force) then
|
229
|
+
begin
|
230
|
+
uri = URI.parse("https://auth.exacttargetapis.com/v1/requestToken?legacy=1")
|
231
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
232
|
+
http.use_ssl = true
|
233
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
234
|
+
jsonPayload = {'clientId' => @clientId, 'clientSecret' => @clientSecret}
|
235
|
+
|
236
|
+
#Pass in the refreshKey if we have it
|
237
|
+
if @refreshKey then
|
238
|
+
jsonPayload['refreshToken'] = @refreshKey
|
239
|
+
end
|
240
|
+
|
241
|
+
request.body = jsonPayload.to_json
|
242
|
+
request.add_field "Content-Type", "application/json"
|
243
|
+
tokenResponse = JSON.parse(http.request(request).body)
|
244
|
+
|
245
|
+
if !tokenResponse.has_key?('accessToken') then
|
246
|
+
raise 'Unable to validate App Keys(ClientID/ClientSecret) provided: ' + http.request(request).body
|
247
|
+
end
|
248
|
+
|
249
|
+
@authToken = tokenResponse['accessToken']
|
250
|
+
@authTokenExpiration = Time.new + tokenResponse['expiresIn']
|
251
|
+
@internalAuthToken = tokenResponse['legacyToken']
|
252
|
+
if tokenResponse.has_key?("refreshToken") then
|
253
|
+
@refreshKey = tokenResponse['refreshToken']
|
254
|
+
end
|
255
|
+
|
256
|
+
if @endpoint.nil? then
|
257
|
+
self.determineStack
|
258
|
+
end
|
259
|
+
|
260
|
+
@authObj = {'oAuth' => {'oAuthToken' => @internalAuthToken}}
|
261
|
+
@authObj[:attributes!] = { 'oAuth' => { 'xmlns' => 'http://exacttarget.com' }}
|
262
|
+
|
263
|
+
myWSDL = File.read(@path + '/ExactTargetWSDL.xml')
|
264
|
+
@auth = Savon.client(
|
265
|
+
soap_header: @authObj,
|
266
|
+
wsdl: myWSDL,
|
267
|
+
endpoint: @endpoint,
|
268
|
+
wsse_auth: ["*", "*"],
|
269
|
+
raise_errors: false,
|
270
|
+
log: @debug
|
271
|
+
)
|
272
|
+
|
273
|
+
rescue Exception => e
|
274
|
+
raise 'Unable to validate App Keys(ClientID/ClientSecret) provided: ' + e.message
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def AddSubscriberToList(emailAddress, listIDs, subscriberKey = nil)
|
280
|
+
newSub = ET_Subscriber.new
|
281
|
+
newSub.authStub = self
|
282
|
+
lists = []
|
283
|
+
|
284
|
+
listIDs.each{ |p|
|
285
|
+
lists.push({"ID"=> p})
|
286
|
+
}
|
287
|
+
|
288
|
+
newSub.props = {"EmailAddress" => emailAddress, "Lists" => lists}
|
289
|
+
if !subscriberKey.nil? then
|
290
|
+
newSub.props['SubscriberKey'] = subscriberKey;
|
291
|
+
end
|
292
|
+
|
293
|
+
# Try to add the subscriber
|
294
|
+
postResponse = newSub.post
|
295
|
+
|
296
|
+
if postResponse.status == false then
|
297
|
+
# If the subscriber already exists in the account then we need to do an update.
|
298
|
+
# Update Subscriber On List
|
299
|
+
if postResponse.results[0][:error_code] == "12014" then
|
300
|
+
patchResponse = newSub.patch
|
301
|
+
return patchResponse
|
302
|
+
end
|
303
|
+
end
|
304
|
+
return postResponse
|
305
|
+
end
|
306
|
+
|
307
|
+
def CreateDataExtensions(dataExtensionDefinitions)
|
308
|
+
newDEs = ET_DataExtension.new
|
309
|
+
newDEs.authStub = self
|
310
|
+
|
311
|
+
newDEs.props = dataExtensionDefinitions
|
312
|
+
postResponse = newDEs.post
|
313
|
+
|
314
|
+
return postResponse
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
protected
|
319
|
+
def determineStack()
|
320
|
+
begin
|
321
|
+
uri = URI.parse("https://www.exacttargetapis.com/platform/v1/endpoints/soap?access_token=" + @authToken)
|
322
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
323
|
+
|
324
|
+
http.use_ssl = true
|
325
|
+
|
326
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
327
|
+
|
328
|
+
contextResponse = JSON.parse(http.request(request).body)
|
329
|
+
@endpoint = contextResponse['url']
|
330
|
+
|
331
|
+
rescue StandardError => e
|
332
|
+
raise 'Unable to determine stack using /platform/v1/tokenContext: ' + e.message
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
class ET_Describe < ET_Constructor
|
338
|
+
def initialize(authStub = nil, objType = nil)
|
339
|
+
begin
|
340
|
+
authStub.refreshToken
|
341
|
+
response = authStub.auth.call(:describe, :message => {
|
342
|
+
'DescribeRequests' =>
|
343
|
+
{'ObjectDefinitionRequest' =>
|
344
|
+
{'ObjectType' => objType}
|
345
|
+
}
|
346
|
+
})
|
347
|
+
ensure
|
348
|
+
super(response)
|
349
|
+
|
350
|
+
if @status then
|
351
|
+
objDef = @@body[:definition_response_msg][:object_definition]
|
352
|
+
|
353
|
+
if objDef then
|
354
|
+
@overallStatus = true
|
355
|
+
else
|
356
|
+
@overallStatus = false
|
357
|
+
end
|
358
|
+
@results = @@body[:definition_response_msg][:object_definition][:properties]
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
class ET_Post < ET_Constructor
|
365
|
+
def initialize(authStub, objType, props = nil)
|
366
|
+
@results = []
|
367
|
+
|
368
|
+
begin
|
369
|
+
authStub.refreshToken
|
370
|
+
if props.is_a? Array then
|
371
|
+
obj = {
|
372
|
+
'Objects' => [],
|
373
|
+
:attributes! => { 'Objects' => { 'xsi:type' => ('tns:' + objType) } }
|
374
|
+
}
|
375
|
+
props.each{ |p|
|
376
|
+
obj['Objects'] << p
|
377
|
+
}
|
378
|
+
else
|
379
|
+
obj = {
|
380
|
+
'Objects' => props,
|
381
|
+
:attributes! => { 'Objects' => { 'xsi:type' => ('tns:' + objType) } }
|
382
|
+
}
|
383
|
+
end
|
384
|
+
|
385
|
+
response = authStub.auth.call(:create, :message => obj)
|
386
|
+
|
387
|
+
ensure
|
388
|
+
super(response)
|
389
|
+
if @status then
|
390
|
+
if @@body[:create_response][:overall_status] != "OK"
|
391
|
+
@status = false
|
392
|
+
end
|
393
|
+
#@results = @@body[:create_response][:results]
|
394
|
+
if !@@body[:create_response][:results].nil? then
|
395
|
+
if !@@body[:create_response][:results].is_a? Hash then
|
396
|
+
@results = @results + @@body[:create_response][:results]
|
397
|
+
else
|
398
|
+
@results.push(@@body[:create_response][:results])
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
class ET_Delete < ET_Constructor
|
407
|
+
|
408
|
+
def initialize(authStub, objType, props = nil)
|
409
|
+
@results = []
|
410
|
+
begin
|
411
|
+
authStub.refreshToken
|
412
|
+
if props.is_a? Array then
|
413
|
+
obj = {
|
414
|
+
'Objects' => [],
|
415
|
+
:attributes! => { 'Objects' => { 'xsi:type' => ('tns:' + objType) } }
|
416
|
+
}
|
417
|
+
props.each{ |p|
|
418
|
+
obj['Objects'] << p
|
419
|
+
}
|
420
|
+
else
|
421
|
+
obj = {
|
422
|
+
'Objects' => props,
|
423
|
+
:attributes! => { 'Objects' => { 'xsi:type' => ('tns:' + objType) } }
|
424
|
+
}
|
425
|
+
end
|
426
|
+
|
427
|
+
response = authStub.auth.call(:delete, :message => obj)
|
428
|
+
ensure
|
429
|
+
super(response)
|
430
|
+
if @status then
|
431
|
+
if @@body[:delete_response][:overall_status] != "OK"
|
432
|
+
@status = false
|
433
|
+
end
|
434
|
+
if !@@body[:delete_response][:results].is_a? Hash then
|
435
|
+
@results = @results + @@body[:delete_response][:results]
|
436
|
+
else
|
437
|
+
@results.push(@@body[:delete_response][:results])
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
class ET_Patch < ET_Constructor
|
445
|
+
def initialize(authStub, objType, props = nil)
|
446
|
+
@results = []
|
447
|
+
begin
|
448
|
+
authStub.refreshToken
|
449
|
+
if props.is_a? Array then
|
450
|
+
obj = {
|
451
|
+
'Objects' => [],
|
452
|
+
:attributes! => { 'Objects' => { 'xsi:type' => ('tns:' + objType) } }
|
453
|
+
}
|
454
|
+
props.each{ |p|
|
455
|
+
obj['Objects'] << p
|
456
|
+
}
|
457
|
+
else
|
458
|
+
obj = {
|
459
|
+
'Objects' => props,
|
460
|
+
:attributes! => { 'Objects' => { 'xsi:type' => ('tns:' + objType) } }
|
461
|
+
}
|
462
|
+
end
|
463
|
+
|
464
|
+
response = authStub.auth.call(:update, :message => obj)
|
465
|
+
|
466
|
+
ensure
|
467
|
+
super(response)
|
468
|
+
if @status then
|
469
|
+
if @@body[:update_response][:overall_status] != "OK"
|
470
|
+
@status = false
|
471
|
+
end
|
472
|
+
if !@@body[:update_response][:results].is_a? Hash then
|
473
|
+
@results = @results + @@body[:update_response][:results]
|
474
|
+
else
|
475
|
+
@results.push(@@body[:update_response][:results])
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
class ET_Continue < ET_Constructor
|
483
|
+
def initialize(authStub, request_id)
|
484
|
+
@results = []
|
485
|
+
authStub.refreshToken
|
486
|
+
obj = {'ContinueRequest' => request_id}
|
487
|
+
response = authStub.auth.call(:retrieve, :message => {'RetrieveRequest' => obj})
|
488
|
+
|
489
|
+
super(response)
|
490
|
+
|
491
|
+
if @status then
|
492
|
+
if @@body[:retrieve_response_msg][:overall_status] != "OK" && @@body[:retrieve_response_msg][:overall_status] != "MoreDataAvailable" then
|
493
|
+
@status = false
|
494
|
+
@message = @@body[:retrieve_response_msg][:overall_status]
|
495
|
+
end
|
496
|
+
|
497
|
+
@moreResults = false
|
498
|
+
if @@body[:retrieve_response_msg][:overall_status] == "MoreDataAvailable" then
|
499
|
+
@moreResults = true
|
500
|
+
end
|
501
|
+
|
502
|
+
if (!@@body[:retrieve_response_msg][:results].is_a? Hash) && (!@@body[:retrieve_response_msg][:results].nil?) then
|
503
|
+
@results = @results + @@body[:retrieve_response_msg][:results]
|
504
|
+
elsif (!@@body[:retrieve_response_msg][:results].nil?)
|
505
|
+
@results.push(@@body[:retrieve_response_msg][:results])
|
506
|
+
end
|
507
|
+
|
508
|
+
# Store the Last Request ID for use with continue
|
509
|
+
@request_id = @@body[:retrieve_response_msg][:request_id]
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
class ET_Get < ET_Constructor
|
515
|
+
def initialize(authStub, objType, props = nil, filter = nil)
|
516
|
+
@results = []
|
517
|
+
authStub.refreshToken
|
518
|
+
if !props then
|
519
|
+
resp = ET_Describe.new(authStub, objType)
|
520
|
+
if resp then
|
521
|
+
props = []
|
522
|
+
resp.results.map { |p|
|
523
|
+
if p[:is_retrievable] then
|
524
|
+
props << p[:name]
|
525
|
+
end
|
526
|
+
}
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
# If the properties is a hash, then we just want to use the keys
|
531
|
+
if props.is_a? Hash then
|
532
|
+
obj = {'ObjectType' => objType,'Properties' => props.keys}
|
533
|
+
else
|
534
|
+
obj = {'ObjectType' => objType,'Properties' => props}
|
535
|
+
end
|
536
|
+
|
537
|
+
if filter then
|
538
|
+
if filter.has_key?('LogicalOperator') then
|
539
|
+
obj['Filter'] = filter
|
540
|
+
obj[:attributes!] = { 'Filter' => { 'xsi:type' => 'tns:ComplexFilterPart' }}
|
541
|
+
obj['Filter'][:attributes!] = { 'LeftOperand' => { 'xsi:type' => 'tns:SimpleFilterPart' }, 'RightOperand' => { 'xsi:type' => 'tns:SimpleFilterPart' }}
|
542
|
+
else
|
543
|
+
obj['Filter'] = filter
|
544
|
+
obj[:attributes!] = { 'Filter' => { 'xsi:type' => 'tns:SimpleFilterPart' } }
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
response = authStub.auth.call(:retrieve, :message => {
|
549
|
+
'RetrieveRequest' => obj
|
550
|
+
})
|
551
|
+
|
552
|
+
super(response)
|
553
|
+
|
554
|
+
if @status then
|
555
|
+
if @@body[:retrieve_response_msg][:overall_status] != "OK" && @@body[:retrieve_response_msg][:overall_status] != "MoreDataAvailable" then
|
556
|
+
@status = false
|
557
|
+
@message = @@body[:retrieve_response_msg][:overall_status]
|
558
|
+
end
|
559
|
+
|
560
|
+
@moreResults = false
|
561
|
+
if @@body[:retrieve_response_msg][:overall_status] == "MoreDataAvailable" then
|
562
|
+
@moreResults = true
|
563
|
+
end
|
564
|
+
|
565
|
+
if (!@@body[:retrieve_response_msg][:results].is_a? Hash) && (!@@body[:retrieve_response_msg][:results].nil?) then
|
566
|
+
@results = @results + @@body[:retrieve_response_msg][:results]
|
567
|
+
elsif (!@@body[:retrieve_response_msg][:results].nil?)
|
568
|
+
@results.push(@@body[:retrieve_response_msg][:results])
|
569
|
+
end
|
570
|
+
|
571
|
+
# Store the Last Request ID for use with continue
|
572
|
+
@request_id = @@body[:retrieve_response_msg][:request_id]
|
573
|
+
end
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
class ET_BaseObject
|
578
|
+
attr_accessor :authStub, :props
|
579
|
+
attr_reader :obj, :lastRequestID, :endpoint
|
580
|
+
|
581
|
+
def initialize
|
582
|
+
@authStub = nil
|
583
|
+
@props = nil
|
584
|
+
@filter = nil
|
585
|
+
@lastRequestID = nil
|
586
|
+
@endpoint = nil
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
class ET_GetSupport < ET_BaseObject
|
591
|
+
attr_accessor :filter
|
592
|
+
|
593
|
+
def get(props = nil, filter = nil)
|
594
|
+
if props and props.is_a? Array then
|
595
|
+
@props = props
|
596
|
+
end
|
597
|
+
|
598
|
+
if @props and @props.is_a? Hash then
|
599
|
+
@props = @props.keys
|
600
|
+
end
|
601
|
+
|
602
|
+
if filter and filter.is_a? Hash then
|
603
|
+
@filter = filter
|
604
|
+
end
|
605
|
+
obj = ET_Get.new(@authStub, @obj, @props, @filter)
|
606
|
+
|
607
|
+
@lastRequestID = obj.request_id
|
608
|
+
|
609
|
+
return obj
|
610
|
+
end
|
611
|
+
|
612
|
+
def info()
|
613
|
+
ET_Describe.new(@authStub, @obj)
|
614
|
+
end
|
615
|
+
|
616
|
+
def getMoreResults()
|
617
|
+
ET_Continue.new(@authStub, @lastRequestID)
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
class ET_CUDSupport < ET_GetSupport
|
622
|
+
|
623
|
+
def post()
|
624
|
+
if props and props.is_a? Hash then
|
625
|
+
@props = props
|
626
|
+
end
|
627
|
+
|
628
|
+
if @extProps then
|
629
|
+
@extProps.each { |key, value|
|
630
|
+
@props[key.capitalize] = value
|
631
|
+
}
|
632
|
+
end
|
633
|
+
|
634
|
+
ET_Post.new(@authStub, @obj, @props)
|
635
|
+
end
|
636
|
+
|
637
|
+
def patch()
|
638
|
+
if props and props.is_a? Hash then
|
639
|
+
@props = props
|
640
|
+
end
|
641
|
+
|
642
|
+
ET_Patch.new(@authStub, @obj, @props)
|
643
|
+
end
|
644
|
+
|
645
|
+
def delete()
|
646
|
+
if props and props.is_a? Hash then
|
647
|
+
@props = props
|
648
|
+
end
|
649
|
+
|
650
|
+
ET_Delete.new(@authStub, @obj, @props)
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
class ET_GetSupportRest < ET_BaseObject
|
655
|
+
attr_reader :urlProps, :urlPropsRequired, :lastPageNumber
|
656
|
+
|
657
|
+
def get(props = nil)
|
658
|
+
if props and props.is_a? Hash then
|
659
|
+
@props = props
|
660
|
+
end
|
661
|
+
|
662
|
+
completeURL = @endpoint
|
663
|
+
additionalQS = {}
|
664
|
+
|
665
|
+
if @props and @props.is_a? Hash then
|
666
|
+
@props.each do |k,v|
|
667
|
+
if @urlProps.include?(k) then
|
668
|
+
completeURL.sub!("{#{k}}", v)
|
669
|
+
else
|
670
|
+
additionalQS[k] = v
|
671
|
+
end
|
672
|
+
end
|
673
|
+
end
|
674
|
+
|
675
|
+
@urlPropsRequired.each do |value|
|
676
|
+
if !@props || !@props.has_key?(value) then
|
677
|
+
raise "Unable to process request due to missing required prop: #{value}"
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
@urlProps.each do |value|
|
682
|
+
completeURL.sub!("/{#{value}}", "")
|
683
|
+
end
|
684
|
+
|
685
|
+
obj = ET_GetRest.new(@authStub, completeURL,additionalQS)
|
686
|
+
|
687
|
+
if obj.results.has_key?('page') then
|
688
|
+
@lastPageNumber = obj.results['page']
|
689
|
+
pageSize = obj.results['pageSize']
|
690
|
+
if obj.results.has_key?('count') then
|
691
|
+
count = obj.results['count']
|
692
|
+
elsif obj.results.has_key?('totalCount') then
|
693
|
+
count = obj.results['totalCount']
|
694
|
+
end
|
695
|
+
|
696
|
+
if !count.nil? && count > (@lastPageNumber * pageSize) then
|
697
|
+
obj.moreResults = true
|
698
|
+
end
|
699
|
+
end
|
700
|
+
return obj
|
701
|
+
end
|
702
|
+
|
703
|
+
def getMoreResults()
|
704
|
+
if props and props.is_a? Hash then
|
705
|
+
@props = props
|
706
|
+
end
|
707
|
+
|
708
|
+
originalPageValue = "1"
|
709
|
+
removePageFromProps = false
|
710
|
+
|
711
|
+
if !@props.nil? && @props.has_key?('$page') then
|
712
|
+
originalPageValue = @props['page']
|
713
|
+
else
|
714
|
+
removePageFromProps = true
|
715
|
+
end
|
716
|
+
|
717
|
+
if @props.nil?
|
718
|
+
@props = {}
|
719
|
+
end
|
720
|
+
|
721
|
+
@props['$page'] = @lastPageNumber + 1
|
722
|
+
|
723
|
+
obj = self.get
|
724
|
+
|
725
|
+
if removePageFromProps then
|
726
|
+
@props.delete('$page')
|
727
|
+
else
|
728
|
+
@props['$page'] = originalPageValue
|
729
|
+
end
|
730
|
+
|
731
|
+
return obj
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
735
|
+
class ET_CUDSupportRest < ET_GetSupportRest
|
736
|
+
|
737
|
+
def post()
|
738
|
+
completeURL = @endpoint
|
739
|
+
|
740
|
+
if @props and @props.is_a? Hash then
|
741
|
+
@props.each do |k,v|
|
742
|
+
if @urlProps.include?(k) then
|
743
|
+
completeURL.sub!("{#{k}}", v)
|
744
|
+
end
|
745
|
+
end
|
746
|
+
end
|
747
|
+
|
748
|
+
@urlPropsRequired.each do |value|
|
749
|
+
if !@props || !@props.has_key?(value) then
|
750
|
+
raise "Unable to process request due to missing required prop: #{value}"
|
751
|
+
end
|
752
|
+
end
|
753
|
+
|
754
|
+
# Clean Optional Parameters from Endpoint URL first
|
755
|
+
@urlProps.each do |value|
|
756
|
+
completeURL.sub!("/{#{value}}", "")
|
757
|
+
end
|
758
|
+
|
759
|
+
ET_PostRest.new(@authStub, completeURL, @props)
|
760
|
+
end
|
761
|
+
|
762
|
+
def patch()
|
763
|
+
completeURL = @endpoint
|
764
|
+
# All URL Props are required when doing Patch
|
765
|
+
@urlProps.each do |value|
|
766
|
+
if !@props || !@props.has_key?(value) then
|
767
|
+
raise "Unable to process request due to missing required prop: #{value}"
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
if @props and @props.is_a? Hash then
|
772
|
+
@props.each do |k,v|
|
773
|
+
if @urlProps.include?(k) then
|
774
|
+
completeURL.sub!("{#{k}}", v)
|
775
|
+
end
|
776
|
+
end
|
777
|
+
end
|
778
|
+
|
779
|
+
obj = ET_PatchRest.new(@authStub, completeURL, @props)
|
780
|
+
end
|
781
|
+
|
782
|
+
def delete()
|
783
|
+
completeURL = @endpoint
|
784
|
+
# All URL Props are required when doing Patch
|
785
|
+
@urlProps.each do |value|
|
786
|
+
if !@props || !@props.has_key?(value) then
|
787
|
+
raise "Unable to process request due to missing required prop: #{value}"
|
788
|
+
end
|
789
|
+
end
|
790
|
+
|
791
|
+
if @props and @props.is_a? Hash then
|
792
|
+
@props.each do |k,v|
|
793
|
+
if @urlProps.include?(k) then
|
794
|
+
completeURL.sub!("{#{k}}", v)
|
795
|
+
end
|
796
|
+
end
|
797
|
+
end
|
798
|
+
|
799
|
+
ET_DeleteRest.new(@authStub, completeURL)
|
800
|
+
end
|
801
|
+
|
802
|
+
end
|
803
|
+
|
804
|
+
|
805
|
+
class ET_GetRest < ET_Constructor
|
806
|
+
def initialize(authStub, endpoint, qs = nil)
|
807
|
+
authStub.refreshToken
|
808
|
+
|
809
|
+
if qs then
|
810
|
+
qs['access_token'] = authStub.authToken
|
811
|
+
else
|
812
|
+
qs = {"access_token" => authStub.authToken}
|
813
|
+
end
|
814
|
+
|
815
|
+
uri = URI.parse(endpoint)
|
816
|
+
uri.query = URI.encode_www_form(qs)
|
817
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
818
|
+
http.use_ssl = true
|
819
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
820
|
+
requestResponse = http.request(request)
|
821
|
+
|
822
|
+
@moreResults = false
|
823
|
+
|
824
|
+
obj = super(requestResponse, true)
|
825
|
+
return obj
|
826
|
+
end
|
827
|
+
end
|
828
|
+
|
829
|
+
|
830
|
+
class ET_ContinueRest < ET_Constructor
|
831
|
+
def initialize(authStub, endpoint, qs = nil)
|
832
|
+
authStub.refreshToken
|
833
|
+
|
834
|
+
if qs then
|
835
|
+
qs['access_token'] = authStub.authToken
|
836
|
+
else
|
837
|
+
qs = {"access_token" => authStub.authToken}
|
838
|
+
end
|
839
|
+
|
840
|
+
uri = URI.parse(endpoint)
|
841
|
+
uri.query = URI.encode_www_form(qs)
|
842
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
843
|
+
http.use_ssl = true
|
844
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
845
|
+
requestResponse = http.request(request)
|
846
|
+
|
847
|
+
@moreResults = false
|
848
|
+
|
849
|
+
super(requestResponse, true)
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
|
854
|
+
class ET_PostRest < ET_Constructor
|
855
|
+
def initialize(authStub, endpoint, payload)
|
856
|
+
authStub.refreshToken
|
857
|
+
|
858
|
+
qs = {"access_token" => authStub.authToken}
|
859
|
+
uri = URI.parse(endpoint)
|
860
|
+
uri.query = URI.encode_www_form(qs)
|
861
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
862
|
+
http.use_ssl = true
|
863
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
864
|
+
request.body = payload.to_json
|
865
|
+
request.add_field "Content-Type", "application/json"
|
866
|
+
requestResponse = http.request(request)
|
867
|
+
|
868
|
+
super(requestResponse, true)
|
869
|
+
|
870
|
+
end
|
871
|
+
end
|
872
|
+
|
873
|
+
class ET_PatchRest < ET_Constructor
|
874
|
+
def initialize(authStub, endpoint, payload)
|
875
|
+
authStub.refreshToken
|
876
|
+
|
877
|
+
qs = {"access_token" => authStub.authToken}
|
878
|
+
uri = URI.parse(endpoint)
|
879
|
+
uri.query = URI.encode_www_form(qs)
|
880
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
881
|
+
http.use_ssl = true
|
882
|
+
request = Net::HTTP::Patch.new(uri.request_uri)
|
883
|
+
request.body = payload.to_json
|
884
|
+
request.add_field "Content-Type", "application/json"
|
885
|
+
requestResponse = http.request(request)
|
886
|
+
super(requestResponse, true)
|
887
|
+
|
888
|
+
end
|
889
|
+
end
|
890
|
+
|
891
|
+
class ET_DeleteRest < ET_Constructor
|
892
|
+
def initialize(authStub, endpoint)
|
893
|
+
authStub.refreshToken
|
894
|
+
|
895
|
+
qs = {"access_token" => authStub.authToken}
|
896
|
+
|
897
|
+
uri = URI.parse(endpoint)
|
898
|
+
uri.query = URI.encode_www_form(qs)
|
899
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
900
|
+
http.use_ssl = true
|
901
|
+
request = Net::HTTP::Delete.new(uri.request_uri)
|
902
|
+
requestResponse = http.request(request)
|
903
|
+
super(requestResponse, true)
|
904
|
+
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
class ET_Campaign < ET_CUDSupportRest
|
909
|
+
def initialize
|
910
|
+
super
|
911
|
+
@endpoint = 'https://www.exacttargetapis.com/hub/v1/campaigns/{id}'
|
912
|
+
@urlProps = ["id"]
|
913
|
+
@urlPropsRequired = []
|
914
|
+
end
|
915
|
+
|
916
|
+
class Asset < ET_CUDSupportRest
|
917
|
+
def initialize
|
918
|
+
super
|
919
|
+
@endpoint = 'https://www.exacttargetapis.com/hub/v1/campaigns/{id}/assets/{assetId}'
|
920
|
+
@urlProps = ["id", "assetId"]
|
921
|
+
@urlPropsRequired = ["id"]
|
922
|
+
end
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
class ET_Subscriber < ET_CUDSupport
|
927
|
+
def initialize
|
928
|
+
super
|
929
|
+
@obj = 'Subscriber'
|
930
|
+
end
|
931
|
+
end
|
932
|
+
|
933
|
+
class ET_DataExtension < ET_CUDSupport
|
934
|
+
attr_accessor :columns
|
935
|
+
|
936
|
+
def initialize
|
937
|
+
super
|
938
|
+
@obj = 'DataExtension'
|
939
|
+
end
|
940
|
+
|
941
|
+
def post
|
942
|
+
originalProps = @props
|
943
|
+
|
944
|
+
if @props.is_a? Array then
|
945
|
+
multiDE = []
|
946
|
+
@props.each { |currentDE|
|
947
|
+
currentDE['Fields'] = {}
|
948
|
+
currentDE['Fields']['Field'] = []
|
949
|
+
currentDE['columns'].each { |key|
|
950
|
+
currentDE['Fields']['Field'].push(key)
|
951
|
+
}
|
952
|
+
currentDE.delete('columns')
|
953
|
+
multiDE.push(currentDE.dup)
|
954
|
+
}
|
955
|
+
|
956
|
+
@props = multiDE
|
957
|
+
else
|
958
|
+
@props['Fields'] = {}
|
959
|
+
@props['Fields']['Field'] = []
|
960
|
+
|
961
|
+
@columns.each { |key|
|
962
|
+
@props['Fields']['Field'].push(key)
|
963
|
+
}
|
964
|
+
end
|
965
|
+
|
966
|
+
obj = super
|
967
|
+
@props = originalProps
|
968
|
+
return obj
|
969
|
+
end
|
970
|
+
|
971
|
+
def patch
|
972
|
+
@props['Fields'] = {}
|
973
|
+
@props['Fields']['Field'] = []
|
974
|
+
@columns.each { |key|
|
975
|
+
@props['Fields']['Field'].push(key)
|
976
|
+
}
|
977
|
+
obj = super
|
978
|
+
@props.delete("Fields")
|
979
|
+
return obj
|
980
|
+
end
|
981
|
+
|
982
|
+
class Column < ET_GetSupport
|
983
|
+
def initialize
|
984
|
+
super
|
985
|
+
@obj = 'DataExtensionField'
|
986
|
+
end
|
987
|
+
|
988
|
+
def get
|
989
|
+
|
990
|
+
if props and props.is_a? Array then
|
991
|
+
@props = props
|
992
|
+
end
|
993
|
+
|
994
|
+
if @props and @props.is_a? Hash then
|
995
|
+
@props = @props.keys
|
996
|
+
end
|
997
|
+
|
998
|
+
if filter and filter.is_a? Hash then
|
999
|
+
@filter = filter
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
fixCustomerKey = false
|
1003
|
+
if filter and filter.is_a? Hash then
|
1004
|
+
@filter = filter
|
1005
|
+
if @filter.has_key?("Property") && @filter["Property"] == "CustomerKey" then
|
1006
|
+
@filter["Property"] = "DataExtension.CustomerKey"
|
1007
|
+
fixCustomerKey = true
|
1008
|
+
end
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
obj = ET_Get.new(@authStub, @obj, @props, @filter)
|
1012
|
+
@lastRequestID = obj.request_id
|
1013
|
+
|
1014
|
+
if fixCustomerKey then
|
1015
|
+
@filter["Property"] = "CustomerKey"
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
return obj
|
1019
|
+
end
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
class Row < ET_CUDSupport
|
1023
|
+
attr_accessor :Name, :CustomerKey
|
1024
|
+
|
1025
|
+
def initialize()
|
1026
|
+
super
|
1027
|
+
@obj = "DataExtensionObject"
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
def get
|
1031
|
+
getName
|
1032
|
+
if props and props.is_a? Array then
|
1033
|
+
@props = props
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
if @props and @props.is_a? Hash then
|
1037
|
+
@props = @props.keys
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
if filter and filter.is_a? Hash then
|
1041
|
+
@filter = filter
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
obj = ET_Get.new(@authStub, "DataExtensionObject[#{@Name}]", @props, @filter)
|
1045
|
+
@lastRequestID = obj.request_id
|
1046
|
+
|
1047
|
+
return obj
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
def post
|
1051
|
+
getCustomerKey
|
1052
|
+
originalProps = @props
|
1053
|
+
## FIX THIS
|
1054
|
+
if @props.is_a? Array then
|
1055
|
+
=begin
|
1056
|
+
multiRow = []
|
1057
|
+
@props.each { |currentDE|
|
1058
|
+
|
1059
|
+
currentDE['columns'].each { |key|
|
1060
|
+
currentDE['Fields'] = {}
|
1061
|
+
currentDE['Fields']['Field'] = []
|
1062
|
+
currentDE['Fields']['Field'].push(key)
|
1063
|
+
}
|
1064
|
+
currentDE.delete('columns')
|
1065
|
+
multiRow.push(currentDE.dup)
|
1066
|
+
}
|
1067
|
+
|
1068
|
+
@props = multiRow
|
1069
|
+
=end
|
1070
|
+
else
|
1071
|
+
currentFields = []
|
1072
|
+
currentProp = {}
|
1073
|
+
|
1074
|
+
@props.each { |key,value|
|
1075
|
+
currentFields.push({"Name" => key, "Value" => value})
|
1076
|
+
}
|
1077
|
+
currentProp['CustomerKey'] = @CustomerKey
|
1078
|
+
currentProp['Properties'] = {}
|
1079
|
+
currentProp['Properties']['Property'] = currentFields
|
1080
|
+
end
|
1081
|
+
|
1082
|
+
obj = ET_Post.new(@authStub, @obj, currentProp)
|
1083
|
+
@props = originalProps
|
1084
|
+
obj
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
def patch
|
1088
|
+
getCustomerKey
|
1089
|
+
currentFields = []
|
1090
|
+
currentProp = {}
|
1091
|
+
|
1092
|
+
@props.each { |key,value|
|
1093
|
+
currentFields.push({"Name" => key, "Value" => value})
|
1094
|
+
}
|
1095
|
+
currentProp['CustomerKey'] = @CustomerKey
|
1096
|
+
currentProp['Properties'] = {}
|
1097
|
+
currentProp['Properties']['Property'] = currentFields
|
1098
|
+
|
1099
|
+
ET_Patch.new(@authStub, @obj, currentProp)
|
1100
|
+
end
|
1101
|
+
def delete
|
1102
|
+
getCustomerKey
|
1103
|
+
currentFields = []
|
1104
|
+
currentProp = {}
|
1105
|
+
|
1106
|
+
@props.each { |key,value|
|
1107
|
+
currentFields.push({"Name" => key, "Value" => value})
|
1108
|
+
}
|
1109
|
+
currentProp['CustomerKey'] = @CustomerKey
|
1110
|
+
currentProp['Keys'] = {}
|
1111
|
+
currentProp['Keys']['Key'] = currentFields
|
1112
|
+
|
1113
|
+
ET_Delete.new(@authStub, @obj, currentProp)
|
1114
|
+
end
|
1115
|
+
|
1116
|
+
private
|
1117
|
+
def getCustomerKey
|
1118
|
+
if @CustomerKey.nil? then
|
1119
|
+
if @CustomerKey.nil? && @Name.nil? then
|
1120
|
+
raise 'Unable to process DataExtension::Row request due to CustomerKey and Name not being defined on ET_DatExtension::row'
|
1121
|
+
else
|
1122
|
+
de = ET_DataExtension.new
|
1123
|
+
de.authStub = @authStub
|
1124
|
+
de.props = ["Name","CustomerKey"]
|
1125
|
+
de.filter = {'Property' => 'CustomerKey','SimpleOperator' => 'equals','Value' => @Name}
|
1126
|
+
getResponse = de.get
|
1127
|
+
if getResponse.status && (getResponse.results.length == 1) then
|
1128
|
+
@CustomerKey = getResponse.results[0][:customer_key]
|
1129
|
+
else
|
1130
|
+
raise 'Unable to process DataExtension::Row request due to unable to find DataExtension based on Name'
|
1131
|
+
end
|
1132
|
+
end
|
1133
|
+
end
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
def getName
|
1137
|
+
if @Name.nil? then
|
1138
|
+
if @CustomerKey.nil? && @Name.nil? then
|
1139
|
+
raise 'Unable to process DataExtension::Row request due to CustomerKey and Name not being defined on ET_DatExtension::row'
|
1140
|
+
else
|
1141
|
+
de = ET_DataExtension.new
|
1142
|
+
de.authStub = @authStub
|
1143
|
+
de.props = ["Name","CustomerKey"]
|
1144
|
+
de.filter = {'Property' => 'CustomerKey','SimpleOperator' => 'equals','Value' => @CustomerKey}
|
1145
|
+
getResponse = de.get
|
1146
|
+
if getResponse.status && (getResponse.results.length == 1) then
|
1147
|
+
@Name = getResponse.results[0][:name]
|
1148
|
+
else
|
1149
|
+
raise 'Unable to process DataExtension::Row request due to unable to find DataExtension based on CustomerKey'
|
1150
|
+
end
|
1151
|
+
end
|
1152
|
+
end
|
1153
|
+
end
|
1154
|
+
end
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
class ET_List < ET_CUDSupport
|
1158
|
+
def initialize
|
1159
|
+
super
|
1160
|
+
@obj = 'List'
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
class Subscriber < ET_GetSupport
|
1164
|
+
def initialize
|
1165
|
+
super
|
1166
|
+
@obj = 'ListSubscriber'
|
1167
|
+
end
|
1168
|
+
end
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
class ET_Email < ET_CUDSupport
|
1172
|
+
def initialize
|
1173
|
+
super
|
1174
|
+
@obj = 'Email'
|
1175
|
+
end
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
class ET_TriggeredSend < ET_CUDSupport
|
1179
|
+
attr_accessor :subscribers
|
1180
|
+
def initialize
|
1181
|
+
super
|
1182
|
+
@obj = 'TriggeredSendDefinition'
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
def send
|
1186
|
+
@tscall = {"TriggeredSendDefinition" => @props, "Subscribers" => @subscribers}
|
1187
|
+
ET_Post.new(@authStub, "TriggeredSend", @tscall)
|
1188
|
+
end
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
class ET_ContentArea < ET_CUDSupport
|
1192
|
+
def initialize
|
1193
|
+
super
|
1194
|
+
@obj = 'ContentArea'
|
1195
|
+
end
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
class ET_Folder < ET_CUDSupport
|
1199
|
+
def initialize
|
1200
|
+
super
|
1201
|
+
@obj = 'DataFolder'
|
1202
|
+
end
|
1203
|
+
end
|
1204
|
+
|
1205
|
+
class ET_SentEvent < ET_GetSupport
|
1206
|
+
def initialize
|
1207
|
+
super
|
1208
|
+
@obj = 'SentEvent'
|
1209
|
+
end
|
1210
|
+
end
|
1211
|
+
|
1212
|
+
class ET_OpenEvent < ET_GetSupport
|
1213
|
+
def initialize
|
1214
|
+
super
|
1215
|
+
@obj = 'OpenEvent'
|
1216
|
+
end
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
class ET_BounceEvent < ET_GetSupport
|
1220
|
+
def initialize
|
1221
|
+
super
|
1222
|
+
@obj = 'BounceEvent'
|
1223
|
+
end
|
1224
|
+
end
|
1225
|
+
|
1226
|
+
class ET_UnsubEvent < ET_GetSupport
|
1227
|
+
def initialize
|
1228
|
+
super
|
1229
|
+
@obj = 'UnsubEvent'
|
1230
|
+
end
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
class ET_ClickEvent < ET_GetSupport
|
1234
|
+
def initialize
|
1235
|
+
super
|
1236
|
+
@obj = 'ClickEvent'
|
1237
|
+
end
|
1238
|
+
end
|
1239
|
+
|
1240
|
+
end
|