sift_email_api 1.0.0

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 (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/sift_email_api.rb +303 -0
  3. metadata +61 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 69ef784ab8e62153a07c33cac5eda53889999787
4
+ data.tar.gz: 4b8f509c4224226f7283a4d5edd02fcd6ab16262
5
+ SHA512:
6
+ metadata.gz: feb3e9a77bfe773bcff8ff687eae3bc2683e46472237369b68c87d42da9743efd75ff2dca73b7aa18eba0d754f30ed18f9169f08ab668c7ea47272d3b3355c25
7
+ data.tar.gz: 1273909567f96b406e7b692b71564a4b6560183c561646dd7ada079d366e39349730540ed2ecc0cb654282b1437e473c9f40a8f5bf38b10b2210c31006cbb652
@@ -0,0 +1,303 @@
1
+ require 'net/http'
2
+ require 'openssl'
3
+ require 'json'
4
+ require 'uri'
5
+ require 'connection_pool'
6
+
7
+ class SiftEmailApi
8
+ # @private
9
+ @@api_endpoint='api.easilydo.com'
10
+ # @private
11
+ @@conn_pool = ConnectionPool.new(size: 20, timeout: 30) do
12
+ http = Net::HTTP.new(@@api_endpoint, 443)
13
+ http.use_ssl=true
14
+ http
15
+ end
16
+
17
+ # Sole constructor
18
+ #
19
+ # @param api_key [String] sift developer's api key
20
+ # @param secret_key [String] sift developer's secret key
21
+ def initialize(api_key, secret_key)
22
+ @api_key=api_key
23
+ @secret_key=secret_key
24
+ end
25
+
26
+ # Get a list of sifts for the given user
27
+ #
28
+ # @param username [String] username of the user to fetch sifts for
29
+ # @param last_update_time [Time] only return sifts updated since this date
30
+ # @param offset [Integer] used for paging, where to start
31
+ # @param limit [Integer] maximum number of results to return
32
+ # @return [Array] list of sifts in descending order of last update time, available fields documented here: {https://developer.easilydo.com/sift/documentation#flights}
33
+ def list_sifts(username, last_update_time=nil, offset=nil, limit=nil)
34
+ path = '/v1/users/%s/sifts' % username
35
+ params = {}
36
+
37
+ if last_update_time
38
+ params['last_update_time'] = last_update_time.to_i()
39
+ end
40
+
41
+ if offset
42
+ params['offset'] = offset
43
+ end
44
+
45
+ if limit
46
+ params['limit'] = limit
47
+ end
48
+
49
+ add_common_params('GET', path, params)
50
+
51
+ uri = URI::HTTPS.build({:host => @@api_endpoint, :path => path, :query => URI.encode_www_form(params)})
52
+ request = Net::HTTP::Get.new uri
53
+
54
+ execute_request(request)
55
+ end
56
+
57
+ # Get a particular sift
58
+ #
59
+ # @param username [String] username of the user to fetch sifts for
60
+ # @param sift_id [Integer] numeric id of the sift to be fetched
61
+ # @return [Hash] the sift corresponding to the provided id, available fields (by domain) documented here: {https://developer.easilydo.com/sift/documentation#flights}
62
+ def get_sift(username, sift_id)
63
+ path = '/v1/users/%s/sifts/%d' % [username, sift_id]
64
+ params = {}
65
+
66
+ add_common_params('GET', path, params)
67
+
68
+ uri = URI::HTTPS.build({:host => @@api_endpoint, :path => path, :query => URI.encode_www_form(params)})
69
+ request = Net::HTTP::Get.new uri
70
+
71
+ execute_request(request)
72
+ end
73
+
74
+ # Register a new user
75
+ #
76
+ # @param username [String] username of the new user
77
+ # @param locale [String] locale of the new user
78
+ # @return [Integer] the numeric user id of the newly created user
79
+ def add_user(username, locale)
80
+ path = '/v1/users'
81
+ params = {'username' => username, 'locale' => locale}
82
+
83
+ add_common_params('POST', path, params)
84
+
85
+ request = Net::HTTP::Post.new path
86
+ request.set_form_data params
87
+
88
+ execute_request(request)
89
+ end
90
+
91
+ # Deletes a user
92
+ #
93
+ # @param username [String] username of the user to delete
94
+ def delete_user(username)
95
+ path = '/v1/users/%s' % username
96
+ params = {}
97
+
98
+ add_common_params('DELETE', path, params)
99
+
100
+ request = Net::HTTP::Delete.new path
101
+ request.set_form_data params
102
+
103
+ execute_request(request)
104
+ end
105
+
106
+ # List a user's email connections
107
+ #
108
+ # @param username [String] username of the new user
109
+ # @return [Array] the list of the user's connections
110
+ def list_connections(username, offset=nil, limit=nil)
111
+ path = '/v1/users/%s/email_connections' % username
112
+ params = {}
113
+
114
+ if offset
115
+ params['offset'] = offset
116
+ end
117
+
118
+ if limit
119
+ params['limit'] = limit
120
+ end
121
+
122
+ add_common_params('GET', path, params)
123
+
124
+ uri = URI::HTTPS.build({:host => @@api_endpoint, :path => path, :query => URI.encode_www_form(params)})
125
+ request = Net::HTTP::Get.new uri
126
+
127
+ execute_request(request)
128
+ end
129
+
130
+ # Add a Gmail connection to the given user account
131
+ #
132
+ # @param username [String] username of the user
133
+ # @param account [String] email address
134
+ # @param refresh_token [String] oauth refresh token of the account
135
+ # @return [Integer] a generated numeric id for the connection
136
+ def add_gmail_connection(username, account, refresh_token)
137
+ credentials = {'refresh_token' => refresh_token}
138
+ add_email_connection(username, account, 'google', credentials)
139
+ end
140
+
141
+ # Add a Yahoo connection to the given user account
142
+ #
143
+ # @param username [String] username of the user
144
+ # @param account [String] email address
145
+ # @param refresh_token [String] oauth refresh token of the account
146
+ # @param redirect_uri [String] redirect uri of the account
147
+ # @return [Integer] a generated numeric id for the connection
148
+ def add_yahoo_connection(username, account, refresh_token, redirect_uri)
149
+ credentials = {'refresh_token' => refresh_token, 'redirect_uri' => redirect_uri}
150
+ add_email_connection(username, account, 'yahoo', credentials)
151
+ end
152
+
153
+ # Add a Microsoft Live connection to the given user account
154
+ #
155
+ # @param username [String] username of the user
156
+ # @param account [String] email address
157
+ # @param refresh_token [String] oauth refresh token of the account
158
+ # @param redirect_uri [String] redirect uri of the account
159
+ # @return [Integer] a generated numeric id for the connection
160
+ def add_live_connection(username, account, refresh_token, redirect_uri)
161
+ credentials = {'refresh_token' => refresh_token, 'redirect_uri' => redirect_uri}
162
+ add_email_connection(username, account, 'live', credentials)
163
+ end
164
+
165
+ # Add an imap connection to the given user account
166
+ # @param username [String] username of the user
167
+ # @param account [String] email address
168
+ # @param password [String] password for the email account
169
+ # @param host [String] imap host to connect to
170
+ # @return [Integer] a generated numeric id for the connection
171
+ def add_imap_connection(username, account, password, host)
172
+ credentials = {'password' => password, 'host' => host}
173
+ add_email_connection(username, account, 'imap', credentials)
174
+ end
175
+
176
+ # Add a Microsoft Exchange connection to the given user account.
177
+ # Sift will attempt to autodiscover the host and account name
178
+ #
179
+ # @param username [String] username of the user
180
+ # @param email [String] email address
181
+ # @param password [String] password for the email account
182
+ # @return [Integer] a generated numeric id for the connection
183
+ def add_exchange_connection(username, email, password, account, host=nil)
184
+ credentials = {'email' => email, 'password' => password}
185
+
186
+ if host
187
+ credentials['host'] = host
188
+ end
189
+
190
+ add_email_connection(username, account, 'exchange', credentials)
191
+ end
192
+
193
+ def add_email_connection(username, account, type, credentials)
194
+ path = '/v1/users/%s/email_connections' % username
195
+ params = credentials.clone()
196
+ params['account_type'] = type
197
+ params['account'] = account
198
+
199
+ add_common_params('POST', path, params)
200
+
201
+ request = Net::HTTP::Post.new path
202
+ request.set_form_data params
203
+
204
+ execute_request(request)
205
+ end
206
+
207
+ # Deletes an email connection
208
+ #
209
+ # @param username [String] username of the user to delete
210
+ # @param conn_id [Integer] numeric id of the email connection
211
+ def delete_connection(username, conn_id)
212
+ path = '/v1/users/%s/email_connections/%d' % [username, conn_id]
213
+ params = {}
214
+
215
+ add_common_params('DELETE', path, params)
216
+
217
+ request = Net::HTTP::Delete.new path
218
+ request.set_form_data params
219
+
220
+ execute_request(request)
221
+ end
222
+
223
+ # Extracts available domain data from the provided eml file.
224
+ #
225
+ # @param eml_str [String] the eml file
226
+ # @return [Array] list of sifts objects with extracted data
227
+ def discovery(eml_str)
228
+ path = '/v1/discovery'
229
+ params = {'email' => eml_str.strip}
230
+
231
+ add_common_params('POST', path, params)
232
+
233
+ request = Net::HTTP::Post.new path
234
+ request.set_form_data params
235
+
236
+ execute_request(request)
237
+ end
238
+
239
+ # Used to notify the Sift development team of emails that were not parsed correctly
240
+ #
241
+ # @param eml_str [String] the eml file
242
+ # @param locale [String] locale of the email
243
+ # @param timezone [String] timezone of the email
244
+ # @return [Hash] contains 2 boolean entries: "classfied" and "extracted"
245
+ def feedback(eml_str, locale, timezone)
246
+ path = '/v1/feedback'
247
+ params = {'email' => eml_str.strip, 'locale' => locale, 'timezone' => timezone}
248
+
249
+ add_common_params('POST', path, params)
250
+
251
+ request = Net::HTTP::Post.new path
252
+ request.set_form_data params
253
+
254
+ execute_request(request)
255
+ end
256
+
257
+ def execute_request(request)
258
+ response = @@conn_pool.with do |conn|
259
+ conn.request(request)
260
+ end
261
+
262
+ #response = Net::HTTP.start(@@api_endpoint, 443, :use_ssl => true) do |http|
263
+ # http.request(req)
264
+ #end
265
+
266
+ case response
267
+ when Net::HTTPClientError, Net::HTTPServerError
268
+ msg = 'Sift API call failed ' + response.inspect()
269
+ #$logger.error(msg)
270
+ raise msg
271
+ end
272
+
273
+ root = JSON.parse(response.body)
274
+
275
+ code = root['code'].to_i()
276
+
277
+ if code >= 400
278
+ msg = "Json response error from sift server. requestId: #{root['id']}, code: #{code}, msg :#{root['message']}}"
279
+ raise msg
280
+ end
281
+
282
+ root['result']
283
+ end
284
+
285
+ def add_common_params(method, path, params)
286
+ params['api_key'] = @api_key
287
+ params['timestamp'] = Time.now.to_i.to_s
288
+ params['signature'] = get_signature(method, path, params)
289
+ end
290
+
291
+ def get_signature(method, path, params)
292
+ base = "#{method}&#{path}"
293
+ params.keys.sort.each { |name|
294
+ base << "&#{name}=#{params[name]}"
295
+ }
296
+
297
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, @secret_key.encode('utf-8'), base.encode('utf-8'))
298
+ end
299
+
300
+ protected :add_common_params, :execute_request, :add_email_connection
301
+ private :get_signature
302
+ end
303
+
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sift_email_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Carl Stritter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: connection_pool
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
27
+ description: Sift identifies certain types of emails and parses email content so you
28
+ can deliver a richer experience to your users. Sift can parse emails from a variety
29
+ of domains.
30
+ email: carl@easilydo.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - lib/sift_email_api.rb
36
+ homepage: https://developer.easilydo.com/sift/documentation
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: 2.0.0
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.0.14
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Ruby class for doing email parsing using EasilyDo's Sift API
60
+ test_files: []
61
+ has_rdoc: