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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +41 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +62 -0
  7. data/Rakefile +1 -0
  8. data/exact-target-api.gemspec +22 -0
  9. data/lib/exact-target-api.rb +43 -0
  10. data/lib/exact-target-api/base_object.rb +28 -0
  11. data/lib/exact-target-api/bounce_event.rb +8 -0
  12. data/lib/exact-target-api/campaign.rb +19 -0
  13. data/lib/exact-target-api/click_event.rb +8 -0
  14. data/lib/exact-target-api/client.rb +175 -0
  15. data/lib/exact-target-api/constructor.rb +34 -0
  16. data/lib/exact-target-api/content_area.rb +8 -0
  17. data/lib/exact-target-api/continue.rb +33 -0
  18. data/lib/exact-target-api/continue_rest.rb +24 -0
  19. data/lib/exact-target-api/create_wsdl.rb +53 -0
  20. data/lib/exact-target-api/cud_support.rb +19 -0
  21. data/lib/exact-target-api/cud_support_rest.rb +72 -0
  22. data/lib/exact-target-api/data_extension.rb +226 -0
  23. data/lib/exact-target-api/delete.rb +38 -0
  24. data/lib/exact-target-api/delete_rest.rb +18 -0
  25. data/lib/exact-target-api/describe.rb +25 -0
  26. data/lib/exact-target-api/email.rb +8 -0
  27. data/lib/exact-target-api/folder.rb +8 -0
  28. data/lib/exact-target-api/get.rb +64 -0
  29. data/lib/exact-target-api/get_rest.rb +25 -0
  30. data/lib/exact-target-api/get_support.rb +23 -0
  31. data/lib/exact-target-api/get_support_rest.rb +86 -0
  32. data/lib/exact-target-api/list.rb +68 -0
  33. data/lib/exact-target-api/list_subscriber.rb +10 -0
  34. data/lib/exact-target-api/open_event.rb +8 -0
  35. data/lib/exact-target-api/patch.rb +39 -0
  36. data/lib/exact-target-api/patch_rest.rb +19 -0
  37. data/lib/exact-target-api/post.rb +34 -0
  38. data/lib/exact-target-api/post_rest.rb +19 -0
  39. data/lib/exact-target-api/sent_event.rb +8 -0
  40. data/lib/exact-target-api/subscriber.rb +81 -0
  41. data/lib/exact-target-api/triggered_send.rb +15 -0
  42. data/lib/exact-target-api/unsub_event.rb +8 -0
  43. data/lib/exact-target-api/version.rb +3 -0
  44. metadata +113 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6cfa8a6154a2844221f392f18b3bd279c04926dc
4
+ data.tar.gz: eaedaa8b1f741d0a6492028726b06848fd772fd9
5
+ SHA512:
6
+ metadata.gz: 432df1a25e5e09a33fe0409d7864108f9dda8f465f0ae175b3bbdd1a6b42b7f22fcde7a9e3f8709979a9a1870ba714a5c6ca0459526a8428bbcaeb616653b9b2
7
+ data.tar.gz: 27a26d976407d8c93bab879bc6b383efc0ac1a5cb4dc8db1286ec246f2459523de569c136768e7242a729f7384c108d2884c5cbb48ed950d63470e885b7e9bdf
@@ -0,0 +1,18 @@
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/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in exact-target-api.gemspec
4
+ gemspec
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ exact-target-api (0.0.1)
5
+ jwt (~> 0.1.8)
6
+ savon (~> 2.2.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ akami (1.2.0)
12
+ gyoku (>= 0.4.0)
13
+ nokogiri (>= 1.4.0)
14
+ builder (3.2.0)
15
+ gyoku (1.0.0)
16
+ builder (>= 2.1.2)
17
+ httpi (2.0.2)
18
+ rack
19
+ jwt (0.1.8)
20
+ multi_json (>= 1.5)
21
+ multi_json (1.7.3)
22
+ nokogiri (1.5.9)
23
+ nori (2.1.0)
24
+ rack (1.5.2)
25
+ savon (2.2.0)
26
+ akami (~> 1.2.0)
27
+ builder (>= 2.1.2)
28
+ gyoku (~> 1.0.0)
29
+ httpi (~> 2.0.2)
30
+ nokogiri (>= 1.4.0)
31
+ nori (~> 2.1.0)
32
+ wasabi (~> 3.1.0)
33
+ wasabi (3.1.0)
34
+ httpi (~> 2.0)
35
+ nokogiri (>= 1.4.0)
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ exact-target-api!
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 thousandsofthem
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,62 @@
1
+ ExactTarget API wrapper
2
+ =====================
3
+
4
+ Usage example:
5
+
6
+ ```ruby
7
+ require 'rubygems'
8
+ require 'bundler/setup'
9
+ require 'exact-target-api'
10
+
11
+ config = {
12
+ clientid: 'xxxxxx',
13
+ clientsecret: 'yyyyyy',
14
+ appsignature: 'zzzzzz' # Optional
15
+ }
16
+
17
+ # All optional
18
+ options = {
19
+ debug: false,
20
+ wsdl: true,
21
+ jwt: params[:jwt]
22
+ }
23
+
24
+ client = ET::Client.new(config, options)
25
+
26
+
27
+ # Create new List
28
+ list = client.list.create(
29
+ ListName: "Test-List",
30
+ Description: "Test List",
31
+ Type: "Private"
32
+ )
33
+
34
+ puts "List ID is #{list.id}"
35
+
36
+ # Find a List
37
+ list2 = client.list.find(list.id)
38
+
39
+ # Create invalid subscriber
40
+ subscriber = client.subscriber.create(email: 'foo@bar.aaaa')
41
+ subscriber = client.subscriber.create(email: 'foo@bar.aaaa', list: list)
42
+ subscriber = client.subscriber.create(email: 'foo@bar.aaaa', list_id: 12345, name: "Foo Bar")
43
+
44
+ puts subscriber.code # 200
45
+ puts subscriber.status # false
46
+ puts subscriber.results # {:status_code=>"Error", :status_message=>"TriggeredSpamFilter", :ordinal_id=>"0", :error_code=>"12002", :new_id=>"0", :object=>{:partner_key=>nil, :object_id=>nil, :email_address=>"foo@bar.aaaa", :lists=>{:partner_key=>nil, :id=>"3488", :object_id=>nil}, :"@xsi:type"=>"Subscriber"}}
47
+
48
+ # Create valid subscriber
49
+ subscriber = client.subscriber.create(email: "RubySDK@bh.exacttarget.com", name: "Foo Bar", Description: "Some text")
50
+ puts subscriber.code # 200
51
+ puts subscriber.status # true
52
+ puts subscriber.results # {:status_code=>"OK", :status_message=>"Created Subscriber.", :ordinal_id=>"0", :new_id=>"24761785", :object=>{:partner_key=>nil, :id=>"24761785", :object_id=>nil, :email_address=>"RubySDK@bh.exacttarget.com", :attributes=>[{:name=>"name", :value=>"Foo Bar"}, {:name=>"Description", :value=>"Some text"}], :"@xsi:type"=>"Subscriber"}}
53
+
54
+ # Find a subscriber
55
+ subscriber = client.subscriber.find("RubySDK@bh.exacttarget.com")
56
+
57
+ puts subscriber.status # true
58
+ puts subscriber.results # {:partner_key=>nil, :object_id=>nil, :email_address=>"RubySDK@bh.exacttarget.com", :subscriber_key=>"RubySDK@bh.exacttarget.com", :status=>"Active", :"@xsi:type"=>"Subscriber"}
59
+
60
+
61
+
62
+ ```
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'exact-target-api/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "exact-target-api"
8
+ gem.version = ET::VERSION
9
+ gem.authors = ["Alexander Shapiotko"]
10
+ gem.email = ["thousandsofthem@gmail.com"]
11
+ gem.description = "ExactTarget API wrapper"
12
+ gem.summary = "ExactTarget API wrapper"
13
+ gem.homepage = "https://github.com/BriteVerify/exact-target-api"
14
+
15
+ gem.add_dependency "savon", "~> 2.2.0"
16
+ gem.add_dependency "jwt", "~> 0.1.8"
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
21
+ gem.require_paths = ["lib"]
22
+ end
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'open-uri'
3
+ require 'savon'
4
+ require 'date'
5
+ require 'json'
6
+ require 'yaml'
7
+ require 'jwt'
8
+
9
+ require "exact-target-api/version"
10
+ require "exact-target-api/base_object"
11
+ require "exact-target-api/get_support"
12
+ require "exact-target-api/bounce_event"
13
+ require "exact-target-api/get_support_rest"
14
+ require "exact-target-api/cud_support_rest"
15
+ require "exact-target-api/campaign"
16
+ require "exact-target-api/click_event"
17
+ require "exact-target-api/create_wsdl"
18
+ require "exact-target-api/client"
19
+ require "exact-target-api/constructor"
20
+ require "exact-target-api/cud_support"
21
+ require "exact-target-api/content_area"
22
+ require "exact-target-api/continue"
23
+ require "exact-target-api/continue_rest"
24
+ require "exact-target-api/data_extension"
25
+ require "exact-target-api/delete"
26
+ require "exact-target-api/delete_rest"
27
+ require "exact-target-api/describe"
28
+ require "exact-target-api/email"
29
+ require "exact-target-api/folder"
30
+ require "exact-target-api/get"
31
+ require "exact-target-api/get_rest"
32
+ require "exact-target-api/list"
33
+ require "exact-target-api/list_subscriber"
34
+ require "exact-target-api/open_event"
35
+ require "exact-target-api/patch"
36
+ require "exact-target-api/patch_rest"
37
+ require "exact-target-api/post"
38
+ require "exact-target-api/post_rest"
39
+ require "exact-target-api/sent_event"
40
+ require "exact-target-api/subscriber"
41
+ require "exact-target-api/triggered_send"
42
+ require "exact-target-api/unsub_event"
43
+
@@ -0,0 +1,28 @@
1
+ module ET
2
+ class BaseObject
3
+ attr_accessor :props, :client
4
+ attr_reader :obj, :lastRequestID, :endpoint
5
+
6
+ def initialize
7
+ @props = nil
8
+ @filter = nil
9
+ @lastRequestID = nil
10
+ @endpoint = nil
11
+ end
12
+
13
+
14
+ def stringify_keys!(params)
15
+ params.keys.each do |key|
16
+ params[key.to_s] = params.delete(key)
17
+ end
18
+ params
19
+ end
20
+
21
+ def symbolize_keys!(params)
22
+ params.keys.each do |key|
23
+ params[key.to_sym] = params.delete(key)
24
+ end
25
+ params
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,8 @@
1
+ module ET
2
+ class BounceEvent < ET::GetSupport
3
+ def initialize
4
+ super
5
+ @obj = 'BounceEvent'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module ET
2
+ class Campaign < ET::CUDSupportRest
3
+ def initialize
4
+ super
5
+ @endpoint = 'https://www.exacttargetapis.com/hub/v1/campaigns/{id}'
6
+ @urlProps = ["id"]
7
+ @urlPropsRequired = []
8
+ end
9
+
10
+ class Asset < ET::CUDSupportRest
11
+ def initialize
12
+ super
13
+ @endpoint = 'https://www.exacttargetapis.com/hub/v1/campaigns/{id}/assets/{assetId}'
14
+ @urlProps = ["id", "assetId"]
15
+ @urlPropsRequired = ["id"]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ module ET
2
+ class ClickEvent < ET::GetSupport
3
+ def initialize
4
+ super
5
+ @obj = 'ClickEvent'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,175 @@
1
+ require 'tmpdir'
2
+
3
+ module ET
4
+ class Client < ET::CreateWSDL
5
+ attr_accessor :auth, :ready, :status, :debug, :authToken
6
+ attr_reader :authTokenExpiration, :internalAuthToken, :wsdlLoc, :clientId, :clientSecret, :soapHeader, :authObj, :path, :appsignature, :stackID, :refreshKey
7
+
8
+ def initialize(config, options = {})
9
+ load_config(config)
10
+ symbolize_keys!(options)
11
+
12
+ get_wsdl = options.has_key?(:wsdl) ? options[:wsdl] : true
13
+
14
+ @debug = options[:debug]
15
+
16
+ @path = Dir.tmpdir
17
+
18
+ begin
19
+ if get_wsdl
20
+ super(@path)
21
+ end
22
+
23
+ if options[:jwt]
24
+ jwt = JWT.decode(options[:jwt], @appsignature, true)
25
+ @authToken = jwt['request']['user']['oauthToken']
26
+ @authTokenExpiration = [Time.at(jwt['exp']), Time.now + jwt['request']['user']['expiresIn']].min
27
+ @internalAuthToken = jwt['request']['user']['internalOauthToken']
28
+ @refreshKey = jwt['request']['user']['refreshToken']
29
+
30
+ self.determineStack
31
+
32
+ @authObj = {'oAuth' => {'oAuthToken' => @internalAuthToken}}
33
+ @authObj[:attributes!] = { 'oAuth' => { 'xmlns' => 'http://exacttarget.com' }}
34
+
35
+ @auth = Savon.client(soap_header: @authObj,
36
+ wsdl: File.read(wsdl_file(@path)),
37
+ endpoint: @endpoint,
38
+ wsse_auth: ["*", "*"],
39
+ raise_errors: false,
40
+ log: @debug,
41
+ open_timeout: 180,
42
+ read_timeout: 180)
43
+ end
44
+ refreshToken
45
+ rescue
46
+ raise
47
+ end
48
+
49
+ @ready = @auth.operations.length > 0 && @status >= 200 && @status <= 400
50
+ end
51
+
52
+ def refreshToken(force = nil)
53
+ #If we don't already have a token or the token expires within 5 min(300 seconds), get one
54
+ if force || @authToken.nil? || Time.now + 300 > @authTokenExpiration
55
+ begin
56
+ uri = URI.parse("https://auth.exacttargetapis.com/v1/requestToken?legacy=1")
57
+ http = Net::HTTP.new(uri.host, uri.port)
58
+ http.use_ssl = true
59
+ request = Net::HTTP::Post.new(uri.request_uri)
60
+
61
+ jsonPayload = {clientId: @clientId, clientSecret: @clientSecret}#, accessType: 'offline'}
62
+ # Pass in the refreshKey if we have it
63
+ jsonPayload[:refreshToken] = @refreshKey if @refreshKey
64
+
65
+ request.body = jsonPayload.to_json
66
+ request.add_field "Content-Type", "application/json"
67
+ tokenResponse = JSON.parse(http.request(request).body)
68
+
69
+ if tokenResponse['accessToken'].nil?
70
+ raise 'Unable to validate App Keys(ClientID/ClientSecret) provided: ' + http.request(request).body
71
+ end
72
+
73
+ @authToken = tokenResponse['accessToken']
74
+ @authTokenExpiration = Time.new + tokenResponse['expiresIn']
75
+ @internalAuthToken = tokenResponse['legacyToken']
76
+ if tokenResponse["refreshToken"]
77
+ @refreshKey = tokenResponse['refreshToken']
78
+ end
79
+
80
+
81
+ self.determineStack if @endpoint.nil?
82
+
83
+ @authObj = {'oAuth' => {'oAuthToken' => @internalAuthToken}}
84
+ @authObj[:attributes!] = {'oAuth' => {'xmlns' => 'http://exacttarget.com' }}
85
+
86
+ @auth = Savon.client(soap_header: @authObj,
87
+ wsdl: File.read(wsdl_file(@path)),
88
+ endpoint: @endpoint,
89
+ wsse_auth: ["*", "*"],
90
+ raise_errors: false,
91
+ log: @debug)
92
+
93
+
94
+ rescue Exception => e
95
+ raise 'Unable to validate App Keys(ClientID/ClientSecret) provided: ' + e.message
96
+ end
97
+ end
98
+ end
99
+
100
+
101
+ def list
102
+ ET::List.new(self)
103
+ end
104
+
105
+ def subscriber
106
+ ET::Subscriber.new(self)
107
+ end
108
+
109
+ #def AddSubscriberToList(emailAddress, listIDs, subscriberKey = nil)
110
+ # newSub = ET::Subscriber.new
111
+ # newSub.authStub = self
112
+ # lists = []
113
+ #
114
+ # listIDs.each{ |p|
115
+ # lists.push({"ID"=> p})
116
+ # }
117
+ #
118
+ # newSub.props = {"EmailAddress" => emailAddress, "Lists" => lists}
119
+ # if !subscriberKey.nil?
120
+ # newSub.props['SubscriberKey'] = subscriberKey
121
+ # end
122
+ #
123
+ # # Try to add the subscriber
124
+ # postResponse = newSub.post
125
+ #
126
+ # if !postResponse.status
127
+ # # If the subscriber already exists in the account then we need to do an update.
128
+ # # Update Subscriber On List
129
+ # if postResponse.results[0][:error_code] == "12014"
130
+ # patchResponse = newSub.patch
131
+ # return patchResponse
132
+ # end
133
+ # end
134
+ # postResponse
135
+ #end
136
+
137
+ #def CreateDataExtensions(dataExtensionDefinitions)
138
+ # newDEs = ET::DataExtension.new
139
+ # newDEs.authStub = self
140
+ #
141
+ # newDEs.props = dataExtensionDefinitions
142
+ # newDEs.post
143
+ #end
144
+
145
+
146
+ protected
147
+
148
+
149
+ def load_config(config)
150
+ symbolize_keys!(config)
151
+
152
+ @clientId = config[:clientid] || raise("Please provide ClientID")
153
+ @clientSecret = config[:clientsecret] || raise("Please provide Client Secret")
154
+ @appsignature = config[:appsignature]
155
+ @wsdl = config[:defaultwsdl] || 'https://webservice.exacttarget.com/etframework.wsdl'
156
+ end
157
+
158
+ def determineStack
159
+ begin
160
+ uri = URI.parse("https://www.exacttargetapis.com/platform/v1/endpoints/soap?access_token=" + @authToken)
161
+ http = Net::HTTP.new(uri.host, uri.port)
162
+
163
+ http.use_ssl = true
164
+
165
+ request = Net::HTTP::Get.new(uri.request_uri)
166
+
167
+ contextResponse = JSON.parse(http.request(request).body)
168
+ @endpoint = contextResponse['url']
169
+
170
+ rescue Exception => e
171
+ raise 'Unable to determine stack using /platform/v1/tokenContext: ' + e.message
172
+ end
173
+ end
174
+ end
175
+ end