eloqua_api 0.0.5 → 0.0.7

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.
@@ -0,0 +1,14 @@
1
+ module Eloqua
2
+ module Export
3
+ def define_export(export)
4
+ post("contact/export", export)
5
+ end
6
+
7
+ def retrieve_export(export_uri, options={})
8
+ options[:page] ||= 1
9
+ options[:pageSize] ||= 50000
10
+
11
+ get("%s/data" % export_uri, options)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module Eloqua
2
+ module Sync
3
+ def sync(export_uri, options={})
4
+ options[:syncedInstanceUri] ||= export_uri
5
+ post("sync", options)
6
+ end
7
+
8
+ def sync_status(sync_uri, options={})
9
+ get(sync_uri, options)
10
+ end
11
+ end
12
+ end
@@ -1,29 +1,13 @@
1
- module Eloqua
2
- class BulkClient < Eloqua::Client
3
- BULK_API_PATH = "/API/Bulk/1.0"
4
-
5
- def bulk_path(path)
6
- BULK_API_PATH + '/' + path
7
- end
8
-
9
- # convenience methods
10
- def define_export(export_definition)
11
- post(bulk_path("contact/export"), export_definition)
12
- end
1
+ require 'eloqua_api/bulk/export'
2
+ require 'eloqua_api/bulk/sync'
13
3
 
14
- def sync(export_uri)
15
- post(bulk_path("sync"), {"syncedInstanceUri" => export_uri}.to_json)
16
- end
17
-
18
- def sync_status(sync_uri)
19
- get(bulk_path(sync_uri))
20
- end
21
-
22
- def retrieve_export(export_uri, options={})
23
- options[:page] ||= 1
24
- options[:page_size] ||= 50000
4
+ module Eloqua
5
+ class BulkClient < Client
6
+ include Export
7
+ include Sync
25
8
 
26
- get(bulk_path("#{export_uri}/data?page=#{options[:page]}&pageSize=#{options[:page_size]}"))
9
+ def build_path(*segments)
10
+ super('/Bulk/', *segments)
27
11
  end
28
12
  end
29
- end
13
+ end
@@ -1,54 +1,239 @@
1
- require 'net/https'
2
1
  require 'json'
2
+ require 'httmultiparty'
3
+ require 'uri'
4
+ require 'cgi'
3
5
 
4
6
  module Eloqua
7
+ class HTTPClient
8
+ include HTTMultiParty
9
+
10
+ class Parser::CustomJSON < HTTParty::Parser
11
+ def parse
12
+ JSON.parse(body) if body
13
+ rescue JSON::ParserError
14
+ body
15
+ end
16
+ end
17
+ parser Parser::CustomJSON
18
+
19
+ headers 'User-Agent' => 'Kapost Eloqua API Client'
20
+ headers 'Accept' => 'application/json'
21
+ headers 'Content-Type' => 'application/json'
22
+
23
+ query_string_normalizer proc { |query|
24
+ qs = HashConversions.to_params(query)
25
+ qs.gsub!(/orderBy=(.*?)%2B(.*?)(&|\?|$)/) do |m|
26
+ "orderBy=#{$1}+#{$2}#{$3}"
27
+ end
28
+ qs
29
+ }
30
+
31
+ format :json
32
+ # debug_output $stdout
33
+ end
34
+
5
35
  class Client
6
- attr_reader :site, :user
36
+ SITE = 'eloqua.com'
37
+ BASE_URI = "https://secure.#{SITE}"
38
+ BASE_LOGIN_URI = "https://login.#{SITE}"
39
+ BASE_VERSION = '1.0'
40
+ BASE_PATH = '/API/'
41
+
42
+ AUTHORIZE_PATH = '/auth/oauth2/authorize'
43
+ TOKEN_PATH = '/auth/oauth2/token'
44
+ TOKEN_PATH_HEADERS =
45
+ {
46
+ 'Accept' => 'application/json, text/javascript, */*; q=0.01',
47
+ 'Accept-Language' => 'en-US,en;q=0.5',
48
+ 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'
49
+ }.freeze
50
+
51
+ attr_reader :opts
52
+
53
+ attr_accessor :on_authorize
54
+ attr_accessor :on_refresh_token
55
+ attr_accessor :on_url_changed
7
56
 
8
- def initialize(site=nil, user=nil, password=nil)
9
- @site = site
10
- @user = user
11
- @password = password
57
+ def initialize(opts={})
58
+ @opts = opts.is_a?(Hash) ? opts.dup : {}
59
+ @opts[:url] ||= BASE_URI
60
+ @opts[:version] ||= BASE_VERSION
61
+ @url_changed = false
62
+ @token_refreshed = false
63
+ end
12
64
 
13
- @https = Net::HTTP.new('secure.eloqua.com', 443)
14
- @https.use_ssl = true
15
- @https.verify_mode = OpenSSL::SSL::VERIFY_PEER
65
+ def version
66
+ @opts[:version]
16
67
  end
17
68
 
18
- METHODS = {
19
- :get => ::Net::HTTP::Get,
20
- :post => ::Net::HTTP::Post,
21
- :put => ::Net::HTTP::Put,
22
- :delete => ::Net::HTTP::Delete
23
- }
69
+ def authorize_url(options={})
70
+ query = {}
71
+ query[:response_type] = 'code'
72
+ query[:client_id] = @opts[:client_id]
73
+ query[:scope] = options[:scope] || @opts[:scope] || 'full'
24
74
 
25
- def delete(path)
26
- request(:delete, path)
75
+ if (state=(options[:state] || @opts[:state]))
76
+ query[:state] = state
77
+ end
78
+
79
+ query[:redirect_uri] = escape_uri(options[:redirect_uri] || @opts[:redirect_uri])
80
+
81
+ "#{BASE_LOGIN_URI}#{AUTHORIZE_PATH}?#{query.map { |k,v| [k, v].join('=') }.join('&')}"
82
+ end
83
+
84
+ def exchange_token(options={})
85
+ auth = [@opts[:client_id], @opts[:client_secret]]
86
+
87
+ body = {}
88
+ if options[:code] and @opts[:redirect_uri]
89
+ body[:grant_type] = 'authorization_code'
90
+ body[:code] = options[:code]
91
+ body[:redirect_uri] = escape_uri(@opts[:redirect_uri])
92
+ elsif refresh_token?
93
+ body[:grant_type] = 'refresh_token'
94
+ body[:refresh_token] = @opts[:refresh_token]
95
+ body[:redirect_uri] = escape_uri(@opts[:redirect_uri])
96
+ else
97
+ raise ArgumentError, 'code and redirect_uri or refresh_token and redirect_uri is required'
98
+ end
99
+
100
+ result = http(BASE_LOGIN_URI, auth).post(TOKEN_PATH, :body => body, :headers => TOKEN_PATH_HEADERS)
101
+ return result unless result.code == 200 and result.parsed_response.is_a? Hash
102
+
103
+ response = result.parsed_response
104
+ return result unless response['access_token'] and response['refresh_token']
105
+
106
+ @opts[:access_token] = response['access_token']
107
+ @opts[:refresh_token] = response['refresh_token']
108
+
109
+ @http = nil
110
+ @token_refreshed = true
111
+
112
+ if refresh_token? and on_refresh_token?
113
+ on_refresh_token.call(response)
114
+ elsif options[:code] and @opts[:redirect_uri] and on_authorize?
115
+ on_authorize.call(response)
116
+ end
117
+
118
+ result
119
+ end
120
+
121
+ def on_authorize?
122
+ on_authorize.is_a? Proc
123
+ end
124
+
125
+ def on_refresh_token?
126
+ on_refresh_token.is_a? Proc
127
+ end
128
+
129
+ def on_url_changed?
130
+ on_url_changed.is_a? Proc
131
+ end
132
+
133
+ def url
134
+ @opts[:url]
135
+ end
136
+
137
+ def url_changed?
138
+ @url_changed
139
+ end
140
+
141
+ def token_refreshed?
142
+ @token_refreshed
143
+ end
144
+
145
+ def build_path(*segments)
146
+ File.join(BASE_PATH, *segments.shift, version, *segments)
147
+ end
148
+
149
+ def login
150
+ @http = nil
151
+
152
+ uri = BASE_URI
153
+ result = http(BASE_LOGIN_URI).get('/id')
154
+ if result.code == 200 and result.parsed_response.is_a? Hash
155
+ uri = result.parsed_response["urls"]["base"]
156
+ end
157
+
158
+ @url_changed = (uri != @opts[:url])
159
+ if @url_changed
160
+ @opts[:url] = uri
161
+ on_url_changed.call(uri) if on_url_changed?
162
+ end
163
+
164
+ result
27
165
  end
28
166
 
29
- def get(path)
30
- request(:get, path)
167
+ def get(path, query={})
168
+ request(:get, build_path(path), :query => query)
31
169
  end
32
170
 
33
171
  def post(path, body={})
34
- request(:post, path, body)
172
+ request(:post, build_path(path), :body => body.to_json)
173
+ end
174
+
175
+ def multipart_post(path, body={})
176
+ request(:post, build_path(path), :body => body)
35
177
  end
36
178
 
37
179
  def put(path, body={})
38
- request(:put, path, body)
180
+ request(:put, build_path(path), :body => body.to_json)
181
+ end
182
+
183
+ def delete(path)
184
+ request(:delete, build_path(path))
185
+ end
186
+
187
+ protected
188
+
189
+ def refresh_token?
190
+ @opts[:refresh_token] and
191
+ @opts[:redirect_uri]
39
192
  end
40
193
 
41
- def request(method, path, body={})
42
- request = METHODS[method].new(path, {'Content-Type' =>'application/json'})
43
- request.basic_auth @site + '\\' + @user, @password
194
+ def escape_uri(url)
195
+ URI.escape(URI.unescape(url))
196
+ end
197
+
198
+ def request(method, path, params={}, login_fallback=true)
199
+ @http ||= http
200
+
201
+ result = @http.send(method, path, params)
202
+ if result.code == 401 and login_fallback
203
+ exchange_token if refresh_token?
204
+
205
+ if login
206
+ request(method, path, params, false)
207
+ else
208
+ result
209
+ end
210
+ else
211
+ result
212
+ end
213
+ end
44
214
 
45
- case method
46
- when :post, :put
47
- request.body = body
215
+ def http(url=nil, auth=nil)
216
+ url ||= @opts[:url]
217
+ auth ||= begin
218
+ if @opts[:access_token]
219
+ @opts[:access_token]
220
+ elsif (site=@opts[:site]) and (username=@opts[:username]) and (password=@opts[:password])
221
+ ["%s\\%s" % [site, username], password]
222
+ else
223
+ nil
224
+ end
48
225
  end
49
226
 
50
- response = @https.request(request)
51
- return response
227
+ Class.new(HTTPClient) do |klass|
228
+ klass.base_uri(url.to_s) if url
229
+
230
+ if auth.is_a?(String) and auth.size > 0
231
+ klass.headers("Authorization" => "Bearer %s" % auth)
232
+ elsif auth.is_a?(Array) and auth.size == 2
233
+ klass.basic_auth(*auth)
234
+ end
235
+ end
52
236
  end
53
237
  end
54
- end
238
+ end
239
+
@@ -0,0 +1,22 @@
1
+ module Eloqua
2
+ module Campaign
3
+ def get_campaign(campaign_id, options={})
4
+ get("assets/campaign/%s" % campaign_id, options)
5
+ end
6
+
7
+ def get_recent_campaigns(options={})
8
+ options[:count] ||= 10
9
+ options[:depth] ||= "minimal"
10
+
11
+ get("assets/campaigns/recent", options)
12
+ end
13
+
14
+ def get_campaigns(options={})
15
+ options[:count] ||= 10
16
+ options[:depth] ||= "minimal"
17
+ options[:orderBy] ||= "createdAt+DESC"
18
+
19
+ get("assets/campaigns", options)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,39 @@
1
+ module Eloqua
2
+ module Contact
3
+ def get_contact(contact_id, options={})
4
+ options[:depth] ||= "minimal"
5
+
6
+ get("data/contact/#{contact_id}", options)
7
+ end
8
+
9
+ def get_contact_fields(options={})
10
+ options[:depth] ||= "minimal"
11
+
12
+ get("assets/contact/fields", options)
13
+ end
14
+
15
+ def create_contact(data)
16
+ post("data/contact", data)
17
+ end
18
+
19
+ def update_contact(contact_id, data)
20
+ put("data/contact/#{contact_id}", data)
21
+ end
22
+
23
+ def get_contacts(options={})
24
+ options[:count] ||= 10
25
+ options[:depth] ||= "minimal"
26
+
27
+ get("data/contacts", options)
28
+ end
29
+
30
+ def contact_activity(contact_id, options={})
31
+ options[:startDate] ||= 1.year.ago.to_i
32
+ options[:endDate] ||= Time.now.to_i
33
+ options[:type] ||= "webVisit"
34
+ options[:count] ||= 1000
35
+
36
+ get("data/activities/contact/%s" % contact_id, options)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,50 @@
1
+ module Eloqua
2
+ module Email
3
+ def create_email(email)
4
+ post("assets/email", email)
5
+ end
6
+
7
+ def delete_email(id)
8
+ delete("assets/email/%s" % id)
9
+ end
10
+
11
+ def get_email(id, options={})
12
+ get("assets/email/%s" % id, options)
13
+ end
14
+
15
+ def get_email_preview(id, options={})
16
+ get("assets/email/%s/preview" % id, options)
17
+ end
18
+
19
+ def get_recent_emails(options={})
20
+ options[:count] ||= 10
21
+ options[:depth] ||= "minimal"
22
+
23
+ get("assets/emails/recent", options)
24
+ end
25
+
26
+ def get_emails(options={})
27
+ options[:count] ||= 10
28
+ options[:depth] ||= "minimal"
29
+ options[:orderBy] ||= "createdAt+DESC"
30
+
31
+ get("assets/emails", options)
32
+ end
33
+
34
+ def get_email_template(id, options={})
35
+ get("assets/email/template/%s" % id, options)
36
+ end
37
+
38
+ def get_email_templates(options={})
39
+ get("assets/templates/email", options)
40
+ end
41
+
42
+ def get_email_deployments(options={})
43
+ options[:count] ||= 50
44
+ options[:depth] ||= "complete"
45
+ options[:orderBy] ||= "createdAt+DESC"
46
+
47
+ get("assets/email/deployments", options)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,43 @@
1
+ module Eloqua
2
+ module ImportedFile
3
+ def create_imported_file(file)
4
+ multipart_post("assets/importedFile/content", file)
5
+ end
6
+
7
+ def replace_imported_file(id, file)
8
+ multipart_post("assets/importedFile/%s/content/replace" % id, file)
9
+ end
10
+
11
+ def get_imported_file(id, options={})
12
+ get("assets/importedFile/%s" % id, options)
13
+ end
14
+
15
+ def update_imported_file(id, file)
16
+ put("assets/importedFile/%s" % id, file)
17
+ end
18
+
19
+ def delete_imported_file(id)
20
+ delete("assets/importedFile/%s" % id)
21
+ end
22
+
23
+ def imported_file_folder(id, options={})
24
+ options[:depth] ||= 'minimal'
25
+
26
+ get("assets/importedFile/folder/%s" % id, options)
27
+ end
28
+
29
+ def imported_file_folder_folders(id, options={})
30
+ options[:count] ||= 10
31
+ options[:depth] ||= 'minimal'
32
+
33
+ get("assets/importedFile/folder/%s/folders" % id, options)
34
+ end
35
+
36
+ def imported_file_folders(options={})
37
+ options[:count] ||= 10
38
+ options[:depth] ||= 'minimal'
39
+
40
+ get("assets/importedFile/folders", options)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,50 @@
1
+ module Eloqua
2
+ module LandingPage
3
+ def create_landing_page(page)
4
+ post("assets/landingPage", page)
5
+ end
6
+
7
+ def delete_landing_page(id)
8
+ delete("assets/landingPage/%s" % id)
9
+ end
10
+
11
+ def validate_landing_page(id, options={})
12
+ get("assets/landingPage/%s/active/validatonErrors" % id)
13
+ end
14
+
15
+ def activate_landing_page(id, options={})
16
+ post("assets/landingPage/%s/active" % id, options)
17
+ end
18
+
19
+ def get_landing_page(id)
20
+ get("assets/landingPage/%s" % id)
21
+ end
22
+
23
+ def get_landing_page_preview(id, options={})
24
+ get("assets/landingPage/%s/preview" % id, options)
25
+ end
26
+
27
+ def get_recent_landing_pages(options={})
28
+ options[:count] ||= 10
29
+ options[:depth] ||= "minimal"
30
+
31
+ get("assets/landingPages/recent", options)
32
+ end
33
+
34
+ def get_landing_pages(options={})
35
+ options[:count] ||= 10
36
+ options[:depth] ||= "minimal"
37
+ options[:orderBy] ||= "createdAt+DESC"
38
+
39
+ get("assets/landingPages", options)
40
+ end
41
+
42
+ def get_landing_page_template(id, options={})
43
+ get("assets/landingPage/template/%s" % id, options)
44
+ end
45
+
46
+ def get_landing_page_templates(options={})
47
+ get("assets/templates/landingpage", options)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,7 @@
1
+ module Eloqua
2
+ module Microsite
3
+ def get_micro_site(id)
4
+ get("assets/microsite/%s" % id)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Eloqua
2
+ module Segment
3
+ def create_segment(segment)
4
+ post("assets/contact/segment", segment)
5
+ end
6
+
7
+ def get_segment(id)
8
+ get("assets/contact/segment/%s" % id)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module Eloqua
2
+ module User
3
+ def get_user(id, options={})
4
+ get("system/user/%s" % id, options)
5
+ end
6
+
7
+ def get_users(options={})
8
+ options[:count] ||= 10
9
+ options[:depth] ||= "minimal"
10
+
11
+ get("system/users", options)
12
+ end
13
+ end
14
+ end
@@ -1,82 +1,25 @@
1
- module Eloqua
2
- class RESTClient < Eloqua::Client
3
- REST_API_PATH = "/API/REST/1.0"
4
-
5
- def rest_path(path)
6
- REST_API_PATH + '/' + path
7
- end
8
-
9
- # convenience methods
10
-
11
- # SEGMENTS
12
- def create_segment(segment_definition)
13
- # debugger
14
- post(rest_path("assets/contact/segment"), segment_definition)
15
- end
16
-
17
- def get_segment(segment_id)
18
- get(rest_path("assets/contact/segment/#{segment_id}"))
19
- end
20
-
21
- # LANDING PAGES
22
- def get_landing_page(landing_page_id)
23
- get(rest_path("assets/landingPage/#{landing_page_id}"))
24
- end
25
-
26
- def get_landing_pages(options={})
27
- options["count"] ||= 10
28
- options["depth"] ||= "minimal"
29
- options["order_by"] ||= "createdAt+DESC"
30
-
31
- query = "count=#{options["count"]}&depth=#{options["depth"]}&orderBy=#{options["order_by"]}"
32
-
33
- get(rest_path("assets/landingPages?#{query}"))
34
- end
35
-
36
- # EMAILS
37
- def get_email(email_id)
38
- get(rest_path("assets/email/#{email_id}"))
39
- end
40
-
41
- def get_emails(options={})
42
- options["count"] ||= 10
43
- options["depth"] ||= "minimal"
44
- options["order_by"] ||= "createdAt+DESC"
45
-
46
- query = "count=#{options["count"]}&depth=#{options["depth"]}&orderBy=#{options["order_by"]}"
47
-
48
- get(rest_path("assets/emails?#{query}"))
49
- end
50
-
51
- # CAMPAIGNS
52
- def get_campaign(campaign_id)
53
- get(rest_path("assets/campaign/#{campaign_id}"))
54
- end
55
-
56
- def get_recent_campaigns(options={})
57
- options["count"] ||= 10
58
- options["depth"] ||= "minimal"
59
- get(rest_path("assets/campaigns/recent?count=#{options["count"]}&depth=#{options["depth"]}"))
60
- end
61
-
62
- def get_campaigns(options={})
63
- options["count"] ||= 10
64
- options["depth"] ||= "minimal"
65
- options["order_by"] ||= "createdAt+DESC"
66
-
67
- query = "count=#{options["count"]}&depth=#{options["depth"]}&orderBy=#{options["order_by"]}"
68
-
69
- get(rest_path("assets/campaigns?#{query}"))
70
- end
1
+ require 'eloqua_api/rest/segment'
2
+ require 'eloqua_api/rest/landing_page'
3
+ require 'eloqua_api/rest/email'
4
+ require 'eloqua_api/rest/campaign'
5
+ require 'eloqua_api/rest/contact'
6
+ require 'eloqua_api/rest/user'
7
+ require 'eloqua_api/rest/microsite'
8
+ require 'eloqua_api/rest/imported_file'
71
9
 
72
- # CONTACTS
73
- def contact_activity(contact_id, options={})
74
- options["start_date"] ||= 1.year.ago.to_i
75
- options["end_date"] ||= Time.now.to_i
76
- options["type"] ||= "webVisit"
77
- options["count"] ||= 1000
78
-
79
- get(rest_path("data/activities/contact/#{contact_id}?startDate=#{options["start_date"]}&endDate=#{options["end_date"]}&type=#{options["type"]}&count=#{options["count"]}"))
10
+ module Eloqua
11
+ class RESTClient < Client
12
+ include Segment
13
+ include LandingPage
14
+ include Email
15
+ include Campaign
16
+ include Contact
17
+ include User
18
+ include Microsite
19
+ include ImportedFile
20
+
21
+ def build_path(*segments)
22
+ super('/REST/', *segments)
80
23
  end
81
24
  end
82
25
  end
data/lib/eloqua_api.rb CHANGED
@@ -1,4 +1,3 @@
1
1
  require 'eloqua_api/client'
2
2
  require 'eloqua_api/rest_client'
3
3
  require 'eloqua_api/bulk_client'
4
-
metadata CHANGED
@@ -1,11 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eloqua_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nader Akhnoukh
9
+ - Mihail Szabolcs
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
@@ -27,14 +28,56 @@ dependencies:
27
28
  - - ! '>='
28
29
  - !ruby/object:Gem::Version
29
30
  version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: httparty
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: httmultiparty
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
30
63
  description: Convenience wrapper for Eloqua REST and Bulk APIs
31
64
  email: nader@kapost.com
32
65
  executables: []
33
66
  extensions: []
34
67
  extra_rdoc_files: []
35
68
  files:
69
+ - lib/eloqua_api/bulk/export.rb
70
+ - lib/eloqua_api/bulk/sync.rb
36
71
  - lib/eloqua_api/bulk_client.rb
37
72
  - lib/eloqua_api/client.rb
73
+ - lib/eloqua_api/rest/campaign.rb
74
+ - lib/eloqua_api/rest/contact.rb
75
+ - lib/eloqua_api/rest/email.rb
76
+ - lib/eloqua_api/rest/imported_file.rb
77
+ - lib/eloqua_api/rest/landing_page.rb
78
+ - lib/eloqua_api/rest/microsite.rb
79
+ - lib/eloqua_api/rest/segment.rb
80
+ - lib/eloqua_api/rest/user.rb
38
81
  - lib/eloqua_api/rest_client.rb
39
82
  - lib/eloqua_api.rb
40
83
  homepage: http://github.com/kapost/eloqua_api