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