marketingcloudsdk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +26 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +92 -0
  5. data/Guardfile +8 -0
  6. data/LICENSE.md +13 -0
  7. data/README.md +130 -0
  8. data/Rakefile +1 -0
  9. data/lib/marketingcloudsdk.rb +74 -0
  10. data/lib/marketingcloudsdk/client.rb +283 -0
  11. data/lib/marketingcloudsdk/http_request.rb +113 -0
  12. data/lib/marketingcloudsdk/objects.rb +757 -0
  13. data/lib/marketingcloudsdk/rest.rb +122 -0
  14. data/lib/marketingcloudsdk/soap.rb +288 -0
  15. data/lib/marketingcloudsdk/targeting.rb +58 -0
  16. data/lib/marketingcloudsdk/utils.rb +47 -0
  17. data/lib/marketingcloudsdk/version.rb +39 -0
  18. data/lib/new.rb +1240 -0
  19. data/marketingcloudsdk.gemspec +30 -0
  20. data/samples/sample-AddSubscriberToList.rb +56 -0
  21. data/samples/sample-CreateAndStartDataExtensionImport.rb +29 -0
  22. data/samples/sample-CreateAndStartListImport.rb +27 -0
  23. data/samples/sample-CreateContentAreas.rb +48 -0
  24. data/samples/sample-CreateDataExtensions.rb +54 -0
  25. data/samples/sample-CreateProfileAttributes.rb +48 -0
  26. data/samples/sample-SendEmailToDataExtension.rb +23 -0
  27. data/samples/sample-SendEmailToList.rb +23 -0
  28. data/samples/sample-SendTriggeredSends.rb +30 -0
  29. data/samples/sample-bounceevent.rb +70 -0
  30. data/samples/sample-campaign.rb +211 -0
  31. data/samples/sample-clickevent.rb +71 -0
  32. data/samples/sample-contentarea.rb +122 -0
  33. data/samples/sample-dataextension.rb +209 -0
  34. data/samples/sample-directverb.rb +55 -0
  35. data/samples/sample-email.rb +122 -0
  36. data/samples/sample-email.senddefinition.rb +134 -0
  37. data/samples/sample-folder.rb +143 -0
  38. data/samples/sample-import.rb +104 -0
  39. data/samples/sample-list.rb +105 -0
  40. data/samples/sample-list.subscriber.rb +97 -0
  41. data/samples/sample-openevent.rb +70 -0
  42. data/samples/sample-profileattribute.rb +57 -0
  43. data/samples/sample-sentevent.rb +70 -0
  44. data/samples/sample-subscriber.rb +136 -0
  45. data/samples/sample-triggeredsend.rb +130 -0
  46. data/samples/sample-unsubevent.rb +72 -0
  47. data/samples/sample_helper.rb.template +8 -0
  48. data/spec/client_spec.rb +210 -0
  49. data/spec/helper_funcs_spec.rb +11 -0
  50. data/spec/http_request_spec.rb +36 -0
  51. data/spec/objects_helper_spec.rb +32 -0
  52. data/spec/objects_spec.rb +484 -0
  53. data/spec/rest_spec.rb +48 -0
  54. data/spec/soap_spec.rb +140 -0
  55. data/spec/spec_helper.rb +14 -0
  56. data/spec/targeting_spec.rb +39 -0
  57. metadata +260 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fb92c32138d7f476a4d9647c1590ad77f8279b8b
4
+ data.tar.gz: f148540bd37ca303fde395d921878b313e09609f
5
+ SHA512:
6
+ metadata.gz: e1676dd588ea91583f7daa21e1db9cd976f89468322df12b6db03cb08186ed7286193f1cb44f4f51ec11b7fc387b793ba1fbb63421c12d483d26ae8ba353b938
7
+ data.tar.gz: b00a949f488613aed5792d03e53279095ec08ab859b7dfedd7cce558d897814f736825242c551f782e426f5286ef35f9cf232e55daf40082e8802f2ed0471d51
@@ -0,0 +1,26 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+ sample.rb
20
+ ExactTargetWSDL.xml
21
+ config.yaml
22
+ /objsamples/config.yaml
23
+ /objsamples/AllTest.bat
24
+ samples/sample_helper.rb
25
+ .DS_STORE
26
+ gengem.bat
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,92 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ marketingcloudsdk (1.0.0)
5
+ json (~> 1.8, >= 1.8.1)
6
+ jwt (~> 1.0, >= 1.0.0)
7
+ savon (= 2.2.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ akami (1.2.2)
13
+ gyoku (>= 0.4.0)
14
+ nokogiri
15
+ builder (3.2.2)
16
+ coderay (1.0.9)
17
+ diff-lcs (1.2.4)
18
+ ffi (1.9.0-x86-mingw32)
19
+ formatador (0.2.4)
20
+ guard (1.8.2)
21
+ formatador (>= 0.2.4)
22
+ listen (>= 1.0.0)
23
+ lumberjack (>= 1.0.2)
24
+ pry (>= 0.9.10)
25
+ thor (>= 0.14.6)
26
+ guard-rspec (2.0.0)
27
+ guard (>= 1.1)
28
+ rspec (~> 2.11)
29
+ gyoku (1.0.0)
30
+ builder (>= 2.1.2)
31
+ httpi (2.0.2)
32
+ rack
33
+ json (1.8.1)
34
+ jwt (1.5.6)
35
+ listen (1.3.0)
36
+ rb-fsevent (>= 0.9.3)
37
+ rb-inotify (>= 0.9)
38
+ rb-kqueue (>= 0.2)
39
+ lumberjack (1.0.4)
40
+ method_source (0.8.2)
41
+ mini_portile2 (2.1.0)
42
+ nokogiri (1.6.8.1-x86-mingw32)
43
+ mini_portile2 (~> 2.1.0)
44
+ nori (2.1.0)
45
+ pry (0.9.10-x86-mingw32)
46
+ coderay (~> 1.0.5)
47
+ method_source (~> 0.8)
48
+ slop (~> 3.4)
49
+ win32console (~> 1.3)
50
+ rack (2.0.1)
51
+ rake (0.9.6)
52
+ rb-fsevent (0.9.3)
53
+ rb-inotify (0.9.1)
54
+ ffi (>= 0.5.0)
55
+ rb-kqueue (0.2.0)
56
+ ffi (>= 0.5.0)
57
+ rspec (2.14.1)
58
+ rspec-core (~> 2.14.0)
59
+ rspec-expectations (~> 2.14.0)
60
+ rspec-mocks (~> 2.14.0)
61
+ rspec-core (2.14.5)
62
+ rspec-expectations (2.14.2)
63
+ diff-lcs (>= 1.1.3, < 2.0)
64
+ rspec-mocks (2.14.3)
65
+ savon (2.2.0)
66
+ akami (~> 1.2.0)
67
+ builder (>= 2.1.2)
68
+ gyoku (~> 1.0.0)
69
+ httpi (~> 2.0.2)
70
+ nokogiri (>= 1.4.0)
71
+ nori (~> 2.1.0)
72
+ wasabi (~> 3.1.0)
73
+ slop (3.4.6)
74
+ thor (0.18.1)
75
+ wasabi (3.1.0)
76
+ httpi (~> 2.0)
77
+ nokogiri (>= 1.4.0)
78
+ win32console (1.3.2-x86-mingw32)
79
+
80
+ PLATFORMS
81
+ x86-mingw32
82
+
83
+ DEPENDENCIES
84
+ bundler (~> 1.3)
85
+ guard (~> 1.1)
86
+ guard-rspec (~> 2.0)
87
+ marketingcloudsdk!
88
+ rake (~> 0.9)
89
+ rspec (~> 2.0)
90
+
91
+ BUNDLED WITH
92
+ 1.13.5
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+ guard 'rspec' do
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ end
8
+
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2013 ExactTarget, Inc.
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
+
11
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,130 @@
1
+ FuelSDK-Ruby / MarketingCloudSDK-Ruby
2
+ =====================================
3
+
4
+ ExactTarget Fuel SDK / SalesforceMarektingCloudSDK for Ruby
5
+
6
+ ## Overview ##
7
+ The Fuel SDK for Ruby provides easy access to ExactTarget's Fuel API Family services, including a collection of REST APIs and a SOAP API. These APIs provide access to ExactTarget functionality via common collection types such as array/hash.
8
+
9
+ ## Migrationg to version to version 1.0 ##
10
+ - **FuelSDK gem has been renamed to MarketingCloudSDK and will be availbale as marketingcloudsdk on ruby gems.
11
+
12
+ ## New Features in Version .9 ##
13
+ - **Streamlined Folder Support**: All objects that support folders within the UI now have a standardized property called folderId.
14
+ - **Interaction Support**: Now supports Import and Email::SendDefinition objects .
15
+ - **Profile Attribute Support**: Added the ability to manage profile attributes through the ProfileAttribute object.
16
+ - **Support for single request to Add/Update**:A single request can be made which will create the object if one doesn't already or update one if it does. This works for Subscriber, DataExtension::Row, and List objects using the Put method.
17
+ - **Tracking Events Batching Support**: By default, all tracking event types will only pull new data since the last time a request was made using the same filter. If you would like to override this functionality to pull all data, simply set the GetSinceLastBatch property to false.
18
+ - **Automatic Asset Organization for Hub Apps**: Applications that authenticate by providing a JWT will automatically have all created assets placed into a folder based on the HubExchange app's name.
19
+ - **Greater Flexibility for Authentication**:Yaml config file is no longer required in order to define the authentication parameters. They are now required inputs when instantiating the Client class so they can be stored anywhere.
20
+
21
+ ## Migrating from old version ##
22
+ - MarkeitngCloudSDK is now gem, Going forward FuelSDK gem will be available as marketingcloudsdk on ruby gems.
23
+ - Config.yaml is no longer used. ClientID/ClientSecret will now need to be passed when instantiating the Client class.
24
+ - Previous versions of the SalesforceMarketingCloudSDK exposed objects with the prefix "ET_". For backwards compatibility you can still access objects this way.
25
+ Subscriber can be accessed using MarketingCloudSDK::Subscriber or ET_Subscriber.
26
+
27
+ ## Requirements ##
28
+ - Ruby Version 2.2.5
29
+ - Savon 2.2.0
30
+
31
+ ## Getting Started ##
32
+ Build the gem from the source
33
+
34
+ ```ruby
35
+ gem build marketingcloudsdk.gemspec
36
+ ```
37
+
38
+ Install the newly built gem
39
+
40
+ ```ruby
41
+ gem install marketingcloudsdk-1.0.0.gem
42
+ ```
43
+
44
+ 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").
45
+
46
+
47
+ ## Example Request ##
48
+
49
+ Add a require statement to reference the SalesforceMarketingCloud SDK's functionality:
50
+ > require 'marketingcloudsdk'
51
+
52
+ Next, create an instance of the Client class:
53
+ > myClient = MarketingCloudSDK::Client.new {'client' => { 'id' => CLIENTID, 'secret' => SECRET }}
54
+
55
+ Create an instance of the object type we want to work with:
56
+ > list = MarketingCloudSDK::List.new
57
+
58
+ Associate the Client to the object using the client property:
59
+ > list.client = myClient
60
+
61
+ Utilize one of the List methods:
62
+ > response = list.get
63
+
64
+ Print out the results for viewing
65
+ > p response
66
+
67
+ **Example Output:**
68
+
69
+ <pre>
70
+ <MarketingCloudSDK::SoapResponse:0x007fb86abcf190
71
+ @body= {:retrieve_response_msg=> {:overall_status=>"OK", :request_id=>"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", :results=>..}
72
+ @code= 200,
73
+ @message= 'OK',
74
+ @request_id="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
75
+ @results=
76
+ [{:client=>{:id=>"xxxx"},
77
+ :partner_key=>nil,
78
+ :created_date=>
79
+ #<DateTime: 2013-05-30T23:02:00+00:00 ((2456443j,82920s,0n),+0s,2299161j)>,
80
+ :id=>"xxxx",
81
+ :object_id=>nil,
82
+ :email_address=>"xxxx",
83
+ :attributes=>
84
+ [{:name=>"Full Name", :value=>"Justin Barber"},
85
+ {:name=>"Gender", :value=>nil},
86
+ {:name=>"Email Address", :value=>"xxx"},
87
+ {:name=>"User Defined", :value=>"02/02/1982"}],
88
+ :subscriber_key=>"xxxx",
89
+ :status=>"Active",
90
+ :email_type_preference=>"HTML",
91
+ :"@xsi:type"=>"Subscriber"},
92
+ @success=true>
93
+ </pre>
94
+
95
+ ## Client Class ##
96
+
97
+ 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.
98
+
99
+ Client class accepts multiple parameters
100
+
101
+ **Parameters** - Allows for passing authentication information for use with SSO with a JWT or for passing ClientID/ClientSecret:
102
+
103
+ Example passing ClientID/ClientSecret:
104
+ > myclient = MarketingCloudSDK::Client.new({'client' => {'id' => 'exampleID','secret' => 'exampleSecret'}})
105
+
106
+ Example passing ClientID/ClientSecret/AppSignature/JWT:
107
+ > myclient = MarketingCloudSDK::Client.new({'client' => {'id' => 'exampleID','secret' => 'exampleSecret', 'signature'=>'examplesig'}, 'jwt'=>'exampleJWT'})
108
+
109
+ **Debug** - If 2nd parameter for debug is set to true, all API requests that the Fuel SDK is making behind the scenes will be logged. This option should only be set to true in order to troubleshoot during the development process and should never be used in a production scenario.
110
+ > myclient = MarketingCloudSDK::Client.new auth, true <br>
111
+
112
+
113
+ ## Responses ##
114
+ All methods on MarketingCloud 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.
115
+
116
+ - success?: Boolean value that indicates if the call was successful
117
+ - code: HTTP Error Code (will always be 200 for SOAP requests)
118
+ - message: Text values containing more details in the event of an error
119
+ - results: Collection containing the details unique to the method called.
120
+ - more? - Boolean value that indicates on Get requests if more data is available.
121
+
122
+
123
+ ## Samples ##
124
+ Find more sample files that illustrate using all of the available functions for ExactTarget objects exposed through the API in the samples directory.
125
+
126
+
127
+
128
+
129
+
130
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +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
@@ -0,0 +1,283 @@
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, :package_name, :package_folders, :parent_folders, :auth_token_expiration, :request_token_url
81
+
82
+ include MarketingCloudSDK::Soap
83
+ include MarketingCloudSDK::Rest
84
+
85
+ def jwt= encoded_jwt
86
+ raise 'Require app signature to decode JWT' unless self.signature
87
+ decoded_jwt = JWT.decode(encoded_jwt, self.signature, true)
88
+
89
+ self.auth_token = decoded_jwt['request']['user']['oauthToken']
90
+ self.internal_token = decoded_jwt['request']['user']['internalOauthToken']
91
+ self.refresh_token = decoded_jwt['request']['user']['refreshToken']
92
+ self.auth_token_expiration = Time.new + decoded_jwt['request']['user']['expiresIn']
93
+ self.package_name = decoded_jwt['request']['application']['package']
94
+ end
95
+
96
+ def initialize(params={}, debug=false)
97
+ @refresh_mutex = Mutex.new
98
+ self.debug = debug
99
+ client_config = params['client']
100
+ if client_config
101
+ self.id = client_config["id"]
102
+ self.secret = client_config["secret"]
103
+ self.signature = client_config["signature"]
104
+ end
105
+
106
+ self.request_token_url = params['request_token_url'] ? params['request_token_url'] : 'https://auth.exacttargetapis.com/v1/requestToken'
107
+ self.jwt = params['jwt'] if params['jwt']
108
+ self.refresh_token = params['refresh_token'] if params['refresh_token']
109
+
110
+ self.wsdl = params["defaultwsdl"] if params["defaultwsdl"]
111
+ end
112
+
113
+ def refresh force=false
114
+ @refresh_mutex.synchronize do
115
+ raise 'Require Client Id and Client Secret to refresh tokens' unless (id && secret)
116
+ #If we don't already have a token or the token expires within 5 min(300 seconds)
117
+ if (self.access_token.nil? || Time.new + 300 > self.auth_token_expiration || force) then
118
+ payload = Hash.new.tap do |h|
119
+ h['clientId']= id
120
+ h['clientSecret'] = secret
121
+ h['refreshToken'] = refresh_token if refresh_token
122
+ h['accessType'] = 'offline'
123
+ end
124
+
125
+ options = Hash.new.tap do |h|
126
+ h['data'] = payload
127
+ h['content_type'] = 'application/json'
128
+ h['params'] = {'legacy' => 1}
129
+ end
130
+ response = post(request_token_url, options)
131
+ raise "Unable to refresh token: #{response['message']}" unless response.has_key?('accessToken')
132
+
133
+ self.access_token = response['accessToken']
134
+ self.internal_token = response['legacyToken']
135
+ self.auth_token_expiration = Time.new + response['expiresIn']
136
+ self.refresh_token = response['refreshToken'] if response.has_key?("refreshToken")
137
+ return true
138
+ else
139
+ return false
140
+ end
141
+ end
142
+ end
143
+
144
+ def refresh!
145
+ refresh true
146
+ end
147
+
148
+ def AddSubscriberToList(email, ids, subscriber_key = nil)
149
+ s = MarketingCloudSDK::Subscriber.new
150
+ s.client = self
151
+ lists = ids.collect{|id| {'ID' => id}}
152
+ s.properties = {"EmailAddress" => email, "Lists" => lists}
153
+ p s.properties
154
+ s.properties['SubscriberKey'] = subscriber_key if subscriber_key
155
+
156
+ # Try to add the subscriber
157
+ if(rsp = s.post and rsp.results.first[:error_code] == '12014')
158
+ # subscriber already exists we need to update.
159
+ rsp = s.patch
160
+ end
161
+ rsp
162
+ end
163
+
164
+ def CreateDataExtensions(definitions)
165
+ de = MarketingCloudSDK::DataExtension.new
166
+ de.client = self
167
+ de.properties = definitions
168
+ de.post
169
+ end
170
+ def SendTriggeredSends(arrayOfTriggeredRecords)
171
+ sendTS = ET_TriggeredSend.new
172
+ sendTS.authStub = self
173
+
174
+ sendTS.properties = arrayOfTriggeredRecords
175
+ sendResponse = sendTS.send
176
+
177
+ return sendResponse
178
+ end
179
+ def SendEmailToList(emailID, listID, sendClassificationCustomerKey)
180
+ email = ET_Email::SendDefinition.new
181
+ email.properties = {"Name"=>SecureRandom.uuid, "CustomerKey"=>SecureRandom.uuid, "Description"=>"Created with RubySDK"}
182
+ email.properties["SendClassification"] = {"CustomerKey"=>sendClassificationCustomerKey}
183
+ email.properties["SendDefinitionList"] = {"List"=> {"ID"=>listID}, "DataSourceTypeID"=>"List"}
184
+ email.properties["Email"] = {"ID"=>emailID}
185
+ email.authStub = self
186
+ result = email.post
187
+ if result.status then
188
+ sendresult = email.send
189
+ if sendresult.status then
190
+ deleteresult = email.delete
191
+ return sendresult
192
+ else
193
+ raise "Unable to send using send definition due to: #{result.results[0][:status_message]}"
194
+ end
195
+ else
196
+ raise "Unable to create send definition due to: #{result.results[0][:status_message]}"
197
+ end
198
+ end
199
+
200
+ def SendEmailToDataExtension(emailID, sendableDataExtensionCustomerKey, sendClassificationCustomerKey)
201
+ email = ET_Email::SendDefinition.new
202
+ email.properties = {"Name"=>SecureRandom.uuid, "CustomerKey"=>SecureRandom.uuid, "Description"=>"Created with RubySDK"}
203
+ email.properties["SendClassification"] = {"CustomerKey"=> sendClassificationCustomerKey}
204
+ email.properties["SendDefinitionList"] = {"CustomerKey"=> sendableDataExtensionCustomerKey, "DataSourceTypeID"=>"CustomObject"}
205
+ email.properties["Email"] = {"ID"=>emailID}
206
+ email.authStub = self
207
+ result = email.post
208
+ if result.status then
209
+ sendresult = email.send
210
+ if sendresult.status then
211
+ deleteresult = email.delete
212
+ return sendresult
213
+ else
214
+ raise "Unable to send using send definition due to: #{result.results[0][:status_message]}"
215
+ end
216
+ else
217
+ raise "Unable to create send definition due to: #{result.results[0][:status_message]}"
218
+ end
219
+ end
220
+ def CreateAndStartListImport(listId,fileName)
221
+ import = ET_Import.new
222
+ import.authStub = self
223
+ import.properties = {"Name"=> "SDK Generated Import #{DateTime.now.to_s}"}
224
+ import.properties["CustomerKey"] = SecureRandom.uuid
225
+ import.properties["Description"] = "SDK Generated Import"
226
+ import.properties["AllowErrors"] = "true"
227
+ import.properties["DestinationObject"] = {"ID"=>listId}
228
+ import.properties["FieldMappingType"] = "InferFromColumnHeadings"
229
+ import.properties["FileSpec"] = fileName
230
+ import.properties["FileType"] = "CSV"
231
+ import.properties["RetrieveFileTransferLocation"] = {"CustomerKey"=>"ExactTarget Enhanced FTP"}
232
+ import.properties["UpdateType"] = "AddAndUpdate"
233
+ result = import.post
234
+
235
+ if result.status then
236
+ return import.start
237
+ else
238
+ raise "Unable to create import definition due to: #{result.results[0][:status_message]}"
239
+ end
240
+ end
241
+
242
+ def CreateAndStartDataExtensionImport(dataExtensionCustomerKey, fileName, overwrite)
243
+ import = ET_Import.new
244
+ import.authStub = self
245
+ import.properties = {"Name"=> "SDK Generated Import #{DateTime.now.to_s}"}
246
+ import.properties["CustomerKey"] = SecureRandom.uuid
247
+ import.properties["Description"] = "SDK Generated Import"
248
+ import.properties["AllowErrors"] = "true"
249
+ import.properties["DestinationObject"] = {"CustomerKey"=>dataExtensionCustomerKey}
250
+ import.properties["FieldMappingType"] = "InferFromColumnHeadings"
251
+ import.properties["FileSpec"] = fileName
252
+ import.properties["FileType"] = "CSV"
253
+ import.properties["RetrieveFileTransferLocation"] = {"CustomerKey"=>"ExactTarget Enhanced FTP"}
254
+ if overwrite then
255
+ import.properties["UpdateType"] = "Overwrite"
256
+ else
257
+ import.properties["UpdateType"] = "AddAndUpdate"
258
+ end
259
+ result = import.post
260
+
261
+ if result.status then
262
+ return import.start
263
+ else
264
+ raise "Unable to create import definition due to: #{result.results[0][:status_message]}"
265
+ end
266
+ end
267
+
268
+ def CreateProfileAttributes(allAttributes)
269
+ attrs = ET_ProfileAttribute.new
270
+ attrs.authStub = self
271
+ attrs.properties = allAttributes
272
+ return attrs.post
273
+ end
274
+
275
+ def CreateContentAreas(arrayOfContentAreas)
276
+ postC = ET_ContentArea.new
277
+ postC.authStub = self
278
+ postC.properties = arrayOfContentAreas
279
+ sendResponse = postC.post
280
+ return sendResponse
281
+ end
282
+ end
283
+ end