sailthru-client 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODBmMmIwZjBhOTdlZTdmZjEzMDFjZmEzYWVmYzM1MTZiZmI2N2FhOA==
4
+ YWFlMjgwYzY1YjJlODhhYzk1YzFkY2ZhM2ViMGE4MzkyYjQ2ZDQ3Mg==
5
5
  data.tar.gz: !binary |-
6
- ZjhhMTg5ZDBmNTlhODU1ZmJiZGZlYmExOGM0YWViNDk3ZjBjZDEzNg==
6
+ ZTY5YjllNGI5Y2MyZjY2MDMwYWE0ZDdlYzdhNDQzODA4YzRiNzc1Mg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MWFkZmE3MzMyNWFlNzk1NTc0ZGViNmNlYzI1YjVkZjdjNTAwYzc0MzRlNmJi
10
- ZDljM2MxMzQyYjRjOWIzMDQxYjkwZTU4NjdjYWRjZmM0ODVlNjA3OWE5OGRh
11
- NGUxNDI2NzY0MDBhOWIzMGE4Mjg1OWJmYWI3YjVhNjFkN2ZkZjc=
9
+ Y2Q4N2JhZWVjN2Y1ZTJjMGUzNDkxNjg0YzYyMjFjZGFmN2QzZWU3M2RlNWJl
10
+ ZGRkOWRmNmJiYjU0ZWRhZjgwMWNjMGE2Njk1ZDMxYzhiZDM4ZDgwZGM1ODdl
11
+ YTA2M2EwODJlMGI2YmIxOGU3YmJkY2U1MjFkZDEzMjUwZmI3YWU=
12
12
  data.tar.gz: !binary |-
13
- NjY4NGRhMDNjMGIwYWE0NmU4MzgwM2QyYzFhNDUwMmIzNDNlZDc3MjNmYWNm
14
- ZjQ2YjNjNTEzYzZiZjQ5MTg1YzExN2ZjMGM1YjU1OWYxNDAyMjYyYzA2MTk5
15
- ZjYwOTA2YzUwYjQwMGQyNjhjZDhlMTYyZWUyNjBlZDI0NTg5YzU=
13
+ MGY0ODNiNzNkMjYwMTQxMjU1N2NjNDA0MGJlNjlhMWM1MGU4Mjk0NjFjZDE5
14
+ ZDliZWViMGFkMmY5NDY0Y2RkZmJkOGI0MmYyMjdjMzU4ZmJhNzhjMzYxYmJk
15
+ NDBlYzMxMjA2MWE1MDg5N2ExM2YzNTY3OWE5MTA1MDRlZmIxOTY=
data/.gitignore CHANGED
@@ -4,3 +4,4 @@
4
4
  *.gem
5
5
  .loadpath
6
6
  rdoc
7
+ Gemfile.lock
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 4.0.0 (TBD)
2
+ - Rename Sailthru::SailthruClient to Sailthru::Client
3
+ - Rework custom exceptions to be StandardErrors
4
+ - Add `Sailthru.credentials` for easy initialization in Rails apps
5
+ - Split sailthru.rb into several smaller files
6
+
7
+ ## 3.0.0 (Jun 16, 2014)
8
+ - Remove Ruby 1.8.7 support.
9
+
1
10
  ## 2.0.0 (Sep 6, 2013)
2
11
  - Added triggers and events
3
12
  - Changed push_content to handle additional parameters
data/Gemfile CHANGED
@@ -1,11 +1,3 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'rake'
4
- gem 'multipart-post'
5
-
6
- group :test do
7
- gem 'json'
8
- gem 'fakeweb'
9
- gem 'minitest'
10
- gem 'mocha'
11
- end
3
+ gemspec
data/lib/sailthru.rb CHANGED
@@ -1,973 +1,31 @@
1
- require 'rubygems'
2
- require 'net/https'
3
- require 'net/http'
4
- require 'uri'
5
- require 'cgi'
6
- require 'json'
7
- require 'digest/md5'
8
- require 'net/http/post/multipart'
1
+ require 'sailthru/version'
2
+ require 'sailthru/client'
9
3
 
10
4
  module Sailthru
11
-
12
- Version = VERSION = '3.0.0'
13
-
14
- class SailthruClientException < Exception
5
+ class ClientError < StandardError
15
6
  end
16
7
 
17
- class SailthruUnavailableException < Exception
8
+ class UnavailableError < StandardError
18
9
  end
19
10
 
20
- module Helpers
21
- # params:
22
- # params, Hash
23
- # returns:
24
- # Array, values of each item in the Hash (and nested hashes)
25
- #
26
- # Extracts the values of a set of parameters, recursing into nested assoc arrays.
27
- def extract_param_values(params)
28
- values = []
29
- params.each do |k, v|
30
- if v.class == Hash
31
- values.concat extract_param_values(v)
32
- elsif v.class == Array
33
- temp_hash = Hash.new()
34
- v.each_with_index do |v_,i_|
35
- temp_hash[i_.to_s] = v_
36
- end
37
- values.concat extract_param_values(temp_hash)
38
- else
39
- values.push v.to_s
40
- end
41
- end
42
- return values
43
- end
44
-
45
- # params:
46
- # params, Hash
47
- # secret, String
48
- # returns:
49
- # String
50
- #
51
- # Returns the unhashed signature string (secret + sorted list of param values) for an API call.
52
- def get_signature_string(params, secret)
53
- return secret + extract_param_values(params).sort.join("")
54
- end
55
-
56
-
57
- # params:
58
- # params, Hash
59
- # secret, String
60
- # returns:
61
- # String
62
- #
63
- # Returns an MD5 hash of the signature string for an API call.
64
- def get_signature_hash(params, secret)
65
- Digest::MD5.hexdigest(get_signature_string(params, secret)).to_s
66
- end
67
-
68
-
69
- # Flatten nested hash for GET / POST request.
70
- def flatten_nested_hash(hash, brackets = true)
71
- f = {}
72
- hash.each do |key, value|
73
- _key = brackets ? "[#{key}]" : key.to_s
74
- if value.class == Hash
75
- flatten_nested_hash(value).each do |k, v|
76
- f["#{_key}#{k}"] = v
77
- end
78
- elsif value.class == Array
79
- temp_hash = Hash.new()
80
- value.each_with_index do |v, i|
81
- temp_hash[i.to_s] = v
82
- end
83
- flatten_nested_hash(temp_hash).each do |k, v|
84
- f["#{_key}#{k}"] = v
85
- end
86
-
87
- else
88
- f[_key] = value
89
- end
90
- end
91
- return f
92
- end
93
-
11
+ # Provides a global place to configure the credentials for an application.
12
+ # For instance, in your Rails app, create +config/initializers/sailthru.rb+
13
+ # and place this line in it:
14
+ #
15
+ # Sailthru.credentials('apikey', 'secret')
16
+ #
17
+ # Now you can create a client instance easily via Sailthru::Client.new
18
+ #
19
+ def self.credentials(api_key, secret)
20
+ @api_key = api_key
21
+ @secret = secret
94
22
  end
95
23
 
96
- class SailthruClient
97
-
98
- include Helpers
99
-
100
- attr_accessor :verify_ssl
101
-
102
- # params:
103
- # api_key, String
104
- # secret, String
105
- # api_uri, String
106
- #
107
- # Instantiate a new client; constructor optionally takes overrides for key/secret/uri and proxy server settings.
108
- def initialize(api_key, secret, api_uri=nil, proxy_host=nil, proxy_port=nil, opts={})
109
- @api_key = api_key
110
- @secret = secret
111
- @api_uri = if api_uri.nil? then 'https://api.sailthru.com' else api_uri end
112
- @proxy_host = proxy_host
113
- @proxy_port = proxy_port
114
- @verify_ssl = true
115
- @opts = opts
116
- end
117
-
118
- # params:
119
- # template_name, String
120
- # email, String
121
- # replacements, Hash
122
- # options, Hash
123
- # replyto: override Reply-To header
124
- # test: send as test email (subject line will be marked, will not count towards stats)
125
- # schedule_time, Date
126
- # returns:
127
- # Hash, response data from server
128
- #
129
- # Send a transactional email, or schedule one for the near future
130
- # http://docs.sailthru.com/api/send
131
- def send(template_name, email, vars={}, options = {}, schedule_time = nil)
132
- warn "[DEPRECATION] `send` is deprecated. Please use `send_email` instead."
133
- send_email(template_name, email, vars, options, schedule_time)
134
- end
135
-
136
- # params:
137
- # template_name, String
138
- # email, String
139
- # vars, Hash
140
- # options, Hash
141
- # replyto: override Reply-To header
142
- # test: send as test email (subject line will be marked, will not count towards stats)
143
- # returns:
144
- # Hash, response data from server
145
- def send_email(template_name, email, vars={}, options = {}, schedule_time = nil, limit = {})
146
- post = {}
147
- post[:template] = template_name
148
- post[:email] = email
149
- post[:vars] = vars if vars.length >= 1
150
- post[:options] = options if options.length >= 1
151
- post[:schedule_time] = schedule_time if !schedule_time.nil?
152
- post[:limit] = limit if limit.length >= 1
153
- return self.api_post(:send, post)
154
- end
155
-
156
-
157
- def multi_send(template_name, emails, vars={}, options = {}, schedule_time = nil, evars = {})
158
- post = {}
159
- post[:template] = template_name
160
- post[:email] = emails
161
- post[:vars] = vars if vars.length >= 1
162
- post[:options] = options if options.length >= 1
163
- post[:schedule_time] = schedule_time if !schedule_time.nil?
164
- post[:evars] = evars if evars.length >= 1
165
- return self.api_post(:send, post)
166
- end
167
-
168
-
169
- # params:
170
- # send_id, Fixnum
171
- # returns:
172
- # Hash, response data from server
173
- #
174
- # Get the status of a send.
175
- def get_send(send_id)
176
- self.api_get(:send, {:send_id => send_id.to_s})
177
- end
178
-
179
-
180
- def cancel_send(send_id)
181
- self.api_delete(:send, {:send_id => send_id.to_s})
182
- end
183
-
184
- # params:
185
- # name, String
186
- # list, String
187
- # schedule_time, String
188
- # from_name, String
189
- # from_email, String
190
- # subject, String
191
- # content_html, String
192
- # content_text, String
193
- # options, Hash
194
- # returns:
195
- # Hash, response data from server
196
- #
197
- # Schedule a mass mail blast
198
- def schedule_blast(name, list, schedule_time, from_name, from_email, subject, content_html, content_text, options = {})
199
- post = options ? options : {}
200
- post[:name] = name
201
- post[:list] = list
202
- post[:schedule_time] = schedule_time
203
- post[:from_name] = from_name
204
- post[:from_email] = from_email
205
- post[:subject] = subject
206
- post[:content_html] = content_html
207
- post[:content_text] = content_text
208
- api_post(:blast, post)
209
- end
210
-
211
- # Schedule a mass mail blast from template
212
- def schedule_blast_from_template(template, list, schedule_time, options={})
213
- post = options ? options : {}
214
- post[:copy_template] = template
215
- post[:list] = list
216
- post[:schedule_time] = schedule_time
217
- api_post(:blast, post)
218
- end
219
-
220
- # Schedule a mass mail blast from previous blast
221
- def schedule_blast_from_blast(blast_id, schedule_time, options={})
222
- post = options ? options : {}
223
- post[:copy_blast] = blast_id
224
- #post[:name] = name
225
- post[:schedule_time] = schedule_time
226
- api_post(:blast, post)
227
- end
228
-
229
-
230
- # params
231
- # blast_id, Fixnum | String
232
- # name, String
233
- # list, String
234
- # schedule_time, String
235
- # from_name, String
236
- # from_email, String
237
- # subject, String
238
- # content_html, String
239
- # content_text, String
240
- # options, hash
241
- #
242
- # updates existing blast
243
- def update_blast(blast_id, name = nil, list = nil, schedule_time = nil, from_name = nil, from_email = nil, subject = nil, content_html = nil, content_text = nil, options = {})
244
- data = options ? options : {}
245
- data[:blast_id] = blast_id
246
- if name != nil
247
- data[:name] = name
248
- end
249
- if list != nil
250
- data[:list] = list
251
- end
252
- if schedule_time != nil
253
- data[:schedule_time] = schedule_time
254
- end
255
- if from_name != nil
256
- data[:from_name] = from_name
257
- end
258
- if from_email != nil
259
- data[:from_email] = from_email
260
- end
261
- if subject != nil
262
- data[:subject] = subject
263
- end
264
- if content_html != nil
265
- data[:content_html] = content_html
266
- end
267
- if content_text != nil
268
- data[:content_text] = content_text
269
- end
270
- api_post(:blast, data)
271
- end
272
-
273
-
274
- # params:
275
- # blast_id, Fixnum | String
276
- # options, hash
277
- # returns:
278
- # Hash, response data from server
279
- #
280
- # Get information on a previously scheduled email blast
281
- def get_blast(blast_id, options={})
282
- options[:blast_id] = blast_id.to_s
283
- api_get(:blast, options)
284
- end
285
-
286
- # params:
287
- # blast_id, Fixnum | String
288
- #
289
- # Cancel a scheduled Blast
290
- def cancel_blast(blast_id)
291
- api_post(:blast, {:blast_id => blast_id, :schedule_time => ''})
292
- end
293
-
294
- # params:
295
- # blast_id, Fixnum | String
296
- #
297
- # Delete a Blast
298
- def delete_blast(blast_id)
299
- api_delete(:blast, {:blast_id => blast_id})
300
- end
301
-
302
- # params:
303
- # email, String
304
- # returns:
305
- # Hash, response data from server
306
- #
307
- # Return information about an email address, including replacement vars and lists.
308
- def get_email(email)
309
- api_get(:email, {:email => email})
310
- end
311
-
312
- # params:
313
- # email, String
314
- # vars, Hash
315
- # lists, Hash mapping list name => 1 for subscribed, 0 for unsubscribed
316
- # options, Hash mapping optional parameters
317
- # returns:
318
- # Hash, response data from server
319
- #
320
- # Set replacement vars and/or list subscriptions for an email address.
321
- def set_email(email, vars = {}, lists = {}, templates = {}, options = {})
322
- data = options
323
- data[:email] = email
324
- data[:vars] = vars unless vars.empty?
325
- data[:lists] = lists unless lists.empty?
326
- data[:templates] = templates unless templates.empty?
327
- self.api_post(:email, data)
328
- end
329
-
330
- # params:
331
- # new_email, String
332
- # old_email, String
333
- # options, Hash mapping optional parameters
334
- # returns:
335
- # Hash of response data.
336
- #
337
- # change a user's email address.
338
- def change_email(new_email, old_email, options = {})
339
- data = options
340
- data[:email] = new_email
341
- data[:change_email] = old_email
342
- self.api_post(:email, data)
343
- end
344
-
345
- # params:
346
- # template_name, String
347
- # returns:
348
- # Hash of response data.
349
- #
350
- # Get a template.
351
- def get_template(template_name)
352
- self.api_get(:template, {:template => template_name})
353
- end
354
-
355
-
356
- # params:
357
- # template_name, String
358
- # template_fields, Hash
359
- # returns:
360
- # Hash containg response from the server.
361
- #
362
- # Save a template.
363
- def save_template(template_name, template_fields)
364
- data = template_fields
365
- data[:template] = template_name
366
- self.api_post(:template, data)
367
- end
368
-
369
- # params:
370
- # template_name, String
371
- # returns:
372
- # Hash of response data.
373
- #
374
- # Delete a template.
375
- def delete_template(template_name)
376
- self.api_delete(:template, {:template => template_name})
377
- end
378
-
379
-
380
- # params:
381
- # params, Hash
382
- # request, String
383
- # returns:
384
- # TrueClass or FalseClass, Returns true if the incoming request is an authenticated verify post.
385
- def receive_verify_post(params, request)
386
- if request.post?
387
- [:action, :email, :send_id, :sig].each { |key| return false unless params.has_key?(key) }
388
-
389
- return false unless params[:action] == :verify
390
-
391
- sig = params.delete(:sig)
392
- sig = sig.delete_if {|key, value| key == :controller}
393
- return false unless sig == get_signature_hash(params, @secret)
394
-
395
- _send = self.get_send(params[:send_id])
396
- return false unless _send.has_key?(:email)
397
-
398
- return false unless _send[:email] == params[:email]
399
-
400
- return true
401
- else
402
- return false
403
- end
404
- end
405
-
406
- # params:
407
- # params, Hash
408
- # request, String
409
- # returns:
410
- # TrueClass or FalseClass, Returns true if the incoming request is an authenticated optout post.
411
- def receive_optout_post(params, request)
412
- if request.post?
413
- [:action, :email, :sig].each { |key| return false unless params.has_key?(key) }
414
-
415
- return false unless params[:action] == 'optout'
416
-
417
- sig = params.delete(:sig)
418
- sig = sig.delete_if {|key, value| key == :controller}
419
- return false unless sig == get_signature_hash(params, @secret)
420
- return true
421
- else
422
- return false
423
- end
424
- end
425
-
426
- # params:
427
- # params, Hash
428
- # request, String
429
- # returns:
430
- # TrueClass or FalseClass, Returns true if the incoming request is an authenticated hardbounce post.
431
- def receive_hardbounce_post(params, request)
432
- if request.post?
433
- [:action, :email, :sig].each { |key| return false unless params.has_key?(key) }
434
-
435
- return false unless params[:action] == 'hardbounce'
436
-
437
- sig = params.delete(:sig)
438
- sig = sig.delete_if {|key, value| key == :controller}
439
- return false unless sig == get_signature_hash(params, @secret)
440
- return true
441
- else
442
- return false
443
- end
444
- end
445
-
446
- # params:
447
- # email, String
448
- # items, String
449
- # incomplete, Integer
450
- # message_id, String
451
- # options, Hash
452
- # returns:
453
- # hash, response from server
454
- #
455
- # Record that a user has made a purchase, or has added items to their purchase total.
456
- def purchase(email, items, incomplete = nil, message_id = nil, options = {})
457
- data = options
458
- data[:email] = email
459
- data[:items] = items
460
-
461
- if incomplete != nil
462
- data[:incomplete] = incomplete.to_i
463
- end
464
-
465
- if message_id != nil
466
- data[:message_id] = message_id
467
- end
468
- api_post(:purchase, data)
469
- end
470
-
471
-
472
- # <b>DEPRECATED:</b> Please use either stats_list or stats_blast
473
- # params:
474
- # stat, String
475
- #
476
- # returns:
477
- # hash, response from server
478
- # Request various stats from Sailthru.
479
- def get_stats(stat)
480
- warn "[DEPRECATION] `get_stats` is deprecated. Please use `stats_list` and `stats_blast` instead"
481
- api_get(:stats, {:stat => stat})
482
- end
483
-
484
-
485
- # params
486
- # list, String
487
- # date, String
488
- #
489
- # returns:
490
- # hash, response from server
491
- # Retrieve information about your subscriber counts on a particular list, on a particular day.
492
- def stats_list(list = nil, date = nil)
493
- data = {}
494
- if list != nil
495
- data[:list] = list
496
- end
497
- if date != nil
498
- data[:date] = date
499
- end
500
- data[:stat] = 'list'
501
- stats(data)
502
- end
503
-
504
-
505
- # params
506
- # blast_id, String
507
- # start_date, String
508
- # end_date, String
509
- # options, Hash
510
- #
511
- # returns:
512
- # hash, response from server
513
- # Retrieve information about a particular blast or aggregated information from all of blasts over a specified date range
514
- def stats_blast(blast_id = nil, start_date = nil, end_date = nil, options = {})
515
- data = options
516
- if blast_id != nil
517
- data[:blast_id] = blast_id
518
- end
519
- if start_date != nil
520
- data[:start_date] = start_date
521
- end
522
- if end_date != nil
523
- data[:end_date] = end_date
524
- end
525
- data[:stat] = 'blast'
526
- stats(data)
527
- end
528
-
529
- # params
530
- # template, String
531
- # start_date, String
532
- # end_date, String
533
- # options, Hash
534
- #
535
- # returns:
536
- # hash, response from server
537
- # Retrieve information about a particular blast or aggregated information from all of blasts over a specified date range
538
- def stats_send(template = nil, start_date = nil, end_date = nil, options = {})
539
- data = options
540
- if template != nil
541
- data[:template] = template
542
- end
543
- if start_date != nil
544
- data[:start_date] = start_date
545
- end
546
- if end_date != nil
547
- data[:end_date] = end_date
548
- end
549
- data[:stat] = 'send'
550
- stats(data)
551
- end
552
-
553
-
554
- # params
555
- # title, String
556
- # url, String
557
- # date, String
558
- # tags, Array or Comma separated string
559
- # vars, Hash
560
- # options, Hash
561
- #
562
- # Push a new piece of content to Sailthru, triggering any applicable alerts.
563
- # http://docs.sailthru.com/api/content
564
- def push_content(title, url, date = nil, tags = nil, vars = {}, options = {})
565
- data = options
566
- data[:title] = title
567
- data[:url] = url
568
- if date != nil
569
- data[:date] = date
570
- end
571
- if tags != nil
572
- if tags.class == Array
573
- tags = tags.join(',')
574
- end
575
- data[:tags] = tags
576
- end
577
- if vars.length > 0
578
- data[:vars] = vars
579
- end
580
- api_post(:content, data)
581
- end
582
-
583
- # params
584
- # list, String
585
- #
586
- # Get information about a list.
587
- def get_list(list)
588
- return api_get(:list, {:list => list})
589
- end
590
-
591
- # params
592
- #
593
- # Get information about all lists
594
- def get_lists()
595
- return api_get(:list, {})
596
- end
597
-
598
- # params
599
- # list, String
600
- # options, Hash
601
- # Create a list, or update a list.
602
- def save_list(list, options = {})
603
- data = options
604
- data[:list] = list
605
- return api_post(:list, data)
606
- end
607
-
608
- # params
609
- # list, String
610
- #
611
- # Deletes a list
612
- def delete_list(list)
613
- api_delete(:list, {:list => list})
614
- end
615
-
616
- # params
617
- # email, String
618
- #
619
- # get user alert data
620
- def get_alert(email)
621
- api_get(:alert, {:email => email})
622
- end
623
-
624
- # params
625
- # email, String
626
- # type, String
627
- # template, String
628
- # _when, String
629
- # options, hash
630
- #
631
- # Add a new alert to a user. You can add either a realtime or a summary alert (daily/weekly).
632
- # _when is only required when alert type is weekly or daily
633
- def save_alert(email, type, template, _when = nil, options = {})
634
- data = options
635
- data[:email] = email
636
- data[:type] = type
637
- data[:template] = template
638
- if (type == 'weekly' || type == 'daily')
639
- data[:when] = _when
640
- end
641
- api_post(:alert, data)
642
- end
643
-
644
-
645
- # params
646
- # email, String
647
- # alert_id, String
648
- #
649
- # delete user alert
650
- def delete_alert(email, alert_id)
651
- data = {:email => email, :alert_id => alert_id}
652
- api_delete(:alert, data)
653
- end
654
-
655
- # Make Stats API Request
656
- def stats(data)
657
- api_get(:stats, data)
658
- end
659
-
660
- # params
661
- # job, String
662
- # options, hash
663
- # report_email, String
664
- # postback_url, String
665
- # binary_key, String
666
- #
667
- # interface for making request to job call
668
- def process_job(job, options = {}, report_email = nil, postback_url = nil, binary_key = nil)
669
- data = options
670
- data['job'] = job
671
- if !report_email.nil?
672
- data['report_email'] = report_email
673
- end
674
-
675
- if !postback_url.nil?
676
- data['postback_url'] = postback_url
677
- end
678
- api_post(:job, data, binary_key)
679
- end
680
-
681
- # params
682
- # emails, String | Array
683
- # implementation for import_job
684
- def process_import_job(list, emails, report_email = nil, postback_url = nil, options = {})
685
- data = options
686
- data['list'] = list
687
- data['emails'] = Array(emails).join(',')
688
- process_job(:import, data, report_email, postback_url)
689
- end
690
-
691
- # implementation for import job using file upload
692
- def process_import_job_from_file(list, file_path, report_email = nil, postback_url = nil, options = {})
693
- data = options
694
- data['list'] = list
695
- data['file'] = file_path
696
- process_job(:import, data, report_email, postback_url, 'file')
697
- end
698
-
699
- # implementation for update job using file upload
700
- def process_update_job_from_file(file_path, report_email = nil, postback_url = nil, options = {})
701
- data = options
702
- data['file'] = file_path
703
- process_job(:update, data, report_email, postback_url, 'file')
704
- end
705
-
706
- # implementation for snapshot job
707
- def process_snapshot_job(query = {}, report_email = nil, postback_url = nil, options = {})
708
- data = options
709
- data['query'] = query
710
- process_job(:snapshot, data, report_email, postback_url)
711
- end
712
-
713
- # implementation for export list job
714
- def process_export_list_job(list, report_email = nil, postback_url = nil, options = {})
715
- data = options
716
- data['list'] = list
717
- process_job(:export_list_data, data, report_email, postback_url)
718
- end
719
-
720
- # get status of a job
721
- def get_job_status(job_id)
722
- api_get(:job, {'job_id' => job_id})
723
- end
724
-
725
- # Get user by Sailthru ID
726
- def get_user_by_sid(id, fields = {})
727
- api_get(:user, {'id' => id, 'fields' => fields})
728
- end
729
-
730
- # Get user by specified key
731
- def get_user_by_key(id, key, fields = {})
732
- data = {
733
- 'id' => id,
734
- 'key' => key,
735
- 'fields' => fields
736
- }
737
- api_get(:user, data)
738
- end
739
-
740
- # Create new user, or update existing user
741
- def save_user(id, options = {})
742
- data = options
743
- data['id'] = id
744
- api_post(:user, data)
745
- end
746
-
747
- # params
748
- # Get an existing trigger
749
- def get_triggers()
750
- api_get(:trigger, {})
751
- end
752
-
753
- # params
754
- # template, String
755
- # trigger_id, String
756
- # Get an existing trigger
757
- def get_trigger_by_template(template, trigger_id = nil)
758
- data = {}
759
- data['template'] = template
760
- if trigger_id != nil then data['trigger_id'] = trigger_id end
761
- api_get(:trigger, data)
762
- end
763
-
764
- # params
765
- # event, String
766
- # Get an existing trigger
767
- def get_trigger_by_event(event)
768
- data = {}
769
- data['event'] = event
770
- api_get(:trigger, data)
771
- end
772
-
773
- # params
774
- # template, String
775
- # time, String
776
- # time_unit, String
777
- # event, String
778
- # zephyr, String
779
- # Create or update a trigger
780
- def post_template_trigger(template, time, time_unit, event, zephyr)
781
- data = {}
782
- data['template'] = template
783
- data['time'] = time
784
- data['time_unit'] = time_unit
785
- data['event'] = event
786
- data['zephyr'] = zephyr
787
- api_post(:trigger, data)
788
- end
789
-
790
- # params
791
- # template, String
792
- # time, String
793
- # time_unit, String
794
- # zephyr, String
795
- # Create or update a trigger
796
- def post_event_trigger(event, time, time_unit, zephyr)
797
- data = {}
798
- data['time'] = time
799
- data['time_unit'] = time_unit
800
- data['event'] = event
801
- data['zephyr'] = zephyr
802
- api_post(:trigger, data)
803
- end
804
-
805
- # params
806
- # id, String
807
- # event, String
808
- # options, Hash (Can contain vars, Hash and/or key)
809
- # Notify Sailthru of an Event
810
- def post_event(id, event, options = {})
811
- data = options
812
- data['id'] = id
813
- data['event'] = event
814
- api_post(:event, data)
815
- end
816
-
817
- # Perform API GET request
818
- def api_get(action, data)
819
- api_request(action, data, 'GET')
820
- end
821
-
822
- # Perform API POST request
823
- def api_post(action, data, binary_key = nil)
824
- api_request(action, data, 'POST', binary_key)
825
- end
826
-
827
- #Perform API DELETE request
828
- def api_delete(action, data)
829
- api_request(action, data, 'DELETE')
830
- end
831
-
832
- protected
833
-
834
- # params:
835
- # action, String
836
- # data, Hash
837
- # request, String "GET" or "POST"
838
- # returns:
839
- # Hash
840
- #
841
- # Perform an API request, using the shared-secret auth hash.
842
- #
843
- def api_request(action, data, request_type, binary_key = nil)
844
- if (!binary_key.nil?)
845
- binary_key_data = data[binary_key]
846
- data.delete(binary_key)
847
- end
848
-
849
- if data[:format].nil? or data[:format] == 'json'
850
- data = self.prepare_json_payload(data)
851
- else
852
- data[:api_key] = @api_key
853
- data[:format] ||= 'json'
854
- data[:sig] = get_signature_hash(data, @secret)
855
- end
856
-
857
- if (!binary_key.nil?)
858
- data[binary_key] = binary_key_data
859
- end
860
- _result = self.http_request("#{@api_uri}/#{action}", data, request_type, binary_key)
861
-
862
- # NOTE: don't do the unserialize here
863
- if data[:format] == 'json'
864
- begin
865
- unserialized = JSON.parse(_result)
866
- return unserialized ? unserialized : _result
867
- rescue JSON::JSONError => e
868
- return {'error' => e}
869
- end
870
- end
871
- return _result
872
- end
873
-
874
- # set up our post request
875
- def set_up_post_request(uri, data, headers, binary_key = nil)
876
- if (!binary_key.nil?)
877
- binary_data = data[binary_key]
878
-
879
- if binary_data.is_a?(StringIO)
880
- data[binary_key] = UploadIO.new(
881
- binary_data, "text/plain", "local.path"
882
- )
883
- else
884
- data[binary_key] = UploadIO.new(
885
- File.open(binary_data), "text/plain"
886
- )
887
- end
888
-
889
- req = Net::HTTP::Post::Multipart.new(uri.path, data)
890
- else
891
- req = Net::HTTP::Post.new(uri.path, headers)
892
- req.set_form_data(data)
893
- end
894
- req
895
- end
896
-
897
- # params:
898
- # uri, String
899
- # data, Hash
900
- # method, String "GET" or "POST"
901
- # returns:
902
- # String, body of response
903
- def http_request(uri, data, method = 'POST', binary_key = nil)
904
- data = flatten_nested_hash(data, false)
905
-
906
- if method != 'POST'
907
- uri += "?" + data.map{ |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}" }.join("&")
908
- end
909
-
910
- req = nil
911
- headers = {"User-Agent" => "Sailthru API Ruby Client #{VERSION}"}
912
-
913
- _uri = URI.parse(uri)
914
-
915
- if method == 'POST'
916
- req = self.set_up_post_request(
917
- _uri, data, headers, binary_key
918
- )
919
-
920
- else
921
- request_uri = "#{_uri.path}?#{_uri.query}"
922
- if method == 'DELETE'
923
- req = Net::HTTP::Delete.new(request_uri, headers)
924
- else
925
- req = Net::HTTP::Get.new(request_uri, headers)
926
- end
927
- end
928
-
929
- begin
930
- http = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(_uri.host, _uri.port)
931
-
932
- if _uri.scheme == 'https'
933
- http.use_ssl = true
934
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @verify_ssl != true # some openSSL client doesn't work without doing this
935
- http.ssl_timeout = @opts[:http_ssl_timeout] || 5
936
- end
937
- http.open_timeout = @opts[:http_open_timeout] || 5
938
- http.read_timeout = @opts[:http_read_timeout] || 10
939
- http.close_on_empty_response = @opts[:http_close_on_empty_response] || true
940
-
941
- response = http.start {
942
- http.request(req)
943
- }
944
-
945
- rescue Timeout::Error, Errno::ETIMEDOUT => e
946
- raise SailthruUnavailableException.new(["Timed out: #{_uri}", e.inspect, e.backtrace].join("\n"));
947
- rescue Exception => e
948
- raise SailthruClientException.new(["Unable to open stream: #{_uri}", e.inspect, e.backtrace].join("\n"));
949
- end
950
-
951
- if response.body
952
- return response.body
953
- else
954
- raise SailthruClientException.new("No response received from stream: #{_uri}")
955
- end
956
- end
957
-
958
- def http_multipart_request(uri, data)
959
- Net::HTTP::Post::Multipart.new url.path,
960
- "file" => UploadIO.new(data['file'], "application/octet-stream")
961
- end
24
+ def self.api_key
25
+ @api_key
26
+ end
962
27
 
963
- def prepare_json_payload(data)
964
- payload = {
965
- :api_key => @api_key,
966
- :format => 'json', #<3 XML
967
- :json => data.to_json
968
- }
969
- payload[:sig] = get_signature_hash(payload, @secret)
970
- payload
971
- end
28
+ def self.secret
29
+ @secret
972
30
  end
973
31
  end