exact-target-api 0.0.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 +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +41 -0
- data/LICENSE.txt +22 -0
- data/README.md +62 -0
- data/Rakefile +1 -0
- data/exact-target-api.gemspec +22 -0
- data/lib/exact-target-api.rb +43 -0
- data/lib/exact-target-api/base_object.rb +28 -0
- data/lib/exact-target-api/bounce_event.rb +8 -0
- data/lib/exact-target-api/campaign.rb +19 -0
- data/lib/exact-target-api/click_event.rb +8 -0
- data/lib/exact-target-api/client.rb +175 -0
- data/lib/exact-target-api/constructor.rb +34 -0
- data/lib/exact-target-api/content_area.rb +8 -0
- data/lib/exact-target-api/continue.rb +33 -0
- data/lib/exact-target-api/continue_rest.rb +24 -0
- data/lib/exact-target-api/create_wsdl.rb +53 -0
- data/lib/exact-target-api/cud_support.rb +19 -0
- data/lib/exact-target-api/cud_support_rest.rb +72 -0
- data/lib/exact-target-api/data_extension.rb +226 -0
- data/lib/exact-target-api/delete.rb +38 -0
- data/lib/exact-target-api/delete_rest.rb +18 -0
- data/lib/exact-target-api/describe.rb +25 -0
- data/lib/exact-target-api/email.rb +8 -0
- data/lib/exact-target-api/folder.rb +8 -0
- data/lib/exact-target-api/get.rb +64 -0
- data/lib/exact-target-api/get_rest.rb +25 -0
- data/lib/exact-target-api/get_support.rb +23 -0
- data/lib/exact-target-api/get_support_rest.rb +86 -0
- data/lib/exact-target-api/list.rb +68 -0
- data/lib/exact-target-api/list_subscriber.rb +10 -0
- data/lib/exact-target-api/open_event.rb +8 -0
- data/lib/exact-target-api/patch.rb +39 -0
- data/lib/exact-target-api/patch_rest.rb +19 -0
- data/lib/exact-target-api/post.rb +34 -0
- data/lib/exact-target-api/post_rest.rb +19 -0
- data/lib/exact-target-api/sent_event.rb +8 -0
- data/lib/exact-target-api/subscriber.rb +81 -0
- data/lib/exact-target-api/triggered_send.rb +15 -0
- data/lib/exact-target-api/unsub_event.rb +8 -0
- data/lib/exact-target-api/version.rb +3 -0
- metadata +113 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module ET
|
2
|
+
class Constructor
|
3
|
+
attr_accessor :status, :code, :message, :results, :request_id, :moreResults
|
4
|
+
|
5
|
+
def initialize(response = nil, rest = false)
|
6
|
+
@results = []
|
7
|
+
if !response.nil? && !rest
|
8
|
+
envelope = response.hash[:envelope]
|
9
|
+
@body = envelope[:body]
|
10
|
+
|
11
|
+
if !response.soap_fault? || !response.http_error?
|
12
|
+
@code = response.http.code
|
13
|
+
@status = true
|
14
|
+
elsif response.soap_fault?
|
15
|
+
@code = response.http.code
|
16
|
+
@message = @body[:fault][:faultstring]
|
17
|
+
@status = false
|
18
|
+
elsif response.http_error?
|
19
|
+
@code = response.http.code
|
20
|
+
@status = false
|
21
|
+
end
|
22
|
+
elsif (@code = response.code)
|
23
|
+
|
24
|
+
@status = @code == "200"
|
25
|
+
|
26
|
+
begin
|
27
|
+
@results = JSON.parse(response.body)
|
28
|
+
rescue
|
29
|
+
@message = response.body
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ET
|
2
|
+
class Continue < ET::Constructor
|
3
|
+
def initialize(authStub, request_id)
|
4
|
+
@results = []
|
5
|
+
authStub.refreshToken
|
6
|
+
obj = {'ContinueRequest' => request_id}
|
7
|
+
response = authStub.auth.call(:retrieve, :message => {'RetrieveRequest' => obj})
|
8
|
+
|
9
|
+
super(response)
|
10
|
+
|
11
|
+
if @status then
|
12
|
+
if @body[:retrieve_response_msg][:overall_status] != "OK" && @body[:retrieve_response_msg][:overall_status] != "MoreDataAvailable" then
|
13
|
+
@status = false
|
14
|
+
@message = @body[:retrieve_response_msg][:overall_status]
|
15
|
+
end
|
16
|
+
|
17
|
+
@moreResults = false
|
18
|
+
if @body[:retrieve_response_msg][:overall_status] == "MoreDataAvailable" then
|
19
|
+
@moreResults = true
|
20
|
+
end
|
21
|
+
|
22
|
+
if (!@body[:retrieve_response_msg][:results].is_a? Hash) && (!@body[:retrieve_response_msg][:results].nil?) then
|
23
|
+
@results = @results + @body[:retrieve_response_msg][:results]
|
24
|
+
elsif (!@body[:retrieve_response_msg][:results].nil?)
|
25
|
+
@results.push(@body[:retrieve_response_msg][:results])
|
26
|
+
end
|
27
|
+
|
28
|
+
# Store the Last Request ID for use with continue
|
29
|
+
@request_id = @body[:retrieve_response_msg][:request_id]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ET
|
2
|
+
class ContinueRest < ET::Constructor
|
3
|
+
def initialize(authStub, endpoint, qs = nil)
|
4
|
+
authStub.refreshToken
|
5
|
+
|
6
|
+
if qs
|
7
|
+
qs['access_token'] = authStub.authToken
|
8
|
+
else
|
9
|
+
qs = {"access_token" => authStub.authToken}
|
10
|
+
end
|
11
|
+
|
12
|
+
uri = URI.parse(endpoint)
|
13
|
+
uri.query = URI.encode_www_form(qs)
|
14
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
15
|
+
http.use_ssl = true
|
16
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
17
|
+
requestResponse = http.request(request)
|
18
|
+
|
19
|
+
@moreResults = false
|
20
|
+
|
21
|
+
super(requestResponse, true)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ET
|
2
|
+
class CreateWSDL
|
3
|
+
def initialize(path)
|
4
|
+
# Get the header info for the correct wsdl
|
5
|
+
response = HTTPI.head(@wsdl)
|
6
|
+
if response && response.code >= 200 && response.code <= 400
|
7
|
+
header = response.headers
|
8
|
+
# Check when the WSDL was last modified
|
9
|
+
modifiedTime = Date.parse(header['last-modified'])
|
10
|
+
p = wsdl_file(path)
|
11
|
+
# Check if a local file already exists
|
12
|
+
if File.file?(p) && File.readable?(p) && !File.zero?(p)
|
13
|
+
createdTime = File.new(p).mtime.to_date
|
14
|
+
|
15
|
+
# Check if the locally created WSDL older than the production WSDL
|
16
|
+
createIt = createdTime < modifiedTime
|
17
|
+
else
|
18
|
+
createIt = true
|
19
|
+
end
|
20
|
+
|
21
|
+
if createIt
|
22
|
+
res = open(@wsdl).read
|
23
|
+
File.open(p, 'w+') do |f|
|
24
|
+
f.write(res)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@status = response.code
|
29
|
+
else
|
30
|
+
@status = response.code
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def wsdl_file(path)
|
36
|
+
path + '/ExactTargetWSDL.xml'
|
37
|
+
end
|
38
|
+
|
39
|
+
def stringify_keys!(params)
|
40
|
+
params.keys.each do |key|
|
41
|
+
params[key.to_s] = params.delete(key)
|
42
|
+
end
|
43
|
+
params
|
44
|
+
end
|
45
|
+
|
46
|
+
def symbolize_keys!(params)
|
47
|
+
params.keys.each do |key|
|
48
|
+
params[key.to_sym] = params.delete(key)
|
49
|
+
end
|
50
|
+
params
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ET
|
2
|
+
class CUDSupport < ET::GetSupport
|
3
|
+
def initialize
|
4
|
+
super
|
5
|
+
end
|
6
|
+
|
7
|
+
def post(data)
|
8
|
+
ET::Post.new(@client, @obj, data)
|
9
|
+
end
|
10
|
+
|
11
|
+
def patch(data)
|
12
|
+
ET::Patch.new(@client, @obj, data)
|
13
|
+
end
|
14
|
+
|
15
|
+
def delete(data)
|
16
|
+
ET::Delete.new(@client, @obj, data)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module ET
|
2
|
+
class CUDSupportRest < ET::GetSupportRest
|
3
|
+
def initialize
|
4
|
+
super
|
5
|
+
end
|
6
|
+
|
7
|
+
def post
|
8
|
+
completeURL = @endpoint
|
9
|
+
|
10
|
+
if @props and @props.is_a? Hash then
|
11
|
+
@props.each do |k,v|
|
12
|
+
if @urlProps.include?(k) then
|
13
|
+
completeURL.sub!("{#{k}}", v)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@urlPropsRequired.each do |value|
|
19
|
+
if !@props || !@props.has_key?(value) then
|
20
|
+
raise "Unable to process request due to missing required prop: #{value}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Clean Optional Parameters from Endpoint URL first
|
25
|
+
@urlProps.each do |value|
|
26
|
+
completeURL.sub!("/{#{value}}", "")
|
27
|
+
end
|
28
|
+
|
29
|
+
ET::PostRest.new(@authStub, completeURL, @props)
|
30
|
+
end
|
31
|
+
|
32
|
+
def patch
|
33
|
+
completeURL = @endpoint
|
34
|
+
# All URL Props are required when doing Patch
|
35
|
+
@urlProps.each do |value|
|
36
|
+
if !@props || !@props.has_key?(value) then
|
37
|
+
raise "Unable to process request due to missing required prop: #{value}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
if @props and @props.is_a? Hash then
|
42
|
+
@props.each do |k,v|
|
43
|
+
if @urlProps.include?(k) then
|
44
|
+
completeURL.sub!("{#{k}}", v)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
ET::PatchRest.new(@authStub, completeURL, @props)
|
50
|
+
end
|
51
|
+
|
52
|
+
def delete
|
53
|
+
completeURL = @endpoint
|
54
|
+
# All URL Props are required when doing Patch
|
55
|
+
@urlProps.each do |value|
|
56
|
+
if !@props || !@props.has_key?(value) then
|
57
|
+
raise "Unable to process request due to missing required prop: #{value}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if @props and @props.is_a? Hash then
|
62
|
+
@props.each do |k,v|
|
63
|
+
if @urlProps.include?(k) then
|
64
|
+
completeURL.sub!("{#{k}}", v)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
ET::DeleteRest.new(@authStub, completeURL)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
module ET
|
2
|
+
class DataExtension < ET::CUDSupport
|
3
|
+
attr_accessor :columns
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@obj = 'DataExtension'
|
8
|
+
end
|
9
|
+
|
10
|
+
def post
|
11
|
+
originalProps = @props
|
12
|
+
|
13
|
+
if @props.is_a? Array
|
14
|
+
multiDE = []
|
15
|
+
@props.each { |currentDE|
|
16
|
+
currentDE['Fields'] = {}
|
17
|
+
currentDE['Fields']['Field'] = []
|
18
|
+
currentDE['columns'].each { |key|
|
19
|
+
currentDE['Fields']['Field'].push(key)
|
20
|
+
}
|
21
|
+
currentDE.delete('columns')
|
22
|
+
multiDE.push(currentDE.dup)
|
23
|
+
}
|
24
|
+
|
25
|
+
@props = multiDE
|
26
|
+
else
|
27
|
+
@props['Fields'] = {'Field' => []}
|
28
|
+
|
29
|
+
@columns.each do |key|
|
30
|
+
@props['Fields']['Field'].push(key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
obj = super
|
35
|
+
@props = originalProps
|
36
|
+
obj
|
37
|
+
end
|
38
|
+
|
39
|
+
def patch
|
40
|
+
@props['Fields'] = {}
|
41
|
+
@props['Fields']['Field'] = []
|
42
|
+
@columns.each { |key|
|
43
|
+
@props['Fields']['Field'].push(key)
|
44
|
+
}
|
45
|
+
obj = super
|
46
|
+
@props.delete("Fields")
|
47
|
+
obj
|
48
|
+
end
|
49
|
+
|
50
|
+
class Column < ET::GetSupport
|
51
|
+
def initialize
|
52
|
+
super
|
53
|
+
@obj = 'DataExtensionField'
|
54
|
+
end
|
55
|
+
|
56
|
+
def get
|
57
|
+
|
58
|
+
if props and props.is_a? Array then
|
59
|
+
@props = props
|
60
|
+
end
|
61
|
+
|
62
|
+
if @props and @props.is_a? Hash then
|
63
|
+
@props = @props.keys
|
64
|
+
end
|
65
|
+
|
66
|
+
if filter and filter.is_a? Hash then
|
67
|
+
@filter = filter
|
68
|
+
end
|
69
|
+
|
70
|
+
fixCustomerKey = false
|
71
|
+
if filter and filter.is_a? Hash
|
72
|
+
@filter = filter
|
73
|
+
if @filter.has_key?("Property") && @filter["Property"] == "CustomerKey"
|
74
|
+
@filter["Property"] = "DataExtension.CustomerKey"
|
75
|
+
fixCustomerKey = true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
obj = ET::Get.new(@authStub, @obj, @props, @filter)
|
80
|
+
@lastRequestID = obj.request_id
|
81
|
+
|
82
|
+
if fixCustomerKey then
|
83
|
+
@filter["Property"] = "CustomerKey"
|
84
|
+
end
|
85
|
+
|
86
|
+
obj
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Row < ET::CUDSupport
|
91
|
+
attr_accessor :Name, :CustomerKey
|
92
|
+
|
93
|
+
def initialize
|
94
|
+
super
|
95
|
+
@obj = "DataExtensionObject"
|
96
|
+
end
|
97
|
+
|
98
|
+
def get
|
99
|
+
getName
|
100
|
+
if props and props.is_a? Array then
|
101
|
+
@props = props
|
102
|
+
end
|
103
|
+
|
104
|
+
if @props and @props.is_a? Hash then
|
105
|
+
@props = @props.keys
|
106
|
+
end
|
107
|
+
|
108
|
+
if filter and filter.is_a? Hash then
|
109
|
+
@filter = filter
|
110
|
+
end
|
111
|
+
|
112
|
+
obj = ET::Get.new(@authStub, "DataExtensionObject[#{@Name}]", @props, @filter)
|
113
|
+
@lastRequestID = obj.request_id
|
114
|
+
|
115
|
+
obj
|
116
|
+
end
|
117
|
+
|
118
|
+
def post
|
119
|
+
getCustomerKey
|
120
|
+
originalProps = @props
|
121
|
+
currentProp = {}
|
122
|
+
## FIX THIS
|
123
|
+
if @props.is_a? Array then
|
124
|
+
=begin
|
125
|
+
multiRow = []
|
126
|
+
@props.each { |currentDE|
|
127
|
+
|
128
|
+
currentDE['columns'].each { |key|
|
129
|
+
currentDE['Fields'] = {}
|
130
|
+
currentDE['Fields']['Field'] = []
|
131
|
+
currentDE['Fields']['Field'].push(key)
|
132
|
+
}
|
133
|
+
currentDE.delete('columns')
|
134
|
+
multiRow.push(currentDE.dup)
|
135
|
+
}
|
136
|
+
|
137
|
+
@props = multiRow
|
138
|
+
=end
|
139
|
+
else
|
140
|
+
currentFields = []
|
141
|
+
|
142
|
+
@props.each { |key,value|
|
143
|
+
currentFields.push({"Name" => key, "Value" => value})
|
144
|
+
}
|
145
|
+
currentProp['CustomerKey'] = @CustomerKey
|
146
|
+
currentProp['Properties'] = {}
|
147
|
+
currentProp['Properties']['Property'] = currentFields
|
148
|
+
end
|
149
|
+
|
150
|
+
obj = ET::Post.new(@authStub, @obj, currentProp)
|
151
|
+
@props = originalProps
|
152
|
+
obj
|
153
|
+
end
|
154
|
+
|
155
|
+
def patch
|
156
|
+
getCustomerKey
|
157
|
+
currentFields = []
|
158
|
+
currentProp = {}
|
159
|
+
|
160
|
+
@props.each { |key,value|
|
161
|
+
currentFields.push({"Name" => key, "Value" => value})
|
162
|
+
}
|
163
|
+
currentProp['CustomerKey'] = @CustomerKey
|
164
|
+
currentProp['Properties'] = {}
|
165
|
+
currentProp['Properties']['Property'] = currentFields
|
166
|
+
|
167
|
+
ET::Patch.new(@authStub, @obj, currentProp)
|
168
|
+
end
|
169
|
+
|
170
|
+
def delete
|
171
|
+
getCustomerKey
|
172
|
+
currentFields = []
|
173
|
+
currentProp = {}
|
174
|
+
|
175
|
+
@props.each { |key,value|
|
176
|
+
currentFields.push({"Name" => key, "Value" => value})
|
177
|
+
}
|
178
|
+
currentProp['CustomerKey'] = @CustomerKey
|
179
|
+
currentProp['Keys'] = {}
|
180
|
+
currentProp['Keys']['Key'] = currentFields
|
181
|
+
|
182
|
+
ET::Delete.new(@authStub, @obj, currentProp)
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def getCustomerKey
|
188
|
+
if @CustomerKey.nil?
|
189
|
+
if @CustomerKey.nil? && @Name.nil?
|
190
|
+
raise 'Unable to process DataExtension::Row request due to CustomerKey and Name not being defined on ET::DatExtension::row'
|
191
|
+
else
|
192
|
+
de = ET::DataExtension.new
|
193
|
+
de.authStub = @authStub
|
194
|
+
de.props = ["Name","CustomerKey"]
|
195
|
+
de.filter = {'Property' => 'CustomerKey','SimpleOperator' => 'equals','Value' => @Name}
|
196
|
+
getResponse = de.get
|
197
|
+
if getResponse.status && (getResponse.results.length == 1) then
|
198
|
+
@CustomerKey = getResponse.results[0][:customer_key]
|
199
|
+
else
|
200
|
+
raise 'Unable to process DataExtension::Row request due to unable to find DataExtension based on Name'
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def getName
|
207
|
+
if @Name.nil?
|
208
|
+
if @CustomerKey.nil? && @Name.nil?
|
209
|
+
raise 'Unable to process DataExtension::Row request due to CustomerKey and Name not being defined on ET::DatExtension::row'
|
210
|
+
else
|
211
|
+
de = ET::DataExtension.new
|
212
|
+
de.authStub = @authStub
|
213
|
+
de.props = ["Name","CustomerKey"]
|
214
|
+
de.filter = {'Property' => 'CustomerKey','SimpleOperator' => 'equals','Value' => @CustomerKey}
|
215
|
+
getResponse = de.get
|
216
|
+
if getResponse.status && getResponse.results.length == 1
|
217
|
+
@Name = getResponse.results[0][:name]
|
218
|
+
else
|
219
|
+
raise 'Unable to process DataExtension::Row request due to unable to find DataExtension based on CustomerKey'
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|