sfmc-fuelsdk-ruby 1.3.0 → 1.3.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/.github/ISSUE_TEMPLATE/bug_report.md +39 -39
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
- data/.gitignore +29 -29
- data/Gemfile +3 -3
- data/Gemfile.lock +104 -92
- data/Guardfile +8 -8
- data/LICENSE.md +13 -13
- data/README.md +200 -194
- data/Rakefile +1 -1
- data/lib/marketingcloudsdk.rb +74 -74
- data/lib/marketingcloudsdk/client.rb +395 -395
- data/lib/marketingcloudsdk/http_request.rb +118 -118
- data/lib/marketingcloudsdk/objects.rb +757 -757
- data/lib/marketingcloudsdk/rest.rb +118 -118
- data/lib/marketingcloudsdk/soap.rb +296 -296
- data/lib/marketingcloudsdk/targeting.rb +99 -99
- data/lib/marketingcloudsdk/utils.rb +47 -47
- data/lib/marketingcloudsdk/version.rb +39 -39
- data/lib/new.rb +1240 -1240
- data/marketingcloudsdk.gemspec +30 -30
- data/samples/sample-AddSubscriberToList.rb +56 -56
- data/samples/sample-CreateAndStartDataExtensionImport.rb +29 -29
- data/samples/sample-CreateAndStartListImport.rb +27 -27
- data/samples/sample-CreateContentAreas.rb +48 -48
- data/samples/sample-CreateDataExtensions.rb +54 -54
- data/samples/sample-CreateProfileAttributes.rb +48 -48
- data/samples/sample-SendEmailToDataExtension.rb +23 -23
- data/samples/sample-SendEmailToList.rb +23 -23
- data/samples/sample-SendTriggeredSends.rb +30 -30
- data/samples/sample-bounceevent.rb +70 -70
- data/samples/sample-campaign.rb +211 -211
- data/samples/sample-clickevent.rb +71 -71
- data/samples/sample-contentarea.rb +122 -122
- data/samples/sample-dataextension.rb +209 -209
- data/samples/sample-directverb.rb +54 -54
- data/samples/sample-email.rb +122 -122
- data/samples/sample-email.senddefinition.rb +134 -134
- data/samples/sample-folder.rb +143 -143
- data/samples/sample-import.rb +103 -103
- data/samples/sample-list.rb +105 -105
- data/samples/sample-list.subscriber.rb +97 -97
- data/samples/sample-openevent.rb +70 -70
- data/samples/sample-profileattribute.rb +56 -56
- data/samples/sample-sentevent.rb +70 -70
- data/samples/sample-subscriber.rb +135 -135
- data/samples/sample-triggeredsend.rb +129 -129
- data/samples/sample-unsubevent.rb +72 -72
- data/samples/sample_helper.rb.template +10 -10
- data/spec/client_spec.rb +416 -416
- data/spec/default_values_fallback_spec.rb +30 -30
- data/spec/helper_funcs_spec.rb +11 -11
- data/spec/http_request_spec.rb +61 -61
- data/spec/objects_helper_spec.rb +32 -32
- data/spec/objects_spec.rb +484 -484
- data/spec/public_or_web_integration_credentials.rb.template +11 -11
- data/spec/rest_spec.rb +48 -48
- data/spec/soap_spec.rb +140 -140
- data/spec/spec_helper.rb +14 -14
- data/spec/targeting_spec.rb +44 -44
- metadata +14 -27
data/Rakefile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/marketingcloudsdk.rb
CHANGED
@@ -1,74 +1,74 @@
|
|
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 "marketingcloudsdk/version"
|
38
|
-
|
39
|
-
require 'rubygems'
|
40
|
-
require 'date'
|
41
|
-
require 'jwt'
|
42
|
-
|
43
|
-
module MarketingCloudSDK
|
44
|
-
require 'marketingcloudsdk/utils'
|
45
|
-
autoload :HTTPRequest, 'marketingcloudsdk/http_request'
|
46
|
-
autoload :Targeting, 'marketingcloudsdk/targeting'
|
47
|
-
autoload :Soap, 'marketingcloudsdk/soap'
|
48
|
-
autoload :Rest, 'marketingcloudsdk/rest'
|
49
|
-
require 'marketingcloudsdk/client'
|
50
|
-
require 'marketingcloudsdk/objects'
|
51
|
-
end
|
52
|
-
|
53
|
-
# backwards compatability
|
54
|
-
ET_Client = MarketingCloudSDK::Client
|
55
|
-
ET_BounceEvent = MarketingCloudSDK::BounceEvent
|
56
|
-
ET_ClickEvent = MarketingCloudSDK::ClickEvent
|
57
|
-
ET_ContentArea = MarketingCloudSDK::ContentArea
|
58
|
-
ET_DataExtension = MarketingCloudSDK::DataExtension
|
59
|
-
ET_DataFolder = MarketingCloudSDK::DataFolder
|
60
|
-
ET_Folder = MarketingCloudSDK::Folder
|
61
|
-
ET_Email = MarketingCloudSDK::Email
|
62
|
-
ET_List = MarketingCloudSDK::List
|
63
|
-
ET_OpenEvent = MarketingCloudSDK::OpenEvent
|
64
|
-
ET_SentEvent = MarketingCloudSDK::SentEvent
|
65
|
-
ET_Subscriber = MarketingCloudSDK::Subscriber
|
66
|
-
ET_UnsubEvent = MarketingCloudSDK::UnsubEvent
|
67
|
-
ET_TriggeredSend = MarketingCloudSDK::TriggeredSend
|
68
|
-
ET_Campaign = MarketingCloudSDK::Campaign
|
69
|
-
ET_Get = MarketingCloudSDK::Get
|
70
|
-
ET_Post = MarketingCloudSDK::Post
|
71
|
-
ET_Delete = MarketingCloudSDK::Delete
|
72
|
-
ET_Patch = MarketingCloudSDK::Patch
|
73
|
-
ET_ProfileAttribute = MarketingCloudSDK::ProfileAttribute
|
74
|
-
ET_Import = MarketingCloudSDK::Import
|
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 "marketingcloudsdk/version"
|
38
|
+
|
39
|
+
require 'rubygems'
|
40
|
+
require 'date'
|
41
|
+
require 'jwt'
|
42
|
+
|
43
|
+
module MarketingCloudSDK
|
44
|
+
require 'marketingcloudsdk/utils'
|
45
|
+
autoload :HTTPRequest, 'marketingcloudsdk/http_request'
|
46
|
+
autoload :Targeting, 'marketingcloudsdk/targeting'
|
47
|
+
autoload :Soap, 'marketingcloudsdk/soap'
|
48
|
+
autoload :Rest, 'marketingcloudsdk/rest'
|
49
|
+
require 'marketingcloudsdk/client'
|
50
|
+
require 'marketingcloudsdk/objects'
|
51
|
+
end
|
52
|
+
|
53
|
+
# backwards compatability
|
54
|
+
ET_Client = MarketingCloudSDK::Client
|
55
|
+
ET_BounceEvent = MarketingCloudSDK::BounceEvent
|
56
|
+
ET_ClickEvent = MarketingCloudSDK::ClickEvent
|
57
|
+
ET_ContentArea = MarketingCloudSDK::ContentArea
|
58
|
+
ET_DataExtension = MarketingCloudSDK::DataExtension
|
59
|
+
ET_DataFolder = MarketingCloudSDK::DataFolder
|
60
|
+
ET_Folder = MarketingCloudSDK::Folder
|
61
|
+
ET_Email = MarketingCloudSDK::Email
|
62
|
+
ET_List = MarketingCloudSDK::List
|
63
|
+
ET_OpenEvent = MarketingCloudSDK::OpenEvent
|
64
|
+
ET_SentEvent = MarketingCloudSDK::SentEvent
|
65
|
+
ET_Subscriber = MarketingCloudSDK::Subscriber
|
66
|
+
ET_UnsubEvent = MarketingCloudSDK::UnsubEvent
|
67
|
+
ET_TriggeredSend = MarketingCloudSDK::TriggeredSend
|
68
|
+
ET_Campaign = MarketingCloudSDK::Campaign
|
69
|
+
ET_Get = MarketingCloudSDK::Get
|
70
|
+
ET_Post = MarketingCloudSDK::Post
|
71
|
+
ET_Delete = MarketingCloudSDK::Delete
|
72
|
+
ET_Patch = MarketingCloudSDK::Patch
|
73
|
+
ET_ProfileAttribute = MarketingCloudSDK::ProfileAttribute
|
74
|
+
ET_Import = MarketingCloudSDK::Import
|
@@ -1,395 +1,395 @@
|
|
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
|
-
|
36
|
-
=end
|
37
|
-
|
38
|
-
require 'securerandom'
|
39
|
-
module MarketingCloudSDK
|
40
|
-
class Response
|
41
|
-
# not doing accessor so user, can't update these values from response.
|
42
|
-
# You will see in the code some of these
|
43
|
-
# items are being updated via back doors and such.
|
44
|
-
attr_reader :code, :message, :results, :request_id, :body, :raw
|
45
|
-
|
46
|
-
# some defaults
|
47
|
-
def success
|
48
|
-
@success ||= false
|
49
|
-
end
|
50
|
-
alias :success? :success
|
51
|
-
alias :status :success # backward compatibility
|
52
|
-
|
53
|
-
def more
|
54
|
-
@more ||= false
|
55
|
-
end
|
56
|
-
alias :more? :more
|
57
|
-
|
58
|
-
def initialize raw, client
|
59
|
-
@client = client # keep connection with client in case we request more
|
60
|
-
@results = []
|
61
|
-
@raw = raw
|
62
|
-
unpack raw
|
63
|
-
rescue => ex # all else fails return raw
|
64
|
-
puts ex.message
|
65
|
-
raw
|
66
|
-
end
|
67
|
-
|
68
|
-
def continue
|
69
|
-
raise NotImplementedError
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
def unpack raw
|
74
|
-
raise NotImplementedError
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
class Client
|
79
|
-
attr_accessor :debug, :access_token, :auth_token, :internal_token, :refresh_token,
|
80
|
-
:id, :secret, :signature, :base_api_url, :package_name, :package_folders, :parent_folders, :auth_token_expiration,
|
81
|
-
:request_token_url, :soap_endpoint, :use_oAuth2_authentication, :account_id, :scope, :application_type, :authorization_code, :redirect_URI
|
82
|
-
|
83
|
-
include MarketingCloudSDK::Soap
|
84
|
-
include MarketingCloudSDK::Rest
|
85
|
-
|
86
|
-
def jwt= encoded_jwt
|
87
|
-
raise 'Require app signature to decode JWT' unless self.signature
|
88
|
-
decoded_jwt = JWT.decode(encoded_jwt, self.signature, true)
|
89
|
-
decoded_jwt_first = decoded_jwt.first
|
90
|
-
|
91
|
-
self.auth_token = decoded_jwt_first['request']['user']['oauthToken']
|
92
|
-
self.internal_token = decoded_jwt_first['request']['user']['internalOauthToken']
|
93
|
-
self.refresh_token = decoded_jwt_first['request']['user']['refreshToken']
|
94
|
-
self.auth_token_expiration = Time.new + decoded_jwt_first['request']['user']['expiresIn']
|
95
|
-
self.package_name = decoded_jwt_first['request']['application']['package']
|
96
|
-
end
|
97
|
-
|
98
|
-
def initialize(params={}, debug=false)
|
99
|
-
@refresh_mutex = Mutex.new
|
100
|
-
self.debug = debug
|
101
|
-
client_config = params['client']
|
102
|
-
if client_config
|
103
|
-
self.id = client_config["id"]
|
104
|
-
self.secret = client_config["secret"]
|
105
|
-
self.signature = client_config["signature"]
|
106
|
-
self.base_api_url = !(client_config["base_api_url"].to_s.strip.empty?) ? client_config["base_api_url"] : 'https://www.exacttargetapis.com'
|
107
|
-
self.request_token_url = client_config["request_token_url"]
|
108
|
-
self.soap_endpoint = client_config["soap_endpoint"]
|
109
|
-
self.use_oAuth2_authentication = client_config["use_oAuth2_authentication"]
|
110
|
-
self.account_id = client_config["account_id"]
|
111
|
-
self.scope = client_config["scope"]
|
112
|
-
self.application_type = client_config["application_type"]
|
113
|
-
self.authorization_code = client_config["authorization_code"]
|
114
|
-
self.redirect_URI = client_config["redirect_URI"]
|
115
|
-
end
|
116
|
-
|
117
|
-
# Set a default value in case no 'client' params is sent
|
118
|
-
if (!self.base_api_url)
|
119
|
-
self.base_api_url = 'https://www.exacttargetapis.com'
|
120
|
-
end
|
121
|
-
|
122
|
-
if (self.request_token_url.to_s.strip.empty?)
|
123
|
-
if(use_oAuth2_authentication == true)
|
124
|
-
raise 'request_token_url (Auth TSE) is mandatory when using OAuth2 authentication'
|
125
|
-
else
|
126
|
-
self.request_token_url = 'https://auth.exacttargetapis.com/v1/requestToken'
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
if application_type.to_s.strip.empty?
|
131
|
-
self.application_type = 'server'
|
132
|
-
end
|
133
|
-
|
134
|
-
if ['web', 'public'].include? application_type
|
135
|
-
if authorization_code.to_s.strip.empty? or redirect_URI.to_s.strip.empty?
|
136
|
-
raise 'authorization_code or redirect_URI is null: For Public/Web Apps, the authorization_code and redirect_URI must be passed when instantiating Client'
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
if application_type == 'public'
|
141
|
-
if id.to_s.strip.empty?
|
142
|
-
raise 'id is null: id must be passed when instantiating Client'
|
143
|
-
end
|
144
|
-
else
|
145
|
-
if id.to_s.strip.empty? or secret.to_s.strip.empty?
|
146
|
-
raise 'id and secret must pe passed when instantiating Client'
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
self.jwt = params['jwt'] if params['jwt']
|
151
|
-
self.refresh_token = params['refresh_token'] if params['refresh_token']
|
152
|
-
|
153
|
-
self.wsdl = params["defaultwsdl"] if params["defaultwsdl"]
|
154
|
-
|
155
|
-
self.refresh
|
156
|
-
end
|
157
|
-
|
158
|
-
def refresh force=false
|
159
|
-
@refresh_mutex.synchronize do
|
160
|
-
|
161
|
-
if (self.use_oAuth2_authentication == true)
|
162
|
-
self.refreshWithOAuth2(force)
|
163
|
-
return
|
164
|
-
end
|
165
|
-
|
166
|
-
#If we don't already have a token or the token expires within 5 min(300 seconds)
|
167
|
-
if (self.access_token.nil? || Time.new + 300 > self.auth_token_expiration || force) then
|
168
|
-
payload = Hash.new.tap do |h|
|
169
|
-
h['clientId']= id
|
170
|
-
h['clientSecret'] = secret
|
171
|
-
h['refreshToken'] = refresh_token if refresh_token
|
172
|
-
h['accessType'] = 'offline'
|
173
|
-
end
|
174
|
-
|
175
|
-
options = Hash.new.tap do |h|
|
176
|
-
h['data'] = payload
|
177
|
-
h['content_type'] = 'application/json'
|
178
|
-
h['params'] = {'legacy' => 1}
|
179
|
-
end
|
180
|
-
response = post(request_token_url, options)
|
181
|
-
raise "Unable to refresh token: #{response['message']}" unless response.has_key?('accessToken')
|
182
|
-
|
183
|
-
self.access_token = response['accessToken']
|
184
|
-
self.internal_token = response['legacyToken']
|
185
|
-
self.auth_token_expiration = Time.new + response['expiresIn']
|
186
|
-
self.refresh_token = response['refreshToken'] if response.has_key?("refreshToken")
|
187
|
-
return true
|
188
|
-
else
|
189
|
-
return false
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
def refreshWithOAuth2 force=false
|
195
|
-
#If we don't already have a token or the token expires within 5 min(300 seconds)
|
196
|
-
if (self.access_token.nil? || Time.new + 300 > self.auth_token_expiration || force) then
|
197
|
-
|
198
|
-
payload = createPayload
|
199
|
-
|
200
|
-
options = Hash.new.tap do |h|
|
201
|
-
h['data'] = payload
|
202
|
-
h['content_type'] = 'application/json'
|
203
|
-
end
|
204
|
-
|
205
|
-
auth_endpoint = request_token_url + '/v2/token'
|
206
|
-
|
207
|
-
response = post(auth_endpoint, options)
|
208
|
-
raise "Unable to refresh token: #{response['message']}" unless response.has_key?('access_token')
|
209
|
-
|
210
|
-
self.access_token = response['access_token']
|
211
|
-
self.auth_token_expiration = Time.new + response['expires_in']
|
212
|
-
self.soap_endpoint = response['soap_instance_url'] + 'service.asmx'
|
213
|
-
self.base_api_url = response['rest_instance_url']
|
214
|
-
|
215
|
-
if response.has_key?('refresh_token')
|
216
|
-
self.refresh_token = response['refresh_token']
|
217
|
-
end
|
218
|
-
|
219
|
-
return true
|
220
|
-
else
|
221
|
-
return false
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
def createPayload
|
226
|
-
payload = Hash.new.tap do |h|
|
227
|
-
h['client_id'] = id
|
228
|
-
|
229
|
-
if application_type != 'public'
|
230
|
-
h['client_secret'] = secret
|
231
|
-
end
|
232
|
-
|
233
|
-
if !refresh_token.to_s.strip.empty?
|
234
|
-
h['grant_type'] = 'refresh_token'
|
235
|
-
h['refresh_token'] = refresh_token
|
236
|
-
elsif ['web', 'public'].include? application_type
|
237
|
-
h['grant_type'] = 'authorization_code'
|
238
|
-
h['code'] = authorization_code
|
239
|
-
h['redirect_uri'] = redirect_URI
|
240
|
-
else
|
241
|
-
h['grant_type'] = 'client_credentials'
|
242
|
-
end
|
243
|
-
|
244
|
-
unless account_id.to_s.strip.empty?
|
245
|
-
h['account_id'] = account_id
|
246
|
-
end
|
247
|
-
|
248
|
-
unless scope.to_s.strip.empty?
|
249
|
-
h['scope'] = scope
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
payload
|
254
|
-
end
|
255
|
-
|
256
|
-
def refresh!
|
257
|
-
refresh true
|
258
|
-
end
|
259
|
-
|
260
|
-
def AddSubscriberToList(email, ids, subscriber_key = nil)
|
261
|
-
s = MarketingCloudSDK::Subscriber.new
|
262
|
-
s.client = self
|
263
|
-
lists = ids.collect{|id| {'ID' => id}}
|
264
|
-
s.properties = {"EmailAddress" => email, "Lists" => lists}
|
265
|
-
p s.properties
|
266
|
-
s.properties['SubscriberKey'] = subscriber_key if subscriber_key
|
267
|
-
|
268
|
-
# Try to add the subscriber
|
269
|
-
if(rsp = s.post and rsp.results.first[:error_code] == '12014')
|
270
|
-
# subscriber already exists we need to update.
|
271
|
-
rsp = s.patch
|
272
|
-
end
|
273
|
-
rsp
|
274
|
-
end
|
275
|
-
|
276
|
-
def CreateDataExtensions(definitions)
|
277
|
-
de = MarketingCloudSDK::DataExtension.new
|
278
|
-
de.client = self
|
279
|
-
de.properties = definitions
|
280
|
-
de.post
|
281
|
-
end
|
282
|
-
def SendTriggeredSends(arrayOfTriggeredRecords)
|
283
|
-
sendTS = ET_TriggeredSend.new
|
284
|
-
sendTS.authStub = self
|
285
|
-
|
286
|
-
sendTS.properties = arrayOfTriggeredRecords
|
287
|
-
sendResponse = sendTS.send
|
288
|
-
|
289
|
-
return sendResponse
|
290
|
-
end
|
291
|
-
def SendEmailToList(emailID, listID, sendClassificationCustomerKey)
|
292
|
-
email = ET_Email::SendDefinition.new
|
293
|
-
email.properties = {"Name"=>SecureRandom.uuid, "CustomerKey"=>SecureRandom.uuid, "Description"=>"Created with RubySDK"}
|
294
|
-
email.properties["SendClassification"] = {"CustomerKey"=>sendClassificationCustomerKey}
|
295
|
-
email.properties["SendDefinitionList"] = {"List"=> {"ID"=>listID}, "DataSourceTypeID"=>"List"}
|
296
|
-
email.properties["Email"] = {"ID"=>emailID}
|
297
|
-
email.authStub = self
|
298
|
-
result = email.post
|
299
|
-
if result.status then
|
300
|
-
sendresult = email.send
|
301
|
-
if sendresult.status then
|
302
|
-
deleteresult = email.delete
|
303
|
-
return sendresult
|
304
|
-
else
|
305
|
-
raise "Unable to send using send definition due to: #{result.results[0][:status_message]}"
|
306
|
-
end
|
307
|
-
else
|
308
|
-
raise "Unable to create send definition due to: #{result.results[0][:status_message]}"
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
def SendEmailToDataExtension(emailID, sendableDataExtensionCustomerKey, sendClassificationCustomerKey)
|
313
|
-
email = ET_Email::SendDefinition.new
|
314
|
-
email.properties = {"Name"=>SecureRandom.uuid, "CustomerKey"=>SecureRandom.uuid, "Description"=>"Created with RubySDK"}
|
315
|
-
email.properties["SendClassification"] = {"CustomerKey"=> sendClassificationCustomerKey}
|
316
|
-
email.properties["SendDefinitionList"] = {"CustomerKey"=> sendableDataExtensionCustomerKey, "DataSourceTypeID"=>"CustomObject"}
|
317
|
-
email.properties["Email"] = {"ID"=>emailID}
|
318
|
-
email.authStub = self
|
319
|
-
result = email.post
|
320
|
-
if result.status then
|
321
|
-
sendresult = email.send
|
322
|
-
if sendresult.status then
|
323
|
-
deleteresult = email.delete
|
324
|
-
return sendresult
|
325
|
-
else
|
326
|
-
raise "Unable to send using send definition due to: #{result.results[0][:status_message]}"
|
327
|
-
end
|
328
|
-
else
|
329
|
-
raise "Unable to create send definition due to: #{result.results[0][:status_message]}"
|
330
|
-
end
|
331
|
-
end
|
332
|
-
def CreateAndStartListImport(listId,fileName)
|
333
|
-
import = ET_Import.new
|
334
|
-
import.authStub = self
|
335
|
-
import.properties = {"Name"=> "SDK Generated Import #{DateTime.now.to_s}"}
|
336
|
-
import.properties["CustomerKey"] = SecureRandom.uuid
|
337
|
-
import.properties["Description"] = "SDK Generated Import"
|
338
|
-
import.properties["AllowErrors"] = "true"
|
339
|
-
import.properties["DestinationObject"] = {"ID"=>listId}
|
340
|
-
import.properties["FieldMappingType"] = "InferFromColumnHeadings"
|
341
|
-
import.properties["FileSpec"] = fileName
|
342
|
-
import.properties["FileType"] = "CSV"
|
343
|
-
import.properties["RetrieveFileTransferLocation"] = {"CustomerKey"=>"ExactTarget Enhanced FTP"}
|
344
|
-
import.properties["UpdateType"] = "AddAndUpdate"
|
345
|
-
result = import.post
|
346
|
-
|
347
|
-
if result.status then
|
348
|
-
return import.start
|
349
|
-
else
|
350
|
-
raise "Unable to create import definition due to: #{result.results[0][:status_message]}"
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
def CreateAndStartDataExtensionImport(dataExtensionCustomerKey, fileName, overwrite)
|
355
|
-
import = ET_Import.new
|
356
|
-
import.authStub = self
|
357
|
-
import.properties = {"Name"=> "SDK Generated Import #{DateTime.now.to_s}"}
|
358
|
-
import.properties["CustomerKey"] = SecureRandom.uuid
|
359
|
-
import.properties["Description"] = "SDK Generated Import"
|
360
|
-
import.properties["AllowErrors"] = "true"
|
361
|
-
import.properties["DestinationObject"] = {"CustomerKey"=>dataExtensionCustomerKey}
|
362
|
-
import.properties["FieldMappingType"] = "InferFromColumnHeadings"
|
363
|
-
import.properties["FileSpec"] = fileName
|
364
|
-
import.properties["FileType"] = "CSV"
|
365
|
-
import.properties["RetrieveFileTransferLocation"] = {"CustomerKey"=>"ExactTarget Enhanced FTP"}
|
366
|
-
if overwrite then
|
367
|
-
import.properties["UpdateType"] = "Overwrite"
|
368
|
-
else
|
369
|
-
import.properties["UpdateType"] = "AddAndUpdate"
|
370
|
-
end
|
371
|
-
result = import.post
|
372
|
-
|
373
|
-
if result.status then
|
374
|
-
return import.start
|
375
|
-
else
|
376
|
-
raise "Unable to create import definition due to: #{result.results[0][:status_message]}"
|
377
|
-
end
|
378
|
-
end
|
379
|
-
|
380
|
-
def CreateProfileAttributes(allAttributes)
|
381
|
-
attrs = ET_ProfileAttribute.new
|
382
|
-
attrs.authStub = self
|
383
|
-
attrs.properties = allAttributes
|
384
|
-
return attrs.post
|
385
|
-
end
|
386
|
-
|
387
|
-
def CreateContentAreas(arrayOfContentAreas)
|
388
|
-
postC = ET_ContentArea.new
|
389
|
-
postC.authStub = self
|
390
|
-
postC.properties = arrayOfContentAreas
|
391
|
-
sendResponse = postC.post
|
392
|
-
return sendResponse
|
393
|
-
end
|
394
|
-
end
|
395
|
-
end
|
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
|
+
|
36
|
+
=end
|
37
|
+
|
38
|
+
require 'securerandom'
|
39
|
+
module MarketingCloudSDK
|
40
|
+
class Response
|
41
|
+
# not doing accessor so user, can't update these values from response.
|
42
|
+
# You will see in the code some of these
|
43
|
+
# items are being updated via back doors and such.
|
44
|
+
attr_reader :code, :message, :results, :request_id, :body, :raw
|
45
|
+
|
46
|
+
# some defaults
|
47
|
+
def success
|
48
|
+
@success ||= false
|
49
|
+
end
|
50
|
+
alias :success? :success
|
51
|
+
alias :status :success # backward compatibility
|
52
|
+
|
53
|
+
def more
|
54
|
+
@more ||= false
|
55
|
+
end
|
56
|
+
alias :more? :more
|
57
|
+
|
58
|
+
def initialize raw, client
|
59
|
+
@client = client # keep connection with client in case we request more
|
60
|
+
@results = []
|
61
|
+
@raw = raw
|
62
|
+
unpack raw
|
63
|
+
rescue => ex # all else fails return raw
|
64
|
+
puts ex.message
|
65
|
+
raw
|
66
|
+
end
|
67
|
+
|
68
|
+
def continue
|
69
|
+
raise NotImplementedError
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def unpack raw
|
74
|
+
raise NotImplementedError
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class Client
|
79
|
+
attr_accessor :debug, :access_token, :auth_token, :internal_token, :refresh_token,
|
80
|
+
:id, :secret, :signature, :base_api_url, :package_name, :package_folders, :parent_folders, :auth_token_expiration,
|
81
|
+
:request_token_url, :soap_endpoint, :use_oAuth2_authentication, :account_id, :scope, :application_type, :authorization_code, :redirect_URI
|
82
|
+
|
83
|
+
include MarketingCloudSDK::Soap
|
84
|
+
include MarketingCloudSDK::Rest
|
85
|
+
|
86
|
+
def jwt= encoded_jwt
|
87
|
+
raise 'Require app signature to decode JWT' unless self.signature
|
88
|
+
decoded_jwt = JWT.decode(encoded_jwt, self.signature, true)
|
89
|
+
decoded_jwt_first = decoded_jwt.first
|
90
|
+
|
91
|
+
self.auth_token = decoded_jwt_first['request']['user']['oauthToken']
|
92
|
+
self.internal_token = decoded_jwt_first['request']['user']['internalOauthToken']
|
93
|
+
self.refresh_token = decoded_jwt_first['request']['user']['refreshToken']
|
94
|
+
self.auth_token_expiration = Time.new + decoded_jwt_first['request']['user']['expiresIn']
|
95
|
+
self.package_name = decoded_jwt_first['request']['application']['package']
|
96
|
+
end
|
97
|
+
|
98
|
+
def initialize(params={}, debug=false)
|
99
|
+
@refresh_mutex = Mutex.new
|
100
|
+
self.debug = debug
|
101
|
+
client_config = params['client']
|
102
|
+
if client_config
|
103
|
+
self.id = client_config["id"]
|
104
|
+
self.secret = client_config["secret"]
|
105
|
+
self.signature = client_config["signature"]
|
106
|
+
self.base_api_url = !(client_config["base_api_url"].to_s.strip.empty?) ? client_config["base_api_url"] : 'https://www.exacttargetapis.com'
|
107
|
+
self.request_token_url = client_config["request_token_url"]
|
108
|
+
self.soap_endpoint = client_config["soap_endpoint"]
|
109
|
+
self.use_oAuth2_authentication = client_config["use_oAuth2_authentication"]
|
110
|
+
self.account_id = client_config["account_id"]
|
111
|
+
self.scope = client_config["scope"]
|
112
|
+
self.application_type = client_config["application_type"]
|
113
|
+
self.authorization_code = client_config["authorization_code"]
|
114
|
+
self.redirect_URI = client_config["redirect_URI"]
|
115
|
+
end
|
116
|
+
|
117
|
+
# Set a default value in case no 'client' params is sent
|
118
|
+
if (!self.base_api_url)
|
119
|
+
self.base_api_url = 'https://www.exacttargetapis.com'
|
120
|
+
end
|
121
|
+
|
122
|
+
if (self.request_token_url.to_s.strip.empty?)
|
123
|
+
if(use_oAuth2_authentication == true)
|
124
|
+
raise 'request_token_url (Auth TSE) is mandatory when using OAuth2 authentication'
|
125
|
+
else
|
126
|
+
self.request_token_url = 'https://auth.exacttargetapis.com/v1/requestToken'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
if application_type.to_s.strip.empty?
|
131
|
+
self.application_type = 'server'
|
132
|
+
end
|
133
|
+
|
134
|
+
if ['web', 'public'].include? application_type
|
135
|
+
if authorization_code.to_s.strip.empty? or redirect_URI.to_s.strip.empty?
|
136
|
+
raise 'authorization_code or redirect_URI is null: For Public/Web Apps, the authorization_code and redirect_URI must be passed when instantiating Client'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if application_type == 'public'
|
141
|
+
if id.to_s.strip.empty?
|
142
|
+
raise 'id is null: id must be passed when instantiating Client'
|
143
|
+
end
|
144
|
+
else
|
145
|
+
if id.to_s.strip.empty? or secret.to_s.strip.empty?
|
146
|
+
raise 'id and secret must pe passed when instantiating Client'
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
self.jwt = params['jwt'] if params['jwt']
|
151
|
+
self.refresh_token = params['refresh_token'] if params['refresh_token']
|
152
|
+
|
153
|
+
self.wsdl = params["defaultwsdl"] if params["defaultwsdl"]
|
154
|
+
|
155
|
+
self.refresh
|
156
|
+
end
|
157
|
+
|
158
|
+
def refresh force=false
|
159
|
+
@refresh_mutex.synchronize do
|
160
|
+
|
161
|
+
if (self.use_oAuth2_authentication == true)
|
162
|
+
self.refreshWithOAuth2(force)
|
163
|
+
return
|
164
|
+
end
|
165
|
+
|
166
|
+
#If we don't already have a token or the token expires within 5 min(300 seconds)
|
167
|
+
if (self.access_token.nil? || Time.new + 300 > self.auth_token_expiration || force) then
|
168
|
+
payload = Hash.new.tap do |h|
|
169
|
+
h['clientId']= id
|
170
|
+
h['clientSecret'] = secret
|
171
|
+
h['refreshToken'] = refresh_token if refresh_token
|
172
|
+
h['accessType'] = 'offline'
|
173
|
+
end
|
174
|
+
|
175
|
+
options = Hash.new.tap do |h|
|
176
|
+
h['data'] = payload
|
177
|
+
h['content_type'] = 'application/json'
|
178
|
+
h['params'] = {'legacy' => 1}
|
179
|
+
end
|
180
|
+
response = post(request_token_url, options)
|
181
|
+
raise "Unable to refresh token: #{response['message']}" unless response.has_key?('accessToken')
|
182
|
+
|
183
|
+
self.access_token = response['accessToken']
|
184
|
+
self.internal_token = response['legacyToken']
|
185
|
+
self.auth_token_expiration = Time.new + response['expiresIn']
|
186
|
+
self.refresh_token = response['refreshToken'] if response.has_key?("refreshToken")
|
187
|
+
return true
|
188
|
+
else
|
189
|
+
return false
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def refreshWithOAuth2 force=false
|
195
|
+
#If we don't already have a token or the token expires within 5 min(300 seconds)
|
196
|
+
if (self.access_token.nil? || Time.new + 300 > self.auth_token_expiration || force) then
|
197
|
+
|
198
|
+
payload = createPayload
|
199
|
+
|
200
|
+
options = Hash.new.tap do |h|
|
201
|
+
h['data'] = payload
|
202
|
+
h['content_type'] = 'application/json'
|
203
|
+
end
|
204
|
+
|
205
|
+
auth_endpoint = request_token_url + '/v2/token'
|
206
|
+
|
207
|
+
response = post(auth_endpoint, options)
|
208
|
+
raise "Unable to refresh token: #{response['message']}" unless response.has_key?('access_token')
|
209
|
+
|
210
|
+
self.access_token = response['access_token']
|
211
|
+
self.auth_token_expiration = Time.new + response['expires_in']
|
212
|
+
self.soap_endpoint = response['soap_instance_url'] + 'service.asmx'
|
213
|
+
self.base_api_url = response['rest_instance_url']
|
214
|
+
|
215
|
+
if response.has_key?('refresh_token')
|
216
|
+
self.refresh_token = response['refresh_token']
|
217
|
+
end
|
218
|
+
|
219
|
+
return true
|
220
|
+
else
|
221
|
+
return false
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def createPayload
|
226
|
+
payload = Hash.new.tap do |h|
|
227
|
+
h['client_id'] = id
|
228
|
+
|
229
|
+
if application_type != 'public'
|
230
|
+
h['client_secret'] = secret
|
231
|
+
end
|
232
|
+
|
233
|
+
if !refresh_token.to_s.strip.empty?
|
234
|
+
h['grant_type'] = 'refresh_token'
|
235
|
+
h['refresh_token'] = refresh_token
|
236
|
+
elsif ['web', 'public'].include? application_type
|
237
|
+
h['grant_type'] = 'authorization_code'
|
238
|
+
h['code'] = authorization_code
|
239
|
+
h['redirect_uri'] = redirect_URI
|
240
|
+
else
|
241
|
+
h['grant_type'] = 'client_credentials'
|
242
|
+
end
|
243
|
+
|
244
|
+
unless account_id.to_s.strip.empty?
|
245
|
+
h['account_id'] = account_id
|
246
|
+
end
|
247
|
+
|
248
|
+
unless scope.to_s.strip.empty?
|
249
|
+
h['scope'] = scope
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
payload
|
254
|
+
end
|
255
|
+
|
256
|
+
def refresh!
|
257
|
+
refresh true
|
258
|
+
end
|
259
|
+
|
260
|
+
def AddSubscriberToList(email, ids, subscriber_key = nil)
|
261
|
+
s = MarketingCloudSDK::Subscriber.new
|
262
|
+
s.client = self
|
263
|
+
lists = ids.collect{|id| {'ID' => id}}
|
264
|
+
s.properties = {"EmailAddress" => email, "Lists" => lists}
|
265
|
+
p s.properties
|
266
|
+
s.properties['SubscriberKey'] = subscriber_key if subscriber_key
|
267
|
+
|
268
|
+
# Try to add the subscriber
|
269
|
+
if(rsp = s.post and rsp.results.first[:error_code] == '12014')
|
270
|
+
# subscriber already exists we need to update.
|
271
|
+
rsp = s.patch
|
272
|
+
end
|
273
|
+
rsp
|
274
|
+
end
|
275
|
+
|
276
|
+
def CreateDataExtensions(definitions)
|
277
|
+
de = MarketingCloudSDK::DataExtension.new
|
278
|
+
de.client = self
|
279
|
+
de.properties = definitions
|
280
|
+
de.post
|
281
|
+
end
|
282
|
+
def SendTriggeredSends(arrayOfTriggeredRecords)
|
283
|
+
sendTS = ET_TriggeredSend.new
|
284
|
+
sendTS.authStub = self
|
285
|
+
|
286
|
+
sendTS.properties = arrayOfTriggeredRecords
|
287
|
+
sendResponse = sendTS.send
|
288
|
+
|
289
|
+
return sendResponse
|
290
|
+
end
|
291
|
+
def SendEmailToList(emailID, listID, sendClassificationCustomerKey)
|
292
|
+
email = ET_Email::SendDefinition.new
|
293
|
+
email.properties = {"Name"=>SecureRandom.uuid, "CustomerKey"=>SecureRandom.uuid, "Description"=>"Created with RubySDK"}
|
294
|
+
email.properties["SendClassification"] = {"CustomerKey"=>sendClassificationCustomerKey}
|
295
|
+
email.properties["SendDefinitionList"] = {"List"=> {"ID"=>listID}, "DataSourceTypeID"=>"List"}
|
296
|
+
email.properties["Email"] = {"ID"=>emailID}
|
297
|
+
email.authStub = self
|
298
|
+
result = email.post
|
299
|
+
if result.status then
|
300
|
+
sendresult = email.send
|
301
|
+
if sendresult.status then
|
302
|
+
deleteresult = email.delete
|
303
|
+
return sendresult
|
304
|
+
else
|
305
|
+
raise "Unable to send using send definition due to: #{result.results[0][:status_message]}"
|
306
|
+
end
|
307
|
+
else
|
308
|
+
raise "Unable to create send definition due to: #{result.results[0][:status_message]}"
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def SendEmailToDataExtension(emailID, sendableDataExtensionCustomerKey, sendClassificationCustomerKey)
|
313
|
+
email = ET_Email::SendDefinition.new
|
314
|
+
email.properties = {"Name"=>SecureRandom.uuid, "CustomerKey"=>SecureRandom.uuid, "Description"=>"Created with RubySDK"}
|
315
|
+
email.properties["SendClassification"] = {"CustomerKey"=> sendClassificationCustomerKey}
|
316
|
+
email.properties["SendDefinitionList"] = {"CustomerKey"=> sendableDataExtensionCustomerKey, "DataSourceTypeID"=>"CustomObject"}
|
317
|
+
email.properties["Email"] = {"ID"=>emailID}
|
318
|
+
email.authStub = self
|
319
|
+
result = email.post
|
320
|
+
if result.status then
|
321
|
+
sendresult = email.send
|
322
|
+
if sendresult.status then
|
323
|
+
deleteresult = email.delete
|
324
|
+
return sendresult
|
325
|
+
else
|
326
|
+
raise "Unable to send using send definition due to: #{result.results[0][:status_message]}"
|
327
|
+
end
|
328
|
+
else
|
329
|
+
raise "Unable to create send definition due to: #{result.results[0][:status_message]}"
|
330
|
+
end
|
331
|
+
end
|
332
|
+
def CreateAndStartListImport(listId,fileName)
|
333
|
+
import = ET_Import.new
|
334
|
+
import.authStub = self
|
335
|
+
import.properties = {"Name"=> "SDK Generated Import #{DateTime.now.to_s}"}
|
336
|
+
import.properties["CustomerKey"] = SecureRandom.uuid
|
337
|
+
import.properties["Description"] = "SDK Generated Import"
|
338
|
+
import.properties["AllowErrors"] = "true"
|
339
|
+
import.properties["DestinationObject"] = {"ID"=>listId}
|
340
|
+
import.properties["FieldMappingType"] = "InferFromColumnHeadings"
|
341
|
+
import.properties["FileSpec"] = fileName
|
342
|
+
import.properties["FileType"] = "CSV"
|
343
|
+
import.properties["RetrieveFileTransferLocation"] = {"CustomerKey"=>"ExactTarget Enhanced FTP"}
|
344
|
+
import.properties["UpdateType"] = "AddAndUpdate"
|
345
|
+
result = import.post
|
346
|
+
|
347
|
+
if result.status then
|
348
|
+
return import.start
|
349
|
+
else
|
350
|
+
raise "Unable to create import definition due to: #{result.results[0][:status_message]}"
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def CreateAndStartDataExtensionImport(dataExtensionCustomerKey, fileName, overwrite)
|
355
|
+
import = ET_Import.new
|
356
|
+
import.authStub = self
|
357
|
+
import.properties = {"Name"=> "SDK Generated Import #{DateTime.now.to_s}"}
|
358
|
+
import.properties["CustomerKey"] = SecureRandom.uuid
|
359
|
+
import.properties["Description"] = "SDK Generated Import"
|
360
|
+
import.properties["AllowErrors"] = "true"
|
361
|
+
import.properties["DestinationObject"] = {"CustomerKey"=>dataExtensionCustomerKey}
|
362
|
+
import.properties["FieldMappingType"] = "InferFromColumnHeadings"
|
363
|
+
import.properties["FileSpec"] = fileName
|
364
|
+
import.properties["FileType"] = "CSV"
|
365
|
+
import.properties["RetrieveFileTransferLocation"] = {"CustomerKey"=>"ExactTarget Enhanced FTP"}
|
366
|
+
if overwrite then
|
367
|
+
import.properties["UpdateType"] = "Overwrite"
|
368
|
+
else
|
369
|
+
import.properties["UpdateType"] = "AddAndUpdate"
|
370
|
+
end
|
371
|
+
result = import.post
|
372
|
+
|
373
|
+
if result.status then
|
374
|
+
return import.start
|
375
|
+
else
|
376
|
+
raise "Unable to create import definition due to: #{result.results[0][:status_message]}"
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def CreateProfileAttributes(allAttributes)
|
381
|
+
attrs = ET_ProfileAttribute.new
|
382
|
+
attrs.authStub = self
|
383
|
+
attrs.properties = allAttributes
|
384
|
+
return attrs.post
|
385
|
+
end
|
386
|
+
|
387
|
+
def CreateContentAreas(arrayOfContentAreas)
|
388
|
+
postC = ET_ContentArea.new
|
389
|
+
postC.authStub = self
|
390
|
+
postC.properties = arrayOfContentAreas
|
391
|
+
sendResponse = postC.post
|
392
|
+
return sendResponse
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|