fuelsdk 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +35 -37
- data/lib/fuelsdk.rb +16 -0
- data/lib/fuelsdk/client.rb +2 -3
- data/lib/fuelsdk/http_request.rb +1 -1
- data/lib/fuelsdk/objects.rb +89 -77
- data/lib/fuelsdk/soap.rb +79 -33
- data/lib/fuelsdk/version.rb +1 -1
- data/samples/sample-bounceevent.rb +3 -3
- data/samples/sample-campaign.rb +14 -14
- data/samples/sample-clickevent.rb +3 -3
- data/samples/sample-contentarea.rb +8 -8
- data/samples/sample-email.rb +8 -8
- data/samples/sample-folder.rb +9 -9
- data/samples/sample-list.rb +7 -7
- data/samples/sample-list.subscriber.rb +6 -6
- data/samples/sample-openevent.rb +3 -3
- data/samples/sample-sentevent.rb +3 -3
- data/samples/sample-subscriber.rb +8 -8
- data/samples/sample-triggeredsend.rb +9 -9
- data/samples/sample-unsubevent.rb +3 -3
- data/spec/{fuelsdk_spec.rb → client_spec.rb} +16 -16
- data/spec/objects_helper_spec.rb +25 -0
- data/spec/objects_spec.rb +111 -0
- data/spec/rest_spec.rb +2 -2
- data/spec/soap_spec.rb +92 -1
- metadata +8 -6
- data/spec/fuelsdk/client_spec.rb +0 -21
data/README.md
CHANGED
@@ -18,22 +18,25 @@ gem 'fuelsdk'
|
|
18
18
|
|
19
19
|
If you have not registered your application or you need to lookup your Application Key or Application Signature values, please go to App Center at [Code@: ExactTarget's Developer Community](http://code.exacttarget.com/appcenter "Code@ App Center").
|
20
20
|
|
21
|
+
## Backwards Compatibility ##
|
22
|
+
Previous versions of the Fuel SDK exposed objects with the prefix "ET_". For backwards compatibility you can still access objects this way.
|
23
|
+
Subscriber can be accessed FuelSDK::Subscriber or ET_Subscriber.
|
24
|
+
|
21
25
|
## Example Request ##
|
22
|
-
All ExactTarget objects exposed through the Fuel SDK begin with be prefixed with "ET\_". Start by working with the ET_List object:
|
23
26
|
|
24
27
|
Add a require statement to reference the Fuel SDK's functionality:
|
25
28
|
> require 'fuelsdk'
|
26
29
|
|
27
|
-
Next, create an instance of the
|
28
|
-
> myClient = FuelSDK::
|
30
|
+
Next, create an instance of the Client class:
|
31
|
+
> myClient = FuelSDK::Client.new {'client' => { 'id' => CLIENTID, 'secret' => SECRET }}
|
29
32
|
|
30
33
|
Create an instance of the object type we want to work with:
|
31
|
-
> list = FuelSDK::
|
34
|
+
> list = FuelSDK::List.new
|
32
35
|
|
33
|
-
Associate the
|
34
|
-
> list.
|
36
|
+
Associate the Client to the object using the client property:
|
37
|
+
> list.client = myClient
|
35
38
|
|
36
|
-
Utilize one of the
|
39
|
+
Utilize one of the List methods:
|
37
40
|
> response = list.get
|
38
41
|
|
39
42
|
Print out the results for viewing
|
@@ -42,36 +45,34 @@ Print out the results for viewing
|
|
42
45
|
**Example Output:**
|
43
46
|
|
44
47
|
<pre>
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
@request_id="41f0f293-954f-4ac7-8e7a-0a5756022218"
|
69
|
-
>
|
48
|
+
<FuelSDK::SoapResponse:0x007fb86abcf190
|
49
|
+
@body= {:retrieve_response_msg=> {:overall_status=>"OK", :request_id=>"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", :results=>..}
|
50
|
+
@code= 200,
|
51
|
+
@message= 'OK',
|
52
|
+
@request_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
|
53
|
+
@results=
|
54
|
+
[{:client=>{:id=>"xxxx"},
|
55
|
+
:partner_key=>nil,
|
56
|
+
:created_date=>
|
57
|
+
#<DateTime: 2013-05-30T23:02:00+00:00 ((2456443j,82920s,0n),+0s,2299161j)>,
|
58
|
+
:id=>"xxxx",
|
59
|
+
:object_id=>nil,
|
60
|
+
:email_address=>"xxxx",
|
61
|
+
:attributes=>
|
62
|
+
[{:name=>"Full Name", :value=>"Justin Barber"},
|
63
|
+
{:name=>"Gender", :value=>nil},
|
64
|
+
{:name=>"Email Address", :value=>"xxx"},
|
65
|
+
{:name=>"User Defined", :value=>"02/02/1982"}],
|
66
|
+
:subscriber_key=>"xxxx",
|
67
|
+
:status=>"Active",
|
68
|
+
:email_type_preference=>"HTML",
|
69
|
+
:"@xsi:type"=>"Subscriber"},
|
70
|
+
@success=true>
|
70
71
|
</pre>
|
71
72
|
|
72
|
-
##
|
73
|
+
## Client Class ##
|
73
74
|
|
74
|
-
The
|
75
|
+
The Client class takes care of many of the required steps when accessing ExactTarget's API, including retrieving appropriate access tokens, handling token state for managing refresh, and determining the appropriate endpoints for API requests. In order to leverage the advantages this class provides, use a single instance of this class for an entire session. Do not instantiate a new Client object for each request made.
|
75
76
|
|
76
77
|
## Responses ##
|
77
78
|
All methods on Fuel SDK objects return a generic object that follows the same structure, regardless of the type of call. This object contains a common set of properties used to display details about the request.
|
@@ -80,9 +81,6 @@ All methods on Fuel SDK objects return a generic object that follows the same st
|
|
80
81
|
- code: HTTP Error Code (will always be 200 for SOAP requests)
|
81
82
|
- message: Text values containing more details in the event of an error
|
82
83
|
- results: Collection containing the details unique to the method called.
|
83
|
-
|
84
|
-
Get Methods also return an addition value to indicate if more information is available (that information can be retrieved using the getMoreResults method):
|
85
|
-
|
86
84
|
- more? - Boolean value that indicates on Get requests if more data is available.
|
87
85
|
|
88
86
|
|
data/lib/fuelsdk.rb
CHANGED
@@ -13,6 +13,22 @@ module FuelSDK
|
|
13
13
|
require 'fuelsdk/objects'
|
14
14
|
end
|
15
15
|
|
16
|
+
# backwards compatability
|
17
|
+
ET_Client = FuelSDK::Client
|
18
|
+
ET_BounceEvent = FuelSDK::BounceEvent
|
19
|
+
ET_ClickEvent = FuelSDK::ClickEvent
|
20
|
+
ET_ContentArea = FuelSDK::ContentArea
|
21
|
+
ET_DataFolder = FuelSDK::DataFolder
|
22
|
+
ET_Folder = FuelSDK::Folder
|
23
|
+
ET_Email = FuelSDK::Email
|
24
|
+
ET_List = FuelSDK::List
|
25
|
+
ET_OpenEvent = FuelSDK::OpenEvent
|
26
|
+
ET_SentEvent = FuelSDK::SentEvent
|
27
|
+
ET_Subscriber = FuelSDK::Subscriber
|
28
|
+
ET_UnsubEvent = FuelSDK::UnsubEvent
|
29
|
+
ET_TriggeredSend = FuelSDK::TriggeredSend
|
30
|
+
ET_Campaign = FuelSDK::Campaign
|
31
|
+
|
16
32
|
=begin
|
17
33
|
class ET_DataExtension < ET_CUDSupport
|
18
34
|
attr_accessor :columns
|
data/lib/fuelsdk/client.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module FuelSDK
|
2
|
-
class
|
2
|
+
class Response
|
3
3
|
# not doing accessor so user, can't update these values from response.
|
4
4
|
# You will see in the code some of these
|
5
5
|
# items are being updated via back doors and such.
|
@@ -21,7 +21,6 @@ module FuelSDK
|
|
21
21
|
@client = client # keep connection with client in case we request more
|
22
22
|
@results = []
|
23
23
|
@raw = raw
|
24
|
-
@body = raw.body
|
25
24
|
unpack raw
|
26
25
|
rescue => ex # all else fails return raw
|
27
26
|
puts ex.message
|
@@ -38,7 +37,7 @@ module FuelSDK
|
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
41
|
-
class
|
40
|
+
class Client
|
42
41
|
attr_accessor :debug, :access_token, :auth_token, :internal_token, :refresh_token,
|
43
42
|
:id, :secret, :signature
|
44
43
|
|
data/lib/fuelsdk/http_request.rb
CHANGED
data/lib/fuelsdk/objects.rb
CHANGED
@@ -1,119 +1,132 @@
|
|
1
1
|
module FuelSDK
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Objects
|
3
|
+
module SoapRead
|
4
|
+
def get
|
5
|
+
client.soap_get id, properties, filter
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
def info
|
9
|
+
client.soap_describe id
|
10
|
+
end
|
9
11
|
end
|
10
|
-
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
module SoapCUD #create, update, delete
|
14
|
+
def post
|
15
|
+
client.soap_post id, properties
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def patch
|
19
|
+
client.soap_patch id, properties
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
def delete
|
23
|
+
client.soap_delete id, properties
|
24
|
+
end
|
23
25
|
end
|
24
|
-
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
module RestRead
|
28
|
+
def get
|
29
|
+
client.rest_get id, properties
|
30
|
+
end
|
29
31
|
end
|
30
|
-
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
module RestCUD
|
34
|
+
def post
|
35
|
+
client.rest_post id, properties
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
def patch
|
39
|
+
client.rest_patch id, properties
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
def delete
|
43
|
+
client.rest_delete id, properties
|
44
|
+
end
|
43
45
|
end
|
44
|
-
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
class Base
|
48
|
+
attr_accessor :filter, :properties, :client
|
49
|
+
attr_reader :id
|
49
50
|
|
50
|
-
|
51
|
-
|
51
|
+
alias props= properties= # backward compatibility
|
52
|
+
alias authStub= client= # backward compatibility
|
52
53
|
|
53
|
-
|
54
|
-
|
54
|
+
def id
|
55
|
+
self.class.id
|
56
|
+
end
|
57
|
+
|
58
|
+
class << self
|
59
|
+
def id
|
60
|
+
self.name.split('::').pop
|
61
|
+
end
|
62
|
+
end
|
55
63
|
end
|
56
64
|
end
|
57
65
|
|
58
|
-
class
|
59
|
-
include
|
66
|
+
class BounceEvent < Objects::Base
|
67
|
+
include Objects::SoapRead
|
60
68
|
end
|
61
69
|
|
62
|
-
class
|
63
|
-
include
|
70
|
+
class ClickEvent < Objects::Base
|
71
|
+
include Objects::SoapRead
|
64
72
|
end
|
65
73
|
|
66
|
-
class
|
67
|
-
include
|
68
|
-
include
|
74
|
+
class ContentArea < Objects::Base
|
75
|
+
include Objects::SoapRead
|
76
|
+
include Objects::SoapCUD
|
69
77
|
end
|
70
78
|
|
71
|
-
class
|
72
|
-
include
|
73
|
-
include
|
74
|
-
|
75
|
-
|
79
|
+
class DataFolder < Objects::Base
|
80
|
+
include Objects::SoapRead
|
81
|
+
include Objects::SoapCUD
|
82
|
+
end
|
83
|
+
|
84
|
+
class Folder < DataFolder
|
85
|
+
class << self
|
86
|
+
def id
|
87
|
+
DataFolder.id
|
88
|
+
end
|
76
89
|
end
|
77
90
|
end
|
78
91
|
|
79
|
-
class
|
80
|
-
include
|
81
|
-
include
|
92
|
+
class Email < Objects::Base
|
93
|
+
include Objects::SoapRead
|
94
|
+
include Objects::SoapCUD
|
82
95
|
end
|
83
96
|
|
84
|
-
class
|
85
|
-
include
|
86
|
-
include
|
97
|
+
class List < Objects::Base
|
98
|
+
include Objects::SoapRead
|
99
|
+
include Objects::SoapCUD
|
87
100
|
|
88
|
-
class Subscriber <
|
89
|
-
include
|
101
|
+
class Subscriber < Objects::Base
|
102
|
+
include Objects::SoapRead
|
90
103
|
def id
|
91
104
|
'ListSubscriber'
|
92
105
|
end
|
93
106
|
end
|
94
107
|
end
|
95
108
|
|
96
|
-
class
|
97
|
-
include
|
109
|
+
class OpenEvent < Objects::Base
|
110
|
+
include Objects::SoapRead
|
98
111
|
end
|
99
112
|
|
100
|
-
class
|
101
|
-
include
|
113
|
+
class SentEvent < Objects::Base
|
114
|
+
include Objects::SoapRead
|
102
115
|
end
|
103
116
|
|
104
|
-
class
|
105
|
-
include
|
106
|
-
include
|
117
|
+
class Subscriber < Objects::Base
|
118
|
+
include Objects::SoapRead
|
119
|
+
include Objects::SoapCUD
|
107
120
|
end
|
108
121
|
|
109
|
-
class
|
110
|
-
include
|
122
|
+
class UnsubEvent < Objects::Base
|
123
|
+
include Objects::SoapRead
|
111
124
|
end
|
112
125
|
|
113
|
-
class
|
126
|
+
class TriggeredSend < Objects::Base
|
114
127
|
attr_accessor :subscribers
|
115
|
-
include
|
116
|
-
include
|
128
|
+
include Objects::SoapRead
|
129
|
+
include Objects::SoapCUD
|
117
130
|
def id
|
118
131
|
'TriggeredSendDefinition'
|
119
132
|
end
|
@@ -122,10 +135,9 @@ module FuelSDK
|
|
122
135
|
end
|
123
136
|
end
|
124
137
|
|
125
|
-
class
|
126
|
-
include
|
127
|
-
include
|
128
|
-
|
138
|
+
class Campaign < Objects::Base
|
139
|
+
include Objects::RestRead
|
140
|
+
include Objects::RestCUD
|
129
141
|
|
130
142
|
def properties
|
131
143
|
@properties ||= {}
|
@@ -137,9 +149,9 @@ module FuelSDK
|
|
137
149
|
"https://www.exacttargetapis.com/hub/v1/campaigns/%{id}"
|
138
150
|
end
|
139
151
|
|
140
|
-
class Asset <
|
141
|
-
include
|
142
|
-
include
|
152
|
+
class Asset < Objects::Base
|
153
|
+
include Objects::RestRead
|
154
|
+
include Objects::RestCUD
|
143
155
|
|
144
156
|
def properties
|
145
157
|
@properties ||= {}
|
data/lib/fuelsdk/soap.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'savon'
|
2
2
|
module FuelSDK
|
3
3
|
|
4
|
-
class SoapResponse < FuelSDK::
|
4
|
+
class SoapResponse < FuelSDK::Response
|
5
5
|
|
6
6
|
def continue
|
7
7
|
rsp = nil
|
@@ -15,43 +15,61 @@ module FuelSDK
|
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
|
-
def
|
19
|
-
@
|
18
|
+
def unpack_body raw
|
19
|
+
@body = raw.body
|
20
20
|
@request_id = raw.body[raw.body.keys.first][:request_id]
|
21
|
+
unpack_msg raw
|
22
|
+
rescue
|
23
|
+
@message = raw.http.body
|
24
|
+
@body = raw.http.body unless @body
|
25
|
+
end
|
21
26
|
|
22
|
-
|
27
|
+
def unpack raw
|
28
|
+
@code = raw.http.code
|
29
|
+
unpack_body raw
|
23
30
|
@success = @message == 'OK'
|
24
|
-
|
25
|
-
|
26
|
-
@results += (parse_rslts raw)
|
31
|
+
@results += (unpack_rslts raw)
|
27
32
|
end
|
28
33
|
|
29
|
-
def
|
30
|
-
raw.soap_fault? ? raw.body[:fault][:faultstring] : raw.body[raw.body.keys.first][:overall_status]
|
34
|
+
def unpack_msg raw
|
35
|
+
@message = raw.soap_fault? ? raw.body[:fault][:faultstring] : raw.body[raw.body.keys.first][:overall_status]
|
31
36
|
end
|
32
37
|
|
33
|
-
def
|
38
|
+
def unpack_rslts raw
|
34
39
|
@more = (raw.body[raw.body.keys.first][:overall_status] == 'MoreDataAvailable')
|
35
40
|
rslts = raw.body[raw.body.keys.first][:results] || []
|
36
41
|
rslts = [rslts] unless rslts.kind_of? Array
|
37
42
|
rslts
|
43
|
+
rescue
|
44
|
+
[]
|
38
45
|
end
|
39
46
|
end
|
40
47
|
|
41
48
|
class DescribeResponse < SoapResponse
|
42
|
-
attr_reader :properties, :retrievable, :updatable, :required
|
49
|
+
attr_reader :properties, :retrievable, :updatable, :required, :extended, :viewable, :editable
|
43
50
|
private
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@
|
51
|
-
@
|
51
|
+
|
52
|
+
def unpack_rslts raw
|
53
|
+
@retrievable, @updatable, @required, @properties, @extended, @viewable, @editable = [], [], [], [], [], [], [], []
|
54
|
+
definition = raw.body[raw.body.keys.first][:object_definition]
|
55
|
+
_props = definition[:properties]
|
56
|
+
_props.each do |p|
|
57
|
+
@retrievable << p[:name] if p[:is_retrievable]
|
58
|
+
@updatable << p[:name] if p[:is_updatable]
|
59
|
+
@required << p[:name] if p[:is_required]
|
60
|
+
@properties << p[:name]
|
61
|
+
end
|
62
|
+
# ugly, but a necessary evil
|
63
|
+
_exts = definition[:extended_properties].nil? ? {} : definition[:extended_properties] # if they have no extended properties nil is returned
|
64
|
+
_exts = _exts[:extended_property] || [] # if no properties nil and we need an array to iterate
|
65
|
+
_exts = [_exts] unless _exts.kind_of? Array # if they have only one extended property we need to wrap it in array to iterate
|
66
|
+
_exts.each do |p|
|
67
|
+
@viewable << p[:name] if p[:is_viewable]
|
68
|
+
@editable << p[:name] if p[:is_editable]
|
69
|
+
@extended << p[:name]
|
52
70
|
end
|
53
71
|
@success = true # overall_status is missing from definition response, so need to set here manually
|
54
|
-
|
72
|
+
_props + _exts
|
55
73
|
rescue
|
56
74
|
@message = "Unable to describe #{raw.locals[:message]['DescribeRequests']['ObjectDefinitionRequest']['ObjectType']}"
|
57
75
|
@success = false
|
@@ -103,7 +121,7 @@ module FuelSDK
|
|
103
121
|
}
|
104
122
|
}
|
105
123
|
|
106
|
-
|
124
|
+
soap_request :describe, message
|
107
125
|
end
|
108
126
|
|
109
127
|
def soap_get object_type, properties=nil, filter=nil
|
@@ -136,7 +154,7 @@ module FuelSDK
|
|
136
154
|
end
|
137
155
|
message = {'RetrieveRequest' => message}
|
138
156
|
|
139
|
-
soap_request :retrieve,
|
157
|
+
soap_request :retrieve, message
|
140
158
|
end
|
141
159
|
|
142
160
|
def soap_post object_type, properties
|
@@ -151,28 +169,56 @@ module FuelSDK
|
|
151
169
|
soap_cud :delete, object_type, properties
|
152
170
|
end
|
153
171
|
|
172
|
+
def format_attributes attributes
|
173
|
+
attrs = []
|
174
|
+
attributes.each do |name, value|
|
175
|
+
attrs.push 'Name' => name, 'Value' => value
|
176
|
+
end
|
177
|
+
|
178
|
+
attrs
|
179
|
+
end
|
180
|
+
|
154
181
|
private
|
182
|
+
|
155
183
|
def soap_cud action, object_type, properties
|
184
|
+
# get a list of attributes so we can seperate
|
185
|
+
# them from standard object properties
|
186
|
+
type_attrs = soap_describe(object_type).editable
|
187
|
+
|
188
|
+
properties = [properties] unless properties.kind_of? Array
|
189
|
+
properties.each do |p|
|
190
|
+
formated_attrs = []
|
191
|
+
p.each do |k, v|
|
192
|
+
if type_attrs.include? k
|
193
|
+
p.delete k
|
194
|
+
attrs = format_attributes k => v
|
195
|
+
formated_attrs.concat attrs
|
196
|
+
end
|
197
|
+
end
|
198
|
+
(p['Attributes'] ||= []).concat formated_attrs unless formated_attrs.empty?
|
199
|
+
end
|
200
|
+
|
156
201
|
message = {
|
157
202
|
'Objects' => properties,
|
158
203
|
:attributes! => { 'Objects' => { 'xsi:type' => ('tns:' + object_type) } }
|
159
204
|
}
|
160
|
-
soap_request action,
|
205
|
+
soap_request action, message
|
161
206
|
end
|
162
207
|
|
163
208
|
def soap_request action, message
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
209
|
+
response = action.eql?(:describe) ? DescribeResponse : SoapResponse
|
210
|
+
retried = false
|
211
|
+
begin
|
212
|
+
rsp = soap_client.call(action, :message => message)
|
213
|
+
rescue
|
214
|
+
raise if retried
|
215
|
+
retried = true
|
216
|
+
retry
|
217
|
+
end
|
218
|
+
response.new rsp, self
|
173
219
|
rescue
|
174
220
|
raise if rsp.nil?
|
175
|
-
|
221
|
+
response.new rsp, self
|
176
222
|
end
|
177
223
|
end
|
178
224
|
end
|